/************************************************************************* * SHELL_IsShortcut [internal] * * Decide if an item id list points to a shell shortcut */ BOOL SHELL_IsShortcut(LPCITEMIDLIST pidlLast) { char szTemp[MAX_PATH]; HKEY keyCls; BOOL ret = FALSE; if (_ILGetExtension(pidlLast, szTemp, MAX_PATH) && HCR_MapTypeToValueA(szTemp, szTemp, MAX_PATH, TRUE)) { if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, KEY_QUERY_VALUE, &keyCls)) { if (ERROR_SUCCESS == RegQueryValueExA(keyCls, "IsShortcut", NULL, NULL, NULL, NULL)) ret = TRUE; RegCloseKey(keyCls); } } return ret; }
/************************************************************************** * DoOpenProperties */ static void DoOpenProperties(ItemCmImpl *This, HWND hwnd) { static const UINT MAX_PROP_PAGES = 99; static const WCHAR wszFolder[] = {'F','o','l','d','e','r', 0}; static const WCHAR wszFiletypeAll[] = {'*',0}; LPSHELLFOLDER lpDesktopSF; LPSHELLFOLDER lpSF; LPDATAOBJECT lpDo; WCHAR wszFiletype[MAX_PATH]; WCHAR wszFilename[MAX_PATH]; PROPSHEETHEADERW psh; HPROPSHEETPAGE hpages[MAX_PROP_PAGES]; HPSXA hpsxa; UINT ret; TRACE("(%p)->(wnd=%p)\n", This, hwnd); ZeroMemory(&psh, sizeof(PROPSHEETHEADERW)); psh.dwSize = sizeof (PROPSHEETHEADERW); psh.hwndParent = hwnd; psh.dwFlags = PSH_PROPTITLE; psh.nPages = 0; psh.u3.phpage = hpages; psh.u2.nStartPage = 0; _ILSimpleGetTextW(This->apidl[0], (LPVOID)&wszFilename, MAX_PATH); psh.pszCaption = (LPCWSTR)&wszFilename; /* Find out where to look for the shell extensions */ if (_ILIsValue(This->apidl[0])) { char sTemp[64]; sTemp[0] = 0; if (_ILGetExtension(This->apidl[0], sTemp, 64)) { HCR_MapTypeToValueA(sTemp, sTemp, 64, TRUE); MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wszFiletype, MAX_PATH); } else { wszFiletype[0] = 0; } } else if (_ILIsFolder(This->apidl[0])) { lstrcpynW(wszFiletype, wszFolder, 64); } else if (_ILIsSpecialFolder(This->apidl[0])) { LPGUID folderGUID; static const WCHAR wszclsid[] = {'C','L','S','I','D','\\', 0}; folderGUID = _ILGetGUIDPointer(This->apidl[0]); lstrcpyW(wszFiletype, wszclsid); StringFromGUID2(folderGUID, &wszFiletype[6], MAX_PATH - 6); } else { FIXME("Requested properties for unknown type.\n"); return; } /* Get a suitable DataObject for accessing the files */ SHGetDesktopFolder(&lpDesktopSF); if (_ILIsPidlSimple(This->pidl)) { ret = IShellFolder_GetUIObjectOf(lpDesktopSF, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject, NULL, (LPVOID *)&lpDo); IShellFolder_Release(lpDesktopSF); } else { IShellFolder_BindToObject(lpDesktopSF, This->pidl, NULL, &IID_IShellFolder, (LPVOID*) &lpSF); ret = IShellFolder_GetUIObjectOf(lpSF, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject, NULL, (LPVOID *)&lpDo); IShellFolder_Release(lpSF); IShellFolder_Release(lpDesktopSF); } if (SUCCEEDED(ret)) { hpsxa = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszFiletype, MAX_PROP_PAGES - psh.nPages, lpDo); if (hpsxa != NULL) { SHAddFromPropSheetExtArray(hpsxa, Properties_AddPropSheetCallback, (LPARAM)&psh); SHDestroyPropSheetExtArray(hpsxa); } hpsxa = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszFiletypeAll, MAX_PROP_PAGES - psh.nPages, lpDo); if (hpsxa != NULL) { SHAddFromPropSheetExtArray(hpsxa, Properties_AddPropSheetCallback, (LPARAM)&psh); SHDestroyPropSheetExtArray(hpsxa); } IDataObject_Release(lpDo); } if (psh.nPages) PropertySheetW(&psh); else FIXME("No property pages found.\n"); }
/************************************************************************** * IExtractIconW::GetIconLocation * * mapping filetype to icon */ static HRESULT WINAPI IExtractIconW_fnGetIconLocation(IExtractIconW * iface, UINT uFlags, LPWSTR szIconFile, UINT cchMax, int * piIndex, UINT * pwFlags) { IExtractIconWImpl *This = impl_from_IExtractIconW(iface); char sTemp[MAX_PATH]; int icon_idx; GUID const * riid; LPITEMIDLIST pSimplePidl = ILFindLastID(This->pidl); TRACE("(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags); if (pwFlags) *pwFlags = 0; if (_ILIsDesktop(pSimplePidl)) { lstrcpynW(szIconFile, swShell32Name, cchMax); *piIndex = -IDI_SHELL_DESKTOP; } /* my computer and other shell extensions */ else if ((riid = _ILGetGUIDPointer(pSimplePidl))) { static const WCHAR fmt[] = { 'C','L','S','I','D','\\', '{','%','0','8','l','x','-','%','0','4','x','-','%','0','4','x','-', '%','0','2','x','%','0','2','x','-','%','0','2','x', '%','0','2','x', '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','}',0 }; WCHAR xriid[50]; sprintfW(xriid, fmt, riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]); if (HCR_GetDefaultIconW(xriid, szIconFile, cchMax, &icon_idx)) { *piIndex = icon_idx; } else { lstrcpynW(szIconFile, swShell32Name, cchMax); if(IsEqualGUID(riid, &CLSID_MyComputer)) *piIndex = -IDI_SHELL_MY_COMPUTER; else if(IsEqualGUID(riid, &CLSID_MyDocuments)) *piIndex = -IDI_SHELL_MY_DOCUMENTS; else if(IsEqualGUID(riid, &CLSID_NetworkPlaces)) *piIndex = -IDI_SHELL_MY_NETWORK_PLACES; else if(IsEqualGUID(riid, &CLSID_UnixFolder) || IsEqualGUID(riid, &CLSID_UnixDosFolder)) *piIndex = -IDI_SHELL_DRIVE; else *piIndex = -IDI_SHELL_FOLDER; } } else if (_ILIsDrive (pSimplePidl)) { static const WCHAR drive[] = { 'D','r','i','v','e',0 }; int icon_idx = -1; if (_ILGetDrive(pSimplePidl, sTemp, MAX_PATH)) { switch(GetDriveTypeA(sTemp)) { case DRIVE_REMOVABLE: icon_idx = IDI_SHELL_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; } } if (icon_idx != -1) { lstrcpynW(szIconFile, swShell32Name, cchMax); *piIndex = -icon_idx; } else { if (HCR_GetDefaultIconW(drive, szIconFile, cchMax, &icon_idx)) { *piIndex = icon_idx; } else { lstrcpynW(szIconFile, swShell32Name, cchMax); *piIndex = -IDI_SHELL_DRIVE; } } } else if (_ILIsFolder (pSimplePidl)) { getIconLocationForFolder(This, uFlags, szIconFile, cchMax, piIndex, pwFlags); } else { BOOL found = FALSE; if (_ILIsCPanelStruct(pSimplePidl)) { if (SUCCEEDED(CPanel_GetIconLocationW(pSimplePidl, szIconFile, cchMax, piIndex))) found = TRUE; } else if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH)) { if (HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE) && HCR_GetDefaultIconA(sTemp, sTemp, MAX_PATH, &icon_idx)) { if (!lstrcmpA("%1", sTemp)) /* icon is in the file */ { SHGetPathFromIDListW(This->pidl, szIconFile); *piIndex = 0; } else { MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax); *piIndex = icon_idx; } found = TRUE; } else if (!lstrcmpiA(sTemp, "lnkfile")) { /* extract icon from shell shortcut */ IShellFolder* dsf; IShellLinkW* psl; if (SUCCEEDED(SHGetDesktopFolder(&dsf))) { HRESULT hr = IShellFolder_GetUIObjectOf(dsf, NULL, 1, (LPCITEMIDLIST*)&This->pidl, &IID_IShellLinkW, NULL, (LPVOID*)&psl); if (SUCCEEDED(hr)) { hr = IShellLinkW_GetIconLocation(psl, szIconFile, MAX_PATH, piIndex); if (SUCCEEDED(hr) && *szIconFile) found = TRUE; IShellLinkW_Release(psl); } IShellFolder_Release(dsf); } } } if (!found) /* default icon */ { lstrcpynW(szIconFile, swShell32Name, cchMax); *piIndex = 0; } } TRACE("-- %s %x\n", debugstr_w(szIconFile), *piIndex); return S_OK; }
/************************************************************************** * IExtractIconW_Constructor */ IExtractIconW* IExtractIconW_Constructor(LPCITEMIDLIST pidl) { CComPtr<IDefaultExtractIconInit> initIcon; IExtractIconW *extractIcon; GUID const * riid; int icon_idx; UINT flags; CHAR sTemp[MAX_PATH]; WCHAR wTemp[MAX_PATH]; LPITEMIDLIST pSimplePidl = ILFindLastID(pidl); HRESULT hr; hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit,&initIcon)); if (FAILED(hr)) return NULL; hr = initIcon->QueryInterface(IID_PPV_ARG(IExtractIconW,&extractIcon)); if (FAILED(hr)) return NULL; if (_ILIsDesktop(pSimplePidl)) { initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DESKTOP); } else if ((riid = _ILGetGUIDPointer(pSimplePidl))) { /* my computer and other shell extensions */ static const WCHAR fmt[] = { 'C', 'L', 'S', 'I', 'D', '\\', '{', '%', '0', '8', 'l', 'x', '-', '%', '0', '4', 'x', '-', '%', '0', '4', 'x', '-', '%', '0', '2', 'x', '%', '0', '2', 'x', '-', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '%', '0', '2', 'x', '}', 0 }; WCHAR xriid[50]; swprintf(xriid, fmt, riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]); const WCHAR* iconname = NULL; if (_ILIsBitBucket(pSimplePidl)) { static const WCHAR szFull[] = {'F','u','l','l',0}; static const WCHAR szEmpty[] = {'E','m','p','t','y',0}; IEnumIDList *EnumIDList = NULL; CoInitialize(NULL); IShellFolder2 *psfRecycleBin = NULL; IShellFolder *psfDesktop = NULL; hr = SHGetDesktopFolder(&psfDesktop); if (SUCCEEDED(hr)) hr = psfDesktop->BindToObject(pSimplePidl, NULL, IID_IShellFolder2, (void**) &psfRecycleBin); if (SUCCEEDED(hr)) hr = psfRecycleBin->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &EnumIDList); ULONG itemcount; LPITEMIDLIST pidl = NULL; if (SUCCEEDED(hr) && (hr = EnumIDList->Next(1, &pidl, &itemcount)) == S_OK) { CoTaskMemFree(pidl); iconname = szFull; } else { iconname = szEmpty; } if (psfDesktop) psfDesktop->Release(); if (psfRecycleBin) psfRecycleBin->Release(); if (EnumIDList) EnumIDList->Release(); } if (HCR_GetIconW(xriid, wTemp, iconname, MAX_PATH, &icon_idx)) { initIcon->SetNormalIcon(wTemp, icon_idx); } else { if (IsEqualGUID(*riid, CLSID_MyComputer)) initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_COMPUTER); else if (IsEqualGUID(*riid, CLSID_MyDocuments)) initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_DOCUMENTS); else if (IsEqualGUID(*riid, CLSID_NetworkPlaces)) initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_NETWORK_PLACES); else initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_FOLDER); } } else if (_ILIsDrive (pSimplePidl)) { static const WCHAR drive[] = { 'D', 'r', 'i', 'v', 'e', 0 }; int icon_idx = -1; if (_ILGetDrive(pSimplePidl, sTemp, MAX_PATH)) { switch(GetDriveTypeA(sTemp)) { case DRIVE_REMOVABLE: icon_idx = IDI_SHELL_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(drive, wTemp, NULL, MAX_PATH, &icon_idx)) initIcon->SetNormalIcon(wTemp, icon_idx); else initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_DRIVE); } } else if (_ILIsFolder (pSimplePidl)) { if (SUCCEEDED(getIconLocationForFolder( pidl, 0, wTemp, MAX_PATH, &icon_idx, &flags))) { initIcon->SetNormalIcon(wTemp, icon_idx); // FIXME: if/when getIconLocationForFolder does something for // GIL_FORSHORTCUT, code below should be uncommented. and // the following line removed. initIcon->SetShortcutIcon(wTemp, icon_idx); } if (SUCCEEDED(getIconLocationForFolder( pidl, GIL_DEFAULTICON, wTemp, MAX_PATH, &icon_idx, &flags))) { initIcon->SetDefaultIcon(wTemp, icon_idx); } // if (SUCCEEDED(getIconLocationForFolder( // pidl, GIL_FORSHORTCUT, wTemp, MAX_PATH, // &icon_idx, // &flags))) // { // initIcon->SetShortcutIcon(wTemp, icon_idx); // } if (SUCCEEDED(getIconLocationForFolder( pidl, GIL_OPENICON, wTemp, MAX_PATH, &icon_idx, &flags))) { initIcon->SetOpenIcon(wTemp, icon_idx); } } else { BOOL found = FALSE; if (_ILIsCPanelStruct(pSimplePidl)) { if (SUCCEEDED(CPanel_GetIconLocationW(pSimplePidl, wTemp, MAX_PATH, &icon_idx))) found = TRUE; } else if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH)) { if (HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE) && HCR_GetIconA(sTemp, sTemp, NULL, MAX_PATH, &icon_idx)) { if (!lstrcmpA("%1", sTemp)) /* icon is in the file */ { SHGetPathFromIDListW(pidl, wTemp); icon_idx = 0; } else { MultiByteToWideChar(CP_ACP, 0, sTemp, -1, wTemp, MAX_PATH); } found = TRUE; } else if (!lstrcmpiA(sTemp, "lnkfile")) { /* extract icon from shell shortcut */ CComPtr<IShellFolder> dsf; CComPtr<IShellLinkW> psl; if (SUCCEEDED(SHGetDesktopFolder(&dsf))) { HRESULT hr = dsf->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidl, IID_IShellLinkW, NULL, (LPVOID *)&psl); if (SUCCEEDED(hr)) { hr = psl->GetIconLocation(wTemp, MAX_PATH, &icon_idx); if (SUCCEEDED(hr) && *sTemp) found = TRUE; } } } } if (!found) /* default icon */ initIcon->SetNormalIcon(swShell32Name, 0); else initIcon->SetNormalIcon(wTemp, icon_idx); } return extractIcon; }