static BOOL __inline PIDLIsType(LPCITEMIDLIST pidl, PIDLTYPE type) { LPPIDLDATA data = _ILGetDataPointer(pidl); if (!data) return FALSE; return (data->type == type); }
VALUEStruct * _ILGetValueStruct(LPCITEMIDLIST pidl) { LPPIDLDATA pdata = _ILGetDataPointer(pidl); if (pdata && pdata->type==0x99) return (VALUEStruct*)&(pdata->u.value); return NULL; }
/************************************************************************** * _ILGetCPanelPointer() * gets a pointer to the control panel struct stored in the pidl */ static PIDLCPanelStruct* _ILGetCPanelPointer(LPCITEMIDLIST pidl) { LPPIDLDATA pdata = _ILGetDataPointer(pidl); if (pdata && pdata->type==PT_CPLAPPLET) return (PIDLCPanelStruct*)&(pdata->u.cpanel); return NULL; }
static PIDLFontStruct * _ILGetFontStruct(LPCITEMIDLIST pidl) { LPPIDLDATA pdata = _ILGetDataPointer(pidl); if (pdata && pdata->type == 0x00) return (PIDLFontStruct*) & (pdata->u.cfont); return NULL; }
static PIDLRecycleStruct * _ILGetRecycleStruct(LPCITEMIDLIST pidl) { LPPIDLDATA pdata = _ILGetDataPointer(pidl); if (pdata && pdata->type == 0x00) return (PIDLRecycleStruct*) & (pdata->u.crecycle); return NULL; }
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; }
LPITEMIDLIST ILCreateNetConnectItem(INetConnection * pItem) { LPITEMIDLIST pidl; LPPIDLDATA pdata; pidl = _ILAlloc(0x99, sizeof(PIDLDATA)); pdata = _ILGetDataPointer(pidl); pdata->u.value.pItem = (INetConnection*)pItem; return pidl; }
IID* _ILGetGUIDPointer(LPCITEMIDLIST pidl) { LPPIDLDATA pdata =_ILGetDataPointer(pidl); if (!pdata) return NULL; if (pdata->type != PT_GUID) return NULL; else return &(pdata->u.guid.guid); }
LPITEMIDLIST _ILCreateNetConnect() { LPITEMIDLIST pidlOut; pidlOut = _ILAlloc(PT_GUID, sizeof(PIDLDATA)); if (pidlOut) { LPPIDLDATA pData = _ILGetDataPointer(pidlOut); memcpy(&(pData->u.guid.guid), &CLSID_NetworkConnections, sizeof(GUID)); } 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; }
HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut) { CComPtr<IDefaultExtractIconInit> initIcon; HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon)); if (FAILED_UNEXPECTEDLY(hr)) return hr; CHAR* pszDrive = _ILGetDataPointer(pidl)->u.drive.szDriveName; WCHAR wTemp[MAX_PATH]; int icon_idx = -1; if (pszDrive) { switch(GetDriveTypeA(pszDrive)) { case DRIVE_REMOVABLE: icon_idx = IDI_SHELL_3_14_FLOPPY; break; case DRIVE_CDROM: icon_idx = IDI_SHELL_CDROM; break; case DRIVE_REMOTE: icon_idx = IDI_SHELL_NETDRIVE; break; case DRIVE_RAMDISK: icon_idx = IDI_SHELL_RAMDISK; break; case DRIVE_NO_ROOT_DIR: icon_idx = IDI_SHELL_CDROM; break; } } if (icon_idx != -1) { initIcon->SetNormalIcon(swShell32Name, -icon_idx); } else { if (HCR_GetIconW(L"Drive", wTemp, NULL, MAX_PATH, &icon_idx)) initIcon->SetNormalIcon(wTemp, icon_idx); else initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DRIVE); } return initIcon->QueryInterface(riid, ppvOut); }
static IID* _dbg_ILGetGUIDPointer(LPCITEMIDLIST pidl) { LPPIDLDATA pdata =_ILGetDataPointer(pidl); if (pdata) { switch (pdata->type) { case PT_SHELLEXT: case PT_GUID: case PT_YAGUID: return &(pdata->u.guid.guid); } } return NULL; }
LPITEMIDLIST _ILAlloc(BYTE type, unsigned int size) { LPITEMIDLIST pidlOut = NULL; pidlOut = (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; }
/*********************************************************************** * SHELL32_CompareIDs */ HRESULT SHELL32_CompareIDs(IShellFolder2 *sf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { int type1, type2; char szTemp1[MAX_PATH]; char szTemp2[MAX_PATH]; HRESULT nReturn; LPITEMIDLIST firstpidl, nextpidl1, nextpidl2; IShellFolder *psf; /* test for empty pidls */ BOOL isEmpty1 = _ILIsDesktop (pidl1); BOOL isEmpty2 = _ILIsDesktop (pidl2); if (isEmpty1 && isEmpty2) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 0 ); if (isEmpty1) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 ); if (isEmpty2) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 ); /* test for different types. Sort order is the PT_* constant */ type1 = _ILGetDataPointer (pidl1)->type; type2 = _ILGetDataPointer (pidl2)->type; if (type1 < type2) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 ); else if (type1 > type2) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 ); /* test for name of pidl */ _ILSimpleGetText (pidl1, szTemp1, MAX_PATH); _ILSimpleGetText (pidl2, szTemp2, MAX_PATH); nReturn = lstrcmpiA (szTemp1, szTemp2); if (nReturn < 0) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 ); else if (nReturn > 0) return MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 ); /* test of complex pidls */ firstpidl = ILCloneFirst (pidl1); nextpidl1 = ILGetNext (pidl1); nextpidl2 = ILGetNext (pidl2); /* optimizing: test special cases and bind not deeper */ /* the deeper shellfolder would do the same */ isEmpty1 = _ILIsDesktop (nextpidl1); isEmpty2 = _ILIsDesktop (nextpidl2); if (isEmpty1 && isEmpty2) { nReturn = MAKE_HRESULT( SEVERITY_SUCCESS, 0, 0 ); } else if (isEmpty1) { nReturn = MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 ); } else if (isEmpty2) { nReturn = MAKE_HRESULT( SEVERITY_SUCCESS, 0, 1 ); /* optimizing end */ } else if (SUCCEEDED(IShellFolder2_BindToObject(sf, firstpidl, NULL, &IID_IShellFolder, (void **)&psf))) { nReturn = IShellFolder_CompareIDs (psf, lParam, nextpidl1, nextpidl2); IShellFolder_Release (psf); } ILFree (firstpidl); return nReturn; }
/*********************************************************************** * SHELL32_GetItemAttributes * * NOTES * Observed values: * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER * file: 0x40000177 FILESYSTEM * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR * (seems to be default for shell extensions if no registry entry exists) * * win2k: * folder: 0xF0400177 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER * file: 0x40400177 FILESYSTEM | CANMONIKER * drive 0xF0400154 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER | CANRENAME (LABEL) * * According to the MSDN documentation this function should not set flags. It claims only to reset flags when necessary. * However it turns out the native shell32.dll _sets_ flags in several cases - so do we. */ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes) { DWORD dwAttributes; BOOL has_guid; static const DWORD dwSupportedAttr= SFGAO_CANCOPY | /*0x00000001 */ SFGAO_CANMOVE | /*0x00000002 */ SFGAO_CANLINK | /*0x00000004 */ SFGAO_CANRENAME | /*0x00000010 */ SFGAO_CANDELETE | /*0x00000020 */ SFGAO_HASPROPSHEET | /*0x00000040 */ SFGAO_DROPTARGET | /*0x00000100 */ SFGAO_LINK | /*0x00010000 */ SFGAO_READONLY | /*0x00040000 */ SFGAO_HIDDEN | /*0x00080000 */ SFGAO_FILESYSANCESTOR | /*0x10000000 */ SFGAO_FOLDER | /*0x20000000 */ SFGAO_FILESYSTEM | /*0x40000000 */ SFGAO_HASSUBFOLDER; /*0x80000000 */ TRACE ("0x%08x\n", *pdwAttributes); if (*pdwAttributes & ~dwSupportedAttr) { WARN ("attributes 0x%08x not implemented\n", (*pdwAttributes & ~dwSupportedAttr)); *pdwAttributes &= dwSupportedAttr; } has_guid = _ILGetGUIDPointer(pidl) != NULL; dwAttributes = *pdwAttributes; if (_ILIsDrive (pidl)) { *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR| SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANLINK; } else if (has_guid && HCR_GetFolderAttributes(pidl, &dwAttributes)) { *pdwAttributes = dwAttributes; } else if (_ILGetDataPointer (pidl)) { dwAttributes = _ILGetFileAttributes (pidl, NULL, 0); if (!dwAttributes && has_guid) { WCHAR path[MAX_PATH]; STRRET strret; /* File attributes are not present in the internal PIDL structure, so get them from the file system. */ HRESULT hr = IShellFolder_GetDisplayNameOf(psf, pidl, SHGDN_FORPARSING, &strret); if (SUCCEEDED(hr)) { hr = StrRetToBufW(&strret, pidl, path, MAX_PATH); /* call GetFileAttributes() only for file system paths, not for parsing names like "::{...}" */ if (SUCCEEDED(hr) && path[0]!=':') dwAttributes = GetFileAttributesW(path); } } /* Set common attributes */ *pdwAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANCOPY; if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) *pdwAttributes |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); else *pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR); if (dwAttributes & FILE_ATTRIBUTE_HIDDEN) *pdwAttributes |= SFGAO_HIDDEN; else *pdwAttributes &= ~SFGAO_HIDDEN; if (dwAttributes & FILE_ATTRIBUTE_READONLY) *pdwAttributes |= SFGAO_READONLY; else *pdwAttributes &= ~SFGAO_READONLY; if (SFGAO_LINK & *pdwAttributes) { char ext[MAX_PATH]; if (!_ILGetExtension(pidl, ext, MAX_PATH) || lstrcmpiA(ext, "lnk")) *pdwAttributes &= ~SFGAO_LINK; } } else { *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK; } TRACE ("-- 0x%08x\n", *pdwAttributes); return S_OK; }