PageRenderTime 27ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Visual Studio 2010/CppVDSUninstallDisks/CppVDSUninstallDisks.cpp

#
C++ | 399 lines | 310 code | 54 blank | 35 comment | 47 complexity | 48f47a54f98495372cc3f6d8b44cfdca MD5 | raw file
  1. /****************************** Module Header ******************************\
  2. Module Name: CppVDSUninstallDisks.cpp
  3. Project: CppVDSUninstallDisks (VDS Uninstall Disks)
  4. Copyright (c) Microsoft Corporation.
  5. Demonstrates disk and volumes uninstall using VDS.
  6. This source is subject to the Microsoft Public License.
  7. See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
  8. All other rights reserved.
  9. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
  10. EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  11. WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
  12. \***************************************************************************/
  13. #include <windows.h>
  14. #include <winioctl.h>
  15. #include <stdio.h>
  16. #include <initguid.h>
  17. #include <vds.h>
  18. // Turn off do..while(TRUE) warnings.
  19. #pragma warning(disable: 4127)
  20. #define SAFE_RELEASE(x) if (x) { x->Release(); x = NULL; }
  21. #define SAFE_FREE(x) if (x) { CoTaskMemFree(x); }
  22. void usage()
  23. {
  24. printf("Warning: uninstalling a disk may lead to potential data loss. \n");
  25. printf("Usage: CppVDSUninstallDisks.exe <disknumber <disknumber> <etc>>\n");
  26. printf(" e.g.: CppVDSUninstallDisks 1 4 2\n");
  27. }
  28. HRESULT GetDiskIds(IEnumVdsObject *pEnumDisk, BOOL bVerbose, VDS_OBJECT_ID **ppDiskArray, DWORD dwDiskNumber)
  29. {
  30. UNREFERENCED_PARAMETER(bVerbose);
  31. IUnknown *pDiskUnk = NULL;
  32. ULONG ulFetchedDisk = 0L;
  33. int iDiskNumber = 1;
  34. HRESULT hr = S_OK;
  35. DWORD dwNumber = 0L;
  36. IVdsDisk *pDisk = NULL;
  37. VDS_DISK_PROP diskprop;
  38. do
  39. {
  40. hr = pEnumDisk->Next(1, &pDiskUnk, &ulFetchedDisk);
  41. if (hr == S_FALSE)
  42. {
  43. break; // end of enumeration
  44. }
  45. if (FAILED(hr))
  46. {
  47. printf("\npEnumDisk->Next(): hr=%X\n", hr);
  48. return hr;
  49. }
  50. printf(" Disk #: %ld\n", iDiskNumber++);
  51. // Get IVdsDisk
  52. hr = pDiskUnk->QueryInterface(IID_IVdsDisk, (void **)&pDisk);
  53. SAFE_RELEASE(pDiskUnk);
  54. if (FAILED(hr))
  55. {
  56. printf("pDiskUnk->QueryInterface(): hr=%X\n", hr);
  57. return hr;
  58. }
  59. // Get properties
  60. hr = pDisk->GetProperties(&diskprop);
  61. if (FAILED(hr))
  62. {
  63. printf("\t pDisk->GetProperties(): hr=%X\n", hr);
  64. SAFE_RELEASE(pDisk);
  65. return hr;
  66. }
  67. if (NULL == diskprop.pwszName || ::wcslen(diskprop.pwszName) < 18)
  68. {
  69. continue;
  70. //printf("\t diskprop.pwszName: %S, %s\n",
  71. // diskprop.pwszName ? diskprop.pwszName : L"UNKNOWN");
  72. }
  73. printf("\t diskprop.pwszName: %ws\n",
  74. diskprop.pwszName ? diskprop.pwszName : L"UNKNOWN");
  75. dwNumber = _wtol(&(diskprop.pwszName[17]));
  76. SAFE_FREE(diskprop.pwszName);
  77. SAFE_FREE(diskprop.pwszDiskAddress);
  78. SAFE_FREE(diskprop.pwszFriendlyName);
  79. SAFE_FREE(diskprop.pwszAdaptorName);
  80. SAFE_FREE(diskprop.pwszDevicePath);
  81. //
  82. // If this disk matches the input disk number, copy
  83. // the disk id to the buffer.
  84. if (dwNumber == dwDiskNumber)
  85. {
  86. ::memcpy((*ppDiskArray), &(diskprop.id), sizeof(VDS_OBJECT_ID));
  87. (*ppDiskArray)++;
  88. }
  89. SAFE_RELEASE(pDisk);
  90. } while (TRUE);
  91. return S_OK;
  92. }
  93. int wmain(int argc, wchar_t *argv[])
  94. {
  95. HRESULT hr;
  96. IVdsService *pService = NULL;
  97. IEnumVdsObject *pEnum = NULL;
  98. IEnumVdsObject *pEnumPack = NULL;
  99. IEnumVdsObject *pEnumDisk = NULL;
  100. IVdsServiceUninstallDisk *pUninstallIntf = NULL;
  101. VDS_OBJECT_ID *pDiskArray = NULL;
  102. VDS_OBJECT_ID *pDiskArrayHead = NULL;
  103. BOOL bVerbose = FALSE;
  104. ULONG ulDisk = 999999L;
  105. HRESULT *pResults = NULL;
  106. BOOLEAN bReboot = FALSE;
  107. LONG i = 0L;
  108. LONG numDisks;
  109. if (argc < 2)
  110. {
  111. usage();
  112. exit(1);
  113. }
  114. numDisks = argc - 1;
  115. pDiskArray = (VDS_OBJECT_ID *) ::CoTaskMemAlloc(sizeof(VDS_OBJECT_ID) * numDisks);
  116. if (NULL == pDiskArray)
  117. {
  118. printf("\tmain, 1: %lX\n", E_OUTOFMEMORY);
  119. goto _bailout;
  120. }
  121. ::memset(pDiskArray, 0, (sizeof(VDS_OBJECT_ID) * numDisks));
  122. pDiskArrayHead = pDiskArray;
  123. if (FAILED(CoInitialize(NULL)))
  124. {
  125. printf("CoInitialize() failed.\n");
  126. return 0;
  127. }
  128. hr = CoInitializeSecurity(
  129. NULL,
  130. -1,
  131. NULL,
  132. NULL,
  133. RPC_C_AUTHN_LEVEL_CONNECT,
  134. RPC_C_IMP_LEVEL_IMPERSONATE,
  135. NULL,
  136. 0,
  137. NULL
  138. );
  139. if (FAILED(hr))
  140. {
  141. printf("CoInitializeSecurity failed: hr=%X.\n", hr);
  142. return 0;
  143. }
  144. // Create a loader instance
  145. IVdsServiceLoader *pLoader;
  146. COSERVERINFO ServerInfo;
  147. MULTI_QI MultiQi;
  148. ServerInfo.dwReserved1 = 0;
  149. ServerInfo.pwszName = NULL;
  150. ServerInfo.pAuthInfo = NULL;
  151. ServerInfo.dwReserved2 = 0;
  152. MultiQi.pIID = &IID_IVdsServiceLoader;
  153. MultiQi.pItf = NULL;
  154. MultiQi.hr = 0;
  155. hr = CoCreateInstanceEx(CLSID_VdsLoader,
  156. NULL,
  157. CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
  158. &ServerInfo,
  159. 1,
  160. &MultiQi
  161. );
  162. if (FAILED(hr))
  163. {
  164. printf("\nCoCreateInstanceEx failed: hr=%X MultiQi.hr=%X\n", hr, MultiQi.hr);
  165. return 0;
  166. }
  167. if (FAILED(MultiQi.hr))
  168. {
  169. printf("\nCoCreateInstanceEx failed: hr=%X MultiQi.hr=%X\n", hr, MultiQi.hr);
  170. return 0;
  171. }
  172. // Load the service on the machine.
  173. pLoader = (IVdsServiceLoader *)MultiQi.pItf;
  174. hr = pLoader->LoadService(NULL, &pService);
  175. pLoader->Release();
  176. pLoader = NULL;
  177. if (FAILED(hr))
  178. {
  179. printf("\nLoadService failed: hr=%X\n", hr);
  180. return 0;
  181. }
  182. // Call QueryUnallocatedDisks.
  183. for (i = 1; i <= numDisks; i++)
  184. {
  185. hr = pService->QueryUnallocatedDisks(&pEnumDisk);
  186. if (FAILED(hr))
  187. {
  188. printf("QueryUnallocatedDisks: hr=%X\n", hr);
  189. return 0;
  190. }
  191. ulDisk = _wtol(argv[i]);
  192. GetDiskIds(pEnumDisk, bVerbose, &pDiskArray, ulDisk);
  193. SAFE_RELEASE(pEnumDisk);
  194. }
  195. // Call QueryProviders
  196. hr = pService->QueryProviders(VDS_QUERY_SOFTWARE_PROVIDERS, &pEnum);
  197. if (FAILED(hr))
  198. {
  199. printf("\nQueryProviders(VDS_QUERY_SOFTWARE_PROVIDERS): hr=%X\n",hr);
  200. goto _bailout;
  201. }
  202. IUnknown *pUnk;
  203. IVdsProvider *pProvider;
  204. ULONG ulFetched = 0;
  205. int iProviderNumber = 1;
  206. do
  207. {
  208. hr = pEnum->Next(1, &pUnk, &ulFetched);
  209. if (hr == S_FALSE)
  210. {
  211. break;
  212. }
  213. if (FAILED(hr))
  214. {
  215. goto _bailout;
  216. }
  217. printf(" Provider #: %ld\n", iProviderNumber++);
  218. // Get IVdsProvider
  219. hr = pUnk->QueryInterface(IID_IVdsProvider, (void **)&pProvider);
  220. SAFE_RELEASE(pUnk);
  221. if (FAILED(hr))
  222. {
  223. printf(" pUnk->QueryInterface(IVdsProvider): hr=%X\n", hr);
  224. goto _bailout;
  225. }
  226. // Get IVdsSwProvider
  227. IVdsSwProvider *pSwProvider;
  228. hr = pProvider->QueryInterface(IID_IVdsSwProvider, (void **)&pSwProvider);
  229. SAFE_RELEASE(pProvider);
  230. if (FAILED(hr))
  231. {
  232. printf(" pProvider->QueryInterface(IVdsSwProvider): hr=%X\n", hr);
  233. goto _bailout;
  234. }
  235. // Get packs
  236. hr = pSwProvider->QueryPacks(&pEnumPack);
  237. SAFE_RELEASE(pSwProvider);
  238. if (FAILED(hr))
  239. {
  240. printf(" pSwProvider->QueryPacks(): hr=%X\n", hr);
  241. goto _bailout;
  242. }
  243. IUnknown *pPackUnk;
  244. ULONG ulFetchedPack;
  245. int iPackNumber = 1;
  246. do
  247. {
  248. hr = pEnumPack->Next(1, &pPackUnk, &ulFetchedPack);
  249. if (hr == S_FALSE)
  250. {
  251. break;
  252. }
  253. if (FAILED(hr))
  254. {
  255. goto _bailout;
  256. }
  257. printf("Pack #: %ld\n", iPackNumber++);
  258. // Get IVdsPack
  259. IVdsPack *pPack;
  260. hr = pPackUnk->QueryInterface(IID_IVdsPack, (void **)&pPack);
  261. SAFE_RELEASE(pPackUnk);
  262. if (FAILED(hr))
  263. {
  264. printf(" pPackUnk->QueryInterface(): hr=%X\n", hr);
  265. goto _bailout;
  266. }
  267. // Get provider
  268. IVdsProvider *pProvider;
  269. hr = pPack->GetProvider(&pProvider);
  270. SAFE_RELEASE(pProvider);
  271. // QueryDisks()
  272. if (FAILED(hr))
  273. {
  274. printf(" pPack->GetProvider(): hr=%X\n", hr);
  275. goto _bailout;
  276. }
  277. for (i = 1; i <= numDisks; i++)
  278. {
  279. ulDisk = _wtol(argv[i]);
  280. hr = pPack->QueryDisks(&pEnumDisk);
  281. hr = GetDiskIds(pEnumDisk, bVerbose, &pDiskArray, ulDisk);
  282. printf("\t\tpPack->GetDiskIds(): hr=%X\n", hr);
  283. SAFE_RELEASE(pEnumDisk);
  284. }
  285. SAFE_RELEASE(pPack);
  286. if (FAILED(hr))
  287. {
  288. goto _bailout;
  289. }
  290. } while (TRUE);
  291. SAFE_RELEASE(pEnumPack);
  292. } while (TRUE);
  293. //
  294. // Uninstall the disks
  295. hr = pService->QueryInterface(
  296. IID_IVdsServiceUninstallDisk,
  297. (void **)&pUninstallIntf
  298. );
  299. if (FAILED(hr))
  300. {
  301. printf("\tIID_IVdsServiceUninstallDisk: %lX\n", hr);
  302. goto _bailout;
  303. }
  304. SIZE_T size = sizeof(HRESULT) * numDisks;
  305. pResults = (HRESULT *) ::CoTaskMemAlloc(size);
  306. if (NULL == pResults)
  307. {
  308. printf("\tmain, 2: %lX\n", E_OUTOFMEMORY);
  309. goto _bailout;
  310. }
  311. pDiskArray = pDiskArrayHead;
  312. hr = pUninstallIntf->UninstallDisks(pDiskArray, numDisks, FALSE, &bReboot, pResults);
  313. if (FAILED(hr))
  314. {
  315. printf("\tUninstallDisks failed: %lX\n", hr);
  316. goto _bailout;
  317. }
  318. else
  319. {
  320. printf("\tUninstallDisks succeeded\n");
  321. for (i = 1; i <= numDisks; i++)
  322. {
  323. printf("uninstall status for disk %d => %lX\n", _wtol(argv[i]), pResults[i-1]);
  324. }
  325. }
  326. _bailout:
  327. SAFE_RELEASE(pUninstallIntf);
  328. SAFE_RELEASE(pEnum);
  329. SAFE_RELEASE(pEnumPack);
  330. SAFE_RELEASE(pEnumDisk);
  331. SAFE_RELEASE(pService);
  332. if (pDiskArray)
  333. {
  334. CoTaskMemFree(pDiskArray);
  335. }
  336. if (pResults)
  337. {
  338. CoTaskMemFree(pResults);
  339. }
  340. CoUninitialize();
  341. return 0;
  342. }