[NETSHELL] Rewrite how pidls are created and accessed.

What we did before was completely wrong as we stored pointers in the pidl.
This commit is contained in:
Giannis Adamopoulos 2018-11-12 22:52:57 +02:00
parent 769b102e5f
commit 21a5a559f2
3 changed files with 231 additions and 324 deletions

View file

@ -7,24 +7,118 @@
#include "precomp.h" #include "precomp.h"
PNETCONIDSTRUCT ILGetConnData(PCITEMID_CHILD pidl)
typedef struct tagGUIDStruct
{ {
BYTE dummy; /* offset 01 is unknown */ if (!pidl || !pidl->mkid.cb || pidl->mkid.abID[0] != 0x99)
GUID guid; /* offset 02 */ return NULL;
} GUIDStruct; return (PNETCONIDSTRUCT)(&pidl->mkid.abID[0]);
}
#define PT_GUID 0x1F PWCHAR ILGetConnName(PCITEMID_CHILD pidl)
typedef struct tagPIDLDATA
{ {
BYTE type; /*00*/ PNETCONIDSTRUCT pdata = ILGetConnData(pidl);
union if (!pdata)
return NULL;
return (PWCHAR)&pidl->mkid.abID[pdata->uNameOffset];
}
PWCHAR ILGetDeviceName(PCITEMID_CHILD pidl)
{
PNETCONIDSTRUCT pdata = ILGetConnData(pidl);
if (!pdata)
return NULL;
return (PWCHAR)&pidl->mkid.abID[pdata->uDeviceNameOffset];
}
PITEMID_CHILD ILCreateNetConnectItem(INetConnection * pItem)
{
PITEMID_CHILD pidl;
ULONG_PTR size;
NETCON_PROPERTIES * pProperties;
PNETCONIDSTRUCT pnetid;
PWCHAR pwchName;
if (pItem->GetProperties(&pProperties) != S_OK)
return NULL;
size = sizeof(WORD); /* nr of bytes in this item */
size += sizeof(NETCONIDSTRUCT);
size += (wcslen(pProperties->pszwName) + 1) * sizeof(WCHAR);
size += (wcslen(pProperties->pszwDeviceName) + 1) * sizeof(WCHAR);
/* Allocate enough memory for the trailing id which will indicate that this is a simple id */
pidl = static_cast<LPITEMIDLIST>(SHAlloc(size + sizeof(SHITEMID)));
pidl->mkid.cb = (WORD)size;
pidl->mkid.abID[0] = 0x99;
/* Copy the connection properties */
pnetid = ILGetConnData(pidl);
pnetid->guidId = pProperties->guidId;
pnetid->Status = pProperties->Status;
pnetid->MediaType = pProperties->MediaType;
pnetid->dwCharacter = pProperties->dwCharacter;
pnetid->uNameOffset = sizeof(NETCONIDSTRUCT);
pnetid->uDeviceNameOffset = pnetid->uNameOffset + (wcslen(pProperties->pszwName) + 1) * sizeof(WCHAR);
pwchName = ILGetConnName(pidl);
wcscpy(pwchName, pProperties->pszwName);
pwchName = ILGetDeviceName(pidl);
wcscpy(pwchName, pProperties->pszwDeviceName);
/* Set the trailing id to null */
memset((void*)((ULONG_PTR)pidl + size), 0, sizeof(SHITEMID));
NcFreeNetconProperties(pProperties);
return pidl;
}
HRESULT ILGetConnection(PCITEMID_CHILD pidl, INetConnection ** pItem)
{
HRESULT hr;
CComPtr<INetConnectionManager> pNetConMan;
CComPtr<IEnumNetConnection> pEnumCon;
CComPtr<INetConnection> INetCon;
ULONG Count;
NETCON_PROPERTIES * pProperties;
PNETCONIDSTRUCT pdata = ILGetConnData(pidl);
if (!pdata)
return E_FAIL;
/* get an instance to of IConnectionManager */
hr = CNetConnectionManager_CreateInstance(IID_PPV_ARG(INetConnectionManager, &pNetConMan));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = pNetConMan->EnumConnections(NCME_DEFAULT, &pEnumCon);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
while (TRUE)
{ {
struct tagGUIDStruct guid; hr = pEnumCon->Next(1, &INetCon, &Count);
struct tagVALUEStruct value; if (hr != S_OK)
} u; return E_FAIL;
} PIDLDATA, *LPPIDLDATA;
hr = INetCon->GetProperties(&pProperties);
if (FAILED_UNEXPECTEDLY(hr))
continue;
BOOL bSame = !memcmp(&pProperties->guidId, &pdata->guidId, sizeof(GUID));
NcFreeNetconProperties(pProperties);
if (bSame)
{
*pItem = INetCon.Detach();
return S_OK;
}
}
return E_FAIL;
}
typedef struct tagENUMLIST typedef struct tagENUMLIST
{ {
@ -232,93 +326,6 @@ CEnumIDList::Clone(
return E_NOTIMPL; return E_NOTIMPL;
} }
LPPIDLDATA _ILGetDataPointer(LPITEMIDLIST pidl)
{
if (pidl && pidl->mkid.cb != 0x00)
return reinterpret_cast<LPPIDLDATA>(&pidl->mkid.abID);
return NULL;
}
LPITEMIDLIST _ILAlloc(BYTE type, unsigned int size)
{
LPITEMIDLIST pidlOut = NULL;
pidlOut = static_cast<LPITEMIDLIST>(SHAlloc(size + 5));
if (pidlOut)
{
LPPIDLDATA pData;
ZeroMemory(pidlOut, size + 5);
pidlOut->mkid.cb = size + 3;
pData = _ILGetDataPointer(pidlOut);
if (pData)
pData->type = type;
}
return pidlOut;
}
PITEMID_CHILD _ILCreateNetConnect()
{
PITEMID_CHILD pidlOut;
pidlOut = _ILAlloc(PT_GUID, sizeof(PIDLDATA));
if (pidlOut)
{
LPPIDLDATA pData = _ILGetDataPointer(pidlOut);
memcpy(&(pData->u.guid.guid), &CLSID_ConnectionFolder, sizeof(GUID));
}
return pidlOut;
}
GUID* _ILGetGUIDPointer(LPITEMIDLIST pidl)
{
LPPIDLDATA pdata = _ILGetDataPointer(pidl);
if (!pdata)
return NULL;
if (pdata->type != PT_GUID)
return NULL;
else
return &(pdata->u.guid.guid);
}
BOOL _ILIsNetConnect(LPCITEMIDLIST pidl)
{
const IID *piid = _ILGetGUIDPointer(const_cast<LPITEMIDLIST>(pidl));
if (piid)
return IsEqualIID(*piid, CLSID_ConnectionFolder);
return FALSE;
}
PITEMID_CHILD ILCreateNetConnectItem(INetConnection * pItem)
{
PITEMID_CHILD pidl;
LPPIDLDATA pdata;
pidl = _ILAlloc(0x99, sizeof(PIDLDATA));
pdata = _ILGetDataPointer(pidl);
pdata->u.value.pItem = pItem;
return pidl;
}
const VALUEStruct * _ILGetValueStruct(LPCITEMIDLIST pidl)
{
LPPIDLDATA pdata = _ILGetDataPointer(const_cast<LPITEMIDLIST>(pidl));
if (pdata && pdata->type==0x99)
return reinterpret_cast<const VALUEStruct*>(&pdata->u.value);
return NULL;
}
HRESULT CEnumIDList_CreateInstance(HWND hwndOwner, DWORD dwFlags, REFIID riid, LPVOID * ppv) HRESULT CEnumIDList_CreateInstance(HWND hwndOwner, DWORD dwFlags, REFIID riid, LPVOID * ppv)
{ {
return ShellObjectCreatorInit<CEnumIDList>(riid, ppv); return ShellObjectCreatorInit<CEnumIDList>(riid, ppv);

View file

@ -49,20 +49,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
#define NCF_FILTER 0x400 #define NCF_FILTER 0x400
#define NCF_NDIS_PROTOCOL 0x4000 #define NCF_NDIS_PROTOCOL 0x4000
typedef struct tagVALUEStruct
{
BYTE dummy;
INetConnection * pItem;
} VALUEStruct;
/* globals */ /* globals */
extern HINSTANCE netshell_hInstance; extern HINSTANCE netshell_hInstance;
/* enumlist.c */ /* enumlist.c */
PITEMID_CHILD _ILCreateNetConnect(void); typedef struct tagNETCONIDSTRUCT
PITEMID_CHILD ILCreateNetConnectItem(INetConnection *pItem); {
BOOL _ILIsNetConnect(LPCITEMIDLIST pidl); BYTE type;
const VALUEStruct * _ILGetValueStruct(LPCITEMIDLIST pidl); GUID guidId;
NETCON_STATUS Status;
NETCON_MEDIATYPE MediaType;
DWORD dwCharacter;
ULONG_PTR uNameOffset;
ULONG_PTR uDeviceNameOffset;
} NETCONIDSTRUCT, *PNETCONIDSTRUCT;
PNETCONIDSTRUCT ILGetConnData(PCITEMID_CHILD pidl);
PWCHAR ILGetConnName(PCITEMID_CHILD pidl);
PWCHAR ILGetDeviceName(PCITEMID_CHILD pidl);
PITEMID_CHILD ILCreateNetConnectItem(INetConnection * pItem);
HRESULT ILGetConnection(PCITEMID_CHILD pidl, INetConnection ** pItem);
HRESULT CEnumIDList_CreateInstance(HWND hwndOwner, DWORD dwFlags, REFIID riid, LPVOID * ppv); HRESULT CEnumIDList_CreateInstance(HWND hwndOwner, DWORD dwFlags, REFIID riid, LPVOID * ppv);
#define NCCF_NOTIFY_DISCONNECTED 0x100000 #define NCCF_NOTIFY_DISCONNECTED 0x100000

View file

@ -51,10 +51,14 @@ static const shvheader NetConnectSFHeader[] = {
#define COLUMN_PHONE 4 #define COLUMN_PHONE 4
#define COLUMN_OWNER 5 #define COLUMN_OWNER 5
HRESULT ShowNetConnectionStatus(IOleCommandTarget * lpOleCmd, INetConnection * pNetConnect, HWND hwnd); HRESULT
ShowNetConnectionStatus(
IOleCommandTarget *lpOleCmd,
PCUITEMID_CHILD pidl,
HWND hwnd);
CNetworkConnections::CNetworkConnections() : CNetworkConnections::CNetworkConnections() :
m_pidlRoot(_ILCreateNetConnect()) m_pidlRoot(NULL)
{ {
HRESULT hr; HRESULT hr;
hr = CoCreateInstance(CLSID_ConnectionTray, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IOleCommandTarget, &m_lpOleCmd)); hr = CoCreateInstance(CLSID_ConnectionTray, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IOleCommandTarget, &m_lpOleCmd));
@ -64,7 +68,8 @@ CNetworkConnections::CNetworkConnections() :
CNetworkConnections::~CNetworkConnections() CNetworkConnections::~CNetworkConnections()
{ {
SHFree(m_pidlRoot); if (m_pidlRoot)
SHFree(m_pidlRoot);
} }
/************************************************************************** /**************************************************************************
@ -181,17 +186,11 @@ HRESULT WINAPI CNetworkConnections::GetAttributesOf(
while (cidl > 0 && *apidl) while (cidl > 0 && *apidl)
{ {
const VALUEStruct * val; PNETCONIDSTRUCT pdata = ILGetConnData(*apidl);
NETCON_PROPERTIES * pProperties; if (!pdata)
val = _ILGetValueStruct(*apidl);
if (!val)
continue; continue;
if (val->pItem->GetProperties(&pProperties) != S_OK) if (!(pdata->dwCharacter & NCCF_ALLOW_RENAME))
continue;
if (!(pProperties->dwCharacter & NCCF_ALLOW_RENAME))
*rgfInOut &= ~SFGAO_CANRENAME; *rgfInOut &= ~SFGAO_CANRENAME;
apidl++; apidl++;
@ -248,55 +247,20 @@ HRESULT WINAPI CNetworkConnections::GetUIObjectOf(
*/ */
HRESULT WINAPI CNetworkConnections::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) HRESULT WINAPI CNetworkConnections::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
{ {
LPWSTR pszName;
HRESULT hr = E_FAIL;
NETCON_PROPERTIES * pProperties;
const VALUEStruct * val;
if (!strRet) if (!strRet)
return E_INVALIDARG; return E_INVALIDARG;
pszName = static_cast<LPWSTR>(CoTaskMemAlloc(MAX_PATH * sizeof(WCHAR))); if (!pidl)
if (!pszName) return SHSetStrRet(strRet, netshell_hInstance, IDS_NETWORKCONNECTION);
return E_OUTOFMEMORY;
if (_ILIsNetConnect(pidl)) PWCHAR pwchName = ILGetConnName(pidl);
if (!pwchName)
{ {
if (LoadStringW(netshell_hInstance, IDS_NETWORKCONNECTION, pszName, MAX_PATH)) ERR("Got invalid pidl!\n");
{ return E_INVALIDARG;
pszName[MAX_PATH-1] = L'\0';
hr = S_OK;
}
}
else
{
val = _ILGetValueStruct(pidl);
if (val)
{
if (val->pItem->GetProperties(&pProperties) == S_OK)
{
if (pProperties->pszwName)
{
wcscpy(pszName, pProperties->pszwName);
hr = S_OK;
}
NcFreeNetconProperties(pProperties);
}
}
} }
if (SUCCEEDED(hr)) return SHSetStrRet(strRet, pwchName);
{
strRet->uType = STRRET_WSTR;
strRet->pOleStr = pszName;
}
else
{
CoTaskMemFree(pszName);
}
return hr;
} }
/************************************************************************** /**************************************************************************
@ -315,22 +279,20 @@ HRESULT WINAPI CNetworkConnections::SetNameOf (
HWND hwndOwner, PCUITEMID_CHILD pidl, /*simple pidl */ HWND hwndOwner, PCUITEMID_CHILD pidl, /*simple pidl */
LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD * pPidlOut) LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD * pPidlOut)
{ {
const VALUEStruct * val;
HRESULT hr; HRESULT hr;
CComPtr<INetConnection> pCon;
val = _ILGetValueStruct(pidl); hr = ILGetConnection(pidl, &pCon);
if (!val) if (FAILED_UNEXPECTEDLY(hr))
return E_FAIL;
if (!val->pItem)
return E_FAIL;
hr = val->pItem->Rename(lpName);
if (FAILED(hr))
return hr; return hr;
/* The pidl hasn't changed */ hr = pCon->Rename(lpName);
*pPidlOut = ILClone(pidl); if (FAILED_UNEXPECTEDLY(hr))
return hr;
*pPidlOut = ILCreateNetConnectItem(pCon);
if (*pPidlOut == NULL)
return E_FAIL;
return S_OK; return S_OK;
} }
@ -372,97 +334,57 @@ HRESULT WINAPI CNetworkConnections::GetDetailsEx(
HRESULT WINAPI CNetworkConnections::GetDetailsOf( HRESULT WINAPI CNetworkConnections::GetDetailsOf(
PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS * psd) PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS * psd)
{ {
WCHAR buffer[MAX_PATH] = {0};
HRESULT hr = E_FAIL;
const VALUEStruct * val;
NETCON_PROPERTIES * pProperties;
if (iColumn >= NETCONNECTSHELLVIEWCOLUMNS) if (iColumn >= NETCONNECTSHELLVIEWCOLUMNS)
return E_FAIL; return E_FAIL;
psd->fmt = NetConnectSFHeader[iColumn].fmt; psd->fmt = NetConnectSFHeader[iColumn].fmt;
psd->cxChar = NetConnectSFHeader[iColumn].cxChar; psd->cxChar = NetConnectSFHeader[iColumn].cxChar;
if (pidl == NULL) if (pidl == NULL)
{ return SHSetStrRet(&psd->str, netshell_hInstance, NetConnectSFHeader[iColumn].colnameid);
psd->str.uType = STRRET_WSTR;
if (LoadStringW(netshell_hInstance, NetConnectSFHeader[iColumn].colnameid, buffer, MAX_PATH))
hr = SHStrDupW(buffer, &psd->str.pOleStr);
return hr; PNETCONIDSTRUCT pdata = ILGetConnData(pidl);
} if (!pdata)
if (iColumn == COLUMN_NAME)
{
psd->str.uType = STRRET_WSTR;
return GetDisplayNameOf(pidl, SHGDN_NORMAL, &psd->str);
}
val = _ILGetValueStruct(pidl);
if (!val)
return E_FAIL; return E_FAIL;
if (!val->pItem)
return E_FAIL;
if (val->pItem->GetProperties(&pProperties) != S_OK)
return E_FAIL;
switch (iColumn) switch (iColumn)
{ {
case COLUMN_NAME:
return SHSetStrRet(&psd->str, ILGetConnName(pidl));
case COLUMN_TYPE: case COLUMN_TYPE:
if (pProperties->MediaType == NCM_LAN || pProperties->MediaType == NCM_SHAREDACCESSHOST_RAS) if (pdata->MediaType == NCM_LAN || pdata->MediaType == NCM_SHAREDACCESSHOST_RAS)
{ {
if (LoadStringW(netshell_hInstance, IDS_TYPE_ETHERNET, buffer, MAX_PATH)) return SHSetStrRet(&psd->str, netshell_hInstance, IDS_TYPE_ETHERNET);
{
psd->str.uType = STRRET_WSTR;
hr = SHStrDupW(buffer, &psd->str.pOleStr);
}
}
break;
case COLUMN_STATUS:
buffer[0] = L'\0';
if (pProperties->Status == NCS_HARDWARE_DISABLED)
LoadStringW(netshell_hInstance, IDS_STATUS_NON_OPERATIONAL, buffer, MAX_PATH);
else if (pProperties->Status == NCS_DISCONNECTED)
LoadStringW(netshell_hInstance, IDS_STATUS_UNREACHABLE, buffer, MAX_PATH);
else if (pProperties->Status == NCS_MEDIA_DISCONNECTED)
LoadStringW(netshell_hInstance, IDS_STATUS_DISCONNECTED, buffer, MAX_PATH);
else if (pProperties->Status == NCS_CONNECTING)
LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTING, buffer, MAX_PATH);
else if (pProperties->Status == NCS_CONNECTED)
LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTED, buffer, MAX_PATH);
if (buffer[0])
{
buffer[MAX_PATH-1] = L'\0';
psd->str.uType = STRRET_WSTR;
hr = SHStrDupW(buffer, &psd->str.pOleStr);
}
break;
case COLUMN_DEVNAME:
if (pProperties->pszwDeviceName)
{
wcscpy(buffer, pProperties->pszwDeviceName);
buffer[MAX_PATH-1] = L'\0';
psd->str.uType = STRRET_WSTR;
hr = SHStrDupW(buffer, &psd->str.pOleStr);
} }
else else
{ {
psd->str.cStr[0] = '\0'; return SHSetStrRet(&psd->str, "");
psd->str.uType = STRRET_CSTR;
} }
break; break;
case COLUMN_STATUS:
switch(pdata->Status)
{
case NCS_HARDWARE_DISABLED:
return SHSetStrRet(&psd->str, netshell_hInstance, IDS_STATUS_NON_OPERATIONAL);
case NCS_DISCONNECTED:
return SHSetStrRet(&psd->str, netshell_hInstance, IDS_STATUS_UNREACHABLE);
case NCS_MEDIA_DISCONNECTED:
return SHSetStrRet(&psd->str, netshell_hInstance, IDS_STATUS_DISCONNECTED);
case NCS_CONNECTING:
return SHSetStrRet(&psd->str, netshell_hInstance, IDS_STATUS_CONNECTING);
case NCS_CONNECTED:
return SHSetStrRet(&psd->str, netshell_hInstance, IDS_STATUS_CONNECTED);
default:
return SHSetStrRet(&psd->str, "");
}
break;
case COLUMN_DEVNAME:
return SHSetStrRet(&psd->str, ILGetDeviceName(pidl));
case COLUMN_PHONE: case COLUMN_PHONE:
case COLUMN_OWNER: case COLUMN_OWNER:
psd->str.cStr[0] = '\0'; return SHSetStrRet(&psd->str, "");
psd->str.uType = STRRET_CSTR;
break;
} }
NcFreeNetconProperties(pProperties); return E_FAIL;
return hr;
} }
HRESULT WINAPI CNetworkConnections::MapColumnToSCID(UINT column, SHCOLUMNID *pscid) HRESULT WINAPI CNetworkConnections::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
@ -548,29 +470,26 @@ HRESULT WINAPI CNetConUiObject::QueryContextMenu(
UINT idCmdLast, UINT idCmdLast,
UINT uFlags) UINT uFlags)
{ {
const VALUEStruct * val; PNETCONIDSTRUCT pdata = ILGetConnData(m_pidl);
NETCON_PROPERTIES * pProperties; if (!pdata)
{
val = _ILGetValueStruct(m_pidl); ERR("Got invalid pidl!\n");
if (!val)
return E_FAIL; return E_FAIL;
}
if (val->pItem->GetProperties(&pProperties) != S_OK) if (pdata->Status == NCS_HARDWARE_DISABLED)
return E_FAIL;
if (pProperties->Status == NCS_HARDWARE_DISABLED)
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_ACTIVATE), MFS_DEFAULT); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_ACTIVATE), MFS_DEFAULT);
else else
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 1, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DEACTIVATE), MFS_ENABLED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 1, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DEACTIVATE), MFS_ENABLED);
if (pProperties->Status == NCS_HARDWARE_DISABLED || pProperties->Status == NCS_MEDIA_DISCONNECTED || pProperties->Status == NCS_DISCONNECTED) if (pdata->Status == NCS_HARDWARE_DISABLED || pdata->Status == NCS_MEDIA_DISCONNECTED || pdata->Status == NCS_DISCONNECTED)
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 2, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_GRAYED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 2, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_GRAYED);
else if (pProperties->Status == NCS_CONNECTED) else if (pdata->Status == NCS_CONNECTED)
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 2, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_DEFAULT); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 2, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_DEFAULT);
else else
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 2, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_ENABLED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 2, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_ENABLED);
if (pProperties->Status == NCS_HARDWARE_DISABLED || pProperties->Status == NCS_MEDIA_DISCONNECTED) if (pdata->Status == NCS_HARDWARE_DISABLED || pdata->Status == NCS_MEDIA_DISCONNECTED)
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 3, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_REPAIR), MFS_GRAYED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 3, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_REPAIR), MFS_GRAYED);
else else
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 3, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_REPAIR), MFS_ENABLED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 3, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_REPAIR), MFS_ENABLED);
@ -578,22 +497,22 @@ HRESULT WINAPI CNetConUiObject::QueryContextMenu(
_InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED);
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 4, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_CREATELINK), MFS_ENABLED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 4, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_CREATELINK), MFS_ENABLED);
if (pProperties->dwCharacter & NCCF_ALLOW_REMOVAL) if (pdata->dwCharacter & NCCF_ALLOW_REMOVAL)
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 5, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DELETE), MFS_ENABLED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 5, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DELETE), MFS_ENABLED);
else else
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 5, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DELETE), MFS_GRAYED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 5, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DELETE), MFS_GRAYED);
if (pProperties->dwCharacter & NCCF_ALLOW_RENAME) if (pdata->dwCharacter & NCCF_ALLOW_RENAME)
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 6, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_RENAME), MFS_ENABLED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 6, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_RENAME), MFS_ENABLED);
else else
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 6, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_RENAME), MFS_GRAYED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 6, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_RENAME), MFS_GRAYED);
_InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED);
if (pProperties->Status == NCS_CONNECTED) if (pdata->Status == NCS_CONNECTED)
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 7, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_PROPERTIES), MFS_ENABLED); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 7, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_PROPERTIES), MFS_ENABLED);
else else
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 7, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_PROPERTIES), MFS_DEFAULT); _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 7, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_PROPERTIES), MFS_DEFAULT);
NcFreeNetconProperties(pProperties);
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 9); return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 9);
} }
@ -614,22 +533,20 @@ PropSheetExCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
HRESULT HRESULT
ShowNetConnectionStatus( ShowNetConnectionStatus(
IOleCommandTarget *lpOleCmd, IOleCommandTarget *lpOleCmd,
INetConnection *pNetConnect, PCUITEMID_CHILD pidl,
HWND hwnd) HWND hwnd)
{ {
NETCON_PROPERTIES *pProperties;
HRESULT hr;
if (!lpOleCmd) if (!lpOleCmd)
return E_FAIL; return E_FAIL;
if (pNetConnect->GetProperties(&pProperties) != S_OK) PNETCONIDSTRUCT pdata = ILGetConnData(pidl);
if (!pdata)
{
ERR("Got invalid pidl!\n");
return E_FAIL; return E_FAIL;
}
hr = lpOleCmd->Exec(&pProperties->guidId, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL); return lpOleCmd->Exec(&pdata->guidId, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
NcFreeNetconProperties(pProperties);
return hr;
} }
HRESULT HRESULT
@ -689,13 +606,8 @@ ShowNetConnectionProperties(
*/ */
HRESULT WINAPI CNetConUiObject::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) HRESULT WINAPI CNetConUiObject::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
{ {
const VALUEStruct * val;
UINT CmdId; UINT CmdId;
val = _ILGetValueStruct(m_pidl);
if (!val)
return E_FAIL;
/* We should get this when F2 is pressed in explorer */ /* We should get this when F2 is pressed in explorer */
if (HIWORD(lpcmi->lpVerb) && !strcmp(lpcmi->lpVerb, "rename")) if (HIWORD(lpcmi->lpVerb) && !strcmp(lpcmi->lpVerb, "rename"))
lpcmi->lpVerb = MAKEINTRESOURCEA(IDS_NET_RENAME); lpcmi->lpVerb = MAKEINTRESOURCEA(IDS_NET_RENAME);
@ -731,9 +643,20 @@ HRESULT WINAPI CNetConUiObject::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
return S_OK; return S_OK;
} }
case IDS_NET_STATUS: case IDS_NET_STATUS:
return ShowNetConnectionStatus(m_lpOleCmd, val->pItem, lpcmi->hwnd); {
return ShowNetConnectionStatus(m_lpOleCmd, m_pidl, lpcmi->hwnd);
}
case IDS_NET_PROPERTIES: case IDS_NET_PROPERTIES:
return ShowNetConnectionProperties(val->pItem, lpcmi->hwnd); {
HRESULT hr;
CComPtr<INetConnection> pCon;
hr = ILGetConnection(m_pidl, &pCon);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
return ShowNetConnectionProperties(pCon, lpcmi->hwnd);
}
} }
return E_NOTIMPL; return E_NOTIMPL;
@ -800,9 +723,6 @@ HRESULT WINAPI CNetConUiObject::GetIconLocation(
int *piIndex, int *piIndex,
UINT *pwFlags) UINT *pwFlags)
{ {
const VALUEStruct *val;
NETCON_PROPERTIES *pProperties;
*pwFlags = 0; *pwFlags = 0;
if (!GetModuleFileNameW(netshell_hInstance, szIconFile, cchMax)) if (!GetModuleFileNameW(netshell_hInstance, szIconFile, cchMax))
{ {
@ -810,27 +730,19 @@ HRESULT WINAPI CNetConUiObject::GetIconLocation(
return E_FAIL; return E_FAIL;
} }
val = _ILGetValueStruct(m_pidl); PNETCONIDSTRUCT pdata = ILGetConnData(m_pidl);
if (!val) if (!pdata)
{ {
ERR("_ILGetValueStruct failed\n"); ERR("Got invalid pidl!\n");
return E_FAIL; return E_FAIL;
} }
if (val->pItem->GetProperties(&pProperties) != NOERROR) if (pdata->Status == NCS_CONNECTED || pdata->Status == NCS_CONNECTING)
{
ERR("INetConnection_GetProperties failed\n");
return E_FAIL;
}
if (pProperties->Status == NCS_CONNECTED || pProperties->Status == NCS_CONNECTING)
*piIndex = -IDI_NET_IDLE; *piIndex = -IDI_NET_IDLE;
else else
*piIndex = -IDI_NET_OFF; *piIndex = -IDI_NET_OFF;
NcFreeNetconProperties(pProperties); return S_OK;
return NOERROR;
} }
/************************************************************************ /************************************************************************
@ -843,21 +755,7 @@ HRESULT WINAPI CNetConUiObject::Extract(
HICON *phiconSmall, HICON *phiconSmall,
UINT nIconSize) UINT nIconSize)
{ {
//IContextMenuImpl * This = impl_from_IExtractIcon(iface); return SHDefExtractIconW(pszFile, nIconIndex, 0, phiconLarge, phiconSmall, nIconSize);
if (nIconIndex == IDI_NET_IDLE)
{
*phiconLarge = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
*phiconSmall = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
return NOERROR;
}
else if (nIconIndex == IDI_NET_OFF)
{
*phiconLarge = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
*phiconSmall = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
return NOERROR;
}
return S_FALSE;
} }
/************************************************************************ /************************************************************************
@ -880,7 +778,8 @@ HRESULT WINAPI CNetworkConnections::GetClassID(CLSID *lpClassId)
*/ */
HRESULT WINAPI CNetworkConnections::Initialize(PCIDLIST_ABSOLUTE pidl) HRESULT WINAPI CNetworkConnections::Initialize(PCIDLIST_ABSOLUTE pidl)
{ {
SHFree(m_pidlRoot); if (m_pidlRoot)
SHFree(m_pidlRoot);
m_pidlRoot = ILClone(pidl); m_pidlRoot = ILClone(pidl);
return S_OK; return S_OK;
@ -904,23 +803,18 @@ HRESULT WINAPI CNetworkConnections::GetCurFolder(PIDLIST_ABSOLUTE *pidl)
*/ */
HRESULT WINAPI CNetworkConnections::Execute(LPSHELLEXECUTEINFOW pei) HRESULT WINAPI CNetworkConnections::Execute(LPSHELLEXECUTEINFOW pei)
{ {
const VALUEStruct *val; PCUITEMID_CHILD pidl = ILFindLastID((ITEMIDLIST*)pei->lpIDList);
NETCON_PROPERTIES * pProperties; PNETCONIDSTRUCT pdata = ILGetConnData(pidl);
if (!pdata)
val = _ILGetValueStruct(ILFindLastID((ITEMIDLIST*)pei->lpIDList));
if (!val)
return E_FAIL;
if (val->pItem->GetProperties(&pProperties) != NOERROR)
return E_FAIL;
if (pProperties->Status == NCS_CONNECTED)
{ {
NcFreeNetconProperties(pProperties); ERR("Got invalid pidl!\n");
return ShowNetConnectionStatus(m_lpOleCmd, val->pItem, pei->hwnd); return E_FAIL;
} }
NcFreeNetconProperties(pProperties); if (pdata->Status == NCS_CONNECTED)
{
return ShowNetConnectionStatus(m_lpOleCmd, pidl, pei->hwnd);
}
return S_OK; return S_OK;
} }