ReactOS 0.4.16-dev-1946-g52006dd
CDrivesFolder.cpp
Go to the documentation of this file.
1/*
2 * Virtual Workplace folder
3 *
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999, 2002 Juergen Schmied
6 * Copyright 2009 Andrew Hill
7 * Copyright 2017-2024 Katayama Hirofumi MZ
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <precomp.h>
25#include <process.h>
26
28
29/*
30CDrivesFolder should create a CRegFolder to represent the virtual items that exist only in
31the registry. The CRegFolder is aggregated by the CDrivesFolder.
32The CDrivesFolderEnum class should enumerate only drives on the system. Since the CRegFolder
33implementation of IShellFolder::EnumObjects enumerates the virtual items, the
34CDrivesFolderEnum is only responsible for returning the physical items.
35
362. At least on my XP system, the drive pidls returned are of type PT_DRIVE1, not PT_DRIVE
373. The parsing name returned for my computer is incorrect. It should be "My Computer"
38*/
39
40static int iDriveIconIds[7] = { IDI_SHELL_NOT_CONNECTED_HDD, /* DRIVE_UNKNOWN */
41 IDI_SHELL_NOT_CONNECTED_HDD, /* DRIVE_NO_ROOT_DIR*/
42 IDI_SHELL_REMOVEABLE, /* DRIVE_REMOVABLE*/
43 IDI_SHELL_DRIVE, /* DRIVE_FIXED*/
44 IDI_SHELL_NETDRIVE, /* DRIVE_REMOTE*/
45 IDI_SHELL_CDROM, /* DRIVE_CDROM*/
46 IDI_SHELL_RAMDISK /* DRIVE_RAMDISK*/
47 };
48
49static int iDriveTypeIds[7] = { IDS_DRIVE_FIXED, /* DRIVE_UNKNOWN */
50 IDS_DRIVE_FIXED, /* DRIVE_NO_ROOT_DIR*/
51 IDS_DRIVE_REMOVABLE, /* DRIVE_REMOVABLE*/
52 IDS_DRIVE_FIXED, /* DRIVE_FIXED*/
53 IDS_DRIVE_NETWORK, /* DRIVE_REMOTE*/
54 IDS_DRIVE_CDROM, /* DRIVE_CDROM*/
55 IDS_DRIVE_FIXED /* FIXME */ /* DRIVE_RAMDISK*/
56 };
57
59{
60 { CLSID_ControlPanel, NULL, REGITEMORDER_MYCOMPUTER_CONTROLS },
61};
63{
66 CLSID_MyComputer,
67 L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
68 L"MyComputer",
69};
70
71static const CLSID* IsRegItem(PCUITEMID_CHILD pidl)
72{
73 if (pidl && pidl->mkid.cb == 2 + 2 + sizeof(CLSID))
74 {
75 if (pidl->mkid.abID[0] == PT_SHELLEXT || pidl->mkid.abID[0] == PT_GUID) // FIXME: Remove PT_GUID when CRegFolder is fixed
76 return (const CLSID*)(&pidl->mkid.abID[2]);
77 }
78 return NULL;
79}
80
82{
83 const CLSID *pClass = IsRegItem(pidl);
84 return pClass && *pClass == clsid;
85}
86
88{
89 if (!_ILIsDrive(pidl))
90 return -1;
91 BYTE letter = ((PIDLDATA*)pidl->mkid.abID)->u.drive.szDriveName[0];
92 BYTE number = (letter | 32) - 'a';
93 return number < 26 ? number : -1;
94}
95
96static INT8 GetDriveNumber(PCWSTR DrivePath)
97{
98 WORD number = (DrivePath[0] | 32) - 'a';
99 return number < 26 ? number : -1;
100}
101
103
105{
106 if (DrvNum < 0 || DrvNum >= 26)
107 return DRIVE_UNKNOWN;
108 if (g_IsFloppyCache & (1 << DrvNum))
109 return DRIVE_REMOVABLE;
110 WCHAR DrvPath[] = { LOWORD('A' + DrvNum), ':', '\\', '\0' };
111 return ::GetDriveTypeW(DrvPath);
112}
113
114static inline UINT GetCachedDriveType(PCWSTR DrivePath)
115{
116 return GetCachedDriveType(GetDriveNumber(DrivePath));
117}
118
119static bool IsFloppyDrive(PCWSTR DrivePath)
120{
121 extern BOOL IsDriveFloppyW(LPCWSTR pszDriveRoot);
122 INT8 DrvNum = GetDriveNumber(DrivePath);
123 if (DrvNum < 0)
124 return false;
125 if (g_IsFloppyCache & (1 << DrvNum))
126 return true;
127 UINT Type = GetCachedDriveType(DrvNum);
128 if (Type == DRIVE_REMOVABLE && IsDriveFloppyW(DrivePath))
129 {
130 g_IsFloppyCache |= (1 << DrvNum);
131 return true;
132 }
133 return false;
134}
135
137{
138 INT8 number = GetDriveNumber(pidl);
139 if (number < 0)
140 return number;
141 Path[0] = 'A' + number;
142 Path[1] = ':';
143 Path[2] = '\\';
144 Path[3] = '\0';
145 return number;
146}
147
149{
150 WCHAR buf[8];
151 if (GetDrivePath(pidl, buf) >= 0 && IsFloppyDrive(buf))
152 return SHDID_COMPUTER_DRIVE35; // TODO: 3.5-inch vs 5.25-inch
154}
155
157{
158 WCHAR szDrive[8];
159 if (!_ILGetDrive(pidl, szDrive, _countof(szDrive)))
160 {
161 ERR("pidl %p is not a drive\n", pidl);
162 return DRIVE_UNKNOWN;
163 }
164 return GetCachedDriveType(GetDriveNumber(szDrive));
165}
166
167static UINT SHELL_GetAutoRunInfPath(PCWSTR DrvPath, PWSTR AriPath, BOOL ForInvoke = FALSE)
168{
169 INT8 DrvNum = GetDriveNumber(DrvPath);
170 if (DrvNum < 0 || DrvPath[1] != ':' || (DrvPath[2] && (DrvPath[2] != '\\' || DrvPath[3])))
171 return 0;
172 if (!ForInvoke && IsFloppyDrive(DrvPath))
173 return 0; // Don't read label nor icon from floppy
175 return 0;
176 return wsprintfW(AriPath, L"%c:\\autorun.inf", DrvPath[0]);
177}
178
179#if 0 // TODO: Call this when the shell is notified about insert disc events
180bool SHELL_CanInvokeAutoRunOnDrive(PCWSTR DrvPath)
181{
182 INT8 DrvNum = GetDriveNumber(DrvPath);
183 if (DrvNum < 0 || (SHRestricted(REST_NODRIVEAUTORUN) & (1 << DrvNum)))
184 return false;
185 return !(SHRestricted(REST_NODRIVETYPEAUTORUN) & (1 << GetCachedDriveType(DrvNum)));
186}
187#endif
188
190{
191 // If this function returns true, the item should be hidden in DefView but not in the Explorer folder tree.
193 wsprintfW(path, L"%s\\%s", REGSTR_PATH_EXPLORER, SubKey);
195 DWORD data = 0, size = sizeof(data);
197}
198
199/***********************************************************************
200* IShellFolder implementation
201*/
202
203#define RETRY_COUNT 3
204#define RETRY_SLEEP 250
206{
207 DWORD dwError, dwBytesReturned;
208 DWORD dwCode = (bLock ? FSCTL_LOCK_VOLUME : FSCTL_UNLOCK_VOLUME);
209 for (DWORD i = 0; i < RETRY_COUNT; ++i)
210 {
211 if (DeviceIoControl(hDrive, dwCode, NULL, 0, NULL, 0, &dwBytesReturned, NULL))
212 return TRUE;
213
214 dwError = GetLastError();
215 if (dwError == ERROR_INVALID_FUNCTION)
216 break; /* don't sleep if function is not implemented */
217
219 }
220 SetLastError(dwError);
221 return FALSE;
222}
223
224// NOTE: See also https://support.microsoft.com/en-us/help/165721/how-to-ejecting-removable-media-in-windows-nt-windows-2000-windows-xp
225static BOOL DoEjectDrive(const WCHAR *physical, UINT nDriveType, INT *pnStringID)
226{
227 /* GENERIC_WRITE isn't needed for umount */
228 DWORD dwAccessMode = GENERIC_READ;
229 DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
230
231 HANDLE hDrive = CreateFile(physical, dwAccessMode, dwShareMode, 0, OPEN_EXISTING, 0, NULL);
232 if (hDrive == INVALID_HANDLE_VALUE)
233 return FALSE;
234
235 BOOL bResult, bNeedUnlock = FALSE;
236 DWORD dwBytesReturned, dwError = NO_ERROR;
237 PREVENT_MEDIA_REMOVAL removal;
238 do
239 {
240 bResult = TryToLockOrUnlockDrive(hDrive, TRUE);
241 if (!bResult)
242 {
243 dwError = GetLastError();
244 *pnStringID = IDS_CANTLOCKVOLUME; /* Unable to lock volume */
245 break;
246 }
247 bResult = DeviceIoControl(hDrive, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
248 if (!bResult)
249 {
250 dwError = GetLastError();
251 *pnStringID = IDS_CANTDISMOUNTVOLUME; /* Unable to dismount volume */
252 bNeedUnlock = TRUE;
253 break;
254 }
255 removal.PreventMediaRemoval = FALSE;
256 bResult = DeviceIoControl(hDrive, IOCTL_STORAGE_MEDIA_REMOVAL, &removal, sizeof(removal), NULL,
257 0, &dwBytesReturned, NULL);
258 if (!bResult)
259 {
260 *pnStringID = IDS_CANTEJECTMEDIA; /* Unable to eject media */
261 dwError = GetLastError();
262 bNeedUnlock = TRUE;
263 break;
264 }
265 bResult = DeviceIoControl(hDrive, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
266 if (!bResult)
267 {
268 *pnStringID = IDS_CANTEJECTMEDIA; /* Unable to eject media */
269 dwError = GetLastError();
270 bNeedUnlock = TRUE;
271 break;
272 }
273 } while (0);
274
275 if (bNeedUnlock)
276 {
278 }
279
280 CloseHandle(hDrive);
281
282 SetLastError(dwError);
283 return bResult;
284}
285
287{
288 UINT nDrive = PtrToUlong(args);
289 WCHAR szPath[] = { LOWORD(L'A' + nDrive), L'\0' }; // Arbitrary, just needs to include nDrive
292 if (FAILED(hr))
293 return hr;
295 return stub.DestroyWindow();
296}
297
299{
301 return succ ? S_OK : E_FAIL;
302}
303
305 HWND hwnd,
306 IDataObject *pdtobj,
307 UINT uMsg,
310{
311 if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND)
312 return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
313
314 PIDLIST_ABSOLUTE pidlFolder;
315 PUITEMID_CHILD *apidl;
316 UINT cidl;
318 HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
320 return hr;
321
322 WCHAR szDrive[8] = {0};
323 if (!_ILGetDrive(apidl[0], szDrive, _countof(szDrive)))
324 {
325 ERR("pidl is not a drive\n");
326 SHFree(pidlFolder);
327 _ILFreeaPidl(apidl, cidl);
328 return E_FAIL;
329 }
330 UINT nDriveType = GetCachedDriveType(szDrive);
331 if (!GetVolumeInformationW(szDrive, NULL, 0, NULL, NULL, &dwFlags, NULL, 0))
332 {
333 if (nDriveType >= DRIVE_REMOTE)
335 else
336 dwFlags = 0; // Assume drive with unknown filesystem, allow format
337 }
338
339// custom command IDs
340#if 0 // Disabled until our menu building system is fixed
341#define CMDID_FORMAT 0
342#define CMDID_EJECT 1
343#define CMDID_DISCONNECT 2
344#else
345/* FIXME: These IDs should start from 0, however there is difference
346 * between ours and Windows' menu building systems, which should be fixed. */
347#define CMDID_FORMAT 1
348#define CMDID_EJECT 2
349#define CMDID_DISCONNECT 3
350#endif
351
352 if (uMsg == DFM_MERGECONTEXTMENU)
353 {
354 QCMINFO *pqcminfo = (QCMINFO *)lParam;
355
356 UINT idCmdFirst = pqcminfo->idCmdFirst;
357 UINT idCmd = 0;
358 if (!(dwFlags & FILE_READ_ONLY_VOLUME) && nDriveType != DRIVE_REMOTE && cidl == 1)
359 {
360 /* add separator and Format */
361 idCmd = idCmdFirst + CMDID_FORMAT;
362 _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
364 }
365 if (nDriveType == DRIVE_REMOVABLE || nDriveType == DRIVE_CDROM)
366 {
367 /* add separator and Eject */
368 idCmd = idCmdFirst + CMDID_EJECT;
369 _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
371 }
372 if (nDriveType == DRIVE_REMOTE)
373 {
374 /* add separator and Disconnect */
375 idCmd = idCmdFirst + CMDID_DISCONNECT;
376 _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
378 }
379
380 if (idCmd)
381#if 0 // see FIXME above
382 pqcminfo->idCmdFirst = ++idCmd;
383#else
384 pqcminfo->idCmdFirst = (idCmd + 2);
385#endif
386 hr = S_OK;
387 }
388 else if (uMsg == DFM_INVOKECOMMAND)
389 {
390 WCHAR wszBuf[4] = L"A:\\";
391 wszBuf[0] = (WCHAR)szDrive[0];
392
393 INT nStringID = 0;
394 DWORD dwError = NO_ERROR;
395
397 {
398 ATLASSERT(pdtobj);
400 // Not setting nStringID because SHOpenPropSheet already displayed an error box
401 }
402 else
403 {
404 if (wParam == CMDID_FORMAT)
405 {
406 hr = DoFormatDriveAsync(hwnd, szDrive[0] - 'A');
407 }
408 else if (wParam == CMDID_EJECT)
409 {
410 /* do eject */
411 WCHAR physical[10];
412 wsprintfW(physical, _T("\\\\.\\%c:"), szDrive[0]);
413
414 if (DoEjectDrive(physical, nDriveType, &nStringID))
415 {
417 }
418 else
419 {
420 dwError = GetLastError();
421 }
422 }
423 else if (wParam == CMDID_DISCONNECT)
424 {
425 /* do disconnect */
426 wszBuf[2] = UNICODE_NULL;
427 dwError = WNetCancelConnection2W(wszBuf, 0, FALSE);
428 if (dwError == NO_ERROR)
429 {
431 }
432 else
433 {
434 nStringID = IDS_CANTDISCONNECT;
435 }
436 }
437 }
438
439 if (nStringID != 0)
440 {
441 /* show error message */
442 WCHAR szFormat[128], szMessage[128];
443 LoadStringW(shell32_hInstance, nStringID, szFormat, _countof(szFormat));
444 wsprintfW(szMessage, szFormat, dwError);
445 MessageBoxW(hwnd, szMessage, NULL, MB_ICONERROR);
446 }
447 }
448
449 SHFree(pidlFolder);
450 _ILFreeaPidl(apidl, cidl);
451
452 return hr;
453}
454
456 HWND hwnd,
457 UINT cidl,
459 IShellFolder *psf,
460 IContextMenu **ppcm)
461{
462 CRegKeyHandleArray keys;
463 AddClassKeyToArray(L"Drive", keys, keys);
464 AddClassKeyToArray(L"Folder", keys, keys);
465 return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, DrivesContextMenuCallback, keys, keys, ppcm);
466}
467
468static HRESULT
470 _In_ PCWSTR pszDrivePath,
471 _Out_writes_z_(cchMax) PWSTR szIconFile,
473 _Out_ int *piIndex,
474 _Out_ UINT *pGilOut)
475{
476 WCHAR wszPath[MAX_PATH];
477 WCHAR wszAutoRunInfPath[MAX_PATH];
478 WCHAR wszValue[MAX_PATH], wszTemp[MAX_PATH];
479
480 if (!SHELL_GetAutoRunInfPath(pszDrivePath, wszAutoRunInfPath))
481 return E_FAIL;
482 wcscpy(wszPath, pszDrivePath);
483
484 // autorun.inf --> wszValue
485 if (GetPrivateProfileStringW(L"autorun", L"icon", NULL, wszValue, _countof(wszValue),
486 wszAutoRunInfPath) && wszValue[0] != 0)
487 {
488 // wszValue --> wszTemp
489 ExpandEnvironmentStringsW(wszValue, wszTemp, _countof(wszTemp));
490
491 *piIndex = PathParseIconLocationW(wszTemp);
492
493 // wszPath + wszTemp --> wszPath
494 if (PathIsRelativeW(wszTemp))
495 PathAppendW(wszPath, wszTemp);
496 else
497 StringCchCopyW(wszPath, _countof(wszPath), wszTemp);
498
499 // wszPath --> szIconFile
500 GetFullPathNameW(wszPath, cchMax, szIconFile, NULL);
501 return S_OK;
502 }
503 return E_FAIL;
504}
505
506static HRESULT
508{
509 WCHAR wszAutoRunInfPath[MAX_PATH];
510 WCHAR wszTemp[MAX_PATH];
511
512 if (!SHELL_GetAutoRunInfPath(wszPath, wszAutoRunInfPath))
513 return E_FAIL;
514
515 if (GetPrivateProfileStringW(L"autorun", L"label", NULL, wszTemp, _countof(wszTemp),
516 wszAutoRunInfPath) && wszTemp[0] != 0)
517 {
518 return StringCchCopyW(szLabel, cchMax, wszTemp);
519 }
520 return E_FAIL;
521}
522
523static inline HRESULT GetRawDriveLabel(PCWSTR DrivePath, LPWSTR szLabel, UINT cchMax)
524{
525 if (GetVolumeInformationW(DrivePath, szLabel, cchMax, NULL, NULL, NULL, NULL, 0))
526 return *szLabel ? S_OK : S_FALSE;
528}
529
530static HRESULT GetDriveLabel(PCWSTR DrivePath, LPWSTR szLabel, UINT cchMax)
531{
532 HRESULT hr = getLabelForDriveFromAutoRun(DrivePath, szLabel, cchMax);
533 return hr == S_OK ? S_OK : GetRawDriveLabel(DrivePath, szLabel, cchMax);
534}
535
537 _In_ INT8 DriveNum,
538 _Out_writes_z_(cchMax) PWSTR szIconFile,
540 _Out_ int *piIndex,
541 _Out_ UINT *pGilOut)
542{
543 WCHAR szKey[200], chDrv = 'A' + DriveNum;
544 wsprintfW(szKey, L"%s\\DriveIcons\\%c\\DefaultIcon", REGSTR_PATH_EXPLORER, chDrv);
545 DWORD cb = cchMax * sizeof(*szIconFile);
547 if (err != ERROR_SUCCESS)
548 {
549 cb = cchMax * sizeof(*szIconFile);
550 wsprintfW(szKey, L"Applications\\Explorer.exe\\Drives\\%c\\DefaultIcon", chDrv);
551 err = RegGetValueW(HKEY_CLASSES_ROOT, szKey, NULL, RRF_RT_REG_SZ, NULL, szIconFile, &cb);
552 }
553 if (err != ERROR_SUCCESS)
554 return false;
555 *piIndex = PathParseIconLocationW(szIconFile);
556 return *szIconFile != UNICODE_NULL;
557}
558
560{
561 CComPtr<IDefaultExtractIconInit> initIcon;
564 return hr;
565
566 WCHAR wTemp[MAX_PATH], szDrive[8];
567 int icon_idx, reg_idx = 0;
568 UINT GilOut = 0;
569 BOOL bFloppy = FALSE;
570 INT8 DriveNum = GetDrivePath(pidl, szDrive);
574
575 switch (DriveType)
576 {
577 case DRIVE_REMOVABLE:
578 bFloppy = IsFloppyDrive(szDrive);
579 reg_idx = bFloppy ? IDI_SHELL_3_14_FLOPPY : IDI_SHELL_REMOVEABLE;
580 break;
581 case DRIVE_FIXED:
582 reg_idx = IDI_SHELL_DRIVE;
583 break;
584 case DRIVE_REMOTE:
585 reg_idx = IDI_SHELL_NETDRIVE;
586 break;
587 case DRIVE_CDROM:
588 reg_idx = IDI_SHELL_CDROM;
589 break;
590 case DRIVE_RAMDISK:
591 reg_idx = IDI_SHELL_RAMDISK;
592 break;
593 }
594
595 hr = getIconLocationForDrive(szDrive, wTemp, _countof(wTemp),
596 &icon_idx, &GilOut);
597 if (SUCCEEDED(hr))
598 {
599 initIcon->SetNormalIcon(wTemp, icon_idx);
600 }
601 else if (DriveType > DRIVE_NO_ROOT_DIR &&
602 GetRegCustomizedDriveIcon(DriveNum, wTemp, _countof(wTemp), &icon_idx, &GilOut))
603 {
604 initIcon->SetNormalIcon(wTemp, icon_idx);
605 }
606 else if (reg_idx && HLM_GetIconW(reg_idx - 1, wTemp, _countof(wTemp), &icon_idx))
607 {
608 initIcon->SetNormalIcon(wTemp, icon_idx);
609 }
610 else if (DriveType == DRIVE_FIXED &&
611 HCR_GetIconW(L"Drive", wTemp, NULL, _countof(wTemp), &icon_idx))
612 {
613 initIcon->SetNormalIcon(wTemp, icon_idx);
614 }
615 else
616 {
617 if (DriveType == DRIVE_REMOVABLE && bFloppy)
618 icon_idx = IDI_SHELL_3_14_FLOPPY;
619 else
620 icon_idx = iDriveIconIds[DriveType];
621 initIcon->SetNormalIcon(swShell32Name, -icon_idx);
622 }
623
624 return initIcon->QueryInterface(riid, ppvOut);
625}
626
628 public CEnumIDListBase
629{
630 public:
631 HRESULT WINAPI Initialize(HWND hwndOwner, DWORD dwFlags, IEnumIDList* pRegEnumerator)
632 {
633 /* enumerate the folders */
634 if (dwFlags & SHCONTF_FOLDERS)
635 {
636 WCHAR wszDriveName[] = {'A', ':', '\\', '\0'};
637 DWORD dwDrivemap = GetLogicalDrives() & ~SHRestricted(REST_NODRIVES);
638 for (; wszDriveName[0] <= 'Z'; wszDriveName[0]++)
639 {
640 if (dwDrivemap & 1)
641 AddToEnumList(_ILCreateDrive(wszDriveName));
642 dwDrivemap >>= 1;
643 }
644 }
645
646 /* Enumerate the items of the reg folder */
647 AppendItemsFromEnumerator(pRegEnumerator);
648
649 return S_OK;
650 }
651
653 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
655};
656
657/***********************************************************************
658* IShellFolder [MyComputer] implementation
659*/
660
667};
668
670 SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
671 SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
673 SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CANLINK;
675 SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
676 SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANCOPY;
677
679{
680 pidlRoot = NULL;
682}
683
685{
686 TRACE("-- destroying IShellFolder(%p)\n", this);
688}
689
691{
692 pidlRoot = _ILCreateMyComputer(); /* my qualified pidl */
693 if (pidlRoot == NULL)
694 return E_OUTOFMEMORY;
695
696 REGFOLDERINITDATA RegInit = { static_cast<IShellFolder*>(this), &g_RegFolderInfo };
698 pidlRoot,
700
701 return hr;
702}
703
704/**************************************************************************
705* CDrivesFolder::ParseDisplayName
706*/
708 DWORD * pchEaten, PIDLIST_RELATIVE * ppidl, DWORD * pdwAttributes)
709{
711
712 TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", this,
713 hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
714 pchEaten, ppidl, pdwAttributes);
715
716 if (!ppidl)
717 return hr;
718
719 *ppidl = NULL;
720
721 if (!lpszDisplayName)
722 return hr;
723
724 /* handle CLSID paths */
725 if (lpszDisplayName[0] == L':' && lpszDisplayName[1] == L':')
726 {
727 return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl,
728 pdwAttributes);
729 }
730
731 if (((L'A' <= lpszDisplayName[0] && lpszDisplayName[0] <= L'Z') ||
732 (L'a' <= lpszDisplayName[0] && lpszDisplayName[0] <= L'z')) &&
733 lpszDisplayName[1] == L':' && (lpszDisplayName[2] == L'\\' || !lpszDisplayName[2]))
734 {
735 // "C:\..."
736 WCHAR szRoot[8];
737 PathBuildRootW(szRoot, ((*lpszDisplayName - 1) & 0x1F));
738
739 if (SHIsFileSysBindCtx(pbc, NULL) != S_OK && !(BindCtx_GetMode(pbc, 0) & STGM_CREATE))
740 {
741 if (::GetDriveType(szRoot) == DRIVE_NO_ROOT_DIR)
743 }
744
745 CComHeapPtr<ITEMIDLIST> pidlTemp(_ILCreateDrive(szRoot));
746 if (!pidlTemp)
747 return E_OUTOFMEMORY;
748
749 if (lpszDisplayName[2] && lpszDisplayName[3])
750 {
751 CComPtr<IShellFolder> pChildFolder;
752 hr = BindToObject(pidlTemp, pbc, IID_PPV_ARG(IShellFolder, &pChildFolder));
754 return hr;
755
756 ULONG chEaten;
757 CComHeapPtr<ITEMIDLIST> pidlChild;
758 hr = pChildFolder->ParseDisplayName(hwndOwner, pbc, &lpszDisplayName[3], &chEaten,
759 &pidlChild, pdwAttributes);
761 return hr;
762
763 hr = SHILCombine(pidlTemp, pidlChild, ppidl);
764 }
765 else
766 {
767 *ppidl = pidlTemp.Detach();
768 if (pdwAttributes && *pdwAttributes)
769 GetAttributesOf(1, (PCUITEMID_CHILD_ARRAY)ppidl, pdwAttributes);
770 hr = S_OK;
771 }
772 }
773
774 TRACE("(%p)->(-- ret=0x%08x)\n", this, hr);
775
776 return hr;
777}
778
779/**************************************************************************
780* CDrivesFolder::EnumObjects
781*/
782HRESULT WINAPI CDrivesFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
783{
784 CComPtr<IEnumIDList> pRegEnumerator;
785 m_regFolder->EnumObjects(hwndOwner, dwFlags, &pRegEnumerator);
786
787 return ShellObjectCreatorInit<CDrivesFolderEnum>(hwndOwner, dwFlags, pRegEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
788}
789
790/**************************************************************************
791* CDrivesFolder::BindToObject
792*/
794{
795 TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this,
796 pidl, pbcReserved, shdebugstr_guid(&riid), ppvOut);
797
798 if (!pidl)
799 return E_INVALIDARG;
800
801 if (_ILIsSpecialFolder(pidl))
802 return m_regFolder->BindToObject(pidl, pbcReserved, riid, ppvOut);
803
804 CHAR* pchDrive = _ILGetDataPointer(pidl)->u.drive.szDriveName;
805
806 PERSIST_FOLDER_TARGET_INFO pfti = {0};
807 pfti.dwAttributes = -1;
808 pfti.csidl = -1;
809 pfti.szTargetParsingName[0] = *pchDrive;
810 pfti.szTargetParsingName[1] = L':';
811 pfti.szTargetParsingName[2] = L'\\';
812
814 &pfti,
815 pidl,
816 &CLSID_ShellFSFolder,
817 riid,
818 ppvOut);
820 return hr;
821
822 return S_OK;
823}
824
825/**************************************************************************
826* CDrivesFolder::BindToStorage
827*/
829{
830 FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", this,
831 pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
832
833 *ppvOut = NULL;
834 return E_NOTIMPL;
835}
836
837/**************************************************************************
838* CDrivesFolder::CompareIDs
839*/
841{
843 UINT iColumn = LOWORD(lParam);
844
845 if (iColumn >= _countof(MyComputerSFHeader))
846 return E_INVALIDARG;
847
848 if (!pidl1 || !pidl2)
849 {
850 ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam, pidl1, pidl2);
851 return E_INVALIDARG;
852 }
853
854 CHAR* pszDrive1 = _ILIsDrive(pidl1) ? _ILGetDataPointer(pidl1)->u.drive.szDriveName : NULL;
855 if (!pszDrive1 && !IsRegItem(pidl1) && FAILED_UNEXPECTEDLY(E_INVALIDARG))
856 return E_INVALIDARG;
857 CHAR* pszDrive2 = _ILIsDrive(pidl2) ? _ILGetDataPointer(pidl2)->u.drive.szDriveName : NULL;
858 if (!pszDrive2 && !IsRegItem(pidl2) && FAILED_UNEXPECTEDLY(E_INVALIDARG))
859 return E_INVALIDARG;
860
861 int result;
862 switch (MyComputerSFHeader[iColumn].colnameid)
863 {
865 {
866 if (!pszDrive1 && !pszDrive2)
867 return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
868 else if (pszDrive1 && pszDrive2)
869 result = _stricmp(pszDrive1, pszDrive2);
870 else
871 result = (int)!pszDrive1 - (int)!pszDrive2; // Sort drives first
873 break;
874 }
875
878 {
879 if (!pszDrive1 || !pszDrive2)
880 {
881 hres = MAKE_COMPARE_HRESULT((int)!pszDrive1 - (int)!pszDrive2);
882 break;
883 }
884
885 ULARGE_INTEGER Drive1Available, Drive1Total, Drive2Available, Drive2Total;
886 BOOL bValid1 = FALSE, bValid2 = FALSE;
887
888 if (GetVolumeInformationA(pszDrive1, NULL, 0, NULL, NULL, NULL, NULL, 0))
889 bValid1 = GetDiskFreeSpaceExA(pszDrive1, &Drive1Available, &Drive1Total, NULL);
890 else
891 Drive1Available.QuadPart = Drive1Total.QuadPart = 0;
892
893 if (GetVolumeInformationA(pszDrive2, NULL, 0, NULL, NULL, NULL, NULL, 0))
894 bValid2 = GetDiskFreeSpaceExA(pszDrive2, &Drive2Available, &Drive2Total, NULL);
895 else
896 Drive2Available.QuadPart = Drive2Total.QuadPart = 0;
897
898 LARGE_INTEGER Diff;
899 if (MyComputerSFHeader[iColumn].colnameid == IDS_SHV_COLUMN_DISK_CAPACITY) /* Size */
900 Diff.QuadPart = Drive1Total.QuadPart - Drive2Total.QuadPart;
901 else /* Size available */
902 Diff.QuadPart = Drive1Available.QuadPart - Drive2Available.QuadPart;
903
904 if (bValid1 != bValid2)
905 hres = MAKE_COMPARE_HRESULT((int)!bValid1 - (int)!bValid2);
906 else
908
909 break;
910 }
913 {
914 /* We want to return immediately because SHELL32_CompareDetails also compares children. */
915 return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
916 }
918 }
919
920 if (HRESULT_CODE(hres) == 0)
921 return SHELL32_CompareChildren(this, lParam, pidl1, pidl2);
922
923 return hres;
924}
925
926/**************************************************************************
927* CDrivesFolder::CreateViewObject
928*/
930{
931 CComPtr<IShellView> pShellView;
933
934 TRACE("(%p)->(hwnd=%p,%s,%p)\n", this,
935 hwndOwner, shdebugstr_guid (&riid), ppvOut);
936
937 if (!ppvOut)
938 return hr;
939
940 *ppvOut = NULL;
941
942 if (IsEqualIID(riid, IID_IDropTarget))
943 {
944 WARN("IDropTarget not implemented\n");
945 hr = E_NOTIMPL;
946 }
947 else if (IsEqualIID(riid, IID_IContextMenu))
948 {
949 DEFCONTEXTMENU dcm = { hwndOwner, this, pidlRoot, this };
950 hr = SHCreateDefaultContextMenu(&dcm, riid, ppvOut);
951 }
952 else if (IsEqualIID(riid, IID_IShellView))
953 {
954 SFV_CREATE sfvparams = { sizeof(SFV_CREATE), this, NULL, this };
955 hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
956 }
957 TRACE("-- (%p)->(interface=%p)\n", this, ppvOut);
958 return hr;
959}
960
961/**************************************************************************
962* CDrivesFolder::GetAttributesOf
963*/
965{
966 TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
967 this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
968
969 if (cidl && !apidl)
970 return E_INVALIDARG;
971
972 if (*rgfInOut == 0)
973 *rgfInOut = ~0;
974
975 if(cidl == 0)
976 *rgfInOut &= dwComputerAttributes;
977 else
978 {
979 for (UINT i = 0; i < cidl; ++i)
980 {
981 if (_ILIsDrive(apidl[i]))
982 {
983 *rgfInOut &= dwDriveAttributes;
984
985 if (_ILGetDriveType(apidl[i]) == DRIVE_CDROM)
986 *rgfInOut &= ~SFGAO_CANRENAME; // CD-ROM drive cannot rename
987 }
988 else if (IsRegItem(apidl[i], CLSID_ControlPanel))
989 {
990 *rgfInOut &= dwControlPanelAttributes;
991 }
992 else if (_ILIsSpecialFolder(*apidl))
993 {
994 m_regFolder->GetAttributesOf(1, &apidl[i], rgfInOut);
995 }
996 else
997 {
998 ERR("Got unknown pidl type!\n");
999 }
1000 }
1001 }
1002
1003 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
1004 *rgfInOut &= ~SFGAO_VALIDATE;
1005
1006 TRACE("-- result=0x%08x\n", *rgfInOut);
1007 return S_OK;
1008}
1009
1010/**************************************************************************
1011* CDrivesFolder::GetUIObjectOf
1012*
1013* PARAMETERS
1014* hwndOwner [in] Parent window for any output
1015* cidl [in] array size
1016* apidl [in] simple pidl array
1017* riid [in] Requested Interface
1018* prgfInOut [ ] reserved
1019* ppvObject [out] Resulting Interface
1020*
1021*/
1023 UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
1024 REFIID riid, UINT *prgfInOut, LPVOID *ppvOut)
1025{
1026 LPVOID pObj = NULL;
1028
1029 TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", this,
1030 hwndOwner, cidl, apidl, shdebugstr_guid (&riid), prgfInOut, ppvOut);
1031
1032 if (!ppvOut)
1033 return hr;
1034
1035 *ppvOut = NULL;
1036
1037 if (IsEqualIID (riid, IID_IContextMenu) && (cidl >= 1))
1038 {
1039 if (_ILIsDrive(apidl[0]))
1040 hr = CDrivesContextMenu_CreateInstance(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), (IContextMenu**)&pObj);
1041 else
1042 hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
1043 }
1044 else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
1045 {
1046 hr = IDataObject_Constructor(hwndOwner,
1047 pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj);
1048 }
1049 else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
1050 {
1051 if (_ILIsDrive(apidl[0]))
1052 hr = CDrivesExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
1053 else
1054 hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
1055 }
1056 else if (IsEqualIID (riid, IID_IDropTarget) && (cidl == 1))
1057 {
1058 CComPtr<IShellFolder> psfChild;
1059 hr = this->BindToObject(apidl[0], NULL, IID_PPV_ARG(IShellFolder, &psfChild));
1061 return hr;
1062
1063 return psfChild->CreateViewObject(NULL, riid, ppvOut);
1064 }
1065 else
1066 hr = E_NOINTERFACE;
1067
1068 if (SUCCEEDED(hr) && !pObj)
1069 hr = E_OUTOFMEMORY;
1070
1071 *ppvOut = pObj;
1072 TRACE("(%p)->hr=0x%08x\n", this, hr);
1073 return hr;
1074}
1075
1076/**************************************************************************
1077* CDrivesFolder::GetDisplayNameOf
1078*/
1080{
1081 WCHAR szDrive[8];
1082
1083 TRACE("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
1084 pdump (pidl);
1085
1086 if (!strRet)
1087 return E_INVALIDARG;
1088
1089 if (!_ILIsPidlSimple (pidl))
1090 {
1091 return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
1092 }
1093 else if (_ILIsSpecialFolder(pidl))
1094 {
1095 return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet);
1096 }
1097 else if (GetDrivePath(pidl, szDrive) < 0)
1098 {
1099 ERR("Wrong pidl type\n");
1100 return E_INVALIDARG;
1101 }
1102
1103 PWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
1104 if (!pszPath)
1105 return E_OUTOFMEMORY;
1106 pszPath[0] = UNICODE_NULL;
1107 szDrive[0] &= ~32; // Always uppercase
1108
1109 /* long view "lw_name (C:)" */
1111 if (!(dwFlags & SHGDN_FORPARSING))
1112 {
1113 if (m_DriveDisplayMode < 0)
1114 {
1115 DWORD err, type, data, cb = sizeof(data);
1116 err = SHRegGetUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
1117 L"ShowDriveLettersFirst", &type, &data, &cb, FALSE, NULL, 0);
1118 m_DriveDisplayMode = (!err && type == REG_DWORD && cb == sizeof(data)) ? (BYTE)data : 0;
1119 }
1120 BOOL bRemoteFirst = m_DriveDisplayMode == 1;
1121 BOOL bNoLetter = m_DriveDisplayMode == 2;
1122 BOOL bAllFirst = m_DriveDisplayMode == 4;
1123 PWSTR pszLabel = pszPath;
1124
1125 if (!bNoLetter && (bAllFirst || (bRemoteFirst && GetCachedDriveType(szDrive) == DRIVE_REMOTE)))
1126 {
1127 bNoLetter = TRUE; // Handling the letter now, don't append it again later
1128 if (!bEditLabel)
1129 pszLabel += wsprintfW(pszPath, L"(%c:) ", szDrive[0]);
1130 }
1131
1132 if (GetDriveLabel(szDrive, pszLabel, MAX_PATH - 7) != S_OK && !bEditLabel)
1133 {
1134 UINT ResId = 0, DrvType = GetCachedDriveType(szDrive);
1135 if (DrvType == DRIVE_REMOVABLE)
1137 else if (DrvType < _countof(iDriveTypeIds))
1138 ResId = iDriveTypeIds[DrvType];
1139
1140 if (ResId)
1141 {
1142 UINT len = LoadStringW(shell32_hInstance, ResId, pszLabel, MAX_PATH - 7);
1143 if (len > MAX_PATH - 7)
1144 pszLabel[MAX_PATH-7] = UNICODE_NULL;
1145 }
1146 }
1147
1148 if (!*pszLabel && !bEditLabel) // No label nor fallback description, use SHGDN_FORPARSING
1149 *pszPath = UNICODE_NULL;
1150 else if (!bNoLetter && !bEditLabel)
1151 wsprintfW(pszPath + wcslen(pszPath), L" (%c:)", szDrive[0]);
1152 }
1153
1154 if (!*pszPath && !bEditLabel) // SHGDN_FORPARSING or failure above (except editing empty label)
1155 {
1157 szDrive[2] = UNICODE_NULL; // Remove backslash
1158 wcscpy(pszPath, szDrive);
1159 }
1160 strRet->uType = STRRET_WSTR;
1161 strRet->pOleStr = pszPath;
1162
1163 TRACE("-- (%p)->(%s)\n", this, strRet->uType == STRRET_CSTR ? strRet->cStr : debugstr_w(strRet->pOleStr));
1164 return S_OK;
1165}
1166
1167/**************************************************************************
1168* CDrivesFolder::SetNameOf
1169* Changes the name of a file object or subfolder, possibly changing its item
1170* identifier in the process.
1171*
1172* PARAMETERS
1173* hwndOwner [in] Owner window for output
1174* pidl [in] simple pidl of item to change
1175* lpszName [in] the items new display name
1176* dwFlags [in] SHGNO formatting flags
1177* ppidlOut [out] simple pidl returned
1178*/
1180 LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
1181{
1182 if (_ILIsDrive(pidl))
1183 {
1184 WCHAR szDrive[8];
1185 HRESULT hr = GetDrivePath(pidl, szDrive) >= 0 ? SetDriveLabel(hwndOwner, szDrive, lpName) : E_FAIL;
1186 if (pPidlOut)
1187 *pPidlOut = SUCCEEDED(hr) ? _ILCreateDrive(szDrive) : NULL;
1188 return hr;
1189 }
1190 return m_regFolder->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
1191}
1192
1194{
1196 if (SUCCEEDED(hr))
1197 SHChangeNotify(SHCNE_RENAMEFOLDER, SHCNF_PATHW, DrivePath, DrivePath); // DisplayName changed
1198 else if (hwndOwner)
1199 SHELL_ErrorBox(hwndOwner, hr);
1200 return hr;
1201}
1202
1204{
1205 FIXME("(%p)\n", this);
1206 return E_NOTIMPL;
1207}
1208
1210{
1211 FIXME("(%p)\n", this);
1212 return E_NOTIMPL;
1213}
1214
1216{
1217 TRACE("(%p)\n", this);
1218
1219 if (pSort)
1220 *pSort = 0;
1221 if (pDisplay)
1222 *pDisplay = 0;
1223 return S_OK;
1224}
1225
1227{
1228 TRACE("(%p)\n", this);
1229
1230 if (!pcsFlags || iColumn >= _countof(MyComputerSFHeader))
1231 return E_INVALIDARG;
1232 *pcsFlags = MyComputerSFHeader[iColumn].colstate;
1233 return S_OK;
1234}
1235
1237{
1238 const CLSID *pCLSID = IsRegItem(pidl);
1239 if (pscid->fmtid == FMTID_ShellDetails)
1240 {
1241 switch (pscid->pid)
1242 {
1243 case PID_DESCRIPTIONID:
1244 {
1245 if (pCLSID)
1248 switch (_ILGetDriveType(pidl))
1249 {
1250 case DRIVE_REMOVABLE: id = _ILGetRemovableTypeId(pidl); break;
1251 case DRIVE_FIXED: id = SHDID_COMPUTER_FIXED; break;
1252 case DRIVE_REMOTE: id = SHDID_COMPUTER_NETDRIVE; break;
1253 case DRIVE_CDROM: id = SHDID_COMPUTER_CDROM; break;
1254 case DRIVE_RAMDISK: id = SHDID_COMPUTER_RAMDISK; break;
1255 }
1256 return SHELL_CreateSHDESCRIPTIONID(pv, id, &CLSID_NULL);
1257 }
1258 }
1259 }
1260 if (pCLSID)
1261 return m_regFolder->GetDetailsEx(pidl, pscid, pv);
1262 return SH32_GetDetailsOfPKeyAsVariant(this, pidl, pscid, pv, FALSE);
1263}
1264
1266{
1267 HRESULT hr;
1268
1269 TRACE("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd);
1270
1271 if (!psd || iColumn >= _countof(MyComputerSFHeader))
1272 return E_INVALIDARG;
1273
1274 if (!pidl)
1275 {
1276 psd->fmt = MyComputerSFHeader[iColumn].fmt;
1277 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
1278 return SHSetStrRet(&psd->str, MyComputerSFHeader[iColumn].colnameid);
1279 }
1280 else if (!_ILIsDrive(pidl))
1281 {
1282 switch (MyComputerSFHeader[iColumn].colnameid)
1283 {
1285 return m_regFolder->GetDetailsOf(pidl, SHFSF_COL_NAME, psd);
1287 return m_regFolder->GetDetailsOf(pidl, SHFSF_COL_TYPE, psd);
1290 return SHSetStrRetEmpty(&psd->str);
1292 return m_regFolder->GetDetailsOf(pidl, SHFSF_COL_COMMENT, psd);
1294 }
1295 }
1296 else
1297 {
1298 ULARGE_INTEGER ulTotalBytes, ulFreeBytes;
1299 WCHAR szDrive[8];
1300 INT8 DriveNum = GetDrivePath(pidl, szDrive);
1301 UINT DriveType = GetCachedDriveType(DriveNum);
1304
1305 switch (MyComputerSFHeader[iColumn].colnameid)
1306 {
1309 break;
1311 if (DriveType == DRIVE_UNKNOWN)
1312 hr = SHSetStrRetEmpty(&psd->str);
1313 else if (DriveType == DRIVE_REMOVABLE && IsFloppyDrive(szDrive))
1314 hr = SHSetStrRet(&psd->str, IDS_DRIVE_FLOPPY);
1315 else
1316 hr = SHSetStrRet(&psd->str, iDriveTypeIds[DriveType]);
1317 break;
1320 psd->str.cStr[0] = 0x00;
1321 psd->str.uType = STRRET_CSTR;
1322 if (GetVolumeInformationW(szDrive, NULL, 0, NULL, NULL, NULL, NULL, 0))
1323 {
1324 GetDiskFreeSpaceExW(szDrive, &ulFreeBytes, &ulTotalBytes, NULL);
1325 if (iColumn == 2)
1326 StrFormatByteSize64A(ulTotalBytes.QuadPart, psd->str.cStr, MAX_PATH);
1327 else
1328 StrFormatByteSize64A(ulFreeBytes.QuadPart, psd->str.cStr, MAX_PATH);
1329 }
1330 hr = S_OK;
1331 break;
1333 hr = SHSetStrRetEmpty(&psd->str); /* FIXME: comments */
1334 break;
1336 }
1337 }
1338
1339 return hr;
1340}
1341
1343{
1344 switch (column < _countof(MyComputerSFHeader) ? MyComputerSFHeader[column].colnameid : ~0UL)
1345 {
1346 case IDS_SHV_COLUMN_NAME: return MakeSCID(*pscid, FMTID_Storage, PID_STG_NAME);
1347 case IDS_SHV_COLUMN_TYPE: return MakeSCID(*pscid, FMTID_Storage, PID_STG_STORAGETYPE);
1348 case IDS_SHV_COLUMN_COMMENTS: return MakeSCID(*pscid, FMTID_SummaryInformation, PIDSI_COMMENTS);
1349 }
1350 return E_INVALIDARG;
1351}
1352
1353/************************************************************************
1354 * CDrivesFolder::GetClassID
1355 */
1357{
1358 TRACE("(%p)\n", this);
1359
1360 if (!lpClassId)
1361 return E_POINTER;
1362
1363 *lpClassId = CLSID_MyComputer;
1364 return S_OK;
1365}
1366
1367/************************************************************************
1368 * CDrivesFolder::Initialize
1369 *
1370 * NOTES: it makes no sense to change the pidl
1371 */
1373{
1374 return S_OK;
1375}
1376
1377/**************************************************************************
1378 * CDrivesFolder::GetCurFolder
1379 */
1381{
1382 TRACE("(%p)->(%p)\n", this, pidl);
1383
1384 if (!pidl)
1385 return E_INVALIDARG; /* xp doesn't have this check and crashes on NULL */
1386
1387 *pidl = ILClone(pidlRoot);
1388 return S_OK;
1389}
1390
1391/**************************************************************************
1392 * CDrivesFolder::ShouldShow
1393 */
1395{
1396 if (const CLSID* pClsid = IsRegItem(pidlItem))
1397 return SHELL32_IsShellFolderNamespaceItemHidden(L"HideMyComputerIcons", *pClsid) ? S_FALSE : S_OK;
1398 return S_OK;
1399}
1400
1401/**************************************************************************
1402 * CDrivesFolder::MessageSFVCB (IShellFolderViewCB)
1403 */
1405{
1406 switch (uMsg)
1407 {
1408 case SFVM_FSNOTIFY:
1409 if (lParam == SHCNE_DRIVEADD && wParam)
1410 {
1411 g_IsFloppyCache = 0;
1413 if (drive >= 0 && ((1UL << drive) & SHRestricted(REST_NODRIVES)))
1414 return S_FALSE;
1415 }
1416 else if (lParam == SHCNE_DRIVEREMOVED)
1417 {
1418 g_IsFloppyCache = 0;
1419 }
1420 break;
1421 #if ROSPOLICY_DRIVESFOLDER_DEFLARGEICONS
1422 case SFVM_DEFVIEWMODE:
1424 return S_OK;
1425 #endif
1426 }
1427 return E_NOTIMPL;
1428}
1429
1430/************************************************************************/
1431/* IContextMenuCB interface */
1432
1434{
1435 enum { IDC_PROPERTIES };
1436 /* no data object means no selection */
1437 if (!pdtobj)
1438 {
1439 if (uMsg == DFM_INVOKECOMMAND && wParam == IDC_PROPERTIES)
1440 {
1441 // "System" properties
1442 return SHELL_ExecuteControlPanelCPL(hwndOwner, L"sysdm.cpl") ? S_OK : E_FAIL;
1443 }
1444 else if (uMsg == DFM_MERGECONTEXTMENU) // TODO: DFM_MERGECONTEXTMENU_BOTTOM
1445 {
1446 QCMINFO *pqcminfo = (QCMINFO *)lParam;
1447 HMENU hpopup = CreatePopupMenu();
1449 pqcminfo->idCmdFirst = Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
1450 DestroyMenu(hpopup);
1451 return S_OK;
1452 }
1453 }
1454 return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
1455}
#define ATLASSERT(x)
Definition: CComVariant.cpp:10
static const REGFOLDERINFO g_RegFolderInfo
static const CLSID * IsRegItem(LPCITEMIDLIST pidl)
HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE *pcsfv, IShellView **ppsv)
Definition: CDefView.cpp:4826
HRESULT WINAPI SHCreateDefaultContextMenu(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv)
HRESULT WINAPI CDefFolderMenu_Create2(PCIDLIST_ABSOLUTE pidlFolder, HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, LPFNDFMCALLBACK lpfn, UINT nKeys, const HKEY *ahkeyClsKeys, IContextMenu **ppcm)
BOOL SHELL32_IsShellFolderNamespaceItemHidden(LPCWSTR SubKey, REFCLSID Clsid)
static HRESULT DoFormatDriveAsync(HWND hwnd, UINT nDrive)
UINT _ILGetDriveType(LPCITEMIDLIST pidl)
static bool IsFloppyDrive(PCWSTR DrivePath)
static UINT _ILGetRemovableTypeId(LPCITEMIDLIST pidl)
#define RETRY_COUNT
HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, IContextMenu **ppcm)
#define CMDID_FORMAT
static const CLSID * IsRegItem(PCUITEMID_CHILD pidl)
static BOOL TryToLockOrUnlockDrive(HANDLE hDrive, BOOL bLock)
static HRESULT getIconLocationForDrive(_In_ PCWSTR pszDrivePath, _Out_writes_z_(cchMax) PWSTR szIconFile, _In_ UINT cchMax, _Out_ int *piIndex, _Out_ UINT *pGilOut)
HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf, HWND hwnd, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
static BOOL DoEjectDrive(const WCHAR *physical, UINT nDriveType, INT *pnStringID)
static const DWORD dwComputerAttributes
BOOL SHELL32_IsShellFolderNamespaceItemHidden(LPCWSTR SubKey, REFCLSID Clsid)
static UINT GetCachedDriveType(INT8 DrvNum)
static const REGFOLDERINFO g_RegFolderInfo
static HRESULT GetRawDriveLabel(PCWSTR DrivePath, LPWSTR szLabel, UINT cchMax)
static int iDriveIconIds[7]
static const shvheader MyComputerSFHeader[]
static int iDriveTypeIds[7]
UINT g_IsFloppyCache
static INT8 GetDriveNumber(PCUITEMID_CHILD pidl)
#define CMDID_EJECT
INT8 GetDrivePath(PCUITEMID_CHILD pidl, PWSTR Path)
static const REQUIREDREGITEM g_RequiredItems[]
static HRESULT getLabelForDriveFromAutoRun(PCWSTR wszPath, LPWSTR szLabel, UINT cchMax)
static const DWORD dwDriveAttributes
static const DWORD dwControlPanelAttributes
#define CMDID_DISCONNECT
#define RETRY_SLEEP
static HRESULT GetDriveLabel(PCWSTR DrivePath, LPWSTR szLabel, UINT cchMax)
static UINT SHELL_GetAutoRunInfPath(PCWSTR DrvPath, PWSTR AriPath, BOOL ForInvoke=FALSE)
static DWORD CALLBACK DoFormatDriveThread(LPVOID args)
HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder *psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvOut)
static bool GetRegCustomizedDriveIcon(_In_ INT8 DriveNum, _Out_writes_z_(cchMax) PWSTR szIconFile, _In_ UINT cchMax, _Out_ int *piIndex, _Out_ UINT *pGilOut)
HRESULT WINAPI SHCreateDefaultExtractIcon(REFIID riid, void **ppv)
HRESULT IDataObject_Constructor(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidl, UINT cidl, BOOL bExtendedObject, IDataObject **dataObject)
HRESULT CRegFolder_CreateInstance(PREGFOLDERINITDATA pInit, LPCITEMIDLIST pidlRoot, REFIID riid, void **ppv)
Definition: CRegFolder.cpp:995
UINT DriveType
signed char INT8
PRTL_UNICODE_STRING_BUFFER Path
#define shell32_hInstance
UINT cchMax
Type
Definition: Type.h:7
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define IDS_PROPERTIES
Definition: resource.h:108
PWCHAR Label
Definition: format.c:70
#define STDMETHODIMP
Definition: basetyps.h:43
#define _stricmp
Definition: cat.c:22
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
HRESULT WINAPI Initialize(HWND hwndOwner, DWORD dwFlags, IEnumIDList *pRegEnumerator)
STDMETHOD() GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *prgfInOut, LPVOID *ppvOut) override
STDMETHOD() GetCurFolder(PIDLIST_ABSOLUTE *pidl) override
STDMETHOD() GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut) override
STDMETHOD() GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) override
STDMETHOD() Initialize(PCIDLIST_ABSOLUTE pidl) override
STDMETHOD() EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList) override
STDMETHOD() GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd) override
STDMETHOD() BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) override
STDMETHOD() GetDefaultSearchGUID(GUID *pguid) override
STDMETHOD() CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam) override
STDMETHOD() ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes) override
STDMETHOD() ShouldShow(IShellFolder *psf, PCIDLIST_ABSOLUTE pidlFolder, PCUITEMID_CHILD pidlItem) override
STDMETHODIMP MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) override
STDMETHOD() GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags) override
STDMETHOD() GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv) override
STDMETHOD() GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay) override
STDMETHOD() MapColumnToSCID(UINT column, SHCOLUMNID *pscid) override
CComPtr< IShellFolder2 > m_regFolder
Definition: CDrivesFolder.h:38
static HRESULT SetDriveLabel(HWND hwndOwner, PCWSTR DrivePath, PCWSTR Label)
STDMETHOD() CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut) override
LPITEMIDLIST pidlRoot
Definition: CDrivesFolder.h:37
INT8 m_DriveDisplayMode
Definition: CDrivesFolder.h:39
STDMETHOD() CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) override
HRESULT WINAPI FinalConstruct()
STDMETHOD() SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut) override
STDMETHOD() BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) override
STDMETHOD() GetClassID(CLSID *lpClassId) override
STDMETHOD() EnumSearches(IEnumExtraSearch **ppenum) override
BOOL AddToEnumList(LPITEMIDLIST pidl)
HRESULT AppendItemsFromEnumerator(IEnumIDList *pEnum)
@ TYPE_FORMATDRIVE
Definition: precomp.h:226
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
wcscpy
#define CHARS_IN_GUID
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
void pdump(LPCITEMIDLIST pidl)
Definition: debughlp.cpp:322
const char * shdebugstr_guid(const struct _GUID *id)
Definition: debughlp.cpp:438
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define IDS_SHV_COLUMN_TYPE
Definition: resource.h:89
#define IDS_SHV_COLUMN_NAME
Definition: resource.h:88
#define IDC_PROPERTIES
Definition: resource.h:32
#define GET_SHGDN_RELATION(dwFlags)
Definition: precomp.h:53
#define DFM_MERGECONTEXTMENU
Definition: precomp.h:44
#define DFM_INVOKECOMMAND
Definition: precomp.h:45
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
BOOL WINAPI _ILIsPidlSimple(LPCITEMIDLIST pidl)
#define CloseHandle
Definition: compat.h:739
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
#define FILE_SHARE_READ
Definition: compat.h:136
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
BOOL WINAPI GetDiskFreeSpaceExW(IN LPCWSTR lpDirectoryName OPTIONAL, OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller, OUT PULARGE_INTEGER lpTotalNumberOfBytes, OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes)
Definition: disk.c:342
BOOL WINAPI GetDiskFreeSpaceExA(IN LPCSTR lpDirectoryName OPTIONAL, OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller, OUT PULARGE_INTEGER lpTotalNumberOfBytes, OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes)
Definition: disk.c:313
BOOL WINAPI GetVolumeInformationW(IN LPCWSTR lpRootPathName, IN LPWSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPWSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:226
BOOL WINAPI GetVolumeInformationA(IN LPCSTR lpRootPathName, IN LPSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:32
BOOL WINAPI SetVolumeLabelW(IN LPCWSTR lpRootPathName, IN LPCWSTR lpVolumeName OPTIONAL)
Definition: volume.c:503
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
INT WINAPI GetPrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR def_val, LPWSTR buffer, UINT len, LPCWSTR filename)
Definition: profile.c:1142
const UINT * keys
Definition: locale.c:416
BOOL WINAPI PathIsRelativeW(const WCHAR *path)
Definition: path.c:1030
int WINAPI PathParseIconLocationW(WCHAR *path)
Definition: path.c:2644
LONG WINAPI SHRegGetUSValueW(const WCHAR *subkey, const WCHAR *value, DWORD *type, void *data, DWORD *data_len, BOOL ignore_hkcu, void *default_data, DWORD default_data_len)
Definition: registry.c:4077
INT WINAPI DECLSPEC_HOTPATCH LoadStringW(HINSTANCE instance, UINT resource_id, LPWSTR buffer, INT buflen)
Definition: string.c:1220
DWORD WINAPI DECLSPEC_HOTPATCH GetLogicalDrives(void)
Definition: volume.c:513
#define RRF_RT_DWORD
Definition: driver.c:581
#define RRF_RT_REG_SZ
Definition: driver.c:575
BOOL IsDriveFloppyW(LPCWSTR pszDriveRoot)
Definition: drvdefext.cpp:320
DWORD WINAPI SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options)
Definition: drive.cpp:762
#define SHELL_ExecuteControlPanelCPL(hwnd, cpl)
Definition: precomp.h:214
DWORD BindCtx_GetMode(_In_ IBindCtx *pbc, _In_ DWORD dwDefault)
Definition: utils.cpp:278
HRESULT SHIsFileSysBindCtx(_In_ IBindCtx *pBindCtx, _Out_opt_ WIN32_FIND_DATAW *pFindData)
Definition: utils.cpp:303
HRESULT SHELL32_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdo, UINT msg)
Definition: shlfolder.cpp:624
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:370
LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
Definition: path.c:348
LPSTR WINAPI StrFormatByteSize64A(LONGLONG llBytes, LPSTR lpszDest, UINT cchMax)
Definition: string.c:2502
BOOL WINAPI SHCreateThread(LPTHREAD_START_ROUTINE pfnThreadProc, VOID *pData, DWORD dwFlags, LPTHREAD_START_ROUTINE pfnCallback)
Definition: thread.c:356
#define FAILED_UNEXPECTEDLY
Definition: utils.cpp:30
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define L(x)
Definition: resources.c:13
#define UlongToPtr(u)
Definition: config.h:106
#define PtrToUlong(u)
Definition: config.h:107
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
WCHAR swShell32Name[MAX_PATH]
Definition: folders.cpp:22
#define FILE_READ_ONLY_VOLUME
Definition: from_kernel.h:246
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
HRESULT SHELL32_ShowFilesystemItemPropertiesDialogAsync(IDataObject *pDO)
Definition: item_prop.cpp:157
#define debugstr_w
Definition: kernel32.h:32
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:581
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:601
#define END_COM_MAP()
Definition: atlcom.h:592
#define PT_COMPUTER_REGITEM
Definition: lnktool.cpp:39
#define HResultFromWin32
Definition: loader.cpp:14
#define DRIVE_CDROM
Definition: machpc98.h:119
LONG_PTR LPARAM
Definition: minwindef.h:175
UINT_PTR WPARAM
Definition: minwindef.h:174
LPCWSTR szPath
Definition: env.c:37
static unsigned int number
Definition: dsound.c:1479
HRESULT hres
Definition: protocol.c:465
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static LPOLESTR
Definition: stg_prop.c:27
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
const CLSID * clsid
Definition: msctf.cpp:50
unsigned int UINT
Definition: ndis.h:50
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define _Out_writes_z_(s)
Definition: no_sal2.h:180
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
#define DEFAULT_UNREACHABLE
#define UNICODE_NULL
#define PID_STG_STORAGETYPE
Definition: ntquery.h:50
#define PID_STG_NAME
Definition: ntquery.h:56
#define STGM_CREATE
Definition: objbase.h:926
interface IBindCtx * LPBC
Definition: objfwd.h:18
const FMTID FMTID_SummaryInformation
const GUID IID_IDataObject
#define PathAppendW
Definition: pathcch.h:310
#define LOWORD(l)
Definition: pedump.c:82
LPITEMIDLIST _ILCreateMyComputer(void)
Definition: pidl.c:1799
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:238
LPITEMIDLIST _ILCreateDrive(LPCWSTR lpszNew)
Definition: pidl.c:2001
LPPIDLDATA _ILGetDataPointer(LPCITEMIDLIST pidl)
Definition: pidl.c:2272
BOOL _ILIsSpecialFolder(LPCITEMIDLIST pidl)
Definition: pidl.c:2120
DWORD _ILGetDrive(LPCITEMIDLIST pidl, LPWSTR pOut, UINT uSize)
Definition: pidl.c:2046
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2608
BOOL _ILIsDrive(LPCITEMIDLIST pidl)
Definition: pidl.c:2131
#define PT_GUID
Definition: pidl.h:87
#define PT_SHELLEXT
Definition: pidl.h:91
#define LVCFMT_LEFT
Definition: commctrl.h:2603
#define LVCFMT_RIGHT
Definition: commctrl.h:2604
#define CLSID_NULL
Definition: guiddef.h:99
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:107
#define IOCTL_STORAGE_MEDIA_REMOVAL
Definition: ntddstor.h:104
@ CTF_PROCESS_REF
Definition: shlwapi.h:73
#define err(...)
#define REGSTR_PATH_EXPLORER
Definition: regstr.h:33
#define REG_DWORD
Definition: sdbapi.c:615
BOOL HCR_GetIconW(LPCWSTR szClass, LPWSTR szDest, LPCWSTR szName, DWORD len, int *picon_idx)
Definition: classes.c:314
static HRESULT SHELL_CreateSHDESCRIPTIONID(VARIANT *pVar, DWORD Id, const CLSID *pCLSID)
Definition: shell32_main.h:293
#define MAKE_COMPARE_HRESULT(x)
Definition: shellutils.h:678
#define SHELL_ErrorBox
Definition: shellutils.h:126
HRESULT SH32_GetDetailsOfPKeyAsVariant(IShellFolder2 *pSF, PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pVar, BOOL UseFsColMap)
Definition: shlfolder.cpp:133
HRESULT SHELL32_BindToSF(LPCITEMIDLIST pidlRoot, PERSIST_FOLDER_TARGET_INFO *ppfti, LPCITEMIDLIST pidl, const GUID *clsid, REFIID riid, LPVOID *ppvOut)
Definition: shlfolder.cpp:293
#define SHFSF_COL_COMMENT
Definition: shfldr.h:49
static HRESULT MakeSCID(SHCOLUMNID &scid, REFCLSID fmtid, UINT pid)
Definition: shfldr.h:99
HRESULT SHELL32_GetDisplayNameOfChild(IShellFolder2 *psf, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
Definition: shlfolder.cpp:331
#define SHFSF_COL_NAME
Definition: shfldr.h:44
HRESULT SHELL32_CompareChildren(IShellFolder2 *psf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: shlfolder.cpp:349
static __inline int SHELL32_GUIDToStringW(REFGUID guid, LPWSTR str)
Definition: shfldr.h:162
#define SHFSF_COL_TYPE
Definition: shfldr.h:46
LSTATUS AddClassKeyToArray(const WCHAR *szClass, HKEY *array, UINT *cKeys)
Definition: shlfolder.cpp:408
HRESULT SHELL32_CompareDetails(IShellFolder2 *isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: shlfolder.cpp:372
HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE *ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl)
Definition: shlfolder.cpp:510
void WINAPI _InsertMenuItemW(HMENU hmenu, UINT indexMenu, BOOL fByPosition, UINT wID, UINT fType, LPCWSTR dwTypeData, UINT fState)
HRESULT hr
Definition: shlfolder.c:183
#define PID_DESCRIPTIONID
Definition: shlguid.h:171
UINT WINAPI Shell_MergeMenus(HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
Definition: shlmenu.c:856
#define SHDID_COMPUTER_NETDRIVE
Definition: shlobj.h:1469
#define SHDID_COMPUTER_FIXED
Definition: shlobj.h:1468
#define SHCNE_DRIVEREMOVED
Definition: shlobj.h:1902
#define SFVM_DEFVIEWMODE
Definition: shlobj.h:1323
#define SHDID_COMPUTER_REMOVABLE
Definition: shlobj.h:1467
#define SHCNE_RENAMEFOLDER
Definition: shlobj.h:1912
#define SHCNE_MEDIAREMOVED
Definition: shlobj.h:1901
#define SHCNE_DRIVEADD
Definition: shlobj.h:1903
#define SHDID_COMPUTER_CDROM
Definition: shlobj.h:1470
#define SHFMT_ID_DEFAULT
Definition: shlobj.h:332
#define SHCNF_PATHW
Definition: shlobj.h:1931
#define SHDID_COMPUTER_OTHER
Definition: shlobj.h:1472
#define MM_ADDSEPARATOR
Definition: shlobj.h:2534
#define SHDID_COMPUTER_DRIVE35
Definition: shlobj.h:1465
struct _SFV_CREATE SFV_CREATE
#define DFM_CMD_PROPERTIES
Definition: shlobj.h:2618
#define SHCNF_FLUSHNOWAIT
Definition: shlobj.h:1935
#define SFVM_FSNOTIFY
Definition: shlobj.h:1312
@ REST_NODRIVEAUTORUN
Definition: shlobj.h:1657
@ REST_NODRIVES
Definition: shlobj.h:1656
@ REST_NODRIVETYPEAUTORUN
Definition: shlobj.h:1658
#define SHDID_COMPUTER_RAMDISK
Definition: shlobj.h:1471
#define SHDID_ROOT_REGITEM
Definition: shlobj.h:1461
FOLDERVIEWMODE
Definition: shobjidl.idl:677
@ FVM_ICON
Definition: shobjidl.idl:679
DWORD WINAPI SHRestricted(RESTRICTIONS rest)
Definition: shpolicy.c:166
#define IDS_DISCONNECT
Definition: shresdef.h:244
#define IDS_DRIVE_CDROM
Definition: shresdef.h:112
#define IDS_CANTDISMOUNTVOLUME
Definition: shresdef.h:148
#define IDS_EJECT
Definition: shresdef.h:243
#define IDI_SHELL_NOT_CONNECTED_HDD
Definition: shresdef.h:647
#define IDS_DRIVE_FIXED
Definition: shresdef.h:111
#define IDS_DRIVE_NETWORK
Definition: shresdef.h:113
#define IDS_DRIVE_REMOVABLE
Definition: shresdef.h:115
#define IDI_SHELL_3_14_FLOPPY
Definition: shresdef.h:600
#define IDI_SHELL_NETDRIVE
Definition: shresdef.h:603
#define IDS_CANTLOCKVOLUME
Definition: shresdef.h:147
#define IDS_DRIVE_FLOPPY
Definition: shresdef.h:114
#define IDS_SHV_COLUMN_DISK_AVAILABLE
Definition: shresdef.h:55
#define IDI_SHELL_CDROM
Definition: shresdef.h:605
#define IDI_SHELL_DRIVE
Definition: shresdef.h:602
#define IDS_CANTEJECTMEDIA
Definition: shresdef.h:149
#define IDI_SHELL_RAMDISK
Definition: shresdef.h:606
#define IDS_CANTDISCONNECT
Definition: shresdef.h:151
#define IDI_SHELL_REMOVEABLE
Definition: shresdef.h:601
#define IDS_SHV_COLUMN_DISK_CAPACITY
Definition: shresdef.h:54
#define IDS_FORMATDRIVE
Definition: shresdef.h:229
#define IDS_SHV_COLUMN_COMMENTS
Definition: shresdef.h:67
ITEMID_CHILD UNALIGNED * PUITEMID_CHILD
Definition: shtypes.idl:68
@ STRRET_CSTR
Definition: shtypes.idl:87
@ STRRET_WSTR
Definition: shtypes.idl:85
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
@ SHCOLSTATE_TYPE_STR
Definition: shtypes.idl:121
@ SHCOLSTATE_ONBYDEFAULT
Definition: shtypes.idl:125
const ITEMIDLIST_RELATIVE UNALIGNED * PCUIDLIST_RELATIVE
Definition: shtypes.idl:57
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
DWORD SHCOLSTATEF
Definition: shtypes.idl:142
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
STRRET str
Definition: shtypes.idl:108
BOOLEAN PreventMediaRemoval
Definition: ntddstor.h:343
HMENU hmenu
Definition: shlobj.h:1395
UINT idCmdLast
Definition: shlobj.h:1398
UINT idCmdFirst
Definition: shlobj.h:1397
UINT indexMenu
Definition: shlobj.h:1396
char cStr[MAX_PATH]
Definition: shtypes.idl:98
UINT uType
Definition: shtypes.idl:93
LPWSTR pOleStr
Definition: shtypes.idl:96
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
Definition: stubgen.c:11
Definition: match.c:390
Definition: name.c:39
WORD colstate
Definition: shfldr.h:32
struct tagDriveStruct drive
Definition: pidl.h:234
union tagPIDLDATA::@617 u
struct _stub stub
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define UL
Definition: tui.h:164
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
#define _T(x)
Definition: vfdio.h:22
#define DRIVE_UNKNOWN
Definition: winbase.h:280
#define DRIVE_NO_ROOT_DIR
Definition: winbase.h:281
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GetDriveType
Definition: winbase.h:3561
#define DRIVE_REMOTE
Definition: winbase.h:277
_In_ LPCSTR lpName
Definition: winbase.h:2543
#define DRIVE_RAMDISK
Definition: winbase.h:279
#define DRIVE_FIXED
Definition: winbase.h:276
#define DRIVE_REMOVABLE
Definition: winbase.h:275
#define CreateFile
Definition: winbase.h:3498
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOINTERFACE
Definition: winerror.h:3479
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define E_POINTER
Definition: winerror.h:3480
#define HRESULT_CODE(hr)
Definition: winerror.h:188
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
#define MFT_SEPARATOR
Definition: winuser.h:755
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_ICONERROR
Definition: winuser.h:798
#define MFS_ENABLED
Definition: winuser.h:761
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define MFT_STRING
Definition: winuser.h:757
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
DWORD WINAPI WNetCancelConnection2W(LPCWSTR lpName, DWORD dwFlags, BOOL fForce)
Definition: wnet.c:2420
#define IID_PPV_ARG(Itype, ppType)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193