ReactOS  0.4.14-dev-77-gd9e7c48
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-2018 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 
27 
28 /*
29 CDrivesFolder should create a CRegFolder to represent the virtual items that exist only in
30 the registry. The CRegFolder is aggregated by the CDrivesFolder.
31 The CDrivesFolderEnum class should enumerate only drives on the system. Since the CRegFolder
32 implementation of IShellFolder::EnumObjects enumerates the virtual items, the
33 CDrivesFolderEnum is only responsible for returning the physical items.
34 
35 2. At least on my XP system, the drive pidls returned are of type PT_DRIVE1, not PT_DRIVE
36 3. The parsing name returned for my computer is incorrect. It should be "My Computer"
37 */
38 
39 static int iDriveIconIds[7] = { IDI_SHELL_DRIVE, /* DRIVE_UNKNOWN */
40  IDI_SHELL_CDROM, /* DRIVE_NO_ROOT_DIR*/
41  IDI_SHELL_3_14_FLOPPY, /* DRIVE_REMOVABLE*/
42  IDI_SHELL_DRIVE, /* DRIVE_FIXED*/
43  IDI_SHELL_NETDRIVE, /* DRIVE_REMOTE*/
44  IDI_SHELL_CDROM, /* DRIVE_CDROM*/
45  IDI_SHELL_RAMDISK /* DRIVE_RAMDISK*/
46  };
47 
48 static int iDriveTypeIds[7] = { IDS_DRIVE_FIXED, /* DRIVE_UNKNOWN */
49  IDS_DRIVE_FIXED, /* DRIVE_NO_ROOT_DIR*/
50  IDS_DRIVE_FLOPPY, /* DRIVE_REMOVABLE*/
51  IDS_DRIVE_FIXED, /* DRIVE_FIXED*/
52  IDS_DRIVE_NETWORK, /* DRIVE_REMOTE*/
53  IDS_DRIVE_CDROM, /* DRIVE_CDROM*/
54  IDS_DRIVE_FIXED /* DRIVE_RAMDISK*/
55  };
56 
57 /***********************************************************************
58 * IShellFolder implementation
59 */
60 
61 #define RETRY_COUNT 3
62 #define RETRY_SLEEP 250
63 static BOOL TryToLockOrUnlockDrive(HANDLE hDrive, BOOL bLock)
64 {
65  DWORD dwError, dwBytesReturned;
66  DWORD dwCode = (bLock ? FSCTL_LOCK_VOLUME : FSCTL_UNLOCK_VOLUME);
67  for (DWORD i = 0; i < RETRY_COUNT; ++i)
68  {
69  if (DeviceIoControl(hDrive, dwCode, NULL, 0, NULL, 0, &dwBytesReturned, NULL))
70  return TRUE;
71 
72  dwError = GetLastError();
73  if (dwError == ERROR_INVALID_FUNCTION)
74  break; /* don't sleep if function is not implemented */
75 
77  }
78  SetLastError(dwError);
79  return FALSE;
80 }
81 
82 // NOTE: See also https://support.microsoft.com/en-us/help/165721/how-to-ejecting-removable-media-in-windows-nt-windows-2000-windows-xp
83 static BOOL DoEjectDrive(const WCHAR *physical, UINT nDriveType, INT *pnStringID)
84 {
85  /* GENERIC_WRITE isn't needed for umount */
86  DWORD dwAccessMode = GENERIC_READ;
87  DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
88 
89  HANDLE hDrive = CreateFile(physical, dwAccessMode, dwShareMode, 0, OPEN_EXISTING, 0, NULL);
90  if (hDrive == INVALID_HANDLE_VALUE)
91  return FALSE;
92 
93  BOOL bResult, bNeedUnlock = FALSE;
94  DWORD dwBytesReturned, dwError = NO_ERROR;
95  PREVENT_MEDIA_REMOVAL removal;
96  do
97  {
98  bResult = TryToLockOrUnlockDrive(hDrive, TRUE);
99  if (!bResult)
100  {
101  dwError = GetLastError();
102  *pnStringID = IDS_CANTLOCKVOLUME; /* Unable to lock volume */
103  break;
104  }
105  bResult = DeviceIoControl(hDrive, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
106  if (!bResult)
107  {
108  dwError = GetLastError();
109  *pnStringID = IDS_CANTDISMOUNTVOLUME; /* Unable to dismount volume */
110  bNeedUnlock = TRUE;
111  break;
112  }
113  removal.PreventMediaRemoval = FALSE;
114  bResult = DeviceIoControl(hDrive, IOCTL_STORAGE_MEDIA_REMOVAL, &removal, sizeof(removal), NULL,
115  0, &dwBytesReturned, NULL);
116  if (!bResult)
117  {
118  *pnStringID = IDS_CANTEJECTMEDIA; /* Unable to eject media */
119  dwError = GetLastError();
120  bNeedUnlock = TRUE;
121  break;
122  }
123  bResult = DeviceIoControl(hDrive, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
124  if (!bResult)
125  {
126  *pnStringID = IDS_CANTEJECTMEDIA; /* Unable to eject media */
127  dwError = GetLastError();
128  bNeedUnlock = TRUE;
129  break;
130  }
131  } while (0);
132 
133  if (bNeedUnlock)
134  {
135  TryToLockOrUnlockDrive(hDrive, FALSE);
136  }
137 
138  CloseHandle(hDrive);
139 
140  SetLastError(dwError);
141  return bResult;
142 }
143 
145  HWND hwnd,
146  IDataObject *pdtobj,
147  UINT uMsg,
148  WPARAM wParam,
149  LPARAM lParam)
150 {
151  if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND)
152  return S_OK;
153 
154  PIDLIST_ABSOLUTE pidlFolder;
155  PUITEMID_CHILD *apidl;
156  UINT cidl;
157  UINT nDriveType;
158  DWORD dwFlags;
159  HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
160  if (FAILED_UNEXPECTEDLY(hr))
161  return hr;
162 
163  char szDrive[8] = {0};
164  if (!_ILGetDrive(apidl[0], szDrive, sizeof(szDrive)))
165  {
166  ERR("pidl is not a drive\n");
167  SHFree(pidlFolder);
168  _ILFreeaPidl(apidl, cidl);
169  return E_FAIL;
170  }
171  nDriveType = GetDriveTypeA(szDrive);
172  GetVolumeInformationA(szDrive, NULL, 0, NULL, NULL, &dwFlags, NULL, 0);
173 
174 // custom command IDs
175 #define CMDID_FORMAT 1
176 #define CMDID_EJECT 2
177 #define CMDID_DISCONNECT 3
178 
179  if (uMsg == DFM_MERGECONTEXTMENU)
180  {
181  QCMINFO *pqcminfo = (QCMINFO *)lParam;
182 
183  UINT idCmdFirst = pqcminfo->idCmdFirst;
184  if (!(dwFlags & FILE_READ_ONLY_VOLUME) && nDriveType != DRIVE_REMOTE)
185  {
186  /* add separator and Format */
187  UINT idCmd = idCmdFirst + CMDID_FORMAT;
188  _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
190  }
191  if (nDriveType == DRIVE_REMOVABLE || nDriveType == DRIVE_CDROM)
192  {
193  /* add separator and Eject */
194  UINT idCmd = idCmdFirst + CMDID_EJECT;
195  _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
197  }
198  if (nDriveType == DRIVE_REMOTE)
199  {
200  /* add separator and Disconnect */
201  UINT idCmd = idCmdFirst + CMDID_DISCONNECT;
202  _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
204  }
205 
206  pqcminfo->idCmdFirst += 3;
207  }
208  else if (uMsg == DFM_INVOKECOMMAND)
209  {
210  WCHAR wszBuf[4] = L"A:\\";
211  wszBuf[0] = (WCHAR)szDrive[0];
212 
213  INT nStringID = 0;
214  DWORD dwError = NO_ERROR;
215 
216  if (wParam == DFM_CMD_PROPERTIES)
217  {
218  hr = SH_ShowDriveProperties(wszBuf, pidlFolder, apidl);
219  if (FAILED(hr))
220  {
221  dwError = ERROR_CAN_NOT_COMPLETE;
222  nStringID = IDS_CANTSHOWPROPERTIES;
223  }
224  }
225  else
226  {
227  if (wParam == CMDID_FORMAT)
228  {
229  /* do format */
230  DWORD dwRet = SHFormatDrive(hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0);
231  switch (dwRet)
232  {
233  case SHFMT_ERROR: case SHFMT_CANCEL: case SHFMT_NOFORMAT:
234  hr = E_FAIL;
235  break;
236  }
237  }
238  else if (wParam == CMDID_EJECT)
239  {
240  /* do eject */
241  WCHAR physical[10];
242  wsprintfW(physical, _T("\\\\.\\%c:"), szDrive[0]);
243 
244  if (DoEjectDrive(physical, nDriveType, &nStringID))
245  {
247  }
248  else
249  {
250  dwError = GetLastError();
251  }
252  }
253  else if (wParam == CMDID_DISCONNECT)
254  {
255  /* do disconnect */
256  wszBuf[2] = UNICODE_NULL;
257  dwError = WNetCancelConnection2W(wszBuf, 0, FALSE);
258  if (dwError == NO_ERROR)
259  {
261  }
262  else
263  {
264  nStringID = IDS_CANTDISCONNECT;
265  }
266  }
267  }
268 
269  if (nStringID != 0)
270  {
271  /* show error message */
272  WCHAR szFormat[128], szMessage[128];
273  LoadStringW(shell32_hInstance, nStringID, szFormat, _countof(szFormat));
274  wsprintfW(szMessage, szFormat, dwError);
275  MessageBoxW(hwnd, szMessage, NULL, MB_ICONERROR);
276  }
277  }
278 
279  SHFree(pidlFolder);
280  _ILFreeaPidl(apidl, cidl);
281 
282  return hr;
283 }
284 
286  HWND hwnd,
287  UINT cidl,
288  PCUITEMID_CHILD_ARRAY apidl,
289  IShellFolder *psf,
290  IContextMenu **ppcm)
291 {
292  HKEY hKeys[2];
293  UINT cKeys = 0;
294  AddClassKeyToArray(L"Drive", hKeys, &cKeys);
295  AddClassKeyToArray(L"Folder", hKeys, &cKeys);
296 
297  return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, DrivesContextMenuCallback, cKeys, hKeys, ppcm);
298 }
299 
300 static HRESULT
302  LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
303 {
304  WCHAR wszPath[MAX_PATH];
305  WCHAR wszAutoRunInfPath[MAX_PATH];
306  WCHAR wszValue[MAX_PATH], wszTemp[MAX_PATH];
307  static const WCHAR wszAutoRunInf[] = { 'a','u','t','o','r','u','n','.','i','n','f',0 };
308  static const WCHAR wszAutoRun[] = { 'a','u','t','o','r','u','n',0 };
309 
310  // get path
311  if (!ILGetDisplayNameExW(psf, pidl, wszPath, 0))
312  return E_FAIL;
313  if (!PathIsDirectoryW(wszPath))
314  return E_FAIL;
315 
316  // build the full path of autorun.inf
317  StringCchCopyW(wszAutoRunInfPath, _countof(wszAutoRunInfPath), wszPath);
318  PathAppendW(wszAutoRunInfPath, wszAutoRunInf);
319 
320  // autorun.inf --> wszValue
321  if (GetPrivateProfileStringW(wszAutoRun, L"icon", NULL, wszValue, _countof(wszValue),
322  wszAutoRunInfPath) && wszValue[0] != 0)
323  {
324  // wszValue --> wszTemp
325  ExpandEnvironmentStringsW(wszValue, wszTemp, _countof(wszTemp));
326 
327  // parse the icon location
328  *piIndex = PathParseIconLocationW(wszTemp);
329 
330  // wszPath + wszTemp --> wszPath
331  if (PathIsRelativeW(wszTemp))
332  PathAppendW(wszPath, wszTemp);
333  else
334  StringCchCopyW(wszPath, _countof(wszPath), wszTemp);
335 
336  // wszPath --> szIconFile
337  GetFullPathNameW(wszPath, cchMax, szIconFile, NULL);
338 
339  return S_OK;
340  }
341 
342  return E_FAIL;
343 }
344 
346 {
347  CComPtr<IDefaultExtractIconInit> initIcon;
349  if (FAILED_UNEXPECTEDLY(hr))
350  return hr;
351 
352  CHAR* pszDrive = _ILGetDataPointer(pidl)->u.drive.szDriveName;
353  UINT DriveType = GetDriveTypeA(pszDrive);
354  if (DriveType > DRIVE_RAMDISK)
356 
357  WCHAR wTemp[MAX_PATH];
358  int icon_idx;
359  UINT flags = 0;
360  if ((DriveType == DRIVE_FIXED || DriveType == DRIVE_UNKNOWN) &&
361  (HCR_GetIconW(L"Drive", wTemp, NULL, MAX_PATH, &icon_idx)))
362  {
363  initIcon->SetNormalIcon(wTemp, icon_idx);
364  }
365  else if (SUCCEEDED(getIconLocationForDrive(psf, pidl, 0, wTemp, _countof(wTemp),
366  &icon_idx, &flags)))
367  {
368  initIcon->SetNormalIcon(wTemp, icon_idx);
369  }
370  else
371  {
372  icon_idx = iDriveIconIds[DriveType];
373  initIcon->SetNormalIcon(swShell32Name, -icon_idx);
374  }
375 
376  return initIcon->QueryInterface(riid, ppvOut);
377 }
378 
380  public CEnumIDListBase
381 {
382  public:
383  HRESULT WINAPI Initialize(HWND hwndOwner, DWORD dwFlags, IEnumIDList* pRegEnumerator)
384  {
385  /* enumerate the folders */
386  if (dwFlags & SHCONTF_FOLDERS)
387  {
388  WCHAR wszDriveName[] = {'A', ':', '\\', '\0'};
389  DWORD dwDrivemap = GetLogicalDrives();
390 
391  while (wszDriveName[0] <= 'Z')
392  {
393  if(dwDrivemap & 0x00000001L)
394  AddToEnumList(_ILCreateDrive(wszDriveName));
395  wszDriveName[0]++;
396  dwDrivemap = dwDrivemap >> 1;
397  }
398  }
399 
400  /* Enumerate the items of the reg folder */
401  AppendItemsFromEnumerator(pRegEnumerator);
402 
403  return S_OK;
404  }
405 
407  COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
408  END_COM_MAP()
409 };
410 
411 /***********************************************************************
412 * IShellFolder [MyComputer] implementation
413 */
414 
415 static const shvheader MyComputerSFHeader[] = {
421 };
422 
423 #define MYCOMPUTERSHELLVIEWCOLUMNS 5
424 
426  SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
427  SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
429  SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CANLINK;
430 static const DWORD dwDriveAttributes =
431  SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
432  SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK;
433 
435 {
436  pidlRoot = NULL;
437 }
438 
440 {
441  TRACE ("-- destroying IShellFolder(%p)\n", this);
442  SHFree(pidlRoot);
443 }
444 
446 {
447  pidlRoot = _ILCreateMyComputer(); /* my qualified pidl */
448  if (pidlRoot == NULL)
449  return E_OUTOFMEMORY;
450 
451  HRESULT hr = CRegFolder_CreateInstance(&CLSID_MyComputer,
452  pidlRoot,
453  L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
454  L"MyComputer",
456 
457  return hr;
458 }
459 
460 /**************************************************************************
461 * CDrivesFolder::ParseDisplayName
462 */
464  DWORD * pchEaten, PIDLIST_RELATIVE * ppidl, DWORD * pdwAttributes)
465 {
467  LPCWSTR szNext = NULL;
468  LPITEMIDLIST pidlTemp = NULL;
469 
470  TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", this,
471  hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
472  pchEaten, ppidl, pdwAttributes);
473 
474  *ppidl = 0;
475  if (pchEaten)
476  *pchEaten = 0; /* strange but like the original */
477 
478  /* handle CLSID paths */
479  if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
480  return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
481 
482  if (PathGetDriveNumberW(lpszDisplayName) < 0)
483  return E_INVALIDARG;
484 
485  pidlTemp = _ILCreateDrive(lpszDisplayName);
486  if (!pidlTemp)
487  return E_OUTOFMEMORY;
488 
489  if (lpszDisplayName[2] == L'\\')
490  {
491  szNext = &lpszDisplayName[3];
492  }
493 
494  if (szNext && *szNext)
495  {
496  hr = SHELL32_ParseNextElement (this, hwndOwner, pbc, &pidlTemp,
497  (LPOLESTR) szNext, pchEaten, pdwAttributes);
498  }
499  else
500  {
501  hr = S_OK;
502  if (pdwAttributes && *pdwAttributes)
503  {
504  if (_ILIsDrive(pidlTemp))
505  *pdwAttributes &= dwDriveAttributes;
506  else if (_ILIsSpecialFolder(pidlTemp))
507  m_regFolder->GetAttributesOf(1, &pidlTemp, pdwAttributes);
508  else
509  ERR("Got an unkown pidl here!\n");
510  }
511  }
512 
513  *ppidl = pidlTemp;
514 
515  TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr);
516 
517  return hr;
518 }
519 
520 /**************************************************************************
521 * CDrivesFolder::EnumObjects
522 */
523 HRESULT WINAPI CDrivesFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
524 {
525  CComPtr<IEnumIDList> pRegEnumerator;
526  m_regFolder->EnumObjects(hwndOwner, dwFlags, &pRegEnumerator);
527 
528  return ShellObjectCreatorInit<CDrivesFolderEnum>(hwndOwner, dwFlags, pRegEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
529 }
530 
531 /**************************************************************************
532 * CDrivesFolder::BindToObject
533 */
535 {
536  TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this,
537  pidl, pbcReserved, shdebugstr_guid(&riid), ppvOut);
538 
539  if (!pidl)
540  return E_INVALIDARG;
541 
542  if (_ILIsSpecialFolder(pidl))
543  return m_regFolder->BindToObject(pidl, pbcReserved, riid, ppvOut);
544 
545  CHAR* pchDrive = _ILGetDataPointer(pidl)->u.drive.szDriveName;
546 
547  PERSIST_FOLDER_TARGET_INFO pfti = {0};
548  pfti.dwAttributes = -1;
549  pfti.csidl = -1;
550  pfti.szTargetParsingName[0] = *pchDrive;
551  pfti.szTargetParsingName[1] = L':';
552  pfti.szTargetParsingName[2] = L'\\';
553 
555  &pfti,
556  pidl,
557  &CLSID_ShellFSFolder,
558  riid,
559  ppvOut);
560  if (FAILED_UNEXPECTEDLY(hr))
561  return hr;
562 
563  return S_OK;
564 }
565 
566 /**************************************************************************
567 * CDrivesFolder::BindToStorage
568 */
570 {
571  FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", this,
572  pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
573 
574  *ppvOut = NULL;
575  return E_NOTIMPL;
576 }
577 
578 /**************************************************************************
579 * CDrivesFolder::CompareIDs
580 */
581 
583 {
584  HRESULT hres;
585 
586  if (!pidl1 || !pidl2)
587  {
588  ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam, pidl1, pidl2);
589  return E_INVALIDARG;
590  }
591 
592  if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
593  return m_regFolder->CompareIDs(lParam, pidl1, pidl2);
594 
595  if (!_ILIsDrive(pidl1) || !_ILIsDrive(pidl2) || LOWORD(lParam) >= MYCOMPUTERSHELLVIEWCOLUMNS)
596  return E_INVALIDARG;
597 
598  CHAR* pszDrive1 = _ILGetDataPointer(pidl1)->u.drive.szDriveName;
599  CHAR* pszDrive2 = _ILGetDataPointer(pidl2)->u.drive.szDriveName;
600 
601  int result;
602  switch(LOWORD(lParam))
603  {
604  case 0: /* name */
605  {
606  result = stricmp(pszDrive1, pszDrive2);
608  break;
609  }
610  case 1: /* comments */
612  break;
613  case 2: /* Type */
614  {
615  /* We want to return immediately because SHELL32_CompareDetails also compares children. */
616  return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
617  }
618  case 3: /* Size */
619  case 4: /* Size Available */
620  {
621  ULARGE_INTEGER Drive1Available, Drive1Total, Drive2Available, Drive2Total;
622 
623  if (GetVolumeInformationA(pszDrive1, NULL, 0, NULL, NULL, NULL, NULL, 0))
624  GetDiskFreeSpaceExA(pszDrive1, &Drive1Available, &Drive1Total, NULL);
625  else
626  Drive1Available.QuadPart = Drive1Total.QuadPart = 0;
627 
628  if (GetVolumeInformationA(pszDrive2, NULL, 0, NULL, NULL, NULL, NULL, 0))
629  GetDiskFreeSpaceExA(pszDrive2, &Drive2Available, &Drive2Total, NULL);
630  else
631  Drive2Available.QuadPart = Drive2Total.QuadPart = 0;
632 
633  LARGE_INTEGER Diff;
634  if (lParam == 3) /* Size */
635  Diff.QuadPart = Drive1Total.QuadPart - Drive2Total.QuadPart;
636  else /* Size available */
637  Diff.QuadPart = Drive1Available.QuadPart - Drive2Available.QuadPart;
638 
640  break;
641  }
642  default:
643  return E_INVALIDARG;
644  }
645 
646  if (HRESULT_CODE(hres) == 0)
647  return SHELL32_CompareChildren(this, lParam, pidl1, pidl2);
648 
649  return hres;
650 }
651 
652 /**************************************************************************
653 * CDrivesFolder::CreateViewObject
654 */
656 {
657  CComPtr<IShellView> pShellView;
659 
660  TRACE("(%p)->(hwnd=%p,%s,%p)\n", this,
661  hwndOwner, shdebugstr_guid (&riid), ppvOut);
662 
663  if (!ppvOut)
664  return hr;
665 
666  *ppvOut = NULL;
667 
668  if (IsEqualIID(riid, IID_IDropTarget))
669  {
670  WARN("IDropTarget not implemented\n");
671  hr = E_NOTIMPL;
672  }
673  else if (IsEqualIID(riid, IID_IContextMenu))
674  {
675  HKEY hKeys[16];
676  UINT cKeys = 0;
677  AddClassKeyToArray(L"Directory\\Background", hKeys, &cKeys);
678 
679  DEFCONTEXTMENU dcm;
680  dcm.hwnd = hwndOwner;
681  dcm.pcmcb = this;
682  dcm.pidlFolder = pidlRoot;
683  dcm.psf = this;
684  dcm.cidl = 0;
685  dcm.apidl = NULL;
686  dcm.cKeys = cKeys;
687  dcm.aKeys = hKeys;
689  hr = SHCreateDefaultContextMenu(&dcm, riid, ppvOut);
690  }
691  else if (IsEqualIID(riid, IID_IShellView))
692  {
693  SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this};
694  hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
695  }
696  TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
697  return hr;
698 }
699 
701 {
702  GUID *guid = _ILGetGUIDPointer(pidl);
703 
704  TRACE("(%p)\n", pidl);
705 
706  if (guid)
707  return IsEqualIID(*guid, CLSID_ControlPanel);
708  return FALSE;
709 }
710 
711 /**************************************************************************
712 * CDrivesFolder::GetAttributesOf
713 */
715 {
716  TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
717  this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
718 
719  if (cidl && !apidl)
720  return E_INVALIDARG;
721 
722  if (*rgfInOut == 0)
723  *rgfInOut = ~0;
724 
725  /* FIXME: always add SFGAO_CANLINK */
726  if(cidl == 0)
727  *rgfInOut &= dwComputerAttributes;
728  else
729  {
730  for (UINT i = 0; i < cidl; ++i)
731  {
732  if (_ILIsDrive(apidl[i]))
733  *rgfInOut &= dwDriveAttributes;
734  else if (_ILIsControlPanel(apidl[i]))
735  *rgfInOut &= dwControlPanelAttributes;
736  else if (_ILIsSpecialFolder(*apidl))
737  m_regFolder->GetAttributesOf(1, &apidl[i], rgfInOut);
738  else
739  ERR("Got unknown pidl type!\n");
740  }
741  }
742 
743  /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
744  *rgfInOut &= ~SFGAO_VALIDATE;
745 
746  TRACE ("-- result=0x%08x\n", *rgfInOut);
747  return S_OK;
748 }
749 
750 /**************************************************************************
751 * CDrivesFolder::GetUIObjectOf
752 *
753 * PARAMETERS
754 * hwndOwner [in] Parent window for any output
755 * cidl [in] array size
756 * apidl [in] simple pidl array
757 * riid [in] Requested Interface
758 * prgfInOut [ ] reserved
759 * ppvObject [out] Resulting Interface
760 *
761 */
763  UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
764  REFIID riid, UINT *prgfInOut, LPVOID *ppvOut)
765 {
766  LPVOID pObj = NULL;
768 
769  TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", this,
770  hwndOwner, cidl, apidl, shdebugstr_guid (&riid), prgfInOut, ppvOut);
771 
772  if (!ppvOut)
773  return hr;
774 
775  *ppvOut = NULL;
776 
777  if (IsEqualIID (riid, IID_IContextMenu) && (cidl >= 1))
778  {
779  if (_ILIsDrive(apidl[0]))
780  hr = CDrivesContextMenu_CreateInstance(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), (IContextMenu**)&pObj);
781  else
782  hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
783  }
784  else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
785  {
786  hr = IDataObject_Constructor (hwndOwner,
787  pidlRoot, apidl, cidl, (IDataObject **)&pObj);
788  }
789  else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
790  {
791  if (_ILIsDrive(apidl[0]))
792  hr = CDrivesExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
793  else
794  hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
795  }
796  else if (IsEqualIID (riid, IID_IDropTarget) && (cidl == 1))
797  {
798  CComPtr<IShellFolder> psfChild;
799  hr = this->BindToObject(apidl[0], NULL, IID_PPV_ARG(IShellFolder, &psfChild));
800  if (FAILED_UNEXPECTEDLY(hr))
801  return hr;
802 
803  return psfChild->CreateViewObject(NULL, riid, ppvOut);
804  }
805  else
806  hr = E_NOINTERFACE;
807 
808  if (SUCCEEDED(hr) && !pObj)
809  hr = E_OUTOFMEMORY;
810 
811  *ppvOut = pObj;
812  TRACE ("(%p)->hr=0x%08x\n", this, hr);
813  return hr;
814 }
815 
816 /**************************************************************************
817 * CDrivesFolder::GetDisplayNameOf
818 */
820 {
821  LPWSTR pszPath;
822  HRESULT hr = S_OK;
823 
824  TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
825  pdump (pidl);
826 
827  if (!strRet)
828  return E_INVALIDARG;
829 
830  if (!_ILIsPidlSimple (pidl))
831  {
832  return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
833  }
834  else if (_ILIsSpecialFolder(pidl))
835  {
836  return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet);
837  }
838  else if (!_ILIsDrive(pidl))
839  {
840  ERR("Wrong pidl type\n");
841  return E_INVALIDARG;
842  }
843 
844  pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
845  if (!pszPath)
846  return E_OUTOFMEMORY;
847 
848  pszPath[0] = 0;
849 
850  _ILSimpleGetTextW(pidl, pszPath, MAX_PATH); /* append my own path */
851  /* long view "lw_name (C:)" */
852  if (!(dwFlags & SHGDN_FORPARSING))
853  {
854  WCHAR wszDrive[18] = {0};
855  DWORD dwVolumeSerialNumber, dwMaximumComponentLength, dwFileSystemFlags;
856  static const WCHAR wszOpenBracket[] = {' ', '(', 0};
857  static const WCHAR wszCloseBracket[] = {')', 0};
858 
859  lstrcpynW(wszDrive, pszPath, 4);
860  pszPath[0] = L'\0';
861  GetVolumeInformationW(wszDrive, pszPath,
862  MAX_PATH - 7,
863  &dwVolumeSerialNumber,
864  &dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0);
865  pszPath[MAX_PATH-1] = L'\0';
866  if (!wcslen(pszPath))
867  {
868  UINT DriveType, ResourceId;
869  DriveType = GetDriveTypeW(wszDrive);
870  switch(DriveType)
871  {
872  case DRIVE_FIXED:
873  ResourceId = IDS_DRIVE_FIXED;
874  break;
875  case DRIVE_REMOTE:
876  ResourceId = IDS_DRIVE_NETWORK;
877  break;
878  case DRIVE_CDROM:
879  ResourceId = IDS_DRIVE_CDROM;
880  break;
881  default:
882  ResourceId = 0;
883  }
884  if (ResourceId)
885  {
886  dwFileSystemFlags = LoadStringW(shell32_hInstance, ResourceId, pszPath, MAX_PATH);
887  if (dwFileSystemFlags > MAX_PATH - 7)
888  pszPath[MAX_PATH-7] = L'\0';
889  }
890  }
891  wcscat (pszPath, wszOpenBracket);
892  wszDrive[2] = L'\0';
893  wcscat (pszPath, wszDrive);
894  wcscat (pszPath, wszCloseBracket);
895  }
896 
897  if (SUCCEEDED(hr))
898  {
899  strRet->uType = STRRET_WSTR;
900  strRet->pOleStr = pszPath;
901  }
902  else
903  CoTaskMemFree(pszPath);
904 
905  TRACE("-- (%p)->(%s)\n", this, strRet->uType == STRRET_CSTR ? strRet->cStr : debugstr_w(strRet->pOleStr));
906  return hr;
907 }
908 
909 /**************************************************************************
910 * CDrivesFolder::SetNameOf
911 * Changes the name of a file object or subfolder, possibly changing its item
912 * identifier in the process.
913 *
914 * PARAMETERS
915 * hwndOwner [in] Owner window for output
916 * pidl [in] simple pidl of item to change
917 * lpszName [in] the items new display name
918 * dwFlags [in] SHGNO formatting flags
919 * ppidlOut [out] simple pidl returned
920 */
922  LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
923 {
924  WCHAR szName[30];
925 
926  if (_ILIsDrive(pidl))
927  {
930  if (pPidlOut)
931  *pPidlOut = _ILCreateDrive(szName);
932  return S_OK;
933  }
934 
935  return m_regFolder->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
936 }
937 
939 {
940  FIXME ("(%p)\n", this);
941  return E_NOTIMPL;
942 }
943 
945 {
946  FIXME ("(%p)\n", this);
947  return E_NOTIMPL;
948 }
949 
951 {
952  TRACE ("(%p)\n", this);
953 
954  if (pSort)
955  *pSort = 0;
956  if (pDisplay)
957  *pDisplay = 0;
958  return S_OK;
959 }
960 
962 {
963  TRACE ("(%p)\n", this);
964 
965  if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS)
966  return E_INVALIDARG;
967  *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
968  return S_OK;
969 }
970 
972 {
973  FIXME ("(%p)\n", this);
974  return E_NOTIMPL;
975 }
976 
978 {
979  HRESULT hr;
980 
981  TRACE ("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd);
982 
983  if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS)
984  return E_INVALIDARG;
985 
986  if (!pidl)
987  {
988  psd->fmt = MyComputerSFHeader[iColumn].fmt;
989  psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
990  return SHSetStrRet(&psd->str, MyComputerSFHeader[iColumn].colnameid);
991  }
992  else if (!_ILIsDrive(pidl))
993  {
994  return m_regFolder->GetDetailsOf(pidl, iColumn, psd);
995  }
996  else
997  {
998  ULARGE_INTEGER ulTotalBytes, ulFreeBytes;
999  CHAR* pszDrive = _ILGetDataPointer(pidl)->u.drive.szDriveName;
1000  UINT DriveType = GetDriveTypeA(pszDrive);
1001  if (DriveType > DRIVE_RAMDISK)
1003 
1004  switch (iColumn)
1005  {
1006  case 0: /* name */
1008  break;
1009  case 1: /* FIXME: comments */
1010  hr = SHSetStrRet(&psd->str, "");
1011  break;
1012  case 2: /* type */
1013  hr = SHSetStrRet(&psd->str, iDriveTypeIds[DriveType]);
1014  break;
1015  case 3: /* total size */
1016  case 4: /* free size */
1017  psd->str.cStr[0] = 0x00;
1018  psd->str.uType = STRRET_CSTR;
1019  if (GetVolumeInformationA(pszDrive, NULL, 0, NULL, NULL, NULL, NULL, 0))
1020  {
1021  GetDiskFreeSpaceExA(pszDrive, &ulFreeBytes, &ulTotalBytes, NULL);
1022  if (iColumn == 3)
1023  StrFormatByteSize64A(ulTotalBytes.QuadPart, psd->str.cStr, MAX_PATH);
1024  else
1025  StrFormatByteSize64A(ulFreeBytes.QuadPart, psd->str.cStr, MAX_PATH);
1026  }
1027  hr = S_OK;
1028  break;
1029  }
1030  }
1031 
1032  return hr;
1033 }
1034 
1036 {
1037  FIXME("(%p)\n", this);
1038  return E_NOTIMPL;
1039 }
1040 
1041 /************************************************************************
1042  * CDrivesFolder::GetClassID
1043  */
1045 {
1046  TRACE ("(%p)\n", this);
1047 
1048  if (!lpClassId)
1049  return E_POINTER;
1050 
1051  *lpClassId = CLSID_MyComputer;
1052  return S_OK;
1053 }
1054 
1055 /************************************************************************
1056  * CDrivesFolder::Initialize
1057  *
1058  * NOTES: it makes no sense to change the pidl
1059  */
1061 {
1062  return S_OK;
1063 }
1064 
1065 /**************************************************************************
1066  * CDrivesFolder::GetCurFolder
1067  */
1069 {
1070  TRACE("(%p)->(%p)\n", this, pidl);
1071 
1072  if (!pidl)
1073  return E_INVALIDARG; /* xp doesn't have this check and crashes on NULL */
1074 
1075  *pidl = ILClone(pidlRoot);
1076  return S_OK;
1077 }
1078 
1079 /************************************************************************/
1080 /* IContextMenuCB interface */
1081 
1083 {
1084  if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND)
1085  return S_OK;
1086 
1087  /* no data object means no selection */
1088  if (!pdtobj)
1089  {
1090  if (uMsg == DFM_INVOKECOMMAND && wParam == 1) // #1
1091  {
1092  // "System" properties
1093  ShellExecuteW(hwndOwner,
1094  NULL,
1095  L"rundll32.exe",
1096  L"shell32.dll,Control_RunDLL sysdm.cpl",
1097  NULL,
1098  SW_SHOWNORMAL);
1099  }
1100  else if (uMsg == DFM_MERGECONTEXTMENU)
1101  {
1102  QCMINFO *pqcminfo = (QCMINFO *)lParam;
1103  HMENU hpopup = CreatePopupMenu();
1104  _InsertMenuItemW(hpopup, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED); // #0
1106  Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu++, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
1107  DestroyMenu(hpopup);
1108  }
1109 
1110  return S_OK;
1111  }
1112 
1113  if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
1114  return S_OK;
1115 
1116  return Shell_DefaultContextMenuCallBack(this, pdtobj);
1117 }
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
void WINAPI _InsertMenuItemW(HMENU hmenu, UINT indexMenu, BOOL fByPosition, UINT wID, UINT fType, LPCWSTR dwTypeData, UINT fState)
HRESULT WINAPI FinalConstruct()
#define IDS_SHV_COLUMN_COMMENTS
Definition: shresdef.h:61
BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
Definition: path.c:1702
virtual HRESULT WINAPI MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define IDS_CANTDISMOUNTVOLUME
Definition: shresdef.h:139
UINT idCmdLast
Definition: shlobj.h:1309
#define MFT_STRING
Definition: winuser.h:741
#define IDI_SHELL_DRIVE
Definition: shresdef.h:472
virtual HRESULT WINAPI GetDefaultSearchGUID(GUID *pguid)
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
INT WINAPI GetPrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR def_val, LPWSTR buffer, UINT len, LPCWSTR filename)
Definition: profile.c:1142
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
BOOL WINAPI PathIsRelativeW(LPCWSTR lpszPath)
Definition: path.c:1558
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
LPPIDLDATA _ILGetDataPointer(LPCITEMIDLIST pidl)
Definition: pidl.c:2162
#define E_NOINTERFACE
Definition: winerror.h:2364
HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder *psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvOut)
UINT WINAPI GetDriveTypeA(IN LPCSTR lpRootPathName)
Definition: disk.c:468
#define CMDID_EJECT
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
UINT WINAPI Shell_MergeMenus(HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
Definition: shlmenu.c:857
HRESULT hr
Definition: shlfolder.c:183
virtual HRESULT WINAPI ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
const HKEY * aKeys
Definition: shlobj.h:2348
#define IOCTL_STORAGE_MEDIA_REMOVAL
Definition: ntddstor.h:93
interface IBindCtx * LPBC
Definition: objfwd.h:18
virtual HRESULT WINAPI GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut)
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
LPSTR WINAPI StrFormatByteSize64A(LONGLONG llBytes, LPSTR lpszDest, UINT cchMax)
Definition: string.c:2454
REFIID riid
Definition: precomp.h:44
virtual HRESULT WINAPI Initialize(PCIDLIST_ABSOLUTE pidl)
static BOOL TryToLockOrUnlockDrive(HANDLE hDrive, BOOL bLock)
LPITEMIDLIST _ILCreateDrive(LPCWSTR lpszNew)
Definition: pidl.c:1794
BOOL AddToEnumList(LPITEMIDLIST pidl)
#define SHFMT_ERROR
Definition: shlobj.h:292
#define _countof(array)
Definition: fontsub.cpp:30
BOOL HCR_GetIconW(LPCWSTR szClass, LPWSTR szDest, LPCWSTR szName, DWORD len, int *picon_idx)
Definition: classes.c:294
#define IDS_SHV_COLUMN_DISK_CAPACITY
Definition: shresdef.h:48
char CHAR
Definition: xmlstorage.h:175
#define CMDID_FORMAT
ITEMID_CHILD UNALIGNED * PUITEMID_CHILD
Definition: shtypes.idl:68
HRESULT WINAPI Shell_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdtobj)
Definition: shlfolder.cpp:450
HRESULT WINAPI SHCreateDefaultContextMenu(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv)
#define WARN(fmt,...)
Definition: debug.h:111
#define CMDID_DISCONNECT
virtual HRESULT WINAPI GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
#define RETRY_SLEEP
void AddClassKeyToArray(const WCHAR *szClass, HKEY *array, UINT *cKeys)
Definition: shlfolder.cpp:267
#define DRIVE_RAMDISK
Definition: winbase.h:252
#define LVCFMT_RIGHT
Definition: commctrl.h:2571
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
IContextMenuCB * pcmcb
Definition: shlobj.h:2341
#define CALLBACK
Definition: compat.h:27
_In_ LPCSTR lpName
Definition: winbase.h:2729
LPWSTR pOleStr
Definition: shtypes.idl:96
HMENU hmenu
Definition: shlobj.h:1306
virtual HRESULT WINAPI GetCurFolder(PIDLIST_ABSOLUTE *pidl)
#define SHFMT_NOFORMAT
Definition: shlobj.h:294
const char * shdebugstr_guid(const struct _GUID *id)
Definition: debughlp.cpp:414
WCHAR swShell32Name[MAX_PATH]
Definition: folders.cpp:22
#define IDS_CANTSHOWPROPERTIES
Definition: shresdef.h:141
#define LVCFMT_LEFT
Definition: commctrl.h:2570
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
UINT DriveType
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1105
HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf, HWND hwnd, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
const GUID IID_IDataObject
#define MAKE_COMPARE_HRESULT(x)
Definition: shellutils.h:513
UINT_PTR WPARAM
Definition: windef.h:207
#define IDS_PROPERTIES
Definition: resource.h:101
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
UINT uFlags
Definition: api.c:60
#define SHFMT_ID_DEFAULT
Definition: shlobj.h:297
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
static LPOLESTR
Definition: stg_prop.c:27
HRESULT SHELL32_BindToSF(LPCITEMIDLIST pidlRoot, PERSIST_FOLDER_TARGET_INFO *ppfti, LPCITEMIDLIST pidl, const GUID *clsid, REFIID riid, LPVOID *ppvOut)
Definition: shlfolder.cpp:159
CComPtr< IShellFolder2 > m_regFolder
Definition: CDrivesFolder.h:36
static const DWORD dwComputerAttributes
virtual HRESULT WINAPI BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
HRESULT IDataObject_Constructor(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidl, UINT cidl, IDataObject **dataObject)
#define NO_ERROR
Definition: dderror.h:5
HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE *pcsfv, IShellView **ppsv)
Definition: CDefView.cpp:3448
#define IID_PPV_ARG(Itype, ppType)
#define E_FAIL
Definition: ddrawi.h:102
#define RETRY_COUNT
#define IDS_DRIVE_CDROM
Definition: shresdef.h:106
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
STRRET str
Definition: shtypes.idl:108
int32_t INT
Definition: typedefs.h:56
WPARAM wParam
Definition: combotst.c:138
#define FILE_SHARE_READ
Definition: compat.h:125
#define DRIVE_REMOVABLE
Definition: winbase.h:248
virtual HRESULT WINAPI CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
#define IDS_SHV_COLUMN_TYPE
Definition: resource.h:75
#define lstrcpynW
Definition: compat.h:397
BOOL WINAPI PathAppendW(LPWSTR lpszPath, LPCWSTR lpszAppend)
Definition: path.c:121
virtual HRESULT WINAPI SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
char cStr[MAX_PATH]
Definition: shtypes.idl:98
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
const GUID * guid
IShellFolder * psf
Definition: shlobj.h:2343
#define DRIVE_REMOTE
Definition: winbase.h:250
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define MFS_ENABLED
Definition: winuser.h:745
HINSTANCE shell32_hInstance
Definition: misc.cpp:82
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define IDS_FORMATDRIVE
Definition: shresdef.h:212
#define UNICODE_NULL
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
static BOOL _ILIsSpecialFolder(LPCITEMIDLIST pidl)
#define IDS_SHV_COLUMN_DISK_AVAILABLE
Definition: shresdef.h:49
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ERROR_CAN_NOT_COMPLETE
Definition: winerror.h:582
static const DWORD dwControlPanelAttributes
HRESULT SHELL32_CompareChildren(IShellFolder2 *psf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: shlfolder.cpp:215
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:96
#define IDS_CANTLOCKVOLUME
Definition: shresdef.h:138
#define E_INVALIDARG
Definition: ddrawi.h:101
HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE *ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl)
Definition: shlfolder.cpp:327
#define DFM_INVOKECOMMAND
Definition: precomp.h:45
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
UINT indexMenu
Definition: shlobj.h:1307
HRESULT SHELL32_GetDisplayNameOfChild(IShellFolder2 *psf, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
Definition: shlfolder.cpp:197
DWORD _ILSimpleGetTextW(LPCITEMIDLIST pidl, LPWSTR szOut, UINT uOutSize)
Definition: pidl.c:2082
static HRESULT getIconLocationForDrive(IShellFolder *psf, PCITEMID_CHILD pidl, UINT uFlags, LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
struct _SFV_CREATE SFV_CREATE
LPITEMIDLIST _ILCreateMyComputer(void)
Definition: pidl.c:1599
BOOL ILGetDisplayNameExW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPWSTR path, DWORD type)
Definition: pidl.c:91
#define DRIVE_UNKNOWN
Definition: winbase.h:253
#define OPEN_EXISTING
Definition: compat.h:426
BOOL WINAPI _ILIsPidlSimple(LPCITEMIDLIST pidl)
virtual HRESULT WINAPI GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *prgfInOut, LPVOID *ppvOut)
_Check_return_ _CRTIMP int __cdecl stricmp(_In_z_ const char *_Str1, _In_z_ const char *_Str2)
HRESULT SHELL32_ParseNextElement(IShellFolder2 *psf, HWND hwndOwner, LPBC pbc, LPITEMIDLIST *pidlInOut, LPOLESTR szNext, DWORD *pEaten, DWORD *pdwAttributes)
Definition: shlfolder.cpp:70
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
HRESULT SHELL32_CompareDetails(IShellFolder2 *isf, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: shlfolder.cpp:238
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:541
HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, LPCWSTR lpszEnumKeyName, REFIID riid, void **ppv)
Definition: CRegFolder.cpp:778
#define _T(x)
Definition: vfdio.h:22
#define IDI_SHELL_3_14_FLOPPY
Definition: shresdef.h:470
#define TRACE(s)
Definition: solgame.cpp:4
static BOOL _ILIsControlPanel(LPCITEMIDLIST pidl)
#define IDS_DRIVE_FIXED
Definition: shresdef.h:105
HRESULT hres
Definition: protocol.c:465
#define SHCNE_MEDIAREMOVED
Definition: shlobj.h:1726
int WINAPI MessageBoxW(_In_opt_ HWND, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_ UINT)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define IDS_CANTEJECTMEDIA
Definition: shresdef.h:140
#define MM_ADDSEPARATOR
Definition: shlobj.h:2319
BOOL WINAPI SetVolumeLabelW(IN LPCWSTR lpRootPathName, IN LPCWSTR lpVolumeName OPTIONAL)
Definition: volume.c:503
LONG HRESULT
Definition: typedefs.h:77
IID * _ILGetGUIDPointer(LPCITEMIDLIST pidl)
Definition: pidl.c:2300
UINT idCmdFirst
Definition: shlobj.h:1308
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:71
static int iDriveTypeIds[7]
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
#define DFM_MERGECONTEXTMENU
Definition: precomp.h:44
#define DFM_CMD_PROPERTIES
Definition: shlobj.h:2403
unsigned long DWORD
Definition: ntddk_ex.h:95
HRESULT AppendItemsFromEnumerator(IEnumIDList *pEnum)
#define IDS_DISCONNECT
Definition: shresdef.h:227
#define SetLastError(x)
Definition: compat.h:409
GLbitfield flags
Definition: glext.h:7161
UINT cchMax
BOOL _ILIsDrive(LPCITEMIDLIST pidl)
Definition: pidl.c:1939
#define MFT_SEPARATOR
Definition: winuser.h:739
BOOLEAN PreventMediaRemoval
Definition: ntddstor.h:251
static const WCHAR L[]
Definition: oid.c:1250
virtual HRESULT WINAPI GetClassID(CLSID *lpClassId)
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MB_ICONERROR
Definition: winuser.h:781
virtual HRESULT WINAPI GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
virtual HRESULT WINAPI GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd)
static int iDriveIconIds[7]
#define GENERIC_READ
Definition: compat.h:124
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
Definition: changenotify.c:340
#define IDS_CANTDISCONNECT
Definition: shresdef.h:142
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2621
HRESULT WINAPI SHCreateDefaultExtractIcon(REFIID riid, void **ppv)
static const DWORD dwDriveAttributes
#define SHFMT_CANCEL
Definition: shlobj.h:293
#define DRIVE_FIXED
Definition: winbase.h:249
DWORD WINAPI WNetCancelConnection2W(LPCWSTR lpName, DWORD dwFlags, BOOL fForce)
Definition: wnet.c:2279
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define SHCNF_PATHW
Definition: shlobj.h:1755
DWORD WINAPI GetLogicalDrives(VOID)
Definition: disk.c:110
#define IDS_DRIVE_NETWORK
Definition: shresdef.h:107
int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
Definition: path.c:1087
#define ERR(fmt,...)
Definition: debug.h:109
DWORD WINAPI SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options)
Definition: drive.cpp:623
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
virtual HRESULT WINAPI CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
HRESULT WINAPI Initialize(HWND hwndOwner, DWORD dwFlags, IEnumIDList *pRegEnumerator)
#define S_OK
Definition: intsafe.h:59
#define SW_SHOWNORMAL
Definition: winuser.h:764
HRESULT SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl)
Definition: drive.cpp:118
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
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN CreateFile
Definition: fatprocs.h:904
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
virtual HRESULT WINAPI GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv)
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:228
#define MYCOMPUTERSHELLVIEWCOLUMNS
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:561
void pdump(LPCITEMIDLIST pidl)
Definition: debughlp.cpp:248
virtual HRESULT WINAPI BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
#define E_NOTIMPL
Definition: ddrawi.h:99
virtual HRESULT WINAPI CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, IContextMenu **ppcm)
#define DRIVE_CDROM
Definition: winbase.h:251
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
virtual HRESULT WINAPI EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
unsigned int UINT
Definition: ndis.h:50
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
WINE_DEFAULT_DEBUG_CHANNEL(shell)
#define IDI_SHELL_CDROM
Definition: shresdef.h:475
virtual HRESULT WINAPI GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
int WINAPI PathGetDriveNumberW(const WCHAR *path)
Definition: path.c:548
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:846
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:331
const ITEMIDLIST_RELATIVE UNALIGNED * PCUIDLIST_RELATIVE
Definition: shtypes.idl:57
#define HRESULT_CODE(hr)
Definition: winerror.h:76
BOOL WINAPI GetDiskFreeSpaceExA(IN LPCSTR lpDirectoryName OPTIONAL, OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller, OUT PULARGE_INTEGER lpTotalNumberOfBytes, OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes)
Definition: disk.c:313
static const WCHAR szName[]
Definition: msipriv.h:1194
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2208
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
unsigned int ULONG
Definition: retypes.h:1
IUnknown * punkAssociationInfo
Definition: shlobj.h:2346
virtual HRESULT WINAPI EnumSearches(IEnumExtraSearch **ppenum)
#define IDI_SHELL_RAMDISK
Definition: shresdef.h:476
#define IDI_SHELL_NETDRIVE
Definition: shresdef.h:473
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define END_COM_MAP()
Definition: atlcom.h:552
#define FILE_READ_ONLY_VOLUME
Definition: from_kernel.h:246
#define IDS_SHV_COLUMN_NAME
Definition: resource.h:74
WCHAR * LPWSTR
Definition: xmlstorage.h:184
UINT uType
Definition: shtypes.idl:93
#define E_POINTER
Definition: winerror.h:2365
static BOOL DoEjectDrive(const WCHAR *physical, UINT nDriveType, INT *pnStringID)
PCUITEMID_CHILD_ARRAY apidl
Definition: shlobj.h:2345
DWORD _ILGetDrive(LPCITEMIDLIST pidl, LPSTR pOut, UINT uSize)
Definition: pidl.c:1841
LPITEMIDLIST pidlRoot
Definition: CDrivesFolder.h:35
GLuint64EXT * result
Definition: glext.h:11304
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
static const shvheader MyComputerSFHeader[]
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
PCIDLIST_ABSOLUTE pidlFolder
Definition: shlobj.h:2342
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define SHCNE_DRIVEREMOVED
Definition: shlobj.h:1727
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
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)
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define SHCNF_FLUSHNOWAIT
Definition: shlobj.h:1759
#define SUCCEEDED(hr)
Definition: intsafe.h:57
LONGLONG QuadPart
Definition: typedefs.h:112
#define IDS_DRIVE_FLOPPY
Definition: shresdef.h:108
#define IDS_EJECT
Definition: shresdef.h:226