HardDriveSerialNumber.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. #include "stdafx.h"
  2. #include "HardDriveSerialNumber.h"
  3. //#include <VersionHelpers.h>
  4. int MasterHardDiskSerial::ReadPhysicalDriveInNTWithAdminRights (void)
  5. {
  6. int iDone = FALSE;
  7. int iDrive = 0;
  8. for (iDrive = 0; iDrive < MAX_IDE_DRIVES; iDrive++)
  9. {
  10. HANDLE hPhysicalDriveIOCTL = 0;
  11. // Try to get a handle to PhysicalDrive IOCTL, report failure
  12. // and exit if can't.
  13. char cszDriveName [256];
  14. sprintf_s(cszDriveName, 256, "\\\\.\\PhysicalDrive%d", iDrive);
  15. // Windows NT, Windows 2000, must have admin rights
  16. hPhysicalDriveIOCTL = CreateFileA (cszDriveName,
  17. GENERIC_READ | GENERIC_WRITE,
  18. FILE_SHARE_READ | FILE_SHARE_WRITE , NULL,
  19. OPEN_EXISTING, 0, NULL);
  20. if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE)
  21. {
  22. SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));
  23. sprintf_s(m_cszErrorMessage,256,"%d ReadPhysicalDriveInNTWithAdminRights ERROR ,CreateFileA(%s) returned INVALID_HANDLE_VALUE",__LINE__, cszDriveName);
  24. }
  25. else
  26. {
  27. GETVERSIONOUTPARAMS VersionParams;
  28. DWORD dwBytesReturned = 0;
  29. // Get the version, etc of PhysicalDrive IOCTL
  30. memset ((void*) &VersionParams, 0, sizeof(VersionParams));
  31. if ( ! DeviceIoControl (hPhysicalDriveIOCTL, DFP_GET_VERSION,
  32. NULL,
  33. 0,
  34. &VersionParams,
  35. sizeof(VersionParams),
  36. &dwBytesReturned, NULL) )
  37. {
  38. DWORD dwErr = GetLastError ();
  39. SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));
  40. #pragma warning(disable: 4311)
  41. #pragma warning(disable: 4302)
  42. int nPhysicalDriveIOCTL = (int)hPhysicalDriveIOCTL;
  43. #pragma warning(default: 4311)
  44. #pragma warning(default: 4302)
  45. sprintf_s(m_cszErrorMessage,256,"%d ReadPhysicalDriveInNTWithAdminRights ERROR DeviceIoControl() %d, DFP_GET_VERSION) returned 0, error is %d\n",__LINE__, nPhysicalDriveIOCTL, (int) dwErr);
  46. }
  47. // If there is a IDE device at number "iI" issue commands
  48. // to the device
  49. if (VersionParams.bIDEDeviceMap <= 0)
  50. {
  51. SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));
  52. sprintf_s(m_cszErrorMessage,256,"%d ReadPhysicalDriveInNTWithAdminRights ERROR No device found at iPosition %d (%d)",__LINE__, (int) iDrive, (int) VersionParams.bIDEDeviceMap);
  53. }
  54. else
  55. {
  56. BYTE bIDCmd = 0; // IDE or ATAPI IDENTIFY cmd
  57. SENDCMDINPARAMS scip;
  58. //SENDCMDOUTPARAMS OutCmd;
  59. // Now, get the ID sector for all IDE devices in the system.
  60. // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,
  61. // otherwise use the IDE_ATA_IDENTIFY command
  62. bIDCmd = (VersionParams.bIDEDeviceMap >> iDrive & 0x10) ? \
  63. IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
  64. memset (&scip, 0, sizeof(scip));
  65. memset (byIdOutCmd, 0, sizeof(byIdOutCmd));
  66. if ( DoIDENTIFY (hPhysicalDriveIOCTL,
  67. &scip,
  68. (PSENDCMDOUTPARAMS)&byIdOutCmd,
  69. (BYTE) bIDCmd,
  70. (BYTE) iDrive,
  71. &dwBytesReturned))
  72. {
  73. DWORD dwDiskData [256];
  74. int iIjk = 0;
  75. USHORT *punIdSector = (USHORT *)
  76. ((PSENDCMDOUTPARAMS) byIdOutCmd) -> bBuffer;
  77. for (iIjk = 0; iIjk < 256; iIjk++)
  78. dwDiskData [iIjk] = punIdSector [iIjk];
  79. PrintIdeInfo (iDrive, dwDiskData);
  80. iDone = TRUE;
  81. }
  82. }
  83. CloseHandle (hPhysicalDriveIOCTL);
  84. }
  85. }
  86. return iDone;
  87. }
  88. int MasterHardDiskSerial::ReadPhysicalDriveInNTUsingSmart (void)
  89. {
  90. int iDone = FALSE;
  91. int iDrive = 0;
  92. for (iDrive = 0; iDrive < MAX_IDE_DRIVES; iDrive++)
  93. {
  94. HANDLE hPhysicalDriveIOCTL = 0;
  95. // Try to get a handle to PhysicalDrive IOCTL, report failure
  96. // and exit if can't.
  97. char cszDriveName [256];
  98. sprintf_s(cszDriveName,256, "\\\\.\\PhysicalDrive%d", iDrive);
  99. // Windows NT, Windows 2000, Windows Server 2003, Vista
  100. hPhysicalDriveIOCTL = CreateFileA (cszDriveName,
  101. GENERIC_READ | GENERIC_WRITE,
  102. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  103. NULL, OPEN_EXISTING, 0, NULL);
  104. // if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE)
  105. // printf ("Unable to open physical iDrive %d, error code: 0x%lX\n",
  106. // iDrive, GetLastError ());
  107. if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE)
  108. {
  109. SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));
  110. sprintf_s(m_cszErrorMessage,256,"%d ReadPhysicalDriveInNTUsingSmart ERROR, CreateFileA(%s) returned INVALID_HANDLE_VALUE Error Code %d",__LINE__, cszDriveName, GetLastError ());
  111. }
  112. else
  113. {
  114. GETVERSIONINPARAMS GetVersionParams;
  115. DWORD dwBytesReturned = 0;
  116. // Get the version, etc of PhysicalDrive IOCTL
  117. memset ((void*) & GetVersionParams, 0, sizeof(GetVersionParams));
  118. #pragma warning(disable: 4311)
  119. #pragma warning(disable: 4302)
  120. if ( ! DeviceIoControl (hPhysicalDriveIOCTL, SMART_GET_VERSION,
  121. NULL,
  122. 0,
  123. &GetVersionParams, sizeof (GETVERSIONINPARAMS),
  124. &dwBytesReturned, NULL) )
  125. {
  126. DWORD dwErr = GetLastError ();
  127. SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));
  128. int nPhysicalDriveIOCTL = (int) hPhysicalDriveIOCTL;
  129. sprintf_s(m_cszErrorMessage,256,"\n%d ReadPhysicalDriveInNTUsingSmart ERROR DeviceIoControl(%d, SMART_GET_VERSION) returned 0, error is %d",__LINE__, nPhysicalDriveIOCTL, (int) dwErr);
  130. }
  131. #pragma warning(default: 4311)
  132. #pragma warning(default: 4302)
  133. else
  134. {
  135. // Print the SMART version
  136. // PrintVersion (& GetVersionParams);
  137. // Allocate the command cszBuffer
  138. ULONG CommandSize = sizeof(SENDCMDINPARAMS) + IDENTIFY_BUFFER_SIZE;
  139. PSENDCMDINPARAMS Command = (PSENDCMDINPARAMS) malloc (CommandSize);
  140. // Retrieve the IDENTIFY data
  141. // Prepare the command
  142. #define ID_CMD 0xEC // Returns ID sector for ATA
  143. Command -> irDriveRegs.bCommandReg = ID_CMD;
  144. DWORD BytesReturned = 0;
  145. if ( ! DeviceIoControl (hPhysicalDriveIOCTL,
  146. SMART_RCV_DRIVE_DATA, Command, sizeof(SENDCMDINPARAMS),
  147. Command, CommandSize,
  148. &BytesReturned, NULL) )
  149. {
  150. SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));
  151. sprintf_s(m_cszErrorMessage,256,"SMART_RCV_DRIVE_DATA IOCTL");
  152. // Print the error
  153. //PrintError ("SMART_RCV_DRIVE_DATA IOCTL", GetLastError());
  154. }
  155. else
  156. {
  157. // Print the IDENTIFY data
  158. DWORD dwDiskData [256];
  159. USHORT *punIdSector = (USHORT *)
  160. (PIDENTIFY_DATA) ((PSENDCMDOUTPARAMS) Command) -> bBuffer;
  161. for (int iIjk = 0; iIjk < 256; iIjk++)
  162. dwDiskData [iIjk] = punIdSector [iIjk];
  163. PrintIdeInfo (iDrive, dwDiskData);
  164. iDone = TRUE;
  165. }
  166. // Done
  167. CloseHandle (hPhysicalDriveIOCTL);
  168. free (Command);
  169. }
  170. }
  171. }
  172. return iDone;
  173. }
  174. char * MasterHardDiskSerial::flipAndCodeBytes ( int iPos, int iFlip, const char * pcszStr, char * pcszBuf)
  175. {
  176. int iI;
  177. int iJ = 0;
  178. int iK = 0;
  179. pcszBuf [0] = '\0';
  180. if (iPos <= 0)
  181. return pcszBuf;
  182. if ( ! iJ)
  183. {
  184. char cP = 0;
  185. // First try to gather all characters representing hex digits only.
  186. iJ = 1;
  187. iK = 0;
  188. pcszBuf[iK] = 0;
  189. for (iI = iPos; iJ && !(pcszStr[iI] == '\0'); ++iI)
  190. {
  191. char cC = (char)tolower(pcszStr[iI]);
  192. if (isspace(cC))
  193. cC = '0';
  194. ++cP;
  195. pcszBuf[iK] <<= 4;
  196. if (cC >= '0' && cC <= '9')
  197. pcszBuf[iK] |= (char) (cC - '0');
  198. else if (cC >= 'a' && cC <= 'f')
  199. pcszBuf[iK] |= (char) (cC - 'a' + 10);
  200. else
  201. {
  202. iJ = 0;
  203. break;
  204. }
  205. if (cP == 2)
  206. {
  207. if ((pcszBuf[iK] != '\0') && ! isprint(pcszBuf[iK]))
  208. {
  209. iJ = 0;
  210. break;
  211. }
  212. ++iK;
  213. cP = 0;
  214. pcszBuf[iK] = 0;
  215. }
  216. }
  217. }
  218. if ( ! iJ)
  219. {
  220. // There are non-digit characters, gather them as is.
  221. iJ = 1;
  222. iK = 0;
  223. for (iI = iPos; iJ && (pcszStr[iI] != '\0'); ++iI)
  224. {
  225. char cC = pcszStr[iI];
  226. if ( ! isprint(cC))
  227. {
  228. iJ = 0;
  229. break;
  230. }
  231. pcszBuf[iK++] = cC;
  232. }
  233. }
  234. if ( ! iJ)
  235. {
  236. // The characters are not there or are not printable.
  237. iK = 0;
  238. }
  239. pcszBuf[iK] = '\0';
  240. if (iFlip)
  241. // Flip adjacent characters
  242. for (iJ = 0; iJ < iK; iJ += 2)
  243. {
  244. char t = pcszBuf[iJ];
  245. pcszBuf[iJ] = pcszBuf[iJ + 1];
  246. pcszBuf[iJ + 1] = t;
  247. }
  248. // Trim any beginning and end space
  249. iI = iJ = -1;
  250. for (iK = 0; (pcszBuf[iK] != '\0'); ++iK)
  251. {
  252. if (! isspace(pcszBuf[iK]))
  253. {
  254. if (iI < 0)
  255. iI = iK;
  256. iJ = iK;
  257. }
  258. }
  259. if ((iI >= 0) && (iJ >= 0))
  260. {
  261. for (iK = iI; (iK <= iJ) && (pcszBuf[iK] != '\0'); ++iK)
  262. pcszBuf[iK - iI] = pcszBuf[iK];
  263. pcszBuf[iK - iI] = '\0';
  264. }
  265. return pcszBuf;
  266. }
  267. int MasterHardDiskSerial::ReadPhysicalDriveInNTWithZeroRights (void)
  268. {
  269. int iDone = FALSE;
  270. int iDrive = 0;
  271. for (iDrive = 0; iDrive < MAX_IDE_DRIVES; iDrive++)
  272. {
  273. HANDLE hPhysicalDriveIOCTL = 0;
  274. // Try to get a handle to PhysicalDrive IOCTL, report failure
  275. // and exit if can't.
  276. char cszDriveName [256];
  277. sprintf_s(cszDriveName,256,"\\\\.\\PhysicalDrive%d", iDrive);
  278. // Windows NT, Windows 2000, Windows XP - admin rights not required
  279. hPhysicalDriveIOCTL = CreateFileA (cszDriveName, 0,
  280. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  281. OPEN_EXISTING, 0, NULL);
  282. if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE)
  283. {
  284. SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));
  285. sprintf_s(m_cszErrorMessage,256,"%d ReadPhysicalDriveInNTWithZeroRights ERROR CreateFileA(%s) returned INVALID_HANDLE_VALUE",__LINE__, cszDriveName);
  286. }
  287. else
  288. {
  289. STORAGE_PROPERTY_QUERY query;
  290. DWORD dwBytesReturned = 0;
  291. char cszBuffer [10000];
  292. memset ((void *) & query, 0, sizeof (query));
  293. query.PropertyId = StorageDeviceProperty;
  294. query.QueryType = PropertyStandardQuery;
  295. memset (cszBuffer, 0, sizeof (cszBuffer));
  296. if ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
  297. & query,
  298. sizeof (query),
  299. & cszBuffer,
  300. sizeof (cszBuffer),
  301. & dwBytesReturned, NULL) )
  302. {
  303. STORAGE_DEVICE_DESCRIPTOR * descrip = (STORAGE_DEVICE_DESCRIPTOR *) & cszBuffer;
  304. char cszSerialNumber [1000];
  305. char cszModelNumber [1000];
  306. char cszVendorId [1000];
  307. char cszProductRevision [1000];
  308. flipAndCodeBytes ( descrip -> VendorIdOffset,
  309. 0,cszBuffer, cszVendorId );
  310. flipAndCodeBytes ( descrip -> ProductIdOffset,
  311. 0,cszBuffer, cszModelNumber );
  312. flipAndCodeBytes ( descrip -> ProductRevisionOffset,
  313. 0,cszBuffer, cszProductRevision );
  314. flipAndCodeBytes ( descrip -> SerialNumberOffset,
  315. 1,cszBuffer, cszSerialNumber );
  316. if (0 == m_cszHardDriveSerialNumber [0] &&
  317. // serial number must be alphanumeric
  318. // (but there can be leading spaces on IBM drives)
  319. (iswalnum (cszSerialNumber [0]) || iswalnum (cszSerialNumber [19])))
  320. {
  321. strcpy_s(m_cszHardDriveSerialNumber, 1024, cszSerialNumber);
  322. strcpy_s(m_cszHardDriveModelNumber, 1024, cszModelNumber);
  323. iDone = TRUE;
  324. }
  325. // Get the disk iDrive geometry.
  326. memset (cszBuffer, 0, sizeof(cszBuffer));
  327. if ( ! DeviceIoControl (hPhysicalDriveIOCTL,
  328. IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
  329. NULL,
  330. 0,
  331. &cszBuffer,
  332. sizeof(cszBuffer),
  333. &dwBytesReturned,
  334. NULL))
  335. {
  336. SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));
  337. sprintf_s(m_cszErrorMessage,"%s ReadPhysicalDriveInNTWithZeroRights ERROR DeviceIoControl(), IOCTL_DISK_GET_DRIVE_GEOMETRY_EX) returned 0", cszDriveName);
  338. }
  339. //else
  340. //{
  341. // DISK_GEOMETRY_EX* geom = (DISK_GEOMETRY_EX*) &cszBuffer;
  342. // int iFixed = (geom->Geometry.MediaType == FixedMedia);
  343. // __int64 i64Size = geom->DiskSize.QuadPart;
  344. //}
  345. }
  346. else
  347. {
  348. DWORD dwErr = GetLastError ();
  349. SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));
  350. sprintf_s (m_cszErrorMessage,"DeviceIOControl IOCTL_STORAGE_QUERY_PROPERTY error = %d\n", dwErr);
  351. }
  352. CloseHandle (hPhysicalDriveIOCTL);
  353. }
  354. }
  355. return iDone;
  356. }
  357. BOOL MasterHardDiskSerial::DoIDENTIFY (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
  358. PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,
  359. PDWORD lpcbBytesReturned)
  360. {
  361. // Set up data structures for IDENTIFY command.
  362. pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;
  363. pSCIP -> irDriveRegs.bFeaturesReg = 0;
  364. pSCIP -> irDriveRegs.bSectorCountReg = 1;
  365. //pSCIP -> irDriveRegs.bSectorNumberReg = 1;
  366. pSCIP -> irDriveRegs.bCylLowReg = 0;
  367. pSCIP -> irDriveRegs.bCylHighReg = 0;
  368. // Compute the iDrive number.
  369. pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);
  370. // The command can either be IDE identify or ATAPI identify.
  371. pSCIP -> irDriveRegs.bCommandReg = bIDCmd;
  372. pSCIP -> bDriveNumber = bDriveNum;
  373. pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;
  374. return ( DeviceIoControl (hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA,
  375. (LPVOID) pSCIP,
  376. sizeof(SENDCMDINPARAMS) - 1,
  377. (LPVOID) pSCOP,
  378. sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
  379. lpcbBytesReturned, NULL) );
  380. }
  381. int MasterHardDiskSerial::ReadIdeDriveAsScsiDriveInNT (void)
  382. {
  383. int iDone = FALSE;
  384. int iController = 0;
  385. for (iController = 0; iController < 2; iController++)
  386. {
  387. HANDLE hScsiDriveIOCTL = 0;
  388. char cszDriveName [256];
  389. // Try to get a handle to PhysicalDrive IOCTL, report failure
  390. // and exit if can't.
  391. sprintf_s (cszDriveName, "\\\\.\\Scsi%d:", iController);
  392. // Windows NT, Windows 2000, any rights should do
  393. hScsiDriveIOCTL = CreateFileA (cszDriveName,
  394. GENERIC_READ | GENERIC_WRITE,
  395. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  396. OPEN_EXISTING, 0, NULL);
  397. if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
  398. {
  399. int iDrive = 0;
  400. for (iDrive = 0; iDrive < 2; iDrive++)
  401. {
  402. char cszBuffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];
  403. SRB_IO_CONTROL *cP = (SRB_IO_CONTROL *) cszBuffer;
  404. SENDCMDINPARAMS *pin =
  405. (SENDCMDINPARAMS *) (cszBuffer + sizeof (SRB_IO_CONTROL));
  406. DWORD dwDummy;
  407. memset (cszBuffer, 0, sizeof (cszBuffer));
  408. cP -> HeaderLength = sizeof (SRB_IO_CONTROL);
  409. cP -> Timeout = 10000;
  410. cP -> Length = SENDIDLENGTH;
  411. cP -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
  412. cP -> Signature[0] = 'S';
  413. cP -> Signature[1] = 'C';
  414. cP -> Signature[2] = 'S';
  415. cP -> Signature[3] = 'I';
  416. cP -> Signature[4] = 'D';
  417. cP -> Signature[5] = 'I';
  418. cP -> Signature[6] = 'S';
  419. cP -> Signature[7] = 'K';
  420. //strncpy ((char *) cP -> Signature, "SCSIDISK", 8);
  421. pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
  422. pin -> bDriveNumber = (BYTE)iDrive;
  423. if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,
  424. cszBuffer,
  425. sizeof (SRB_IO_CONTROL) +
  426. sizeof (SENDCMDINPARAMS) - 1,
  427. cszBuffer,
  428. sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,
  429. &dwDummy, NULL))
  430. {
  431. SENDCMDOUTPARAMS *pOut =
  432. (SENDCMDOUTPARAMS *) (cszBuffer + sizeof (SRB_IO_CONTROL));
  433. IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);
  434. if (pId -> sModelNumber [0])
  435. {
  436. DWORD dwDiskData [256];
  437. int iIjk = 0;
  438. USHORT *punIdSector = (USHORT *) pId;
  439. for (iIjk = 0; iIjk < 256; iIjk++)
  440. dwDiskData [iIjk] = punIdSector [iIjk];
  441. PrintIdeInfo (iController * 2 + iDrive, dwDiskData);
  442. iDone = TRUE;
  443. }
  444. }
  445. }
  446. CloseHandle (hScsiDriveIOCTL);
  447. }
  448. }
  449. return iDone;
  450. }
  451. void MasterHardDiskSerial::PrintIdeInfo (int /*iDrive*/, DWORD dwDiskData [256])
  452. {
  453. char cszSerialNumber [1024];
  454. char cszModelNumber [1024];
  455. char cszRevisionNumber [1024];
  456. char bufferSize [32];
  457. //__int64 i64Sectors = 0;
  458. //__int64 i64Byte = 0;
  459. // copy the hard iDrive serial number to the cszBuffer
  460. ConvertToString (dwDiskData, 10, 19, cszSerialNumber);
  461. ConvertToString (dwDiskData, 27, 46, cszModelNumber);
  462. ConvertToString (dwDiskData, 23, 26, cszRevisionNumber);
  463. sprintf_s(bufferSize,32, "%u", dwDiskData [21] * 512);
  464. if (0 == m_cszHardDriveSerialNumber [0] &&
  465. // serial number must be alphanumeric
  466. // (but there can be leading spaces on IBM drives)
  467. (isalnum (cszSerialNumber [0]) || isalnum (cszSerialNumber [19])))
  468. {
  469. strcpy_s(m_cszHardDriveSerialNumber,1024, cszSerialNumber);
  470. strcpy_s(m_cszHardDriveModelNumber,1024, cszModelNumber);
  471. }
  472. }
  473. /**
  474. * Get the id of this computer as a string.
  475. */
  476. CString MasterHardDiskSerial::GetHardDriveComputerIdAsString(void)
  477. {
  478. if (m_nComputerId == 0)
  479. {
  480. getHardDriveComputerID();
  481. }
  482. CString sRet;
  483. int nHiHi, nHiLo, nLoHi, nLoLo;
  484. #pragma warning( push )
  485. #pragma warning( disable : 4244 )
  486. nHiHi = m_nComputerId >> 48;
  487. nHiLo = (m_nComputerId >> 32) & 0xfff;
  488. nLoHi = (m_nComputerId >> 16) & 0xfff;
  489. nLoLo = m_nComputerId & 0xffff;
  490. #pragma warning( pop )
  491. CString sId;
  492. sId.Format(_T("%04X%04X%04X%04X"),
  493. nHiHi, nHiLo, nLoHi, nLoLo);
  494. int nSeedX = 12 - m_nComputerId % 10;
  495. int nSeedY = 15 - nSeedX;
  496. CString sEncryptId;
  497. int nIdLen = sId.GetLength();
  498. LPTSTR idStr = sEncryptId.GetBuffer(nIdLen);
  499. for (unsigned int i = 0; i < nIdLen; ++i)
  500. {
  501. int nValue = 0;
  502. if (sId[i] >= _T('0') && sId[i] <= _T('9'))
  503. {
  504. nValue = sId[i] - _T('0');
  505. }
  506. if (sId[i] >= _T('a') && sId[i] <= _T('f'))
  507. {
  508. nValue = sId[i] - _T('a') + 10;
  509. }
  510. if (sId[i] >= _T('A') && sId[i] <= _T('F'))
  511. {
  512. nValue = sId[i] - _T('A') + 10;
  513. }
  514. idStr[i] = _T('A') + ((nValue + i + 1) * nSeedX + nSeedY) % 26;
  515. }
  516. sEncryptId.ReleaseBuffer();
  517. sRet.Format(_T("%s-%s-%s-%s"),
  518. (LPCTSTR)sEncryptId.Right(4), (LPCTSTR)sEncryptId.Left(4), (LPCTSTR)sEncryptId.Mid(4, 4), (LPCTSTR)sEncryptId.Mid(8, 4)
  519. );
  520. return sRet;
  521. }
  522. __int64 MasterHardDiskSerial::getHardDriveComputerID()
  523. {
  524. int iDone = FALSE;
  525. m_nComputerId = 0;
  526. strcpy_s(m_cszHardDriveSerialNumber,1024, "");
  527. //if (IsWindowsXPOrGreater())
  528. if (true)
  529. {
  530. // this works under WinNT4 or Win2K or WinXP if you have any rights
  531. if (!iDone)
  532. iDone = ReadPhysicalDriveInNTWithZeroRights ();
  533. // this works under WinNT4 or Win2K or WinXP or Windows Server 2003 or Vista if you have any rights
  534. if (!iDone)
  535. iDone = ReadPhysicalDriveInNTUsingSmart ();
  536. // this works under WinNT4 or Win2K if you have admin rights
  537. if (!iDone)
  538. iDone = ReadPhysicalDriveInNTWithAdminRights();
  539. // this should work in WinNT or Win2K if previous did not work
  540. // this is kind of a backdoor via the SCSI mini port driver into
  541. // the IDE drives
  542. if (!iDone)
  543. iDone = ReadIdeDriveAsScsiDriveInNT ();
  544. }
  545. else
  546. {
  547. return 0;
  548. }
  549. if (m_cszHardDriveSerialNumber [0] > 0)
  550. {
  551. char *cP = m_cszHardDriveSerialNumber;
  552. // ignore first 5 characters from western digital hard drives if
  553. // the first four characters are WD-W
  554. if ( ! strncmp (m_cszHardDriveSerialNumber, "WD-W", 4))
  555. cP += 5;
  556. for ( ; cP && *cP; cP++)
  557. {
  558. if ('-' == *cP)
  559. continue;
  560. m_nComputerId *= 10;
  561. switch (*cP)
  562. {
  563. case '0': m_nComputerId += 0; break;
  564. case '1': m_nComputerId += 1; break;
  565. case '2': m_nComputerId += 2; break;
  566. case '3': m_nComputerId += 3; break;
  567. case '4': m_nComputerId += 4; break;
  568. case '5': m_nComputerId += 5; break;
  569. case '6': m_nComputerId += 6; break;
  570. case '7': m_nComputerId += 7; break;
  571. case '8': m_nComputerId += 8; break;
  572. case '9': m_nComputerId += 9; break;
  573. case 'a': case 'A': m_nComputerId += 10; break;
  574. case 'b': case 'B': m_nComputerId += 11; break;
  575. case 'c': case 'C': m_nComputerId += 12; break;
  576. case 'd': case 'D': m_nComputerId += 13; break;
  577. case 'e': case 'E': m_nComputerId += 14; break;
  578. case 'f': case 'F': m_nComputerId += 15; break;
  579. case 'g': case 'G': m_nComputerId += 16; break;
  580. case 'h': case 'H': m_nComputerId += 17; break;
  581. case 'i': case 'I': m_nComputerId += 18; break;
  582. case 'j': case 'J': m_nComputerId += 19; break;
  583. case 'k': case 'K': m_nComputerId += 20; break;
  584. case 'l': case 'L': m_nComputerId += 21; break;
  585. case 'm': case 'M': m_nComputerId += 22; break;
  586. case 'n': case 'N': m_nComputerId += 23; break;
  587. case 'o': case 'O': m_nComputerId += 24; break;
  588. case 'p': case 'P': m_nComputerId += 25; break;
  589. case 'q': case 'Q': m_nComputerId += 26; break;
  590. case 'r': case 'R': m_nComputerId += 27; break;
  591. case 's': case 'S': m_nComputerId += 28; break;
  592. case 't': case 'T': m_nComputerId += 29; break;
  593. case 'u': case 'U': m_nComputerId += 30; break;
  594. case 'v': case 'V': m_nComputerId += 31; break;
  595. case 'w': case 'W': m_nComputerId += 32; break;
  596. case 'x': case 'X': m_nComputerId += 33; break;
  597. case 'y': case 'Y': m_nComputerId += 34; break;
  598. case 'z': case 'Z': m_nComputerId += 35; break;
  599. }
  600. }
  601. }
  602. m_nComputerId %= 100000000;
  603. if (strstr (m_cszHardDriveModelNumber, "IBM-"))
  604. m_nComputerId += 300000000;
  605. else if (strstr (m_cszHardDriveModelNumber, "MAXTOR") ||
  606. strstr (m_cszHardDriveModelNumber, "Maxtor"))
  607. m_nComputerId += 400000000;
  608. else if (strstr (m_cszHardDriveModelNumber, "WDC "))
  609. m_nComputerId += 500000000;
  610. else
  611. m_nComputerId += 600000000;
  612. return m_nComputerId;
  613. }
  614. int MasterHardDiskSerial::GetSerialNo(std::vector<char> &serialNumber)
  615. {
  616. getHardDriveComputerID();
  617. size_t numberLength = strlen(m_cszHardDriveSerialNumber);
  618. if (numberLength == 0)
  619. return -1;
  620. serialNumber.resize(numberLength);
  621. memcpy(&serialNumber.front(), m_cszHardDriveSerialNumber, serialNumber.size());
  622. return 0;
  623. }
  624. char *MasterHardDiskSerial::ConvertToString (DWORD dwDiskData [256],
  625. int iFirstIndex,
  626. int iLastIndex,
  627. char* pcszBuf)
  628. {
  629. int iIndex = 0;
  630. int iPosition = 0;
  631. // each integer has two characters stored in it backwards
  632. // Removes the spaces from the serial no
  633. for ( iIndex = iFirstIndex; iIndex <= iLastIndex ; iIndex++ )
  634. {
  635. // get high byte for 1st character
  636. char ctemp = (char) (dwDiskData [iIndex] / 256);
  637. char cszmyspace[] = " ";
  638. if ( !(ctemp == *cszmyspace))
  639. {
  640. pcszBuf [iPosition++] = ctemp ;
  641. }
  642. // get low byte for 2nd character
  643. char ctemp1 = (char) (dwDiskData [iIndex] % 256);
  644. if ( !(ctemp1 == *cszmyspace))
  645. {
  646. pcszBuf [iPosition++] = ctemp1 ;
  647. }
  648. }
  649. // end the string
  650. pcszBuf[iPosition] = '\0';
  651. // cut off the trailing blanks
  652. for (iIndex = iPosition - 1; iIndex > 0 && isspace(pcszBuf [iIndex]); iIndex--)
  653. pcszBuf [iIndex] = '\0';
  654. return pcszBuf;
  655. }
  656. int MasterHardDiskSerial::GetErrorMessage(TCHAR* tszErrorMessage)
  657. {
  658. if (strlen(m_cszErrorMessage)!=0)
  659. {
  660. size_t len = 0;
  661. mbstowcs_s(&len, (wchar_t *)tszErrorMessage, sizeof(m_cszErrorMessage) + 1, m_cszErrorMessage, sizeof(m_cszErrorMessage));
  662. //mbstowcs((wchar_t *)tszErrorMessage,m_cszErrorMessage,sizeof(m_cszErrorMessage));
  663. return 0;
  664. }
  665. else
  666. return -1;
  667. }
  668. MasterHardDiskSerial::MasterHardDiskSerial()
  669. : m_nComputerId(0)
  670. {
  671. SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));
  672. SecureZeroMemory(m_cszHardDriveModelNumber,sizeof(m_cszHardDriveModelNumber));
  673. SecureZeroMemory(m_cszHardDriveSerialNumber,sizeof(m_cszHardDriveSerialNumber));
  674. }
  675. MasterHardDiskSerial::~MasterHardDiskSerial()
  676. {
  677. }