* 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_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);
+}
+
class CDrivesFolderEnum :
public CEnumIDListBase
{
*/
static const shvheader MyComputerSFHeader[] = {
- {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
- {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
+ {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
+ {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
{IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
{IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
};
#define MYCOMPUTERSHELLVIEWCOLUMNS 4
+static const DWORD dwComputerAttributes =
+ SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
+ SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
+static const DWORD dwControlPanelAttributes =
+ SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CANLINK;
+static const DWORD dwDriveAttributes =
+ SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
+ SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK;
+
CDrivesFolderEnum::CDrivesFolderEnum()
{
}
CDrivesFolder::CDrivesFolder()
{
pidlRoot = NULL;
- sName = NULL;
}
CDrivesFolder::~CDrivesFolder()
HRESULT WINAPI CDrivesFolder::FinalConstruct()
{
- DWORD dwSize;
- WCHAR szName[MAX_PATH];
- WCHAR wszMyCompKey[256];
- INT i;
-
pidlRoot = _ILCreateMyComputer(); /* my qualified pidl */
if (pidlRoot == NULL)
return E_OUTOFMEMORY;
- i = swprintf(wszMyCompKey, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\");
- StringFromGUID2(CLSID_MyComputer, wszMyCompKey + i, sizeof(wszMyCompKey) / sizeof(wszMyCompKey[0]) - i);
- dwSize = sizeof(szName);
- if (RegGetValueW(HKEY_CURRENT_USER, wszMyCompKey,
- NULL, RRF_RT_REG_SZ, NULL, szName, &dwSize) == ERROR_SUCCESS)
- {
- sName = (LPWSTR)SHAlloc((wcslen(szName) + 1) * sizeof(WCHAR));
- if (sName)
- wcscpy(sName, szName);
- TRACE("sName %s\n", debugstr_w(sName));
- }
- return S_OK;
+ HRESULT hr = CRegFolder_CreateInstance(&CLSID_MyComputer,
+ pidlRoot,
+ L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
+ IID_PPV_ARG(IShellFolder2, &m_regFolder));
+
+ return hr;
}
/**************************************************************************
{
HRESULT hr = E_INVALIDARG;
LPCWSTR szNext = NULL;
- WCHAR szElement[MAX_PATH];
LPITEMIDLIST pidlTemp = NULL;
- CLSID clsid;
TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", this,
hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
/* handle CLSID paths */
if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
+ return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
+
+ if (PathGetDriveNumberW(lpszDisplayName) < 0)
+ return E_INVALIDARG;
+
+ pidlTemp = _ILCreateDrive(lpszDisplayName);
+ if (!pidlTemp)
+ return E_OUTOFMEMORY;
+
+ if (lpszDisplayName[2] == L'\\')
{
- szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
- TRACE ("-- element: %s\n", debugstr_w (szElement));
- CLSIDFromString (szElement + 2, &clsid);
- pidlTemp = _ILCreateGuid (PT_GUID, clsid);
- }
- /* do we have an absolute path name ? */
- else if (PathGetDriveNumberW (lpszDisplayName) >= 0 &&
- lpszDisplayName[2] == (WCHAR) '\\')
- {
- szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
- /* make drive letter uppercase to enable PIDL comparison */
- szElement[0] = toupper(szElement[0]);
- pidlTemp = _ILCreateDrive (szElement);
+ szNext = &lpszDisplayName[3];
}
if (szNext && *szNext)
}
else
{
- if (pdwAttributes && *pdwAttributes)
- SHELL32_GetItemAttributes (this,
- pidlTemp, pdwAttributes);
hr = S_OK;
+ if (pdwAttributes && *pdwAttributes)
+ {
+ if (_ILIsDrive(pidlTemp))
+ *pdwAttributes &= dwDriveAttributes;
+ else if (_ILIsSpecialFolder(pidlTemp))
+ m_regFolder->GetAttributesOf(1, &pidlTemp, pdwAttributes);
+ else
+ ERR("Got an unkown pidl here!\n");
+ }
}
*ppidl = pidlTemp;
TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this,
pidl, pbcReserved, shdebugstr_guid(&riid), ppvOut);
- return SHELL32_BindToChild(pidlRoot, NULL, pidl, riid, ppvOut);
+ if (_ILIsSpecialFolder(pidl))
+ return m_regFolder->BindToObject(pidl, pbcReserved, riid, ppvOut);
+
+ LPITEMIDLIST pidlChild = ILCloneFirst (pidl);
+ if (!pidlChild)
+ return E_OUTOFMEMORY;
+
+ CComPtr<IShellFolder> psf;
+ HRESULT hr = SHELL32_CoCreateInitSF(pidlRoot,
+ NULL,
+ pidlChild,
+ &CLSID_ShellFSFolder,
+ -1,
+ IID_PPV_ARG(IShellFolder, &psf));
+
+ ILFree(pidlChild);
+
+ if (FAILED(hr))
+ return hr;
+
+ if (_ILIsPidlSimple (pidl))
+ {
+ return psf->QueryInterface(riid, ppvOut);
+ }
+ else
+ {
+ return psf->BindToObject(ILGetNext (pidl), pbcReserved, riid, ppvOut);
+ }
}
/**************************************************************************
HRESULT WINAPI CDrivesFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
- int nReturn;
+ HRESULT hres;
+
+ if (!pidl1 || !pidl2)
+ {
+ ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam, pidl1, pidl2);
+ return E_INVALIDARG;
+ }
+
+ if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
+ return m_regFolder->CompareIDs(lParam, pidl1, pidl2);
+
+ if (!_ILIsDrive(pidl1) || !_ILIsDrive(pidl2) || LOWORD(lParam) >= MYCOMPUTERSHELLVIEWCOLUMNS)
+ return E_INVALIDARG;
+
+ CHAR* pszDrive1 = _ILGetDataPointer(pidl1)->u.drive.szDriveName;
+ CHAR* pszDrive2 = _ILGetDataPointer(pidl2)->u.drive.szDriveName;
- TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
- nReturn = SHELL32_CompareIDs (this, lParam, pidl1, pidl2);
- TRACE("-- %i\n", nReturn);
- return nReturn;
+ int result;
+ switch(LOWORD(lParam))
+ {
+ case 0: /* name */
+ {
+ result = stricmp(pszDrive1, pszDrive2);
+ hres = MAKE_COMPARE_HRESULT(result);
+ break;
+ }
+ case 1: /* Type */
+ {
+ /* We want to return immediately because SHELL32_CompareDetails also compares children. */
+ return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
+ }
+ case 2: /* Size */
+ case 3: /* Size Available */
+ {
+ ULARGE_INTEGER Drive1Available, Drive1Total, Drive2Available, Drive2Total;
+
+ if (GetVolumeInformationA(pszDrive1, NULL, 0, NULL, NULL, NULL, NULL, 0))
+ GetDiskFreeSpaceExA(pszDrive1, &Drive1Available, &Drive1Total, NULL);
+ else
+ Drive1Available.QuadPart = Drive1Total.QuadPart = 0;
+
+ if (GetVolumeInformationA(pszDrive2, NULL, 0, NULL, NULL, NULL, NULL, 0))
+ GetDiskFreeSpaceExA(pszDrive2, &Drive2Available, &Drive2Total, NULL);
+ else
+ Drive2Available.QuadPart = Drive2Total.QuadPart = 0;
+
+ LARGE_INTEGER Diff;
+ if (lParam == 2) /* Size */
+ Diff.QuadPart = Drive1Total.QuadPart - Drive2Total.QuadPart;
+ else /* Size available */
+ Diff.QuadPart = Drive1Available.QuadPart - Drive2Available.QuadPart;
+
+ hres = MAKE_COMPARE_HRESULT(Diff.QuadPart);
+ break;
+ }
+ default:
+ return E_INVALIDARG;
+ }
+
+ if (HRESULT_CODE(hres) == 0)
+ return SHELL32_CompareChildren(this, lParam, pidl1, pidl2);
+
+ return hres;
}
/**************************************************************************
}
else if (IsEqualIID(riid, IID_IShellView))
{
- hr = IShellView_Constructor ((IShellFolder *)this, &pShellView);
- if (pShellView)
- {
- hr = pShellView->QueryInterface(riid, ppvOut);
- }
+ hr = CDefView_Constructor(this, riid, ppvOut);
}
TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
return hr;
*/
HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD * rgfInOut)
{
- static const DWORD dwComputerAttributes =
- SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
- SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
- static const DWORD dwControlPanelAttributes =
- SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CANLINK;
- static const DWORD dwDriveAttributes =
- SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
- SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK;
-
TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
*rgfInOut &= dwDriveAttributes;
else if (_ILIsControlPanel(apidl[i]))
*rgfInOut &= dwControlPanelAttributes;
+ else if (_ILIsSpecialFolder(*apidl))
+ m_regFolder->GetAttributesOf(1, &apidl[i], rgfInOut);
else
- {
- pdump(apidl[i]);
- SHELL32_GetItemAttributes(this, apidl[i], rgfInOut);
- }
+ ERR("Got unknown pidl type!\n");
}
}
UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
REFIID riid, UINT *prgfInOut, LPVOID *ppvOut)
{
- LPITEMIDLIST pidl;
- IUnknown *pObj = NULL;
+ LPVOID pObj = NULL;
HRESULT hr = E_INVALIDARG;
TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", this,
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))
{
hr = IDataObject_Constructor (hwndOwner,
pidlRoot, apidl, cidl, (IDataObject **)&pObj);
}
- else if (IsEqualIID (riid, IID_IExtractIconA) && (cidl == 1))
+ else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
{
- pidl = ILCombine (pidlRoot, apidl[0]);
- pObj = IExtractIconA_Constructor (pidl);
- SHFree (pidl);
- hr = S_OK;
- }
- else if (IsEqualIID (riid, IID_IExtractIconW) && (cidl == 1))
- {
- pidl = ILCombine (pidlRoot, apidl[0]);
- pObj = IExtractIconW_Constructor (pidl);
- SHFree (pidl);
- hr = S_OK;
- }
- else if (IsEqualIID (riid, IID_IDropTarget) && (cidl >= 1))
- {
- IDropTarget * pDt = NULL;
- hr = this->QueryInterface(IID_PPV_ARG(IDropTarget, &pDt));
- pObj = pDt;
+ if (_ILIsDrive(apidl[0]))
+ hr = CDrivesExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
+ else
+ hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
}
- else if ((IsEqualIID(riid, IID_IShellLinkW) ||
- IsEqualIID(riid, IID_IShellLinkA)) && (cidl == 1))
+ else if (IsEqualIID (riid, IID_IDropTarget) && (cidl == 1))
{
- pidl = ILCombine (pidlRoot, apidl[0]);
- hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*) &pObj);
- SHFree (pidl);
+ 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;
if (!strRet)
return E_INVALIDARG;
+ if (!_ILIsPidlSimple (pidl))
+ {
+ return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
+ }
+ else if (_ILIsSpecialFolder(pidl))
+ {
+ return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet);
+ }
+ else if (!_ILIsDrive(pidl))
+ {
+ ERR("Wrong pidl type\n");
+ return E_INVALIDARG;
+ }
+
pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
if (!pszPath)
return E_OUTOFMEMORY;
pszPath[0] = 0;
- if (!pidl->mkid.cb)
+ _ILSimpleGetTextW(pidl, pszPath, MAX_PATH); /* append my own path */
+ /* long view "lw_name (C:)" */
+ if (!(dwFlags & SHGDN_FORPARSING))
{
- /* parsing name like ::{...} */
- pszPath[0] = ':';
- pszPath[1] = ':';
- SHELL32_GUIDToStringW(CLSID_MyComputer, &pszPath[2]);
- }
- else if (_ILIsPidlSimple(pidl))
- {
- /* take names of special folders only if its only this folder */
- if (_ILIsSpecialFolder(pidl))
+ WCHAR wszDrive[18] = {0};
+ DWORD dwVolumeSerialNumber, dwMaximumComponentLength, dwFileSystemFlags;
+ static const WCHAR wszOpenBracket[] = {' ', '(', 0};
+ static const WCHAR wszCloseBracket[] = {')', 0};
+
+ lstrcpynW(wszDrive, pszPath, 4);
+ pszPath[0] = L'\0';
+ GetVolumeInformationW(wszDrive, pszPath,
+ MAX_PATH - 7,
+ &dwVolumeSerialNumber,
+ &dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0);
+ pszPath[MAX_PATH-1] = L'\0';
+ if (!wcslen(pszPath))
{
- GUID const *clsid;
-
- clsid = _ILGetGUIDPointer (pidl);
- if (clsid)
+ UINT DriveType, ResourceId;
+ DriveType = GetDriveTypeW(wszDrive);
+ switch(DriveType)
{
- if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)
- {
- static const WCHAR clsidW[] = L"CLSID\\";
- static const WCHAR shellfolderW[] = L"\\shellfolder";
- static const WCHAR wantsForParsingW[] = L"WantsForParsing";
- BOOL bWantsForParsing = FALSE;
- WCHAR szRegPath[100];
- LONG r;
-
- /*
- * We can only get a filesystem path from a shellfolder
- * if the value WantsFORPARSING exists in
- * CLSID\\{...}\\shellfolder
- * exception: the MyComputer folder has this keys not
- * but like any filesystem backed
- * folder it needs these behaviour
- *
- * Get the "WantsFORPARSING" flag from the registry
- */
-
- wcscpy(szRegPath, clsidW);
- SHELL32_GUIDToStringW(*clsid, &szRegPath[6]);
- wcscat(szRegPath, shellfolderW);
- r = SHGetValueW(HKEY_CLASSES_ROOT, szRegPath,
- wantsForParsingW, NULL, NULL, NULL);
- if (r == ERROR_SUCCESS)
- bWantsForParsing = TRUE;
-
- if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
- bWantsForParsing)
- {
- /*
- * We need the filesystem path to the destination folder
- * Only the folder itself can know it
- */
- hr = SHELL32_GetDisplayNameOfChild (this, pidl,
- dwFlags, pszPath, MAX_PATH);
- }
- else
- {
- LPWSTR p = pszPath;
-
- /* parsing name like ::{...} */
- p[0] = ':';
- p[1] = ':';
- p += 2;
- p += SHELL32_GUIDToStringW(CLSID_MyComputer, p);
-
- /* \:: */
- p[0] = '\\';
- p[1] = ':';
- p[2] = ':';
- p += 3;
- SHELL32_GUIDToStringW(*clsid, p);
- }
- }
- else
- {
- /* user friendly name */
-
- if (_ILIsMyComputer(pidl) && sName)
- wcscpy(pszPath, sName);
- else
- HCR_GetClassNameW (*clsid, pszPath, MAX_PATH);
-
- TRACE("pszPath %s\n", debugstr_w(pszPath));
- }
+ case DRIVE_FIXED:
+ ResourceId = IDS_DRIVE_FIXED;
+ break;
+ case DRIVE_REMOTE:
+ ResourceId = IDS_DRIVE_NETWORK;
+ break;
+ case DRIVE_CDROM:
+ ResourceId = IDS_DRIVE_CDROM;
+ break;
+ default:
+ ResourceId = 0;
}
- else
+ if (ResourceId)
{
- /* append my own path */
- _ILSimpleGetTextW(pidl, pszPath, MAX_PATH);
+ dwFileSystemFlags = LoadStringW(shell32_hInstance, ResourceId, pszPath, MAX_PATH);
+ if (dwFileSystemFlags > MAX_PATH - 7)
+ pszPath[MAX_PATH-7] = L'\0';
}
}
- else if (_ILIsDrive(pidl))
- {
-
- _ILSimpleGetTextW(pidl, pszPath, MAX_PATH); /* append my own path */
- /* long view "lw_name (C:)" */
- if (!(dwFlags & SHGDN_FORPARSING))
- {
- WCHAR wszDrive[18] = {0};
- DWORD dwVolumeSerialNumber, dwMaximumComponentLength, dwFileSystemFlags;
- static const WCHAR wszOpenBracket[] = {' ', '(', 0};
- static const WCHAR wszCloseBracket[] = {')', 0};
-
- lstrcpynW(wszDrive, pszPath, 4);
- pszPath[0] = L'\0';
- GetVolumeInformationW(wszDrive, pszPath,
- MAX_PATH - 7,
- &dwVolumeSerialNumber,
- &dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0);
- pszPath[MAX_PATH-1] = L'\0';
- if (!wcslen(pszPath))
- {
- UINT DriveType, ResourceId;
- DriveType = GetDriveTypeW(wszDrive);
- switch(DriveType)
- {
- case DRIVE_FIXED:
- ResourceId = IDS_DRIVE_FIXED;
- break;
- case DRIVE_REMOTE:
- ResourceId = IDS_DRIVE_NETWORK;
- break;
- case DRIVE_CDROM:
- ResourceId = IDS_DRIVE_CDROM;
- break;
- default:
- ResourceId = 0;
- }
- if (ResourceId)
- {
- dwFileSystemFlags = LoadStringW(shell32_hInstance, ResourceId, pszPath, MAX_PATH);
- if (dwFileSystemFlags > MAX_PATH - 7)
- pszPath[MAX_PATH-7] = L'\0';
- }
- }
- wcscat (pszPath, wszOpenBracket);
- wszDrive[2] = L'\0';
- wcscat (pszPath, wszDrive);
- wcscat (pszPath, wszCloseBracket);
- }
- }
- else
- {
- /* Neither a shell namespace extension nor a drive letter. */
- ERR("Wrong pidl type\n");
- CoTaskMemFree(pszPath);
- return E_INVALIDARG;
- }
- }
- else
- {
- /* Complex pidl. Let the child folder do the work */
- hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, pszPath, MAX_PATH);
+ wcscat (pszPath, wszOpenBracket);
+ wszDrive[2] = L'\0';
+ wcscat (pszPath, wszDrive);
+ wcscat (pszPath, wszCloseBracket);
}
if (SUCCEEDED(hr))
HRESULT WINAPI CDrivesFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl,
LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
{
- LPWSTR sName;
- HKEY hKey;
- UINT length;
WCHAR szName[30];
- TRACE("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this,
- hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
-
if (_ILIsDrive(pidl))
{
if (_ILSimpleGetTextW(pidl, szName, _countof(szName)))
return S_OK;
}
-
- if (pPidlOut != NULL)
- *pPidlOut = _ILCreateMyComputer();
-
- length = (wcslen(lpName) + 1) * sizeof(WCHAR);
- sName = (LPWSTR)SHAlloc(length);
-
- if (!sName)
- return E_OUTOFMEMORY;
-
- if (RegOpenKeyExW(HKEY_CURRENT_USER,
- L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
- 0,
- KEY_WRITE,
- &hKey) != ERROR_SUCCESS)
- {
- WARN("Error: failed to open registry key\n");
- }
- else
- {
- RegSetValueExW(hKey, NULL, 0, REG_SZ, (const LPBYTE)lpName, length);
- RegCloseKey(hKey);
- }
-
- wcscpy(sName, lpName);
- SHFree(this->sName);
- this->sName = sName;
- TRACE("result %s\n", debugstr_w(sName));
- return S_OK;
+ return m_regFolder->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
}
HRESULT WINAPI CDrivesFolder::GetDefaultSearchGUID(GUID * pguid)
return E_NOTIMPL;
}
-/* FIXME: drive size >4GB is rolling over */
HRESULT WINAPI CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd)
{
HRESULT hr;
{
psd->fmt = MyComputerSFHeader[iColumn].fmt;
psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
- psd->str.uType = STRRET_CSTR;
- LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid,
- psd->str.cStr, MAX_PATH);
- return S_OK;
+ return SHSetStrRet(&psd->str, MyComputerSFHeader[iColumn].colnameid);
+ }
+ else if (_ILIsSpecialFolder(pidl))
+ {
+ return m_regFolder->GetDetailsOf(pidl, iColumn, psd);
}
else
{
switch (iColumn)
{
case 0: /* name */
- hr = GetDisplayNameOf(pidl,
- SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
+ hr = GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
break;
case 1: /* type */
_ILGetFileType(pidl, psd->str.cStr, MAX_PATH);
break;
case 2: /* total size */
- if (_ILIsDrive(pidl))
+ _ILSimpleGetText (pidl, szPath, MAX_PATH);
+ if (GetVolumeInformationA(szPath, NULL, 0, NULL, NULL, NULL, NULL, 0))
{
- _ILSimpleGetText (pidl, szPath, MAX_PATH);
- GetDiskFreeSpaceExA (szPath, NULL, &ulBytes, NULL);
- StrFormatByteSizeA (ulBytes.LowPart, psd->str.cStr, MAX_PATH);
+ GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
+ StrFormatByteSize64A(ulBytes.QuadPart, psd->str.cStr, MAX_PATH);
}
break;
case 3: /* free size */
- if (_ILIsDrive(pidl))
+ _ILSimpleGetText (pidl, szPath, MAX_PATH);
+ if (GetVolumeInformationA(szPath, NULL, 0, NULL, NULL, NULL, NULL, 0))
{
- _ILSimpleGetText (pidl, szPath, MAX_PATH);
- GetDiskFreeSpaceExA (szPath, &ulBytes, NULL, NULL);
- StrFormatByteSizeA (ulBytes.LowPart, psd->str.cStr, MAX_PATH);
+ GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
+ StrFormatByteSize64A(ulBytes.QuadPart, psd->str.cStr, MAX_PATH);
}
break;
}
*/
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;