* IShellFolder implementation
*/
+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, pqcminfo->idCmdFirst++, MFT_STRING, MAKEINTRESOURCEW(IDS_FORMATDRIVE), MFS_ENABLED);
+ }
+ }
+ }
+ else if (uMsg == DFM_INVOKECOMMAND)
+ {
+ 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;
+ }
+ else
+ {
+ SHFormatDrive(hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0);
+ }
+ }
+
+ SHFree(pidlFolder);
+ _ILFreeaPidl(apidl, cidl);
+
+ return hr;
+}
+
+HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
+ HWND hwnd,
+ UINT cidl,
+ PCUITEMID_CHILD_ARRAY apidl,
+ IShellFolder *psf,
+ IContextMenu **ppcm)
+{
+ HKEY hKeys[2];
+ UINT cKeys = 0;
+ AddClassKeyToArray(L"Drive", hKeys, &cKeys);
+ AddClassKeyToArray(L"Folder", hKeys, &cKeys);
+
+ return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, DrivesContextMenuCallback, cKeys, hKeys, ppcm);
+}
+
HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut)
{
CComPtr<IDefaultExtractIconInit> initIcon;
HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon));
- if (FAILED(hr))
- return NULL;
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
CHAR* pszDrive = _ILGetDataPointer(pidl)->u.drive.szDriveName;
WCHAR wTemp[MAX_PATH];
if (IsEqualIID (riid, IID_IContextMenu) && (cidl >= 1))
{
- hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder*)this, NULL, 0, NULL, (IContextMenu**)&pObj);
+ if (_ILIsDrive(apidl[0]))
+ hr = CDrivesContextMenu_CreateInstance(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), (IContextMenu**)&pObj);
+ else
+ hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
}
else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
{
else
hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
}
- else if (IsEqualIID (riid, IID_IDropTarget) && (cidl >= 1))
+ else if (IsEqualIID (riid, IID_IDropTarget) && (cidl == 1))
{
- IDropTarget * pDt = NULL;
- hr = this->QueryInterface(IID_PPV_ARG(IDropTarget, &pDt));
- pObj = pDt;
+ CComPtr<IShellFolder> psfChild;
+ hr = this->BindToObject(apidl[0], NULL, IID_PPV_ARG(IShellFolder, &psfChild));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ return psfChild->CreateViewObject(NULL, riid, ppvOut);
}
else
hr = E_NOINTERFACE;
*/
HRESULT WINAPI CDrivesFolder::Initialize(LPCITEMIDLIST pidl)
{
- TRACE ("(%p)->(%p)\n", this, pidl);
-
- if (pidlRoot)
- SHFree((LPVOID)pidlRoot);
-
- pidlRoot = ILClone(pidl);
return S_OK;
}
TRACE("(%p)->(%p)\n", this, pidl);
if (!pidl)
- return E_POINTER;
+ return E_INVALIDARG; /* xp doesn't have this check and crashes on NULL */
*pidl = ILClone(pidlRoot);
return S_OK;