Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

900 lines
23 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include "pch.h"
  6. #include <atlbase.h>
  7. #include <stdio.h>
  8. #include <wbemcli.h>
  9. #include <comdef.h>
  10. #include <winioctl.h>
  11. #include <ntddvol.h> // IOCTL_VOLUME_IS_OFFLINE
  12. #include "..\..\..\inc\ntrkcomm.h"
  13. #include "..\..\..\inc\objectpath.h"
  14. #include "..\..\schema.cpp"
  15. #include "..\..\volutil.cpp"
  16. #define INITGUIDS
  17. #include <dskquota.h>
  18. BOOL g_fVerbose = FALSE;
  19. typedef enum _Variation
  20. {
  21. Variation_None = 0,
  22. Variation_ValProp,
  23. Variation_End
  24. } Variation;
  25. void
  26. PrintVerbose(CHAR* pwszFormat, ...)
  27. {
  28. if (g_fVerbose)
  29. {
  30. va_list marker;
  31. va_start( marker, pwszFormat );
  32. vprintf(pwszFormat, marker );
  33. va_end( marker );
  34. }
  35. }
  36. class CVolumeValidation
  37. {
  38. public:
  39. CVolumeValidation()
  40. {
  41. m_fStatus = TRUE;
  42. m_wszLabel[0] = L'\0';
  43. m_wszFileSystem[0] = L'\0';
  44. m_dwSerialNumber = 0;
  45. m_cchMaxFileNameLen = 0;
  46. m_dwFileSystemFlags = 0;
  47. m_fGotVolumeInformation = FALSE;
  48. m_fGotQuotaInformation = FALSE;
  49. m_fGotSizeInformation = FALSE;
  50. m_cbCapacity = 0;
  51. m_cbFreeSpace = 0;
  52. m_fQuotasEnabled = FALSE;
  53. m_fQuotasIncomplete = FALSE;
  54. m_fQuotasRebuilding = FALSE;
  55. }
  56. ~CVolumeValidation() {}
  57. BOOL Validate(IWbemClassObject* pIObj);
  58. private:
  59. CWbemClassObject m_wcoVol;
  60. BOOL m_fStatus;
  61. BOOL m_fGotVolumeInformation;
  62. BOOL m_fGotQuotaInformation;
  63. BOOL m_fGotSizeInformation;
  64. _bstr_t m_bstrVolume;
  65. WCHAR m_wszLabel[g_cchVolumeLabelMax+1];
  66. WCHAR m_wszFileSystem[g_cchFileSystemNameMax+1];
  67. DWORD m_dwSerialNumber;
  68. DWORD m_cchMaxFileNameLen;
  69. DWORD m_dwFileSystemFlags;
  70. ULONGLONG m_cbCapacity;
  71. ULONGLONG m_cbFreeSpace;
  72. BOOL m_fQuotasEnabled;
  73. BOOL m_fQuotasIncomplete;
  74. BOOL m_fQuotasRebuilding;
  75. void ValidateAutomount();
  76. void ValidateBlockSize();
  77. void ValidateBootVolume();
  78. void ValidateCapacity();
  79. void ValidateCaptionName();
  80. void ValidateCompressed();
  81. void ValidateCrashdump();
  82. void ValidateDirtyBitSet();
  83. void ValidateDriveLetter();
  84. void ValidateDriveType();
  85. void ValidateFileSystem();
  86. void ValidateFreeSpace();
  87. void ValidateIndexingEnabled();
  88. void ValidateLabel();
  89. void ValidateMaximumFileNameLength();
  90. void ValidatePagefile();
  91. void ValidateQuotasEnabled();
  92. void ValidateQuotasIncomplete();
  93. void ValidateQuotasRebuilding();
  94. void ValidateSerialNumber();
  95. void ValidateSupportsDiskQuotas();
  96. void ValidateSupportsFileBasedCompression();
  97. void ValidateSystemName();
  98. void ValidateSystemVolume();
  99. BOOL ValidatePropertyIsNull(
  100. IN const WCHAR* pwszName);
  101. BOOL ValidatePropertyNotNull(
  102. IN const WCHAR* pwszName);
  103. void CompareProperty(
  104. IN const WCHAR* pwszName,
  105. IN WCHAR* pwszAPI);
  106. void CompareProperty(
  107. IN const WCHAR* pwszName,
  108. IN DWORD dwAPI);
  109. void CompareProperty(
  110. IN const WCHAR* pwszName,
  111. IN ULONGLONG llAPI);
  112. void GetVolumeInformationLocal();
  113. void GetSizeInformation();
  114. void GetQuotaInformation();
  115. };
  116. void
  117. CVolumeValidation::CompareProperty(
  118. const WCHAR* pwszName,
  119. WCHAR* pwszAPI)
  120. {
  121. _bstr_t bstrWMI;
  122. m_wcoVol.GetProperty(bstrWMI, pwszName);
  123. if (pwszAPI == NULL && bstrWMI.length() == 0)
  124. {
  125. PrintVerbose(" %lS<%lS> OK\n", pwszName, (WCHAR*)bstrWMI);
  126. }
  127. else if (pwszAPI == NULL && bstrWMI.length() != 0)
  128. {
  129. m_fStatus = FALSE;
  130. printf(" Error: %lS<%lS> should be <NULL>\n", pwszName, (WCHAR*)bstrWMI);
  131. }
  132. else if (bstrWMI.length() == 0 && wcslen(pwszAPI) == 0)
  133. {
  134. PrintVerbose(" %lS<NULL> OK\n", pwszName, (WCHAR*)bstrWMI);
  135. }
  136. else if (bstrWMI.length() != 0 && _wcsicmp((WCHAR*)bstrWMI, pwszAPI) == 0)
  137. {
  138. PrintVerbose(" %lS<%lS> OK\n", pwszName, (WCHAR*)bstrWMI);
  139. }
  140. else
  141. {
  142. m_fStatus = FALSE;
  143. printf(" Error: %lS<NULL> should be <%lS>\n", pwszName, pwszAPI);
  144. }
  145. }
  146. void
  147. CVolumeValidation::CompareProperty(
  148. const WCHAR* pwszName,
  149. ULONGLONG llAPI)
  150. {
  151. LONGLONG llWMI = 0;
  152. if (ValidatePropertyNotNull(pwszName))
  153. {
  154. m_wcoVol.GetPropertyI64(&llWMI, pwszName);
  155. if (llWMI == llAPI)
  156. {
  157. PrintVerbose(" %lS<%I64d> OK\n", pwszName, llWMI);
  158. }
  159. else
  160. {
  161. m_fStatus = FALSE;
  162. printf(" Error: %lS<%I64d> should be <%I64d>\n", pwszName, llWMI, llAPI);
  163. }
  164. }
  165. }
  166. void
  167. CVolumeValidation::CompareProperty(
  168. const WCHAR* pwszName,
  169. DWORD dwAPI)
  170. {
  171. DWORD dwWMI = 0;
  172. if (ValidatePropertyNotNull(pwszName))
  173. {
  174. m_wcoVol.GetProperty(&dwWMI, pwszName);
  175. if (dwWMI == dwAPI)
  176. {
  177. PrintVerbose(" %lS<%d> OK\n", pwszName, dwWMI);
  178. }
  179. else
  180. {
  181. m_fStatus = FALSE;
  182. printf(" Error: %lS<%d> should be <%d>\n", pwszName, dwWMI, dwAPI);
  183. }
  184. }
  185. }
  186. BOOL
  187. CVolumeValidation::ValidatePropertyIsNull(
  188. const WCHAR* pwszName)
  189. {
  190. _variant_t varVal;
  191. BOOL fStatus = TRUE;
  192. HRESULT hr = m_wcoVol.data()->Get(
  193. _bstr_t(pwszName),
  194. 0,
  195. &varVal,
  196. NULL,
  197. NULL
  198. );
  199. if (SUCCEEDED(hr))
  200. {
  201. if (varVal.vt == VT_NULL)
  202. {
  203. PrintVerbose(" %lS<NULL> OK\n", pwszName);
  204. }
  205. else
  206. {
  207. printf(" Error: %lS should be NULL\n", pwszName);
  208. m_fStatus = FALSE;
  209. fStatus = FALSE;
  210. }
  211. }
  212. else
  213. {
  214. printf(" Error: %lS not found\n", pwszName);
  215. m_fStatus = FALSE;
  216. fStatus = FALSE;
  217. }
  218. return fStatus;
  219. }
  220. BOOL
  221. CVolumeValidation::ValidatePropertyNotNull(
  222. const WCHAR* pwszName)
  223. {
  224. _variant_t varVal;
  225. BOOL fStatus = TRUE;
  226. HRESULT hr = m_wcoVol.data()->Get(
  227. _bstr_t(pwszName),
  228. 0,
  229. &varVal,
  230. NULL,
  231. NULL
  232. );
  233. if (SUCCEEDED(hr))
  234. {
  235. if (varVal.vt == VT_NULL)
  236. {
  237. printf(" Error: %lS should not be NULL\n", pwszName);
  238. m_fStatus = FALSE;
  239. fStatus = FALSE;
  240. }
  241. }
  242. else
  243. {
  244. printf(" Error: %lS not found\n", pwszName);
  245. m_fStatus = FALSE;
  246. fStatus = FALSE;
  247. }
  248. return fStatus;
  249. }
  250. BOOL
  251. CVolumeValidation::Validate(IWbemClassObject* pIVolume)
  252. {
  253. m_wcoVol = pIVolume;
  254. try
  255. {
  256. m_wcoVol.GetProperty(m_bstrVolume, PVDR_PROP_DEVICEID);
  257. printf("VolumeGUID<%lS>\n", (WCHAR*)m_bstrVolume);
  258. ValidateSystemName();
  259. ValidateCaptionName();
  260. ValidateAutomount();
  261. ValidateDriveType();
  262. if (VolumeIsMountable(m_bstrVolume) && VolumeIsReady(m_bstrVolume))
  263. {
  264. ValidateBlockSize();
  265. ValidateBootVolume();
  266. ValidateCapacity();
  267. ValidateCompressed();
  268. ValidateCrashdump();
  269. ValidateDirtyBitSet();
  270. ValidateDriveLetter();
  271. ValidateFileSystem();
  272. ValidateFreeSpace();
  273. ValidateIndexingEnabled();
  274. ValidateLabel();
  275. ValidateMaximumFileNameLength();
  276. ValidatePagefile();
  277. ValidateQuotasEnabled();
  278. ValidateQuotasIncomplete();
  279. ValidateQuotasRebuilding();
  280. ValidateSerialNumber();
  281. ValidateSupportsDiskQuotas();
  282. ValidateSupportsFileBasedCompression();
  283. ValidateSystemVolume();
  284. }
  285. else
  286. {
  287. ValidatePropertyIsNull(PVDR_PROP_BLOCKSIZE);
  288. ValidatePropertyIsNull(PVDR_PROP_CAPACITY);
  289. ValidatePropertyIsNull(PVDR_PROP_COMPRESSED);
  290. ValidatePropertyIsNull(PVDR_PROP_DIRTYBITSET);
  291. ValidatePropertyIsNull(PVDR_PROP_FILESYSTEM);
  292. ValidatePropertyIsNull(PVDR_PROP_FREESPACE);
  293. ValidatePropertyIsNull(PVDR_PROP_INDEXINGENABLED);
  294. ValidatePropertyIsNull(PVDR_PROP_LABEL);
  295. ValidatePropertyIsNull(PVDR_PROP_MAXIMUMFILENAMELENGTH);
  296. ValidatePropertyIsNull(PVDR_PROP_QUOTASENABLED);
  297. ValidatePropertyIsNull(PVDR_PROP_QUOTASINCOMPLETE);
  298. ValidatePropertyIsNull(PVDR_PROP_QUOTASREBUILDING);
  299. ValidatePropertyIsNull(PVDR_PROP_SERIALNUMBER);
  300. ValidatePropertyIsNull(PVDR_PROP_SUPPORTSDISKQUOTAS);
  301. }
  302. ValidatePropertyIsNull(PVDR_PROP_DESCRIPTION);
  303. ValidatePropertyIsNull(L"Access");
  304. ValidatePropertyIsNull(L"Availability");
  305. ValidatePropertyIsNull(L"ConfigManagerErrorCode");
  306. ValidatePropertyIsNull(L"ConfigManagerUserConfig");
  307. ValidatePropertyIsNull(L"CreationClassName");
  308. ValidatePropertyIsNull(L"ErrorCleared");
  309. ValidatePropertyIsNull(L"ErrorDescription");
  310. ValidatePropertyIsNull(L"ErrorMethodology");
  311. ValidatePropertyIsNull(L"InstallDate");
  312. ValidatePropertyIsNull(L"LastErrorCode");
  313. ValidatePropertyIsNull(L"NumberOfBlocks");
  314. ValidatePropertyIsNull(L"PNPDeviceID");
  315. ValidatePropertyIsNull(L"PowerManagementCapabilities");
  316. ValidatePropertyIsNull(L"PowerManagementSupported");
  317. ValidatePropertyIsNull(L"Purpose");
  318. ValidatePropertyIsNull(L"Status");
  319. ValidatePropertyIsNull(L"StatusInfo");
  320. ValidatePropertyIsNull(L"SystemCreationClassName");
  321. #ifdef NEVER
  322. ft.hr = CoCreateInstance(
  323. CLSID_DiskQuotaControl,
  324. NULL,
  325. CLSCTX_INPROC_SERVER,
  326. IID_IDiskQuotaControl,
  327. (void **)&pIDQC);
  328. if (ft.HrFailed())
  329. {
  330. ft.Throw(VSSDBG_VSSADMIN, ft.hr, L"unable to CoCreate IDiskQuotaControl");
  331. }
  332. spIDQC.Attach(pIDQC);
  333. ft.hr = spIDQC->Initialize(pwszVolume, FALSE /* read only */);
  334. if (ft.HrFailed())
  335. {
  336. ft.Trace(VSSDBG_VSSADMIN, L"IDiskQuotaControl::Initialize failed for volume %lS", pwszVolume);
  337. }
  338. else
  339. {
  340. DWORD dwState = 0;
  341. ft.hr = spIDQC->GetQuotaState(&dwState);
  342. if (ft.HrSucceeded())
  343. {
  344. wcoInstance.SetProperty(!(DISKQUOTA_IS_DISABLED(dwState)), PVDR_PROP_QUOTASENABLED);
  345. }
  346. }
  347. }
  348. #endif
  349. }
  350. catch(CProvException ex)
  351. {
  352. printf("exception caught while validating volume, hr<%#x>\n", ex.hrGetError());
  353. m_fStatus = FALSE;
  354. }
  355. catch(HRESULT hrEx)
  356. {
  357. printf("exception caught while validating volume, hr<%#x>\n", hrEx);
  358. m_fStatus = FALSE;
  359. }
  360. return m_fStatus;
  361. }
  362. void
  363. CVolumeValidation::ValidateAutomount()
  364. {
  365. WCHAR wszPath[MAX_PATH+1] ;
  366. DWORD dwProp = 0;
  367. // Check Mountable (Automount)
  368. BOOL fMountable = VolumeIsMountable(m_bstrVolume);
  369. CompareProperty(PVDR_PROP_MOUNTABLE, (DWORD)fMountable);
  370. }
  371. void
  372. CVolumeValidation::ValidateBlockSize()
  373. {
  374. LONGLONG llProp = 0;
  375. DWORD cSectorsPerCluster = 0;
  376. DWORD cBytesPerSector = 0;
  377. DWORD cDontCare = 0;
  378. // Check BlockSize
  379. if (GetDiskFreeSpace(
  380. m_bstrVolume,
  381. &cSectorsPerCluster,
  382. &cBytesPerSector,
  383. &cDontCare, // total bytes
  384. &cDontCare)) // total free bytes
  385. {
  386. LONGLONG cbBytesPerCluster = cBytesPerSector * cSectorsPerCluster;
  387. CompareProperty(PVDR_PROP_BLOCKSIZE, (ULONGLONG)cbBytesPerCluster);
  388. }
  389. else
  390. {
  391. ValidatePropertyIsNull(PVDR_PROP_BLOCKSIZE);
  392. }
  393. }
  394. void
  395. CVolumeValidation::ValidateCapacity()
  396. {
  397. GetSizeInformation();
  398. CompareProperty(PVDR_PROP_CAPACITY, m_cbCapacity);
  399. }
  400. void
  401. CVolumeValidation::ValidateCaptionName()
  402. {
  403. WCHAR wszPath[MAX_PATH+1] ;
  404. _bstr_t bstrProp;
  405. // Check Name & Caption
  406. VssGetVolumeDisplayName(
  407. m_bstrVolume,
  408. wszPath,
  409. MAX_PATH);
  410. CompareProperty(PVDR_PROP_NAME, wszPath);
  411. CompareProperty(PVDR_PROP_CAPTION, wszPath);
  412. }
  413. void
  414. CVolumeValidation::ValidateCompressed()
  415. {
  416. GetVolumeInformationLocal();
  417. CompareProperty(PVDR_PROP_COMPRESSED, m_dwFileSystemFlags & FS_VOL_IS_COMPRESSED);
  418. }
  419. void
  420. CVolumeValidation::ValidateDirtyBitSet()
  421. {
  422. DWORD dwProp = 0;
  423. BOOL fDirty = FALSE;
  424. DWORD dwRet = VolumeIsDirty(m_bstrVolume, &fDirty);
  425. if (dwRet != ERROR_SUCCESS)
  426. {
  427. printf("VolumeIsDirty failed %#x\n", dwRet);
  428. throw HRESULT_FROM_WIN32(dwRet);
  429. }
  430. CompareProperty(PVDR_PROP_DIRTYBITSET, (DWORD)fDirty);
  431. }
  432. void
  433. CVolumeValidation::ValidateDriveLetter()
  434. {
  435. WCHAR wszDriveLetter[g_cchDriveName];
  436. _bstr_t bstrProp;
  437. if (GetVolumeDrive(
  438. m_bstrVolume,
  439. g_cchDriveName,
  440. wszDriveLetter))
  441. {
  442. wszDriveLetter[wcslen(wszDriveLetter) - 1] = L'\0'; // Remove the trailing '\'
  443. CompareProperty(PVDR_PROP_DRIVELETTER, wszDriveLetter);
  444. }
  445. else
  446. ValidatePropertyIsNull(PVDR_PROP_DRIVELETTER);
  447. }
  448. void
  449. CVolumeValidation::ValidateDriveType()
  450. {
  451. WCHAR wszDriveLetter[g_cchDriveName];
  452. _bstr_t bstrProp;
  453. CompareProperty(PVDR_PROP_DRIVETYPE, (DWORD)GetDriveType(m_bstrVolume));
  454. }
  455. void
  456. CVolumeValidation::ValidateFreeSpace()
  457. {
  458. GetSizeInformation();
  459. CompareProperty(PVDR_PROP_FREESPACE, m_cbFreeSpace);
  460. }
  461. void
  462. CVolumeValidation::ValidateFileSystem()
  463. {
  464. GetVolumeInformationLocal();
  465. CompareProperty(PVDR_PROP_FILESYSTEM, m_wszFileSystem);
  466. }
  467. void
  468. CVolumeValidation::ValidateLabel()
  469. {
  470. GetVolumeInformationLocal();
  471. CompareProperty(PVDR_PROP_LABEL, m_wszLabel);
  472. }
  473. void
  474. CVolumeValidation::ValidateIndexingEnabled()
  475. {
  476. DWORD dwAttributes = GetFileAttributes(m_bstrVolume);
  477. if (dwAttributes == INVALID_FILE_ATTRIBUTES)
  478. {
  479. printf("GetFileAttributes failed %#x\n", GetLastError());
  480. throw HRESULT_FROM_WIN32(GetLastError());
  481. }
  482. BOOL fIndexingEnabled = !(dwAttributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
  483. CompareProperty(PVDR_PROP_INDEXINGENABLED, (DWORD)fIndexingEnabled);
  484. }
  485. void
  486. CVolumeValidation::ValidateMaximumFileNameLength()
  487. {
  488. GetVolumeInformationLocal();
  489. CompareProperty(PVDR_PROP_MAXIMUMFILENAMELENGTH, m_cchMaxFileNameLen);
  490. }
  491. void
  492. CVolumeValidation::ValidateQuotasEnabled()
  493. {
  494. GetQuotaInformation();
  495. if (m_fGotQuotaInformation)
  496. CompareProperty(PVDR_PROP_QUOTASENABLED, (DWORD)m_fQuotasEnabled);
  497. else
  498. ValidatePropertyIsNull(PVDR_PROP_QUOTASENABLED);
  499. }
  500. void
  501. CVolumeValidation::ValidateQuotasIncomplete()
  502. {
  503. GetQuotaInformation();
  504. if (m_fGotQuotaInformation)
  505. CompareProperty(PVDR_PROP_QUOTASINCOMPLETE, (DWORD)m_fQuotasIncomplete);
  506. else
  507. ValidatePropertyIsNull(PVDR_PROP_QUOTASINCOMPLETE);
  508. }
  509. void
  510. CVolumeValidation::ValidateQuotasRebuilding()
  511. {
  512. GetQuotaInformation();
  513. if (m_fGotQuotaInformation)
  514. CompareProperty(PVDR_PROP_QUOTASREBUILDING, (DWORD)m_fQuotasRebuilding);
  515. else
  516. ValidatePropertyIsNull(PVDR_PROP_QUOTASREBUILDING);
  517. }
  518. void
  519. CVolumeValidation::ValidateSerialNumber()
  520. {
  521. GetVolumeInformationLocal();
  522. CompareProperty(PVDR_PROP_SERIALNUMBER, m_dwSerialNumber);
  523. }
  524. void
  525. CVolumeValidation::ValidateSupportsDiskQuotas()
  526. {
  527. GetVolumeInformationLocal();
  528. CompareProperty(PVDR_PROP_SUPPORTSDISKQUOTAS,
  529. (m_dwFileSystemFlags & FILE_VOLUME_QUOTAS)?(DWORD)1:(DWORD)0);
  530. }
  531. void
  532. CVolumeValidation::ValidateSupportsFileBasedCompression()
  533. {
  534. GetVolumeInformationLocal();
  535. CompareProperty(PVDR_PROP_SUPPORTSFILEBASEDCOMPRESSION,
  536. (DWORD)(m_dwFileSystemFlags & FS_FILE_COMPRESSION)?(DWORD)1:(DWORD)0);
  537. }
  538. void
  539. CVolumeValidation::ValidateSystemName()
  540. {
  541. WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH];
  542. DWORD cchBuf = MAX_COMPUTERNAME_LENGTH;
  543. // Check SystemName
  544. if (!GetComputerName(wszComputerName, &cchBuf))
  545. {
  546. printf("GetComputerName failed %#x\n", GetLastError());
  547. throw HRESULT_FROM_WIN32(GetLastError());
  548. }
  549. CompareProperty(PVDR_PROP_SYSTEMNAME, wszComputerName);
  550. }
  551. void
  552. CVolumeValidation::ValidateBootVolume()
  553. {
  554. CompareProperty(PVDR_PROP_BOOTVOLUME, (DWORD)FALSE);
  555. }
  556. void
  557. CVolumeValidation::ValidateCrashdump()
  558. {
  559. CompareProperty(PVDR_PROP_CRASHDUMP, (DWORD)FALSE);
  560. }
  561. void
  562. CVolumeValidation::ValidatePagefile()
  563. {
  564. CompareProperty(PVDR_PROP_PAGEFILE, (DWORD)FALSE);
  565. }
  566. void
  567. CVolumeValidation::ValidateSystemVolume()
  568. {
  569. CompareProperty(PVDR_PROP_SYSTEMVOLUME, (DWORD)FALSE);
  570. }
  571. void
  572. CVolumeValidation::GetVolumeInformationLocal()
  573. {
  574. if (!m_fGotVolumeInformation)
  575. {
  576. if (!GetVolumeInformation(
  577. m_bstrVolume,
  578. m_wszLabel,
  579. g_cchVolumeLabelMax,
  580. &m_dwSerialNumber,
  581. &m_cchMaxFileNameLen,
  582. &m_dwFileSystemFlags,
  583. m_wszFileSystem,
  584. g_cchFileSystemNameMax))
  585. {
  586. printf("GetVolumeInformation failed for volume %lS, %#x\n", (WCHAR*)m_bstrVolume, GetLastError());
  587. throw HRESULT_FROM_WIN32(GetLastError());
  588. }
  589. m_fGotVolumeInformation = TRUE;
  590. }
  591. }
  592. void
  593. CVolumeValidation::GetSizeInformation()
  594. {
  595. if (!m_fGotSizeInformation)
  596. {
  597. ULARGE_INTEGER cbCapacity = {0, 0};
  598. ULARGE_INTEGER cbFreeSpace = {0, 0};
  599. ULARGE_INTEGER cbUserFreeSpace = {0, 0};
  600. if (!GetDiskFreeSpaceEx(
  601. m_bstrVolume,
  602. &cbUserFreeSpace,
  603. &cbCapacity,
  604. &cbFreeSpace))
  605. {
  606. printf("GetDiskFreeSpaceEx failed for volume %lS, %#x\n", (WCHAR*)m_bstrVolume, GetLastError());
  607. throw HRESULT_FROM_WIN32(GetLastError());
  608. }
  609. m_cbCapacity = cbCapacity.QuadPart;
  610. m_cbFreeSpace = cbFreeSpace.QuadPart;
  611. m_fGotSizeInformation = TRUE;
  612. }
  613. }
  614. void
  615. CVolumeValidation::GetQuotaInformation()
  616. {
  617. HRESULT hr = S_OK;
  618. CComPtr<IDiskQuotaControl> spIDQC;
  619. IDiskQuotaControl* pIDQC = NULL;
  620. hr = CoCreateInstance(
  621. CLSID_DiskQuotaControl,
  622. NULL,
  623. CLSCTX_INPROC_SERVER,
  624. IID_IDiskQuotaControl,
  625. (void **)&pIDQC);
  626. if (FAILED(hr))
  627. {
  628. printf("IDiskQuotaControl CoCreateInstance failed, %#x\n",hr);
  629. throw hr;
  630. }
  631. spIDQC.Attach(pIDQC);
  632. // OK if this fails on some volumes with file systems that don't support quotas.
  633. hr = spIDQC->Initialize(m_bstrVolume, FALSE /* read only */);
  634. if (SUCCEEDED(hr))
  635. {
  636. DWORD dwState = 0;
  637. hr = spIDQC->GetQuotaState(&dwState);
  638. if (FAILED(hr))
  639. {
  640. printf("IDiskQuotaControl::GetQuotaState failed for volume %lS, %#x\n", m_bstrVolume, hr);
  641. throw hr;
  642. }
  643. m_fQuotasEnabled = !(DISKQUOTA_IS_DISABLED(dwState));
  644. m_fQuotasIncomplete = DISKQUOTA_FILE_INCOMPLETE(dwState);
  645. m_fQuotasRebuilding = DISKQUOTA_FILE_REBUILDING(dwState);
  646. m_fGotQuotaInformation = TRUE;
  647. }
  648. }
  649. HRESULT
  650. testValProp(IWbemServices* pISvc)
  651. {
  652. HRESULT hr = S_OK;
  653. BOOL bStatus = TRUE;
  654. do
  655. {
  656. CComPtr<IEnumWbemClassObject> spEnum;
  657. hr = pISvc->CreateInstanceEnum(
  658. _bstr_t(L"Win32_Volume"), 0, NULL, &spEnum);
  659. if (FAILED(hr))
  660. {
  661. printf("Win32_Volume enumeration failed <%#x>\n", hr);
  662. break;
  663. }
  664. while(true)
  665. {
  666. CComPtr<IWbemClassObject> spVolume;
  667. CVolumeValidation validation;
  668. ULONG cVolume = 0;
  669. hr = spEnum->Next(WBEM_INFINITE, 1, &spVolume, &cVolume);
  670. if (FAILED(hr))
  671. {
  672. printf("IEnumWbem::Next failed <%#x>\n", hr);
  673. goto Exit;
  674. }
  675. if (hr == S_FALSE)
  676. {
  677. hr = S_OK;
  678. break;
  679. }
  680. if (!validation.Validate(spVolume))
  681. {
  682. bStatus = FALSE;
  683. }
  684. }
  685. }
  686. while (false);
  687. if (bStatus == FALSE)
  688. {
  689. printf("testValProp: instance validation failed for at least one volume\n");
  690. hr = S_FALSE;
  691. }
  692. Exit:
  693. return hr;
  694. }
  695. void
  696. PrintUsage()
  697. {
  698. printf("Usage: valprop [-v] variation_number [volume_name]\n");
  699. printf("variations:\n");
  700. printf("1 - validate properties against Win32 APIs\n");
  701. }
  702. HRESULT
  703. RunTest(
  704. WCHAR* pwszVolume,
  705. long nVariation)
  706. {
  707. HRESULT hr = E_FAIL;
  708. do
  709. {
  710. CComPtr<IWbemLocator> spILocator;
  711. CComPtr<IWbemServices> spISvc;
  712. hr = CoInitialize(NULL);
  713. if (FAILED(hr))
  714. {
  715. printf("CoInitialize failed <%#x>\n", hr);
  716. break;
  717. }
  718. hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
  719. RPC_C_AUTHN_LEVEL_CONNECT,
  720. RPC_C_IMP_LEVEL_IMPERSONATE,
  721. NULL, EOAC_NONE, 0);
  722. if (FAILED(hr))
  723. {
  724. printf("CoInitializeSecurity failed <%#x>\n", hr);
  725. break;
  726. }
  727. hr = spILocator.CoCreateInstance(__uuidof(WbemLocator));
  728. if (FAILED(hr))
  729. {
  730. printf("IWbemLocator CoCreateInstance failed <%#x>\n", hr);
  731. break;
  732. }
  733. hr = spILocator->ConnectServer(
  734. _bstr_t("\\\\.\\root\\cimv2"),
  735. NULL, NULL, NULL, 0, NULL, NULL, &spISvc);
  736. if (FAILED(hr))
  737. {
  738. printf("IWbemLocator::ConnectServer failed <%#x>\n", hr);
  739. break;
  740. }
  741. switch (nVariation)
  742. {
  743. case Variation_ValProp:
  744. hr = testValProp(spISvc);
  745. break;
  746. default:
  747. printf("invalid variation number <%d>\n", nVariation);
  748. PrintUsage();
  749. hr = E_INVALIDARG;
  750. }
  751. }
  752. while (false);
  753. CoUninitialize();
  754. return hr;
  755. }
  756. _cdecl wmain(int argc, wchar_t* argv[])
  757. {
  758. HRESULT hr = E_FAIL;
  759. if (argc < 2)
  760. {
  761. PrintUsage();
  762. return 1;
  763. }
  764. int nArg = 1;
  765. if (_wcsicmp(argv[nArg], L"-v") == 0)
  766. {
  767. g_fVerbose = TRUE;
  768. nArg++;
  769. }
  770. long nVariation = wcstol(argv[nArg++], NULL, 10);
  771. WCHAR* pwszVolume = argv[nArg];
  772. hr = RunTest(pwszVolume, nVariation);
  773. if (hr != S_OK)
  774. printf("test failed <%#x>\n", hr);
  775. else
  776. printf("test succeeded\n");
  777. return hr == S_OK;
  778. }