BOOL SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl) { HPSXA hpsxa[3] = {NULL, NULL, NULL}; CComObject<CFileDefExt> *pFileDefExt = NULL; TRACE("SH_ShowPropertiesDialog entered filename %s\n", debugstr_w(pwszPath)); if (pwszPath == NULL || !wcslen(pwszPath)) return FALSE; HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE]; memset(hppages, 0x0, sizeof(HPROPSHEETPAGE) * MAX_PROPERTY_SHEET_PAGE); /* Make a copy of path */ WCHAR wszPath[MAX_PATH]; StringCbCopyW(wszPath, sizeof(wszPath), pwszPath); /* remove trailing \\ at the end of path */ PathRemoveBackslashW(wszPath); /* Handle drives */ if (PathIsRootW(wszPath)) return SH_ShowDriveProperties(wszPath, pidlFolder, apidl); /* Handle files and folders */ PROPSHEETHEADERW Header; memset(&Header, 0x0, sizeof(PROPSHEETHEADERW)); Header.dwSize = sizeof(PROPSHEETHEADERW); Header.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE; Header.phpage = hppages; Header.pszCaption = PathFindFileNameW(wszPath); CComPtr<IDataObject> pDataObj; HRESULT hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_IDataObject, (LPVOID *)&pDataObj); if (SUCCEEDED(hr)) { hr = CComObject<CFileDefExt>::CreateInstance(&pFileDefExt); if (SUCCEEDED(hr)) { pFileDefExt->AddRef(); // CreateInstance returns object with 0 ref count hr = pFileDefExt->Initialize(pidlFolder, pDataObj, NULL); if (SUCCEEDED(hr)) { hr = pFileDefExt->AddPages(AddPropSheetPageCallback, (LPARAM)&Header); if (FAILED(hr)) ERR("AddPages failed\n"); } else ERR("Initialize failed\n"); } LoadPropSheetHandlers(wszPath, &Header, MAX_PROPERTY_SHEET_PAGE - 1, hpsxa, pDataObj); } INT_PTR Result = PropertySheetW(&Header); for (UINT i = 0; i < 3; ++i) if (hpsxa[i]) SHDestroyPropSheetExtArray(hpsxa[i]); if (pFileDefExt) pFileDefExt->Release(); return (Result != -1); }
HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf, HWND hwnd, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND) return S_OK; PIDLIST_ABSOLUTE pidlFolder; PUITEMID_CHILD *apidl; UINT cidl; HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl); if (FAILED_UNEXPECTEDLY(hr)) return hr; char szDrive[8] = {0}; if (!_ILGetDrive(apidl[0], szDrive, sizeof(szDrive))) { ERR("pidl is not a drive\n"); SHFree(pidlFolder); _ILFreeaPidl(apidl, cidl); return E_FAIL; } if (uMsg == DFM_MERGECONTEXTMENU) { QCMINFO *pqcminfo = (QCMINFO *)lParam; DWORD dwFlags; if (GetVolumeInformationA(szDrive, NULL, 0, NULL, NULL, &dwFlags, NULL, 0)) { /* Disable format if read only */ if (!(dwFlags & FILE_READ_ONLY_VOLUME) && GetDriveTypeA(szDrive) != DRIVE_REMOTE) { _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0x7ABC, MFT_STRING, MAKEINTRESOURCEW(IDS_FORMATDRIVE), MFS_ENABLED); } } } else if (uMsg == DFM_INVOKECOMMAND) { if(wParam == 0x7ABC) { SHFormatDrive(hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0); } else if (wParam == DFM_CMD_PROPERTIES) { WCHAR wszBuf[4]; wcscpy(wszBuf, L"A:\\"); wszBuf[0] = (WCHAR)szDrive[0]; if (!SH_ShowDriveProperties(wszBuf, pidlFolder, apidl)) hr = E_FAIL; } } SHFree(pidlFolder); _ILFreeaPidl(apidl, cidl); return hr; }