Source code of Windows XP (NT5)
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.

1065 lines
29 KiB

  1. /******************************************************************************
  2. Copyright(c) Microsoft Corporation
  3. Module Name:
  4. guid.cpp
  5. Abstract:
  6. This file is written for the implementation of functionality
  7. of the mirror plex List operation.
  8. Author:
  9. J.S.Vasu 9/5/2001 .
  10. Revision History:
  11. J.S.Vasu 9/5/2001 Created it.
  12. NOTE : This File is no longer being used . All the required properties
  13. for the Mirror Plex List operation are available from the
  14. DeviceIoControl API .
  15. ******************************************************************************/
  16. #pragma once
  17. #include <pch.h>
  18. #include <diskguid.h>
  19. #include <rpc.h>
  20. #include <TCHAR.H>
  21. #include "BootCfg.h"
  22. #include "BootCfg64.h"
  23. #include "resource.h"
  24. UINT32 Crc32Table[] = {
  25. 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
  26. 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
  27. 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
  28. 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
  29. 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
  30. 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
  31. 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
  32. 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
  33. 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
  34. 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
  35. 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
  36. 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
  37. 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
  38. 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
  39. 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
  40. 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
  41. 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
  42. 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
  43. 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
  44. 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
  45. 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
  46. 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
  47. 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
  48. 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
  49. 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
  50. 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
  51. 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
  52. 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
  53. 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
  54. 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
  55. 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
  56. 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
  57. 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
  58. 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
  59. 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
  60. 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
  61. 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
  62. 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
  63. 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
  64. 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
  65. 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
  66. 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
  67. 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
  68. };
  69. //
  70. // Global Variables
  71. //
  72. HANDLE g_hDisk;
  73. DWORD g_nBytesPerSector;
  74. DISK_GEOMETRY_EX g_sDiskGeometry;
  75. BOOLEAN g_bProtectiveMBRFound ;
  76. GPT_HEADER g_sGPTHeader ;
  77. GPT_HEADER g_sBackupGPTHeader;
  78. PGPT_ENTRY g_pGPTEntryHead;
  79. PGPT_ENTRY g_pBackupGPTEntryHead;
  80. DWORD g_nTotalGPTEntries;
  81. DWORD g_nTotalBackupGPTEntries;
  82. UINT32 g_nComputedCRCGPTHeader;
  83. UINT32 g_nComputedCRCBackupGPTHeader;
  84. UINT32 g_nComputedCRCGPTEntries;
  85. UINT32 g_nComputedCRCBackupGPTEntries;
  86. //
  87. // Global UI Variables
  88. //
  89. PCHAR pReportBuffer;
  90. GUID g_GuidArr[256] ;
  91. DWORD g_dwCnt = 0 ;
  92. HANDLE OpenDisk(DWORD nPhysicalDrive);
  93. void CloseDisk(HANDLE hDisk);
  94. UINT32 ReadBlock(HANDLE hDisk, UINT64 nStart, UINT32 nSize, PVOID lpBuffer);
  95. UINT32 WriteBlock(HANDLE hDisk, UINT64 nStart, UINT32 nSize, PVOID lpBuffer);
  96. UINT32 GetGPTHeaderAndEntries(HANDLE hDisk, GPT_HEADER *pGPTHeader, UINT64 nHeaderSector);
  97. UINT32 DumpGPTHeader(PGPT_HEADER pGPTHeader);
  98. UINT32 DumpPartitionEntries(PGPT_ENTRY pGPTEntryHead);
  99. UINT32 ComputeCRC32(UCHAR *pBuffer, UINT32 nLength);
  100. void AddReportSection(PTCHAR pString);
  101. void FreeGPTEntries(PGPT_ENTRY pGPTEntryHead);
  102. UINT32 GetDriveGeometry(HANDLE hDisk, PDISK_GEOMETRY_EX pDiskGeometry);
  103. UINT32 CheckProtectiveMBR(HANDLE hDisk);
  104. void AddReport1(PTCHAR pString);
  105. void GetSystemDrivePath();
  106. // ***************************************************************************
  107. //
  108. // Name : OpenDisk
  109. //
  110. // Synopsis : This routine is used to open a disk and get a handle to it.
  111. //
  112. // Parameters : DWORD nPhysicalDrive (in) - Drive to be opened.
  113. //
  114. //
  115. // Return Type : HANDLE -- handle of the opened drive.
  116. //
  117. //
  118. // Global Variables : None
  119. //
  120. // ***************************************************************************
  121. HANDLE OpenDisk(DWORD nPhysicalDrive)
  122. {
  123. TCHAR szDriveName[50];
  124. _stprintf(szDriveName, _T("\\\\.\\physicaldrive%d"), nPhysicalDrive);
  125. return CreateFile(szDriveName,
  126. GENERIC_READ|GENERIC_WRITE,
  127. FILE_SHARE_READ|FILE_SHARE_WRITE,
  128. NULL,
  129. OPEN_EXISTING,
  130. 0,
  131. NULL);
  132. }
  133. // ***************************************************************************
  134. //
  135. // Routine description : This routine is used to close a disk .
  136. //
  137. // Arguments:
  138. // [in] HANDLE : Handle to the Specified Disk.
  139. //
  140. // Return Value : VOID
  141. //
  142. //
  143. // ***************************************************************************
  144. void CloseDisk(HANDLE hDisk)
  145. {
  146. CloseHandle(hDisk);
  147. }
  148. // ***************************************************************************
  149. //
  150. // Routine description : This routine is used to read a specified block
  151. //
  152. // Arguments:
  153. // [in] HANDLE :
  154. // [in] nStart : starting position of the block.,
  155. // [in] nSize :ending position of the block.
  156. // [out] lpBuffer : output buffer. Handle to the Specified Disk.
  157. //
  158. // Return Value : VOID
  159. //
  160. // ***************************************************************************
  161. UINT32 ReadBlock(HANDLE hDisk, UINT64 nStart, UINT32 nSize, PVOID lpBuffer)
  162. {
  163. UINT64 nPosition;
  164. DWORD nBytesRead;
  165. UINT32 pLoHi[2];
  166. nPosition = nStart * 512;
  167. //assign the lsb of 64 bit no to the zero array and MSB to the first array element.
  168. *((PUINT64)pLoHi) = nPosition;
  169. nBytesRead = 0;
  170. SetFilePointer(hDisk, (LONG) pLoHi[0], (long *) &pLoHi[1], FILE_BEGIN);
  171. if(!ReadFile(hDisk, lpBuffer, nSize * 512, &nBytesRead, NULL) )
  172. {
  173. return 0 ;
  174. }
  175. return nBytesRead;
  176. }
  177. // ***************************************************************************
  178. //
  179. // Routine description : This routine is used to write a specified block
  180. //
  181. // Arguments:
  182. // [in] HANDLE : handle of the opened disk.
  183. // [in] nStart : starting position of the block.,
  184. // [in] nSize :ending position of the block.
  185. // [out] lpBuffer : output buffer. Handle to the Specified Disk.
  186. //
  187. // Return Value : VOID
  188. //
  189. // ***************************************************************************
  190. UINT32 WriteBlock(HANDLE hDisk, UINT64 nStart, UINT32 nSize, PVOID lpBuffer)
  191. {
  192. UINT64 nPosition;
  193. DWORD nBytesRead;
  194. UINT32 pLoHi[2];
  195. nPosition = nStart * 512;
  196. //assign the lsb of 64 bit no to the zero array and MSB to the first array element.
  197. *((PUINT64)pLoHi) = nPosition;
  198. nBytesRead = 0;
  199. SetFilePointer(hDisk, (LONG) pLoHi[0], (long *) &pLoHi[1], FILE_BEGIN);
  200. if(!WriteFile(hDisk, lpBuffer, nSize * 512, &nBytesRead, NULL))
  201. {
  202. return 0 ;
  203. }
  204. return nBytesRead;
  205. }
  206. // ***************************************************************************
  207. //
  208. // Routine description : This routine is used to write a specified block
  209. //
  210. // Arguments:
  211. // [in] Drive : Drive to be scanned
  212. //
  213. // Return Value : UINT32
  214. //
  215. // ***************************************************************************
  216. UINT32 ScanGPT(DWORD nPhysicalDrive)
  217. {
  218. UINT64 nAlternateLBA;
  219. UINT32 Result = 0;
  220. TCHAR szMessage[MAX_RES_STRING] = NULL_STRING ;
  221. //
  222. // Get a handle to the physical drive
  223. //
  224. g_hDisk = OpenDisk(nPhysicalDrive);
  225. if (g_hDisk == INVALID_HANDLE_VALUE)
  226. {
  227. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_DRIVE) );
  228. return EXIT_FAILURE;
  229. }
  230. if (GetDriveGeometry(g_hDisk, &g_sDiskGeometry)== EXIT_FAILURE )
  231. {
  232. return EXIT_FAILURE;
  233. }
  234. //
  235. // Get primary GPT Header and its partition entries
  236. //
  237. if (GetGPTHeaderAndEntries(g_hDisk, &g_sGPTHeader, 1))
  238. {
  239. g_sGPTHeader.Healthy = TRUE;
  240. }
  241. else
  242. {
  243. //
  244. // This can happen if we have junk value in GPT header.
  245. // In this case we dont perform certain tests
  246. //
  247. g_sGPTHeader.Healthy = FALSE;
  248. }
  249. //
  250. // Get backup GPT Header and its partition entries
  251. //
  252. nAlternateLBA = (g_sDiskGeometry.DiskSize.QuadPart / g_sDiskGeometry.Geometry.BytesPerSector) - 1;
  253. if (GetGPTHeaderAndEntries(g_hDisk, &g_sBackupGPTHeader, nAlternateLBA))
  254. {
  255. g_sBackupGPTHeader.Healthy = TRUE;
  256. }
  257. else
  258. {
  259. //
  260. // This can happen if we have junk value in Backup GPT Header
  261. // In this case we dont perform certain tests
  262. //
  263. g_sBackupGPTHeader.Healthy = FALSE;
  264. }
  265. // display the header
  266. DISPLAY_MESSAGE(stdout,GetResString(IDS_HEADER1));
  267. DISPLAY_MESSAGE(stdout,GetResString(IDS_HEADER_DASH1));
  268. Result = DumpGPTHeader(&g_sGPTHeader);
  269. if (Result == EXIT_FAILURE)
  270. {
  271. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_DISPLAY));
  272. return EXIT_FAILURE;
  273. }
  274. DISPLAY_MESSAGE(stdout,GetResString(IDS_HEADER2));
  275. DISPLAY_MESSAGE(stdout,GetResString(IDS_HEADER2_DASH));
  276. Result = DumpPartitionEntries(g_sGPTHeader.FirstGPTEntry);
  277. if (Result == EXIT_FAILURE)
  278. {
  279. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_DISPLAY));
  280. return EXIT_FAILURE;
  281. }
  282. //
  283. // Clean up
  284. //
  285. FreeGPTEntries(g_sGPTHeader.FirstGPTEntry);
  286. FreeGPTEntries(g_sBackupGPTHeader.FirstGPTEntry);
  287. CloseDisk(g_hDisk);
  288. return EXIT_SUCCESS;
  289. }
  290. // ***************************************************************************
  291. //
  292. // Routine description : This routine is used to read GPT Header and entries
  293. //
  294. // Arguments:
  295. // [in] hDisk : Drive to be scanned
  296. // [in] pGPTHeader : GPT Header to be scanned.
  297. // [in] nHeaderSector : Sector to be read.
  298. //
  299. // Return Value : UINT32
  300. //
  301. // ***************************************************************************
  302. UINT32 GetGPTHeaderAndEntries(HANDLE hDisk, GPT_HEADER *pGPTHeader, UINT64 nHeaderSector)
  303. {
  304. UCHAR *lpSectorBuffer;
  305. DWORD nBytesReturned;
  306. DWORD ti, tj;
  307. PGPT_ENTRY pGPTEntry, pPrevGPTEntry;
  308. UINT32 nTempCRC, nTempCount;
  309. char sStr[200];
  310. TCHAR szString[256];
  311. if (!hDisk || INVALID_HANDLE_VALUE == hDisk || !pGPTHeader)
  312. {
  313. return EXIT_FAILURE;
  314. }
  315. //
  316. // Allocate memory for sector
  317. //
  318. lpSectorBuffer = (UCHAR *) GlobalAlloc(GPTR, g_nBytesPerSector);
  319. if (!lpSectorBuffer)
  320. {
  321. return EXIT_FAILURE;
  322. }
  323. nBytesReturned = ReadBlock(g_hDisk, nHeaderSector, 1, lpSectorBuffer);
  324. if (nBytesReturned != g_nBytesPerSector)
  325. {
  326. _stprintf(szString,GetResString(IDS_ERROR_READ), nHeaderSector);
  327. DISPLAY_MESSAGE(stderr,szString);
  328. if(lpSectorBuffer)
  329. {
  330. GlobalFree(lpSectorBuffer);
  331. }
  332. return EXIT_FAILURE;
  333. }
  334. //
  335. // Unpack the values
  336. //
  337. ti = 0;
  338. // dest,source , sizeof destination datatype.
  339. memcpy((void *)&pGPTHeader->Signature,
  340. (void *) lpSectorBuffer,
  341. sizeof(pGPTHeader->Signature) );
  342. ti += sizeof(pGPTHeader->Signature);
  343. memcpy((void *)&pGPTHeader->Revision, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->Revision));
  344. ti += sizeof(pGPTHeader->Revision);
  345. memcpy((void *)&pGPTHeader->HeaderSize, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->HeaderSize));
  346. ti += sizeof(pGPTHeader->HeaderSize);
  347. memcpy((void *)&pGPTHeader->HeaderCRC32, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->HeaderCRC32));
  348. ti += sizeof(pGPTHeader->HeaderCRC32);
  349. memcpy((void *)&pGPTHeader->Reserved0, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->Reserved0));
  350. ti += sizeof(pGPTHeader->Reserved0);
  351. memcpy((void *)&pGPTHeader->MyLBA, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->MyLBA));
  352. ti += sizeof(pGPTHeader->MyLBA);
  353. memcpy((void *)&pGPTHeader->AlternateLBA, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->AlternateLBA));
  354. ti += sizeof(pGPTHeader->AlternateLBA);
  355. memcpy((void *)&pGPTHeader->FirstUsableLBA, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->FirstUsableLBA));
  356. ti += sizeof(pGPTHeader->FirstUsableLBA);
  357. memcpy((void *)&pGPTHeader->LastUsableLBA, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->LastUsableLBA));
  358. ti += sizeof(pGPTHeader->LastUsableLBA);
  359. memcpy((void *)&pGPTHeader->DiskGUID, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->DiskGUID));
  360. ti += sizeof(pGPTHeader->DiskGUID);
  361. memcpy((void *)&pGPTHeader->PartitionEntryLBA, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->PartitionEntryLBA));
  362. ti += sizeof(pGPTHeader->PartitionEntryLBA);
  363. memcpy((void *)&pGPTHeader->NumberOfPartitionEntries, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->NumberOfPartitionEntries));
  364. ti += sizeof(pGPTHeader->NumberOfPartitionEntries);
  365. memcpy((void *)&pGPTHeader->SizeOfPartitionEntry, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->SizeOfPartitionEntry));
  366. ti += sizeof(pGPTHeader->SizeOfPartitionEntry);
  367. memcpy((void *)&pGPTHeader->PartitionEntryArrayCRC32, (void *) (lpSectorBuffer+ti), sizeof(pGPTHeader->PartitionEntryArrayCRC32));
  368. ti += sizeof(pGPTHeader->PartitionEntryArrayCRC32);
  369. //
  370. // Compute HeaderCRC32
  371. //
  372. nTempCRC = pGPTHeader->HeaderCRC32;
  373. pGPTHeader->HeaderCRC32 = 0;
  374. if (pGPTHeader->HeaderSize > sizeof(GPT_HEADER))
  375. {
  376. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_GPT));
  377. if(lpSectorBuffer)
  378. {
  379. GlobalFree(lpSectorBuffer);
  380. }
  381. return EXIT_FAILURE;
  382. }
  383. pGPTHeader->ComputedHeaderCRC32 = ComputeCRC32((PUCHAR) pGPTHeader, pGPTHeader->HeaderSize);
  384. pGPTHeader->HeaderCRC32 = nTempCRC;
  385. //
  386. // Free this memory
  387. //
  388. GlobalFree(lpSectorBuffer);
  389. //
  390. // Preliminary checks
  391. //
  392. if (!pGPTHeader->SizeOfPartitionEntry || !pGPTHeader->NumberOfPartitionEntries)
  393. {
  394. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_GPT_HEADER));
  395. return EXIT_FAILURE;
  396. }
  397. //
  398. // Allocate memory for GPT Entries
  399. //
  400. nTempCount = (pGPTHeader->SizeOfPartitionEntry * pGPTHeader->NumberOfPartitionEntries) / g_nBytesPerSector;
  401. if ((pGPTHeader->SizeOfPartitionEntry * pGPTHeader->NumberOfPartitionEntries) % g_nBytesPerSector)
  402. {
  403. nTempCount++;
  404. }
  405. if (!nTempCount)
  406. {
  407. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_GPT_HEADER));
  408. return EXIT_FAILURE;
  409. }
  410. lpSectorBuffer = (UCHAR *) GlobalAlloc(GPTR, nTempCount * g_nBytesPerSector);
  411. if (!lpSectorBuffer)
  412. {
  413. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_MEM_GPT));
  414. return EXIT_FAILURE;
  415. }
  416. //
  417. // Build partition entries info based on g_sGPTHeader
  418. //
  419. nBytesReturned = ReadBlock(g_hDisk,
  420. pGPTHeader->PartitionEntryLBA,
  421. nTempCount,
  422. lpSectorBuffer);
  423. if (nBytesReturned != nTempCount * g_nBytesPerSector)
  424. {
  425. if(lpSectorBuffer)
  426. {
  427. GlobalFree(lpSectorBuffer);
  428. }
  429. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_READ_GPT_ENTRIES));
  430. return EXIT_FAILURE;
  431. }
  432. ti = 0;
  433. while (lpSectorBuffer[ti])
  434. {
  435. //
  436. // Create a linked list of GPT_ENTRY
  437. //
  438. pGPTEntry = (PGPT_ENTRY) GlobalAlloc(GPTR, sizeof(GPT_ENTRY));
  439. if (ti == 0)
  440. {
  441. pGPTHeader->FirstGPTEntry = pGPTEntry;
  442. }
  443. else
  444. {
  445. pPrevGPTEntry->NextGPTEntry = pGPTEntry;
  446. }
  447. pPrevGPTEntry = pGPTEntry;
  448. pGPTEntry->NextGPTEntry = NULL;
  449. //
  450. // Get the values
  451. //
  452. tj = 0;
  453. memcpy((void *) &pGPTEntry->PartitionTypeGUID, (void *) (lpSectorBuffer + ti) , sizeof(pGPTEntry->PartitionTypeGUID));
  454. tj = tj + sizeof(pGPTEntry->PartitionTypeGUID);
  455. memcpy((void *) &pGPTEntry->UniquePartitionGUID, (void *) (lpSectorBuffer + ti + tj) , sizeof(pGPTEntry->UniquePartitionGUID));
  456. tj = tj + sizeof(pGPTEntry->UniquePartitionGUID);
  457. memcpy((void *) &pGPTEntry->StartingLBA, (void *) (lpSectorBuffer + ti + tj) , sizeof(pGPTEntry->StartingLBA));
  458. tj = tj + sizeof(pGPTEntry->StartingLBA);
  459. memcpy((void *) &pGPTEntry->EndingLBA, (void *) (lpSectorBuffer + ti + tj) , sizeof(pGPTEntry->EndingLBA));
  460. tj = tj + sizeof(pGPTEntry->EndingLBA);
  461. memcpy((void *) &pGPTEntry->Attributes, (void *) (lpSectorBuffer + ti + tj) , sizeof(pGPTEntry->Attributes));
  462. tj = tj + sizeof(pGPTEntry->Attributes);
  463. memcpy((void *) &pGPTEntry->PartitionName, (void *) (lpSectorBuffer + ti + tj) , sizeof(pGPTEntry->PartitionName));
  464. tj = tj + sizeof(pGPTEntry->PartitionName);
  465. ti += pGPTHeader->SizeOfPartitionEntry;
  466. if (ti >= pGPTHeader->NumberOfPartitionEntries * pGPTHeader->SizeOfPartitionEntry)
  467. {
  468. //
  469. // Just be safe
  470. //
  471. break;
  472. }
  473. }
  474. //
  475. // Compute CRC32 for backup GPT Entries
  476. //
  477. pGPTHeader->ComputedPartitionEntryArrayCRC32 = ComputeCRC32(lpSectorBuffer, pGPTHeader->SizeOfPartitionEntry *
  478. pGPTHeader->NumberOfPartitionEntries);
  479. //
  480. // Used partition entries
  481. //
  482. pGPTHeader->UsedPartitionEntries = ti / pGPTHeader->SizeOfPartitionEntry;
  483. if(lpSectorBuffer)
  484. {
  485. GlobalFree(lpSectorBuffer);
  486. }
  487. return EXIT_SUCCESS;
  488. }
  489. // ***************************************************************************
  490. //
  491. // Routine description : This routine is used to dump GPT Header
  492. //
  493. // Arguments:
  494. // [in] pGPTHeader : GPT Header to be dumped.
  495. //
  496. //
  497. // Return Value : UINT32
  498. //
  499. // ***************************************************************************
  500. UINT32 DumpGPTHeader(PGPT_HEADER pGPTHeader)
  501. {
  502. TCHAR *pGUIDStr;
  503. TCHAR szString[256] = NULL_STRING ;
  504. if ( !pGPTHeader )
  505. {
  506. return EXIT_FAILURE;
  507. }
  508. //
  509. // Disk GUID
  510. //
  511. _tcscpy(szString,GetResString(IDS_PARTITION1));
  512. if (( UuidToString((UUID *)&pGPTHeader->DiskGUID, &pGUIDStr) != RPC_S_OK) || ( !pGUIDStr ) )
  513. {
  514. return EXIT_FAILURE;
  515. }
  516. _tcscat(szString,(PTCHAR)pGUIDStr);
  517. _tcscat(szString,GetResString(IDS_PARTITION2));
  518. DISPLAY_MESSAGE(stdout,szString);
  519. if(pGUIDStr)
  520. {
  521. RpcStringFree(&pGUIDStr);
  522. }
  523. return EXIT_SUCCESS;
  524. }
  525. // ***************************************************************************
  526. //
  527. // Routine description : This routine is used to dump GPT Partition entries.
  528. //
  529. // Arguments:
  530. // [in] pGPTEntryHead : GPT Header to be dumped.
  531. //
  532. //
  533. // Return Value : UINT32
  534. //
  535. // ***************************************************************************
  536. UINT32 DumpPartitionEntries(PGPT_ENTRY pGPTEntryHead)
  537. {
  538. PTCHAR pGUIDStr;
  539. PGPT_ENTRY pEntryStep;
  540. char sStr[100];
  541. char *sStr2;
  542. TCHAR szString[256] ; //= NULL_STRING ;
  543. if (!pGPTEntryHead) {
  544. return EXIT_FAILURE;
  545. }
  546. sStr2 = (char *) GlobalAlloc(GPTR, 1024);
  547. if (!sStr2)
  548. {
  549. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_DUMP_GPT_ENTRIES));
  550. return EXIT_FAILURE;
  551. }
  552. pEntryStep = pGPTEntryHead;
  553. if (!pEntryStep)
  554. {
  555. DISPLAY_MESSAGE(stdout,GetResString(IDS_INFO_DUMP_GPT_ENTRIES));
  556. if(sStr2)
  557. {
  558. GlobalFree(sStr2);
  559. }
  560. return EXIT_FAILURE;
  561. }
  562. while (pEntryStep)
  563. {
  564. _tcscpy(szString,GetResString(IDS_PARTITION1));
  565. if( UuidToString((UUID *)&pEntryStep->UniquePartitionGUID, &pGUIDStr) != RPC_S_OK )
  566. {
  567. if(sStr2)
  568. {
  569. GlobalFree(sStr2);
  570. }
  571. return EXIT_FAILURE;
  572. }
  573. _tcscat(szString,(PTCHAR)pGUIDStr);
  574. _tcscat(szString,GetResString(IDS_PARTITION2));
  575. RpcStringFree(&pGUIDStr);
  576. DISPLAY_MESSAGE(stdout,szString);
  577. _tcscpy(szString,GetResString(IDS_PARTITION3));
  578. if( UuidToString((UUID *)&pEntryStep->PartitionTypeGUID, &pGUIDStr)!= RPC_S_OK )
  579. {
  580. if(sStr2)
  581. {
  582. GlobalFree(sStr2);
  583. }
  584. return EXIT_FAILURE;
  585. }
  586. _tcscat(szString,(PTCHAR)pGUIDStr);
  587. _tcscat(szString,GetResString(IDS_PARTITION2));
  588. RpcStringFree(&pGUIDStr);
  589. DISPLAY_MESSAGE(stdout,szString);
  590. _stprintf(szString ,GetResString(IDS_START_LBA), pEntryStep->StartingLBA);
  591. _tcscpy(szString,GetResString(IDS_PARTITION4));
  592. _tcscat(szString, pEntryStep->PartitionName);
  593. _tcscat(szString,_T("\r\n"));
  594. DISPLAY_MESSAGE(stdout,szString);
  595. pEntryStep = pEntryStep->NextGPTEntry;
  596. }
  597. if(sStr2)
  598. {
  599. GlobalFree(sStr2);
  600. }
  601. return EXIT_SUCCESS;
  602. }
  603. // ***************************************************************************
  604. //
  605. // Routine description : This routine is used to compute CRC32
  606. //
  607. // Arguments:
  608. // [in] pBuffer : buffer.
  609. // [in] nLength : Length .
  610. //
  611. // Return Value : UINT32
  612. //
  613. // ***************************************************************************
  614. UINT32 ComputeCRC32(UCHAR *pBuffer, UINT32 nLength)
  615. {
  616. //
  617. // Code taken from RtlComputeCRC32, but the parameters have been modified to force PartitionCrc to 0
  618. //
  619. UINT32 Crc;
  620. UINT32 ti;
  621. UINT32 PartialCrc;
  622. //
  623. // Compute the CRC32 checksum.
  624. //
  625. PartialCrc = 0;
  626. Crc = PartialCrc ^ 0xffffffffL;
  627. for (ti = 0; ti < nLength; ti++) {
  628. Crc = Crc32Table [(Crc ^ pBuffer[ti]) & 0xff] ^ (Crc >> 8);
  629. }
  630. return (Crc ^ 0xffffffffL);
  631. }
  632. // ***************************************************************************
  633. //
  634. // Routine description : This routine is free GPT entries
  635. //
  636. // Arguments:
  637. // [in] pGPTEntryHead : GPT Header to be freed..
  638. // [in] nLength : Length .
  639. //
  640. // Return Value : UINT32
  641. //
  642. // ***************************************************************************
  643. void FreeGPTEntries(PGPT_ENTRY pGPTEntryHead)
  644. {
  645. PGPT_ENTRY pFreeGPTEntry;
  646. while (pGPTEntryHead)
  647. {
  648. pFreeGPTEntry = pGPTEntryHead;
  649. pGPTEntryHead = pGPTEntryHead->NextGPTEntry;
  650. GlobalFree(pFreeGPTEntry);
  651. }
  652. }
  653. // ***************************************************************************
  654. //
  655. // Routine description : This routine is determine Drive Geometry
  656. //
  657. // Arguments:
  658. // [in] hDisk : disk whose geometry has to be found.
  659. // [in] pDiskGeometry : structure containing the drive details. .
  660. //
  661. // Return Value : UINT32
  662. //
  663. // ***************************************************************************
  664. UINT32 GetDriveGeometry(HANDLE hDisk, PDISK_GEOMETRY_EX pDiskGeometry)
  665. {
  666. UINT32 nBytesReturned;
  667. //
  668. // Get drive goemetry
  669. //
  670. if (!DeviceIoControl(hDisk,
  671. IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
  672. NULL,
  673. 0,
  674. pDiskGeometry,
  675. sizeof(DISK_GEOMETRY_EX),
  676. (PULONG) &nBytesReturned,
  677. NULL))
  678. {
  679. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_READ_GEOMETRY));
  680. return EXIT_FAILURE;
  681. }
  682. g_nBytesPerSector = pDiskGeometry->Geometry.BytesPerSector;
  683. return EXIT_SUCCESS;
  684. }
  685. // ***************************************************************************
  686. //
  687. // Routine description : This routine is display the results.
  688. //
  689. // Arguments:
  690. // [in] pString : pointer to the string to be displayed.
  691. //
  692. //
  693. // Return Value : VOID
  694. //
  695. // ***************************************************************************
  696. void AddReportSection(PTCHAR pString)
  697. {
  698. TCHAR StringLine[100];
  699. int ti, tj;
  700. AddReport1(pString);
  701. tj = _tcslen(pString);
  702. //
  703. // Make a line like "========" about the size of the string to be displayed as title
  704. //
  705. for (ti = 0; (ti < tj) && (ti < 97); ti++)
  706. {
  707. StringLine[ti] = _T('-');
  708. }
  709. StringLine[ti] = '\r';
  710. StringLine[ti+1] = '\n';
  711. StringLine[ti+2] = 0;
  712. AddReport1(StringLine);
  713. }
  714. // ***************************************************************************
  715. //
  716. // Routine description : This routine is display the results.
  717. //
  718. // Arguments:
  719. // [in] pString : string to be displayed.
  720. //
  721. //
  722. // Return Value : UINT32
  723. //
  724. // ***************************************************************************
  725. void AddReport1(PTCHAR pString)
  726. {
  727. DISPLAY_MESSAGE(stdout,pString);
  728. }
  729. // ***************************************************************************
  730. //
  731. // Routine Description : Frames the Boot File path.
  732. // Arguments :
  733. // [ in ] szComputerName : System name
  734. //
  735. // Return Type : DWORD
  736. // ***************************************************************************
  737. DWORD GetBootFilePath(LPTSTR szComputerName,LPTSTR szBootPath)
  738. {
  739. HKEY hKey1 = 0;
  740. HKEY hRemoteKey = 0;
  741. TCHAR szCurrentPath[MAX_STRING_LENGTH + 1] = NULL_STRING;
  742. TCHAR szPath[MAX_STRING_LENGTH + 1] = SUBKEY1 ;
  743. DWORD dwValueSize = MAX_STRING_LENGTH + 1;
  744. DWORD dwRetCode = ERROR_SUCCESS;
  745. DWORD dwError = 0;
  746. TCHAR szTmpCompName[MAX_STRING_LENGTH+1] = NULL_STRING;
  747. TCHAR szTemp[MAX_RES_STRING+1] = NULL_STRING ;
  748. DWORD len = lstrlen(szTemp);
  749. TCHAR szVal[MAX_RES_STRING+1] = NULL_STRING ;
  750. DWORD dwLength = MAX_STRING_LENGTH ;
  751. LPTSTR szReturnValue = NULL ;
  752. DWORD dwCode = 0 ;
  753. LPTSTR szOsLoaderPath = NULL;
  754. szReturnValue = ( LPTSTR ) malloc( dwLength*sizeof( TCHAR ) );
  755. szOsLoaderPath = ( LPTSTR ) malloc( dwLength*sizeof( TCHAR ) );
  756. if((szReturnValue == NULL) || (szOsLoaderPath == NULL ) )
  757. {
  758. SAFEFREE(szReturnValue);
  759. return ERROR_RETREIVE_REGISTRY ;
  760. }
  761. if(lstrlen(szComputerName)!= 0 )
  762. {
  763. lstrcpy(szTmpCompName,TOKEN_BACKSLASH4);
  764. lstrcat(szTmpCompName,szComputerName);
  765. }
  766. else
  767. {
  768. lstrcpy(szTmpCompName,szComputerName);
  769. }
  770. // Get Remote computer local machine key
  771. dwError = RegConnectRegistry(szTmpCompName,HKEY_LOCAL_MACHINE,&hRemoteKey);
  772. if (dwError == ERROR_SUCCESS)
  773. {
  774. dwError = RegOpenKeyEx(hRemoteKey,szPath,0,KEY_READ,&hKey1);
  775. if (dwError == ERROR_SUCCESS)
  776. {
  777. dwRetCode = RegQueryValueEx(hKey1, IDENTIFIER_VALUE2, NULL, NULL,(LPBYTE) szReturnValue, &dwValueSize);
  778. if (dwRetCode == ERROR_MORE_DATA)
  779. {
  780. dwValueSize += 1024 ;
  781. szReturnValue = ( LPTSTR ) realloc( szReturnValue , dwValueSize * sizeof( TCHAR ) );
  782. if(szReturnValue == NULL)
  783. {
  784. SAFEFREE(szOsLoaderPath);
  785. SAFEFREE(szReturnValue);
  786. return ERROR_RETREIVE_REGISTRY ;
  787. }
  788. dwRetCode = RegQueryValueEx(hKey1, IDENTIFIER_VALUE2, NULL, NULL,(LPBYTE) szReturnValue, &dwValueSize);
  789. }
  790. if(dwRetCode != ERROR_SUCCESS)
  791. {
  792. RegCloseKey(hKey1);
  793. RegCloseKey(hRemoteKey);
  794. SAFEFREE(szOsLoaderPath);
  795. SAFEFREE(szReturnValue);
  796. return ERROR_RETREIVE_REGISTRY ;
  797. }
  798. dwRetCode = RegQueryValueEx(hKey1, IDENTIFIER_VALUE3, NULL, NULL,(LPBYTE) szOsLoaderPath, &dwValueSize);
  799. if (dwRetCode == ERROR_MORE_DATA)
  800. {
  801. dwValueSize += 1024 ;
  802. szOsLoaderPath = ( LPTSTR ) realloc( szOsLoaderPath, dwValueSize * sizeof( TCHAR ) );
  803. if(szOsLoaderPath == NULL)
  804. {
  805. SAFEFREE(szOsLoaderPath);
  806. SAFEFREE(szReturnValue);
  807. return ERROR_RETREIVE_REGISTRY ;
  808. }
  809. dwRetCode = RegQueryValueEx(hKey1, IDENTIFIER_VALUE3, NULL, NULL,(LPBYTE) szOsLoaderPath, &dwValueSize);
  810. }
  811. if(dwRetCode != ERROR_SUCCESS)
  812. {
  813. RegCloseKey(hKey1);
  814. RegCloseKey(hRemoteKey);
  815. SAFEFREE(szOsLoaderPath);
  816. SAFEFREE(szReturnValue);
  817. return ERROR_RETREIVE_REGISTRY ;
  818. }
  819. }
  820. else
  821. {
  822. RegCloseKey(hRemoteKey);
  823. SAFEFREE(szOsLoaderPath);
  824. SAFEFREE(szReturnValue);
  825. return ERROR_RETREIVE_REGISTRY ;
  826. }
  827. _tcscat(szReturnValue,szOsLoaderPath);
  828. lstrcpy(szBootPath,szReturnValue);
  829. RegCloseKey(hKey1);
  830. }
  831. else
  832. {
  833. RegCloseKey(hRemoteKey);
  834. SAFEFREE(szOsLoaderPath);
  835. SAFEFREE(szReturnValue);
  836. return ERROR_RETREIVE_REGISTRY ;
  837. }
  838. RegCloseKey(hRemoteKey);
  839. SAFEFREE(szOsLoaderPath);
  840. SAFEFREE(szReturnValue);
  841. return dwCode ;
  842. }//GetBootFilePath
  843. // ***************************************************************************
  844. //
  845. // Routine Description : Retreives the ARC signature path.
  846. // Arguments :
  847. // [ in ] szComputerName : System name
  848. // [ out ] szFinalPath : Final OutPut string.
  849. //
  850. // Return Type : DWORD
  851. // ***************************************************************************
  852. BOOL GetARCSignaturePath(LPTSTR szString,LPTSTR szFinalPath)
  853. {
  854. TCHAR szSystemPath[256] = NULL_STRING ;
  855. UINT RetVal = 0;
  856. DWORD dwSize = 256;
  857. PTCHAR pszTok = NULL ;
  858. RetVal = GetWindowsDirectory(szSystemPath,256);
  859. //concatenate some charater which we are sure will not occur
  860. //in the string.
  861. _tcscat(szSystemPath,_T("*"));
  862. pszTok = _tcstok(szSystemPath,TOKEN_BACKSLASH2);
  863. if(pszTok == NULL)
  864. {
  865. return FALSE ;
  866. }
  867. pszTok = _tcstok(NULL,_T("*"));
  868. if(pszTok == NULL)
  869. {
  870. return FALSE ;
  871. }
  872. lstrcpy(szFinalPath,szString);//szString
  873. lstrcat(szFinalPath,_T("\\"));
  874. lstrcat(szFinalPath,pszTok);
  875. return TRUE ;
  876. }