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.

1808 lines
56 KiB

  1. #include "dfioctl.h"
  2. #include <stdio.h>
  3. #include <winioctl.h>
  4. #pragma warning(disable: 4200)
  5. #include <ntddcdvd.h>
  6. #include <ntddmmc.h>
  7. #include <ntddcdrm.h>
  8. #include "dferr.h"
  9. #include "dfhlprs.h"
  10. #include "drvfull.h"
  11. #include "dfeject.h"
  12. #define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0]))
  13. ///////////////////////////////////////////////////////////////////////////////
  14. // MEDIA_TYPE
  15. _sFLAG_DESCR _mediatypeFD[] =
  16. {
  17. FLAG_DESCR_COMMENT(Unknown, TEXT("Format is unknown")),
  18. FLAG_DESCR_COMMENT(F5_1Pt2_512, TEXT("5.25, 1.2MB, 512 bytes/sector")),
  19. FLAG_DESCR_COMMENT(F3_1Pt44_512, TEXT("3.5, 1.44MB, 512 bytes/sector")),
  20. FLAG_DESCR_COMMENT(F3_2Pt88_512, TEXT("3.5, 2.88MB, 512 bytes/sector")),
  21. FLAG_DESCR_COMMENT(F3_20Pt8_512, TEXT("3.5, 20.8MB, 512 bytes/sector")),
  22. FLAG_DESCR_COMMENT(F3_720_512, TEXT("3.5, 720KB, 512 bytes/sector")),
  23. FLAG_DESCR_COMMENT(F5_360_512, TEXT("5.25, 360KB, 512 bytes/sector")),
  24. FLAG_DESCR_COMMENT(F5_320_512, TEXT("5.25, 320KB, 512 bytes/sector")),
  25. FLAG_DESCR_COMMENT(F5_320_1024, TEXT("5.25, 320KB, 1024 bytes/sector")),
  26. FLAG_DESCR_COMMENT(F5_180_512, TEXT("5.25, 180KB, 512 bytes/sector")),
  27. FLAG_DESCR_COMMENT(F5_160_512, TEXT("5.25, 160KB, 512 bytes/sector")),
  28. FLAG_DESCR_COMMENT(RemovableMedia, TEXT("Removable media other than floppy")),
  29. FLAG_DESCR_COMMENT(FixedMedia, TEXT("Fixed hard disk media")),
  30. FLAG_DESCR_COMMENT(F3_120M_512, TEXT("3.5, 120M Floppy")),
  31. FLAG_DESCR_COMMENT(F3_640_512, TEXT("3.5 , 640KB, 512 bytes/sector")),
  32. FLAG_DESCR_COMMENT(F5_640_512, TEXT("5.25, 640KB, 512 bytes/sector")),
  33. FLAG_DESCR_COMMENT(F5_720_512, TEXT("5.25, 720KB, 512 bytes/sector")),
  34. FLAG_DESCR_COMMENT(F3_1Pt2_512, TEXT("3.5 , 1.2Mb, 512 bytes/sector")),
  35. FLAG_DESCR_COMMENT(F3_1Pt23_1024, TEXT("3.5 , 1.23Mb, 1024 bytes/sector")),
  36. FLAG_DESCR_COMMENT(F5_1Pt23_1024, TEXT("5.25, 1.23MB, 1024 bytes/sector")),
  37. FLAG_DESCR_COMMENT(F3_128Mb_512, TEXT("3.5 MO 128Mb 512 bytes/sector")),
  38. FLAG_DESCR_COMMENT(F3_230Mb_512, TEXT("3.5 MO 230Mb 512 bytes/sector")),
  39. FLAG_DESCR_COMMENT(F8_256_128, TEXT("8, 256KB, 128 bytes/sector")),
  40. //
  41. FLAG_DESCR_COMMENT(DDS_4mm, TEXT("Tape - DAT DDS1,2,... (all vendors)")),
  42. FLAG_DESCR_COMMENT(MiniQic, TEXT("Tape - miniQIC Tape")),
  43. FLAG_DESCR_COMMENT(Travan, TEXT("Tape - Travan TR-1,2,3,...")),
  44. FLAG_DESCR_COMMENT(QIC, TEXT("Tape - QIC")),
  45. FLAG_DESCR_COMMENT(MP_8mm, TEXT("Tape - 8mm Exabyte Metal Particle")),
  46. FLAG_DESCR_COMMENT(AME_8mm, TEXT("Tape - 8mm Exabyte Advanced Metal Evap")),
  47. FLAG_DESCR_COMMENT(AIT1_8mm, TEXT("Tape - 8mm Sony AIT1")),
  48. FLAG_DESCR_COMMENT(DLT, TEXT("Tape - DLT Compact IIIxt, IV")),
  49. FLAG_DESCR_COMMENT(NCTP, TEXT("Tape - Philips NCTP")),
  50. FLAG_DESCR_COMMENT(IBM_3480, TEXT("Tape - IBM 3480")),
  51. FLAG_DESCR_COMMENT(IBM_3490E, TEXT("Tape - IBM 3490E")),
  52. FLAG_DESCR_COMMENT(IBM_Magstar_3590, TEXT("Tape - IBM Magstar 3590")),
  53. FLAG_DESCR_COMMENT(IBM_Magstar_MP, TEXT("Tape - IBM Magstar MP")),
  54. FLAG_DESCR_COMMENT(STK_DATA_D3, TEXT("Tape - STK Data D3")),
  55. FLAG_DESCR_COMMENT(SONY_DTF, TEXT("Tape - Sony DTF")),
  56. FLAG_DESCR_COMMENT(DV_6mm, TEXT("Tape - 6mm Digital Video")),
  57. FLAG_DESCR_COMMENT(DMI, TEXT("Tape - Exabyte DMI and compatibles")),
  58. FLAG_DESCR_COMMENT(SONY_D2, TEXT("Tape - Sony D2S and D2L")),
  59. FLAG_DESCR_COMMENT(CLEANER_CARTRIDGE, TEXT("Cleaner - All Drive types that support Drive Cleaners")),
  60. FLAG_DESCR_COMMENT(CD_ROM, TEXT("Opt_Disk - CD")),
  61. FLAG_DESCR_COMMENT(CD_R, TEXT("Opt_Disk - CD-Recordable (Write Once)")),
  62. FLAG_DESCR_COMMENT(CD_RW, TEXT("Opt_Disk - CD-Rewriteable")),
  63. FLAG_DESCR_COMMENT(DVD_ROM, TEXT("Opt_Disk - DVD-ROM")),
  64. FLAG_DESCR_COMMENT(DVD_R, TEXT("Opt_Disk - DVD-Recordable (Write Once)")),
  65. FLAG_DESCR_COMMENT(DVD_RW, TEXT("Opt_Disk - DVD-Rewriteable")),
  66. FLAG_DESCR_COMMENT(MO_3_RW, TEXT("Opt_Disk - 3.5\" Rewriteable MO Disk")),
  67. FLAG_DESCR_COMMENT(MO_5_WO, TEXT("Opt_Disk - MO 5.25\" Write Once")),
  68. FLAG_DESCR_COMMENT(MO_5_RW, TEXT("Opt_Disk - MO 5.25\" Rewriteable (not LIMDOW)")),
  69. FLAG_DESCR_COMMENT(MO_5_LIMDOW, TEXT("Opt_Disk - MO 5.25\" Rewriteable (LIMDOW)")),
  70. FLAG_DESCR_COMMENT(PC_5_WO, TEXT("Opt_Disk - Phase Change 5.25\" Write Once Optical")),
  71. FLAG_DESCR_COMMENT(PC_5_RW, TEXT("Opt_Disk - Phase Change 5.25\" Rewriteable")),
  72. FLAG_DESCR_COMMENT(PD_5_RW, TEXT("Opt_Disk - PhaseChange Dual Rewriteable")),
  73. FLAG_DESCR_COMMENT(ABL_5_WO, TEXT("Opt_Disk - Ablative 5.25\" Write Once Optical")),
  74. FLAG_DESCR_COMMENT(PINNACLE_APEX_5_RW, TEXT("Opt_Disk - Pinnacle Apex 4.6GB Rewriteable Optical")),
  75. FLAG_DESCR_COMMENT(SONY_12_WO, TEXT("Opt_Disk - Sony 12\" Write Once")),
  76. FLAG_DESCR_COMMENT(PHILIPS_12_WO, TEXT("Opt_Disk - Philips/LMS 12\" Write Once")),
  77. FLAG_DESCR_COMMENT(HITACHI_12_WO, TEXT("Opt_Disk - Hitachi 12\" Write Once")),
  78. FLAG_DESCR_COMMENT(CYGNET_12_WO, TEXT("Opt_Disk - Cygnet/ATG 12\" Write Once")),
  79. FLAG_DESCR_COMMENT(KODAK_14_WO, TEXT("Opt_Disk - Kodak 14\" Write Once")),
  80. FLAG_DESCR_COMMENT(MO_NFR_525, TEXT("Opt_Disk - Near Field Recording (Terastor)")),
  81. FLAG_DESCR_COMMENT(NIKON_12_RW, TEXT("Opt_Disk - Nikon 12\" Rewriteable")),
  82. FLAG_DESCR_COMMENT(IOMEGA_ZIP, TEXT("Mag_Disk - Iomega Zip")),
  83. FLAG_DESCR_COMMENT(IOMEGA_JAZ, TEXT("Mag_Disk - Iomega Jaz")),
  84. FLAG_DESCR_COMMENT(SYQUEST_EZ135, TEXT("Mag_Disk - Syquest EZ135")),
  85. FLAG_DESCR_COMMENT(SYQUEST_EZFLYER, TEXT("Mag_Disk - Syquest EzFlyer")),
  86. FLAG_DESCR_COMMENT(SYQUEST_SYJET, TEXT("Mag_Disk - Syquest SyJet")),
  87. FLAG_DESCR_COMMENT(AVATAR_F2, TEXT("Mag_Disk - 2.5\" Floppy")),
  88. FLAG_DESCR_COMMENT(MP2_8mm, TEXT("Tape - 8mm Hitachi")),
  89. FLAG_DESCR_COMMENT(DST_S, TEXT("Ampex DST Small Tapes")),
  90. FLAG_DESCR_COMMENT(DST_M, TEXT("Ampex DST Medium Tapes")),
  91. FLAG_DESCR_COMMENT(DST_L, TEXT("Ampex DST Large Tapes")),
  92. FLAG_DESCR_COMMENT(VXATape_1, TEXT("Ecrix 8mm Tape")),
  93. FLAG_DESCR_COMMENT(VXATape_2, TEXT("Ecrix 8mm Tape")),
  94. FLAG_DESCR_COMMENT(LTO_Ultrium, TEXT("IBM, HP, Seagate LTO Ultrium")),
  95. FLAG_DESCR_COMMENT(LTO_Accelis, TEXT("IBM, HP, Seagate LTO Accelis")),
  96. };
  97. int _PrintMediaTypeReport(DWORD dwFlags[], DWORD cchIndent, MEDIA_TYPE mt)
  98. {
  99. int i = 0;
  100. // for now let's assume raw
  101. i += _PrintFlag(mt, _mediatypeFD, ARRAYSIZE(_mediatypeFD), cchIndent,
  102. TRUE, TRUE, TRUE, FALSE);
  103. return i;
  104. }
  105. ///////////////////////////////////////////////////////////////////////////////
  106. // IOCTL_DISK_GET_DRIVE_LAYOUT
  107. _sFLAG_DESCR _partitiontypeFD[] =
  108. {
  109. FLAG_DESCR_COMMENT(PARTITION_ENTRY_UNUSED, TEXT("Entry unused")),
  110. FLAG_DESCR_COMMENT(PARTITION_FAT_12, TEXT("12-bit FAT entries")),
  111. FLAG_DESCR_COMMENT(PARTITION_XENIX_1, TEXT("Xenix")),
  112. FLAG_DESCR_COMMENT(PARTITION_XENIX_2, TEXT("Xenix")),
  113. FLAG_DESCR_COMMENT(PARTITION_FAT_16, TEXT("16-bit FAT entries")),
  114. FLAG_DESCR_COMMENT(PARTITION_EXTENDED, TEXT("Extended partition entry")),
  115. FLAG_DESCR_COMMENT(PARTITION_HUGE, TEXT("Huge partition MS-DOS V4")),
  116. FLAG_DESCR_COMMENT(PARTITION_IFS, TEXT("IFS Partition")),
  117. FLAG_DESCR_COMMENT(PARTITION_FAT32, TEXT("FAT32")),
  118. FLAG_DESCR_COMMENT(PARTITION_FAT32_XINT13, TEXT("FAT32 using extended int13 services")),
  119. FLAG_DESCR_COMMENT(PARTITION_XINT13, TEXT("Win95 partition using extended int13 services")),
  120. FLAG_DESCR_COMMENT(PARTITION_XINT13_EXTENDED, TEXT("Same as type 5 but uses extended int13 services")),
  121. FLAG_DESCR_COMMENT(PARTITION_PREP, TEXT("PowerPC Reference Platform (PReP) Boot Partition")),
  122. FLAG_DESCR_COMMENT(PARTITION_LDM, TEXT("Logical Disk Manager partition")),
  123. FLAG_DESCR_COMMENT(PARTITION_UNIX, TEXT("Unix")),
  124. };
  125. int _PrintLayoutReport(DWORD dwFlags[], DWORD cchIndent,
  126. DRIVE_LAYOUT_INFORMATION* pdli)
  127. {
  128. int i = 0;
  129. // for now let's assume raw
  130. _PrintIndent(cchIndent);
  131. i += wprintf(TEXT("Oper: CreateFile + GENERIC_READ; DeviceIoControl + "\
  132. TEXT("IOCTL_DISK_GET_DRIVE_LAYOUT;\n")));
  133. _PrintElapsedTime(cchIndent, TRUE);
  134. _PrintIndent(cchIndent);
  135. i += wprintf(TEXT("DRIVE_LAYOUT_INFORMATION\n"));
  136. _PrintIndent(cchIndent);
  137. i += wprintf(TEXT("{\n"));
  138. _PrintIndent(cchIndent + 2);
  139. i += wprintf(TEXT("0x%02u (DWORD PartitionCount)\n"),
  140. pdli->PartitionCount);
  141. _PrintIndent(cchIndent + 2);
  142. i += wprintf(TEXT("0x%08X (DWORD Signature)\n"), pdli->Signature);
  143. _PrintIndent(cchIndent + 2);
  144. i += wprintf(TEXT("{\n"));
  145. for (DWORD dw = 0; dw < pdli->PartitionCount; ++dw)
  146. {
  147. PARTITION_INFORMATION* ppi = &(pdli->PartitionEntry[dw]);
  148. LPTSTR pszBool;
  149. TCHAR szTrue[] = TEXT("TRUE");
  150. TCHAR szFalse[] = TEXT("FALSE");
  151. _PrintIndent(cchIndent + 4);
  152. i += wprintf(TEXT("PARTITION_INFORMATION\n"));
  153. _PrintIndent(cchIndent + 4);
  154. i += wprintf(TEXT("{\n"));
  155. _PrintIndent(cchIndent + 6);
  156. i += wprintf(TEXT("0x%08X (lo), 0x%08X (hi) (LARGE_INTEGER StartingOffset)\n"),
  157. ppi->StartingOffset.LowPart, ppi->StartingOffset.HighPart);
  158. _PrintIndent(cchIndent + 6);
  159. i += wprintf(TEXT("0x%08X (lo), 0x%08X (hi) (LARGE_INTEGER PartitionLength)\n"),
  160. ppi->PartitionLength.LowPart, ppi->PartitionLength.HighPart);
  161. _PrintIndent(cchIndent + 6);
  162. i += wprintf(TEXT("0x%08X (DWORD HiddenSectors)\n"),
  163. ppi->HiddenSectors);
  164. _PrintIndent(cchIndent + 6);
  165. i += wprintf(TEXT("0x%02u (DWORD PartitionNumber)\n"),
  166. ppi->PartitionNumber);
  167. i += _PrintFlag(ppi->PartitionType, _partitiontypeFD, ARRAYSIZE(_partitiontypeFD),
  168. cchIndent + 6, TRUE, TRUE, TRUE, FALSE);
  169. i += wprintf(TEXT(" (BYTE PartitionType)\n"));
  170. if (ppi->BootIndicator)
  171. {
  172. pszBool = szTrue;
  173. }
  174. else
  175. {
  176. pszBool = szFalse;
  177. }
  178. _PrintIndent(cchIndent + 6);
  179. i += wprintf(TEXT("%s (BOOLEAN BootIndicator)\n"),
  180. pszBool);
  181. if (ppi->RecognizedPartition)
  182. {
  183. pszBool = szTrue;
  184. }
  185. else
  186. {
  187. pszBool = szFalse;
  188. }
  189. _PrintIndent(cchIndent + 6);
  190. i += wprintf(TEXT("%s (BOOLEAN RecognizedPartition)\n"),
  191. pszBool);
  192. if (ppi->RewritePartition)
  193. {
  194. pszBool = szTrue;
  195. }
  196. else
  197. {
  198. pszBool = szFalse;
  199. }
  200. _PrintIndent(cchIndent + 6);
  201. i += wprintf(TEXT("%s (BOOLEAN RewritePartition)\n"),
  202. pszBool);
  203. _PrintIndent(cchIndent + 4);
  204. i += wprintf(TEXT("}\n"));
  205. }
  206. _PrintIndent(cchIndent + 2);
  207. i += wprintf(TEXT("}\n"));
  208. _PrintIndent(cchIndent);
  209. i += wprintf(TEXT("}\n"));
  210. return i;
  211. }
  212. HRESULT _IOCTLLayout(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  213. {
  214. HRESULT hres = E_FAIL;
  215. HANDLE hDevice;
  216. _StartClock();
  217. hDevice = _GetDeviceHandle(pszArg, GENERIC_READ);
  218. if (INVALID_HANDLE_VALUE != hDevice)
  219. {
  220. DWORD dwDummy;
  221. BOOL b;
  222. DWORD cbdli = 4096;//sizeof(DRIVE_LAYOUT_INFORMATION) + 8 * sizeof(PARTITION_INFORMATION);
  223. DRIVE_LAYOUT_INFORMATION* pdli = (DRIVE_LAYOUT_INFORMATION*)LocalAlloc(LPTR, cbdli);
  224. b = DeviceIoControl(hDevice,
  225. IOCTL_DISK_GET_DRIVE_LAYOUT, // dwIoControlCode operation to perform
  226. NULL, // lpInBuffer; must be NULL
  227. 0, // nInBufferSize; must be zero
  228. (LPVOID)pdli, // pointer to output buffer
  229. (DWORD)cbdli, // size of output buffer
  230. &dwDummy, // receives number of bytes returned
  231. NULL);
  232. _StopClock();
  233. if (b)
  234. {
  235. _PrintLayoutReport(dwFlags, cchIndent, pdli);
  236. hres = S_OK;
  237. }
  238. else
  239. {
  240. _PrintGetLastError(cchIndent);
  241. hres = E_FAIL;
  242. }
  243. CloseHandle(hDevice);
  244. }
  245. else
  246. {
  247. _PrintIndent(cchIndent);
  248. wprintf(TEXT("Cannot open device\n"));
  249. _PrintGetLastError(cchIndent);
  250. hres = E_DF_CANNOTOPENDEVICE;
  251. }
  252. return hres;
  253. }
  254. ///////////////////////////////////////////////////////////////////////////////
  255. // IOCTL_DISK_GET_DRIVE_GEOMETRY
  256. int _PrintGeometryReport(DWORD dwFlags[], DWORD cchIndent, DISK_GEOMETRY* pdg)
  257. {
  258. int i = 0;
  259. // for now let's assume raw
  260. _PrintIndent(cchIndent);
  261. i += wprintf(TEXT("Oper: CreateFile + GENERIC_READ; DeviceIoControl + "\
  262. TEXT("IOCTL_DISK_GET_DRIVE_GEOMETRY;\n")));
  263. _PrintElapsedTime(cchIndent, TRUE);
  264. _PrintIndent(cchIndent);
  265. i += wprintf(TEXT("DISK_GEOMETRY\n"));
  266. _PrintIndent(cchIndent);
  267. i += wprintf(TEXT("{\n"));
  268. _PrintIndent(cchIndent + 2);
  269. i += wprintf(TEXT("0x%08X (lo), 0x%08X (hi) (LARGE_INTEGER Cylinders)\n"),
  270. pdg->Cylinders.LowPart, pdg->Cylinders.HighPart);
  271. i += _PrintMediaTypeReport(dwFlags, cchIndent + 2, pdg->MediaType);
  272. i += wprintf(TEXT(" (MEDIA_TYPE MediaType)\n"));
  273. _PrintIndent(cchIndent + 2);
  274. i += wprintf(TEXT("%u (DWORD TracksPerCylinder)\n"), pdg->TracksPerCylinder);
  275. _PrintIndent(cchIndent + 2);
  276. i += wprintf(TEXT("%u (DWORD SectorsPerTrack)\n"), pdg->SectorsPerTrack);
  277. _PrintIndent(cchIndent + 2);
  278. i += wprintf(TEXT("%u (DWORD BytesPerSector)\n"), pdg->BytesPerSector);
  279. _PrintIndent(cchIndent);
  280. i += wprintf(TEXT("}\n"));
  281. return i;
  282. }
  283. HRESULT _IOCTLGeometry(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  284. {
  285. HRESULT hres = E_FAIL;
  286. HANDLE hDevice;
  287. _StartClock();
  288. hDevice = _GetDeviceHandle(pszArg, GENERIC_READ);
  289. if (INVALID_HANDLE_VALUE != hDevice)
  290. {
  291. DWORD dwDummy;
  292. BOOL b;
  293. DISK_GEOMETRY dg = {0};
  294. b = DeviceIoControl(hDevice,
  295. IOCTL_DISK_GET_DRIVE_GEOMETRY, // dwIoControlCode operation to perform
  296. NULL, // lpInBuffer; must be NULL
  297. 0, // nInBufferSize; must be zero
  298. &dg, // pointer to output buffer
  299. sizeof(dg), // size of output buffer
  300. &dwDummy, // receives number of bytes returned
  301. NULL);
  302. _StopClock();
  303. if (b)
  304. {
  305. _PrintGeometryReport(dwFlags, cchIndent, &dg);
  306. hres = S_OK;
  307. }
  308. else
  309. {
  310. _PrintGetLastError(cchIndent);
  311. hres = E_FAIL;
  312. }
  313. CloseHandle(hDevice);
  314. }
  315. else
  316. {
  317. _PrintIndent(cchIndent);
  318. wprintf(TEXT("Cannot open device\n"));
  319. _PrintGetLastError(cchIndent);
  320. hres = E_DF_CANNOTOPENDEVICE;
  321. }
  322. return hres;
  323. }
  324. HRESULT _IOCTLPartition(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  325. {
  326. HRESULT hres = E_FAIL;
  327. if (_IsFlagSet(IOCTL_PARTITION, dwFlags))
  328. {
  329. _PrintIndent(cchIndent);
  330. wprintf(TEXT("Are you really sure? You know what partioning a drive does, right? If so the real switch is \'-hpsure\'.\n"));
  331. hres = S_OK;
  332. }
  333. else
  334. {
  335. if (_IsFlagSet(IOCTL_PARTITIONSURE, dwFlags))
  336. {
  337. HANDLE hDevice;
  338. _StartClock();
  339. hDevice = _GetDeviceHandle(pszArg, GENERIC_WRITE | GENERIC_READ);
  340. if (INVALID_HANDLE_VALUE != hDevice)
  341. {
  342. DWORD dwDummy;
  343. BOOL b;
  344. DISK_GEOMETRY dg = {0};
  345. b = DeviceIoControl(hDevice,
  346. IOCTL_DISK_GET_DRIVE_GEOMETRY, // dwIoControlCode operation to perform
  347. NULL, // lpInBuffer; must be NULL
  348. 0, // nInBufferSize; must be zero
  349. &dg, // pointer to output buffer
  350. sizeof(dg), // size of output buffer
  351. &dwDummy, // receives number of bytes returned
  352. NULL);
  353. if (b)
  354. {
  355. // Calc size
  356. DRIVE_LAYOUT_INFORMATION dli = {0};
  357. dli.PartitionCount = 1;
  358. dli.Signature = 0x57EF57EF;
  359. dli.PartitionEntry[0].StartingOffset.QuadPart = ((LONGLONG)dg.SectorsPerTrack) *
  360. ((LONGLONG)dg.BytesPerSector);
  361. dli.PartitionEntry[0].PartitionLength.QuadPart = ((LONGLONG)(dg.Cylinders.QuadPart - 1)) *
  362. ((LONGLONG)dg.TracksPerCylinder) * ((LONGLONG)dg.SectorsPerTrack) *
  363. ((LONGLONG)dg.BytesPerSector) - ((LONGLONG)dg.SectorsPerTrack) *
  364. ((LONGLONG)dg.BytesPerSector);
  365. dli.PartitionEntry[0].PartitionNumber = 1;
  366. dli.PartitionEntry[0].PartitionType = PARTITION_IFS; // is that OK?
  367. dli.PartitionEntry[0].RecognizedPartition = TRUE;
  368. dli.PartitionEntry[0].RewritePartition = TRUE;
  369. b = DeviceIoControl(hDevice,
  370. IOCTL_DISK_SET_DRIVE_LAYOUT, // dwIoControlCode operation to perform
  371. &dli, // pointer to output buffer
  372. sizeof(dli), // size of output buffer
  373. NULL, // lpInBuffer; must be NULL
  374. 0, // nInBufferSize; must be zero
  375. &dwDummy, // receives number of bytes returned
  376. NULL);
  377. hres = S_OK;
  378. if (b)
  379. {
  380. wprintf(TEXT("Succeeded!\n"));
  381. }
  382. else
  383. {
  384. wprintf(TEXT("Failed!\n"));
  385. }
  386. }
  387. else
  388. {
  389. _PrintGetLastError(cchIndent);
  390. hres = E_FAIL;
  391. }
  392. CloseHandle(hDevice);
  393. }
  394. else
  395. {
  396. _PrintIndent(cchIndent);
  397. wprintf(TEXT("Cannot open device\n"));
  398. _PrintGetLastError(cchIndent);
  399. hres = E_DF_CANNOTOPENDEVICE;
  400. }
  401. }
  402. }
  403. return hres;
  404. }
  405. HRESULT _IOCTLPartitionGPT(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  406. {
  407. HRESULT hres = E_FAIL;
  408. //HANDLE hDevice = _GetDeviceHandle(pszArg, GENERIC_WRITE | GENERIC_READ);
  409. //HANDLE hDevice = _GetDeviceHandle(pszArg, GENERIC_READ);
  410. HANDLE hDevice = _GetDeviceHandle(pszArg, FILE_READ_ATTRIBUTES);
  411. if (hDevice)
  412. {
  413. PARTITION_INFORMATION_EX partitionEx;
  414. DWORD cbReturned;
  415. if (DeviceIoControl(hDevice, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0,
  416. (void*)&partitionEx, sizeof(PARTITION_INFORMATION_EX),
  417. &cbReturned, NULL))
  418. {
  419. hres = S_OK;
  420. if (partitionEx.PartitionStyle == PARTITION_STYLE_GPT)
  421. {
  422. wprintf(TEXT("Succeeded!\n"));
  423. }
  424. else
  425. {
  426. wprintf(TEXT("Failed!\n"));
  427. }
  428. }
  429. else
  430. {
  431. _PrintGetLastError(cchIndent);
  432. }
  433. CloseHandle(hDevice);
  434. }
  435. else
  436. {
  437. _PrintIndent(cchIndent);
  438. wprintf(TEXT("Cannot open device\n"));
  439. _PrintGetLastError(cchIndent);
  440. hres = E_DF_CANNOTOPENDEVICE;
  441. }
  442. return hres;
  443. }
  444. ///////////////////////////////////////////////////////////////////////////////
  445. // IOCTL_CDROM_GET_CONFIGURATION
  446. HRESULT _IOCTLCDROMGetConfig(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  447. {
  448. HRESULT hres = E_FAIL;
  449. HANDLE hDevice;
  450. _StartClock();
  451. hDevice = _GetDeviceHandle(pszArg, GENERIC_READ);
  452. if (INVALID_HANDLE_VALUE != hDevice)
  453. {
  454. DWORD cbReturned;
  455. GET_CONFIGURATION_IOCTL_INPUT input;
  456. // GET_CONFIGURATION_HEADER header;
  457. DWORD cbHeader = sizeof(GET_CONFIGURATION_HEADER) + sizeof(FEATURE_HEADER);
  458. GET_CONFIGURATION_HEADER* pheader = (GET_CONFIGURATION_HEADER*)LocalAlloc(LPTR,
  459. cbHeader);
  460. if (pheader)
  461. {
  462. LPWSTR pszSucceeded = NULL;
  463. LPWSTR pszFailed = NULL;
  464. input.RequestType = SCSI_GET_CONFIGURATION_REQUEST_TYPE_ONE;
  465. input.Reserved[0] = NULL;
  466. input.Reserved[1] = NULL;
  467. if (_IsFlagSet(IOCTL_CDROMGETCONFIGMMC2, dwFlags))
  468. {
  469. input.Feature = FeatureProfileList;
  470. pszSucceeded = TEXT("MMC2 Compliant drive\n");
  471. pszFailed = TEXT("NOT MMC2 Compliant drive\n");
  472. }
  473. else
  474. {
  475. if (_IsFlagSet(IOCTL_CDROMGETCONFIGDVDRAM, dwFlags))
  476. {
  477. input.Feature = FeatureDvdRead;
  478. pszSucceeded = TEXT("DVD RAM drive\n");
  479. pszFailed = TEXT("NOT DVD RAM drive\n");
  480. }
  481. else
  482. {
  483. if (_IsFlagSet(IOCTL_CDROMGETCONFIGRW, dwFlags))
  484. {
  485. input.Feature = FeatureRandomWritable;
  486. pszSucceeded = TEXT("Random Writable drive\n");
  487. pszFailed = TEXT("NOT Random Writable drive\n");
  488. }
  489. else
  490. {
  491. if (_IsFlagSet(IOCTL_CDROMGETCONFIGWO, dwFlags))
  492. {
  493. input.Feature = FeatureWriteOnce;
  494. pszSucceeded = TEXT("Write Once drive\n");
  495. pszFailed = TEXT("NOT Write Once drive\n");
  496. }
  497. else
  498. {
  499. if (_IsFlagSet(IOCTL_CDROMGETCONFIGISW, dwFlags))
  500. {
  501. input.Feature = FeatureIncrementalStreamingWritable;
  502. pszSucceeded = TEXT("Inc Streaming Writable drive\n");
  503. pszFailed = TEXT("NOT Inc Streaming Writable drive\n");
  504. }
  505. else
  506. {
  507. pszSucceeded = TEXT("ERROR: Bad option!\n");
  508. pszFailed = pszSucceeded;
  509. }
  510. }
  511. }
  512. }
  513. }
  514. BOOL f = DeviceIoControl(hDevice,
  515. IOCTL_CDROM_GET_CONFIGURATION,
  516. &input,
  517. sizeof(GET_CONFIGURATION_IOCTL_INPUT),
  518. pheader,
  519. // sizeof(GET_CONFIGURATION_HEADER),
  520. cbHeader,
  521. &cbReturned,
  522. NULL);
  523. FEATURE_HEADER* pfh = (FEATURE_HEADER*)(pheader->Data);
  524. _StopClock();
  525. _PrintElapsedTime(cchIndent, TRUE);
  526. _PrintIndent(cchIndent);
  527. if (f)
  528. {
  529. hres = S_OK;
  530. wprintf(pszSucceeded);
  531. input.RequestType = SCSI_GET_CONFIGURATION_REQUEST_TYPE_CURRENT;
  532. f = DeviceIoControl(hDevice,
  533. IOCTL_CDROM_GET_CONFIGURATION,
  534. &input,
  535. sizeof(GET_CONFIGURATION_IOCTL_INPUT),
  536. pheader,
  537. cbHeader,
  538. &cbReturned,
  539. NULL);
  540. if (f)
  541. {
  542. if (pfh->Current)
  543. {
  544. wprintf(TEXT("Feature currently ON\n"));
  545. }
  546. else
  547. {
  548. wprintf(TEXT("Feature currently OFF\n"));
  549. }
  550. }
  551. }
  552. else
  553. {
  554. wprintf(pszFailed);
  555. }
  556. CloseHandle(hDevice);
  557. }
  558. else
  559. {
  560. _PrintIndent(cchIndent);
  561. wprintf(TEXT("Cannot open device\n"));
  562. _PrintGetLastError(cchIndent);
  563. hres = E_DF_CANNOTOPENDEVICE;
  564. }
  565. }
  566. return hres;
  567. }
  568. _sFLAG_DESCR _featurenumberFD[] =
  569. {
  570. FLAG_DESCR(FeatureProfileList),
  571. FLAG_DESCR(FeatureCore),
  572. FLAG_DESCR(FeatureMorphing),
  573. FLAG_DESCR(FeatureRemovableMedium),
  574. FLAG_DESCR(FeatureRandomReadable),
  575. FLAG_DESCR(FeatureMultiRead),
  576. FLAG_DESCR(FeatureCdRead),
  577. FLAG_DESCR(FeatureDvdRead),
  578. FLAG_DESCR(FeatureRandomWritable),
  579. FLAG_DESCR(FeatureIncrementalStreamingWritable),
  580. FLAG_DESCR(FeatureSectorErasable),
  581. FLAG_DESCR(FeatureFormattable),
  582. FLAG_DESCR(FeatureDefectManagement),
  583. FLAG_DESCR(FeatureWriteOnce),
  584. FLAG_DESCR(FeatureRestrictedOverwrite),
  585. FLAG_DESCR(FeatureWriteProtect),
  586. FLAG_DESCR(FeatureCdrwCAVWrite),
  587. FLAG_DESCR(FeatureRigidRestrictedOverwrite),
  588. FLAG_DESCR(FeatureCdTrackAtOnce),
  589. FLAG_DESCR(FeatureCdMastering),
  590. FLAG_DESCR(FeatureDvdRecordableWrite),
  591. FLAG_DESCR(FeaturePowerManagement),
  592. FLAG_DESCR(FeatureSMART),
  593. FLAG_DESCR(FeatureEmbeddedChanger),
  594. FLAG_DESCR(FeatureCDAudioAnalogPlay),
  595. FLAG_DESCR(FeatureMicrocodeUpgrade),
  596. FLAG_DESCR(FeatureTimeout),
  597. FLAG_DESCR(FeatureDvdCSS),
  598. FLAG_DESCR(FeatureRealTimeStreaming),
  599. FLAG_DESCR(FeatureLogicalUnitSerialNumber),
  600. FLAG_DESCR(FeatureDiscControlBlocks),
  601. FLAG_DESCR(FeatureDvdCPRM),
  602. };
  603. ///////////////////////////////////////////////////////////////////////////////
  604. // IOCTL_CDROM_GET_CONFIGURATION
  605. HRESULT _IOCTLCDROMGetConfigListAll(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  606. {
  607. HRESULT hres = E_FAIL;
  608. HANDLE hDevice = _GetDeviceHandle(pszArg, GENERIC_READ);
  609. if (INVALID_HANDLE_VALUE != hDevice)
  610. {
  611. DWORD cbReturned;
  612. GET_CONFIGURATION_IOCTL_INPUT input;
  613. DWORD cbHeader = sizeof(GET_CONFIGURATION_HEADER) + sizeof(FEATURE_HEADER);
  614. GET_CONFIGURATION_HEADER* pheader = (GET_CONFIGURATION_HEADER*)LocalAlloc(LPTR,
  615. cbHeader);
  616. if (pheader)
  617. {
  618. FEATURE_HEADER* pfh;
  619. input.RequestType = SCSI_GET_CONFIGURATION_REQUEST_TYPE_ONE;
  620. input.Reserved[0] = NULL;
  621. input.Reserved[1] = NULL;
  622. _PrintIndent(cchIndent);
  623. wprintf(TEXT("Supported features (* = Current):\n\n"));
  624. for (DWORD dw = 0; dw < ARRAYSIZE(_featurenumberFD); ++dw)
  625. {
  626. input.Feature = (FEATURE_NUMBER)(_featurenumberFD[dw].dwFlag);
  627. BOOL f = DeviceIoControl(hDevice,
  628. IOCTL_CDROM_GET_CONFIGURATION,
  629. &input,
  630. sizeof(GET_CONFIGURATION_IOCTL_INPUT),
  631. pheader,
  632. cbHeader,
  633. &cbReturned,
  634. NULL);
  635. pfh = (FEATURE_HEADER*)(pheader->Data);
  636. if (f)
  637. {
  638. WORD w = (pfh->FeatureCode[0]) << 8 | (pfh->FeatureCode[1]);
  639. if (w == (WORD)(_featurenumberFD[dw].dwFlag))
  640. {
  641. _PrintIndent(cchIndent +2);
  642. if (pfh->Current)
  643. {
  644. wprintf(TEXT("* "));
  645. }
  646. else
  647. {
  648. wprintf(TEXT(" "));
  649. }
  650. _PrintFlag(_featurenumberFD[dw].dwFlag, _featurenumberFD, ARRAYSIZE(_featurenumberFD),
  651. 0, FALSE, FALSE, FALSE, FALSE);
  652. _PrintCR();
  653. }
  654. hres = S_OK;
  655. }
  656. }
  657. CloseHandle(hDevice);
  658. }
  659. else
  660. {
  661. _PrintIndent(cchIndent);
  662. wprintf(TEXT("Cannot open device\n"));
  663. _PrintGetLastError(cchIndent);
  664. hres = E_DF_CANNOTOPENDEVICE;
  665. }
  666. }
  667. return hres;
  668. }
  669. ///////////////////////////////////////////////////////////////////////////////
  670. // IOCTL_STORAGE_CHECK_VERIFY
  671. HRESULT _IOCTLCheckVerify(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  672. {
  673. HRESULT hres = E_FAIL;
  674. HANDLE hDevice;
  675. _StartClock();
  676. hDevice = _GetDeviceHandle(pszArg, GENERIC_READ);
  677. if (INVALID_HANDLE_VALUE != hDevice)
  678. {
  679. DWORD dwDummy;
  680. SetLastError(0);
  681. BOOL b = DeviceIoControl(hDevice,
  682. IOCTL_STORAGE_CHECK_VERIFY, // dwIoControlCode operation to perform
  683. NULL, // lpInBuffer; must be NULL
  684. 0, // nInBufferSize; must be zero
  685. NULL, // pointer to output buffer
  686. 0, // size of output buffer
  687. &dwDummy, // receives number of bytes returned
  688. NULL);
  689. _StopClock();
  690. _PrintIndent(cchIndent);
  691. wprintf(TEXT("Oper: CreateFile + GENERIC_READ; DeviceIoControl + "\
  692. TEXT("IOCTL_STORAGE_CHECK_VERIFY;\n")));
  693. _PrintElapsedTime(cchIndent, TRUE);
  694. _PrintIndent(cchIndent);
  695. wprintf(TEXT("Accessible: "));
  696. hres = S_OK;
  697. if (b)
  698. {
  699. wprintf(TEXT("Y\n"));
  700. }
  701. else
  702. {
  703. if (ERROR_NOT_READY == GetLastError())
  704. {
  705. wprintf(TEXT("N\n"));
  706. }
  707. else
  708. {
  709. _PrintGetLastError(cchIndent);
  710. hres = E_FAIL;
  711. }
  712. }
  713. CloseHandle(hDevice);
  714. }
  715. else
  716. {
  717. _PrintIndent(cchIndent);
  718. wprintf(TEXT("Cannot open device\n"));
  719. _PrintGetLastError(cchIndent);
  720. hres = E_DF_CANNOTOPENDEVICE;
  721. }
  722. return hres;
  723. }
  724. ///////////////////////////////////////////////////////////////////////////////
  725. // IOCTL_STORAGE_GET_DEVICE_NUMBER
  726. _sFLAG_DESCR _devicetypeFD[] =
  727. {
  728. FLAG_DESCR(FILE_DEVICE_BEEP),
  729. FLAG_DESCR(FILE_DEVICE_CD_ROM),
  730. FLAG_DESCR(FILE_DEVICE_CD_ROM_FILE_SYSTEM),
  731. FLAG_DESCR(FILE_DEVICE_CONTROLLER),
  732. FLAG_DESCR(FILE_DEVICE_DATALINK),
  733. FLAG_DESCR(FILE_DEVICE_DFS),
  734. FLAG_DESCR(FILE_DEVICE_DISK),
  735. FLAG_DESCR(FILE_DEVICE_DISK_FILE_SYSTEM),
  736. FLAG_DESCR(FILE_DEVICE_FILE_SYSTEM),
  737. FLAG_DESCR(FILE_DEVICE_INPORT_PORT),
  738. FLAG_DESCR(FILE_DEVICE_KEYBOARD),
  739. FLAG_DESCR(FILE_DEVICE_MAILSLOT),
  740. FLAG_DESCR(FILE_DEVICE_MIDI_IN),
  741. FLAG_DESCR(FILE_DEVICE_MIDI_OUT),
  742. FLAG_DESCR(FILE_DEVICE_MOUSE),
  743. FLAG_DESCR(FILE_DEVICE_MULTI_UNC_PROVIDER),
  744. FLAG_DESCR(FILE_DEVICE_NAMED_PIPE),
  745. FLAG_DESCR(FILE_DEVICE_NETWORK),
  746. FLAG_DESCR(FILE_DEVICE_NETWORK_BROWSER),
  747. FLAG_DESCR(FILE_DEVICE_NETWORK_FILE_SYSTEM),
  748. FLAG_DESCR(FILE_DEVICE_NULL),
  749. FLAG_DESCR(FILE_DEVICE_PARALLEL_PORT),
  750. FLAG_DESCR(FILE_DEVICE_PHYSICAL_NETCARD),
  751. FLAG_DESCR(FILE_DEVICE_PRINTER),
  752. FLAG_DESCR(FILE_DEVICE_SCANNER),
  753. FLAG_DESCR(FILE_DEVICE_SERIAL_MOUSE_PORT),
  754. FLAG_DESCR(FILE_DEVICE_SERIAL_PORT),
  755. FLAG_DESCR(FILE_DEVICE_SCREEN),
  756. FLAG_DESCR(FILE_DEVICE_SOUND),
  757. FLAG_DESCR(FILE_DEVICE_STREAMS),
  758. FLAG_DESCR(FILE_DEVICE_TAPE),
  759. FLAG_DESCR(FILE_DEVICE_TAPE_FILE_SYSTEM),
  760. FLAG_DESCR(FILE_DEVICE_TRANSPORT),
  761. FLAG_DESCR(FILE_DEVICE_UNKNOWN),
  762. FLAG_DESCR(FILE_DEVICE_VIDEO),
  763. FLAG_DESCR(FILE_DEVICE_VIRTUAL_DISK),
  764. FLAG_DESCR(FILE_DEVICE_WAVE_IN),
  765. FLAG_DESCR(FILE_DEVICE_WAVE_OUT),
  766. FLAG_DESCR(FILE_DEVICE_8042_PORT),
  767. FLAG_DESCR(FILE_DEVICE_NETWORK_REDIRECTOR),
  768. FLAG_DESCR(FILE_DEVICE_BATTERY),
  769. FLAG_DESCR(FILE_DEVICE_BUS_EXTENDER),
  770. FLAG_DESCR(FILE_DEVICE_MODEM),
  771. FLAG_DESCR(FILE_DEVICE_VDM),
  772. FLAG_DESCR(FILE_DEVICE_MASS_STORAGE),
  773. FLAG_DESCR(FILE_DEVICE_SMB),
  774. FLAG_DESCR(FILE_DEVICE_KS),
  775. FLAG_DESCR(FILE_DEVICE_CHANGER),
  776. FLAG_DESCR(FILE_DEVICE_SMARTCARD),
  777. FLAG_DESCR(FILE_DEVICE_ACPI),
  778. FLAG_DESCR(FILE_DEVICE_DVD),
  779. FLAG_DESCR(FILE_DEVICE_FULLSCREEN_VIDEO),
  780. FLAG_DESCR(FILE_DEVICE_DFS_FILE_SYSTEM),
  781. FLAG_DESCR(FILE_DEVICE_DFS_VOLUME),
  782. FLAG_DESCR(FILE_DEVICE_SERENUM),
  783. FLAG_DESCR(FILE_DEVICE_TERMSRV),
  784. FLAG_DESCR(FILE_DEVICE_KSEC),
  785. };
  786. int _PrintDeviceNumberReport(DWORD dwFlags[], DWORD cchIndent,
  787. STORAGE_DEVICE_NUMBER* psdn)
  788. {
  789. int i = 0;
  790. // for now let's assume raw
  791. _PrintIndent(cchIndent);
  792. i += wprintf(TEXT("Oper: CreateFile + GENERIC_READ; DeviceIoControl + "\
  793. TEXT("IOCTL_STORAGE_GET_DEVICE_NUMBER;\n")));
  794. _PrintElapsedTime(cchIndent, TRUE);
  795. _PrintIndent(cchIndent);
  796. i += wprintf(TEXT("STORAGE_DEVICE_NUMBER\n"));
  797. _PrintIndent(cchIndent);
  798. i += wprintf(TEXT("{\n"));
  799. i += _PrintFlag(psdn->DeviceType, _devicetypeFD, ARRAYSIZE(_devicetypeFD),
  800. cchIndent + 2, TRUE, TRUE, FALSE, FALSE);
  801. i += wprintf(TEXT(" (DEVICE_TYPE DeviceType)\n"));
  802. _PrintIndent(cchIndent + 2);
  803. i += wprintf(TEXT("%u (DWORD DeviceNumber)\n"), psdn->DeviceNumber);
  804. _PrintIndent(cchIndent + 2);
  805. i += wprintf(TEXT("%u (DWORD PartitionNumber)\n"), psdn->PartitionNumber);
  806. _PrintIndent(cchIndent);
  807. i += wprintf(TEXT("}\n"));
  808. return i;
  809. }
  810. HRESULT _IOCTLDeviceNumber(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  811. {
  812. HRESULT hres = E_FAIL;
  813. HANDLE hDevice;
  814. _StartClock();
  815. hDevice = _GetDeviceHandle(pszArg, 0);
  816. if (INVALID_HANDLE_VALUE != hDevice)
  817. {
  818. STORAGE_DEVICE_NUMBER sdn = {0};
  819. DWORD dwDummy;
  820. BOOL b = DeviceIoControl(hDevice,
  821. IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode operation to perform
  822. NULL, // lpInBuffer; must be NULL
  823. 0, // nInBufferSize; must be zero
  824. &sdn,
  825. sizeof(sdn),
  826. &dwDummy, // receives number of bytes returned
  827. NULL);
  828. _StopClock();
  829. if (b)
  830. {
  831. _PrintDeviceNumberReport(dwFlags, cchIndent, &sdn);
  832. hres = S_OK;
  833. }
  834. else
  835. {
  836. _PrintGetLastError(cchIndent);
  837. hres = E_FAIL;
  838. }
  839. CloseHandle(hDevice);
  840. }
  841. else
  842. {
  843. _PrintIndent(cchIndent);
  844. wprintf(TEXT("Cannot open device\n"));
  845. _PrintGetLastError(cchIndent);
  846. hres = E_DF_CANNOTOPENDEVICE;
  847. }
  848. return hres;
  849. }
  850. ///////////////////////////////////////////////////////////////////////////////
  851. // IOCTL_STORAGE_MCN_CONTROL
  852. HRESULT _IOCTLMCNControl(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  853. {
  854. HRESULT hres = E_FAIL;
  855. HANDLE hDevice;
  856. _StartClock();
  857. hDevice = _GetDeviceHandle(pszArg, FILE_READ_ATTRIBUTES);
  858. if (INVALID_HANDLE_VALUE != hDevice)
  859. {
  860. STORAGE_DEVICE_NUMBER sdn = {0};
  861. DWORD dwDummy;
  862. PREVENT_MEDIA_REMOVAL mediaRemoval;
  863. mediaRemoval.PreventMediaRemoval = FALSE;
  864. BOOL b = DeviceIoControl(hDevice,
  865. IOCTL_STORAGE_MCN_CONTROL, // dwIoControlCode operation to perform
  866. &mediaRemoval, // lpInBuffer; must be NULL
  867. sizeof(mediaRemoval), // nInBufferSize; must be zero
  868. NULL,
  869. 0,
  870. &dwDummy, // receives number of bytes returned
  871. NULL);
  872. _StopClock();
  873. if (b)
  874. {
  875. hres = S_OK;
  876. }
  877. else
  878. {
  879. _PrintGetLastError(cchIndent);
  880. hres = E_FAIL;
  881. }
  882. CloseHandle(hDevice);
  883. }
  884. else
  885. {
  886. _PrintIndent(cchIndent);
  887. wprintf(TEXT("Cannot open device\n"));
  888. _PrintGetLastError(cchIndent);
  889. hres = E_DF_CANNOTOPENDEVICE;
  890. }
  891. return hres;
  892. }
  893. ///////////////////////////////////////////////////////////////////////////////
  894. // IOCTL_DISK_IS_WRITABLE
  895. HRESULT _IOCTLDiskWritable(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  896. {
  897. HRESULT hres = E_FAIL;
  898. HANDLE hDevice;
  899. _StartClock();
  900. hDevice = _GetDeviceHandle(pszArg, GENERIC_READ);
  901. if (INVALID_HANDLE_VALUE != hDevice)
  902. {
  903. DWORD dwDummy;
  904. SetLastError(0);
  905. BOOL b = DeviceIoControl(hDevice,
  906. IOCTL_DISK_IS_WRITABLE, // dwIoControlCode operation to perform
  907. NULL, // lpInBuffer; must be NULL
  908. 0, // nInBufferSize; must be zero
  909. NULL, // pointer to output buffer
  910. 0, // size of output buffer
  911. &dwDummy, // receives number of bytes returned
  912. NULL);
  913. _StopClock();
  914. _PrintIndent(cchIndent);
  915. wprintf(TEXT("Oper: CreateFile + GENERIC_READ; DeviceIoControl + "\
  916. TEXT("IOCTL_DISK_IS_WRITABLE;\n")));
  917. _PrintElapsedTime(cchIndent, TRUE);
  918. _PrintIndent(cchIndent);
  919. wprintf(TEXT("Write protected: "));
  920. hres = S_OK;
  921. // Don't check return value for nothing
  922. if (ERROR_WRITE_PROTECT == GetLastError())
  923. {
  924. wprintf(L"Y\n");
  925. }
  926. else
  927. {
  928. wprintf(L"N\n");
  929. }
  930. CloseHandle(hDevice);
  931. }
  932. else
  933. {
  934. _PrintIndent(cchIndent);
  935. wprintf(TEXT("Cannot open device\n"));
  936. _PrintGetLastError(cchIndent);
  937. hres = E_DF_CANNOTOPENDEVICE;
  938. }
  939. return hres;
  940. }
  941. ///////////////////////////////////////////////////////////////////////////////
  942. // IOCTL_STORAGE_GET_MEDIA_TYPES
  943. HRESULT _IOCTLMediaTypes(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  944. {
  945. HRESULT hres = E_FAIL;
  946. HANDLE hDevice;
  947. _StartClock();
  948. hDevice = _GetDeviceHandle(pszArg, GENERIC_READ);
  949. if (INVALID_HANDLE_VALUE != hDevice)
  950. {
  951. DWORD dwDummy;
  952. BOOL b;
  953. DISK_GEOMETRY dg[12] = {0};
  954. DWORD cb = sizeof(dg);
  955. DWORD dwIoCtl;
  956. if (_IsFlagSet(IOCTL_MEDIATYPES, dwFlags))
  957. {
  958. dwIoCtl = IOCTL_STORAGE_GET_MEDIA_TYPES;
  959. }
  960. else
  961. {
  962. dwIoCtl = IOCTL_DISK_GET_MEDIA_TYPES;
  963. }
  964. b = DeviceIoControl(hDevice,
  965. dwIoCtl,
  966. NULL, // lpInBuffer; must be NULL
  967. 0, // nInBufferSize; must be zero
  968. dg,
  969. cb,
  970. &dwDummy, // receives number of bytes returned
  971. NULL);
  972. _StopClock();
  973. _PrintIndent(cchIndent);
  974. wprintf(TEXT("Oper: CreateFile + GENERIC_READ; DeviceIoControl + "\
  975. TEXT("IOCTL_STORAGE_GET_MEDIA_TYPES;\n")));
  976. _PrintElapsedTime(cchIndent, TRUE);
  977. _PrintIndent(cchIndent);
  978. if (b)
  979. {
  980. DWORD c = dwDummy / sizeof(DISK_GEOMETRY);
  981. wprintf(TEXT("Media types:\n"));
  982. for (DWORD dw = 0; dw < c; ++dw)
  983. {
  984. _PrintMediaTypeReport(dwFlags, cchIndent + 2, dg[dw].MediaType);
  985. _PrintCR();
  986. }
  987. }
  988. else
  989. {
  990. _PrintGetLastError(cchIndent);
  991. hres = E_FAIL;
  992. }
  993. CloseHandle(hDevice);
  994. }
  995. else
  996. {
  997. _PrintIndent(cchIndent);
  998. wprintf(TEXT("Cannot open device\n"));
  999. _PrintGetLastError(cchIndent);
  1000. hres = E_DF_CANNOTOPENDEVICE;
  1001. }
  1002. return hres;
  1003. }
  1004. ///////////////////////////////////////////////////////////////////////////////
  1005. // FSCTL_GET_REPARSE_POINT
  1006. HRESULT _FSCTLGetReparsePoint(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  1007. {
  1008. HRESULT hres = E_FAIL;
  1009. HANDLE hDevice;
  1010. _StartClock();
  1011. hDevice = _GetDeviceHandle(pszArg, GENERIC_READ,
  1012. FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT);
  1013. if (INVALID_HANDLE_VALUE != hDevice)
  1014. {
  1015. DWORD dwDummy;
  1016. BYTE buffer[1024];
  1017. BOOL b = DeviceIoControl(hDevice, //
  1018. FSCTL_GET_REPARSE_POINT, //
  1019. NULL,
  1020. NULL,
  1021. &buffer,
  1022. sizeof(buffer),
  1023. &dwDummy,
  1024. NULL);
  1025. _StopClock();
  1026. _PrintElapsedTime(cchIndent, TRUE);
  1027. _PrintIndent(cchIndent);
  1028. if (!b)
  1029. {
  1030. if (ERROR_MORE_DATA == GetLastError())
  1031. {
  1032. // That's OK
  1033. REPARSE_GUID_DATA_BUFFER* pb = (REPARSE_GUID_DATA_BUFFER*)&buffer;
  1034. _PrintGUID(&(pb->ReparseGuid));
  1035. hres = S_OK;
  1036. }
  1037. else
  1038. {
  1039. _PrintGetLastError(cchIndent);
  1040. hres = E_FAIL;
  1041. }
  1042. }
  1043. else
  1044. {
  1045. REPARSE_GUID_DATA_BUFFER* pb = (REPARSE_GUID_DATA_BUFFER*)&buffer;
  1046. _PrintGUID(&(pb->ReparseGuid));
  1047. hres = S_OK;
  1048. }
  1049. CloseHandle(hDevice);
  1050. }
  1051. else
  1052. {
  1053. _PrintIndent(cchIndent);
  1054. wprintf(TEXT("Cannot open device\n"));
  1055. _PrintGetLastError(cchIndent);
  1056. hres = E_DF_CANNOTOPENDEVICE;
  1057. }
  1058. return hres;
  1059. }
  1060. ///////////////////////////////////////////////////////////////////////////////
  1061. // IOCTL_DVD_READ_KEY
  1062. HRESULT _IOCTLDvd(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  1063. {
  1064. HRESULT hres = E_FAIL;
  1065. HANDLE hDevice;
  1066. _StartClock();
  1067. hDevice = _GetDeviceHandle(pszArg, GENERIC_READ);
  1068. if (INVALID_HANDLE_VALUE != hDevice)
  1069. {
  1070. DWORD dwDummy;
  1071. BOOL b;
  1072. BYTE bBuf[DVD_RPC_KEY_LENGTH];
  1073. DWORD cbBuf = DVD_RPC_KEY_LENGTH;
  1074. DVD_COPY_PROTECT_KEY* pdcpk = (DVD_COPY_PROTECT_KEY*)bBuf;
  1075. ZeroMemory(pdcpk, cbBuf);
  1076. pdcpk->KeyLength = cbBuf;
  1077. pdcpk->KeyType = DvdGetRpcKey;
  1078. b = DeviceIoControl(hDevice, //
  1079. IOCTL_DVD_READ_KEY, //
  1080. pdcpk,
  1081. cbBuf,
  1082. pdcpk,
  1083. cbBuf,
  1084. &dwDummy,
  1085. NULL);
  1086. _StopClock();
  1087. _PrintIndent(cchIndent);
  1088. wprintf(TEXT("Oper: CreateFile + GENERIC_READ; DeviceIoControl + "\
  1089. TEXT("IOCTL_DVD_READ_KEY;\n")));
  1090. _PrintElapsedTime(cchIndent, TRUE);
  1091. _PrintIndent(cchIndent);
  1092. if (b)
  1093. {
  1094. // If succeeded, DVD drive
  1095. wprintf(TEXT("Succeeded.\n"));
  1096. hres = S_OK;
  1097. }
  1098. else
  1099. {
  1100. // If fail with 1 (ERROR_INVALID_FUNCTION), then it is not a DVD drive
  1101. _PrintGetLastError(cchIndent);
  1102. hres = E_FAIL;
  1103. }
  1104. CloseHandle(hDevice);
  1105. }
  1106. else
  1107. {
  1108. _PrintIndent(cchIndent);
  1109. wprintf(TEXT("Cannot open device\n"));
  1110. _PrintGetLastError(cchIndent);
  1111. hres = E_DF_CANNOTOPENDEVICE;
  1112. }
  1113. return hres;
  1114. }
  1115. ///////////////////////////////////////////////////////////////////////////////
  1116. // IOCTL_STORAGE_GET_MEDIA_TYPES_EX
  1117. _sFLAG_DESCR _devicemediatypeFD[] =
  1118. {
  1119. FLAG_DESCR(MEDIA_ERASEABLE),
  1120. FLAG_DESCR(MEDIA_WRITE_ONCE),
  1121. FLAG_DESCR(MEDIA_READ_ONLY),
  1122. FLAG_DESCR(MEDIA_READ_WRITE),
  1123. FLAG_DESCR(MEDIA_WRITE_PROTECTED),
  1124. FLAG_DESCR(MEDIA_CURRENTLY_MOUNTED),
  1125. };
  1126. int _PrintDeviceMediaInfoReport(DWORD dwFlags[], DWORD cchIndent,
  1127. DEVICE_MEDIA_INFO* pdmi)
  1128. {
  1129. int i = 0;
  1130. // for now let's assume raw
  1131. // BUGBUG: We use DiskInfo whatever what the disk is
  1132. _PrintIndent(cchIndent);
  1133. i += wprintf(TEXT("DEVICE_MEDIA_INFO\n"));
  1134. _PrintIndent(cchIndent);
  1135. i += wprintf(TEXT("{\n"));
  1136. _PrintIndent(cchIndent + 2);
  1137. i += wprintf(TEXT("0x%08X (lo), 0x%08X (hi) (LARGE_INTEGER Cylinders)\n"),
  1138. pdmi->DeviceSpecific.DiskInfo.Cylinders.LowPart, pdmi->DeviceSpecific.DiskInfo.Cylinders.HighPart);
  1139. i += _PrintMediaTypeReport(dwFlags, cchIndent + 2, (MEDIA_TYPE)pdmi->DeviceSpecific.DiskInfo.MediaType);
  1140. i += wprintf(TEXT(" (MEDIA_TYPE MediaType)\n"));
  1141. _PrintIndent(cchIndent + 2);
  1142. i += wprintf(TEXT("%u (DWORD TracksPerCylinder)\n"), pdmi->DeviceSpecific.DiskInfo.TracksPerCylinder);
  1143. _PrintIndent(cchIndent + 2);
  1144. i += wprintf(TEXT("%u (DWORD SectorsPerTrack)\n"), pdmi->DeviceSpecific.DiskInfo.SectorsPerTrack);
  1145. _PrintIndent(cchIndent + 2);
  1146. i += wprintf(TEXT("%u (DWORD BytesPerSector)\n"), pdmi->DeviceSpecific.DiskInfo.BytesPerSector);
  1147. _PrintIndent(cchIndent + 2);
  1148. i += wprintf(TEXT("%u (DWORD NumberMediaSides)\n"), pdmi->DeviceSpecific.DiskInfo.NumberMediaSides);
  1149. _PrintIndent(cchIndent + 2);
  1150. i += wprintf(TEXT("(DWORD MediaCharacteristics):\n"));
  1151. i += _PrintFlag(pdmi->DeviceSpecific.DiskInfo.MediaCharacteristics, _devicemediatypeFD,
  1152. ARRAYSIZE(_devicemediatypeFD), cchIndent + 4, TRUE, TRUE, FALSE, TRUE);
  1153. _PrintCR();
  1154. _PrintIndent(cchIndent);
  1155. i += wprintf(TEXT("}\n"));
  1156. return i;
  1157. }
  1158. HRESULT _IOCTLMediaTypesEx(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  1159. {
  1160. HRESULT hres = E_FAIL;
  1161. HANDLE hDevice;
  1162. _StartClock();
  1163. hDevice = _GetDeviceHandle(pszArg, GENERIC_READ);
  1164. if (INVALID_HANDLE_VALUE != hDevice)
  1165. {
  1166. DWORD dwDummy;
  1167. BOOL b;
  1168. BYTE bBuf[8192];
  1169. b = DeviceIoControl(hDevice,
  1170. IOCTL_STORAGE_GET_MEDIA_TYPES_EX,
  1171. NULL,
  1172. 0,
  1173. bBuf,
  1174. sizeof(bBuf),
  1175. &dwDummy,
  1176. NULL);
  1177. _StopClock();
  1178. _PrintIndent(cchIndent);
  1179. wprintf(TEXT("Oper: CreateFile + GENERIC_READ; DeviceIoControl + "\
  1180. TEXT("IOCTL_STORAGE_GET_MEDIA_TYPES_EX;\n")));
  1181. _PrintElapsedTime(cchIndent, TRUE);
  1182. _PrintIndent(cchIndent);
  1183. wprintf(TEXT("Media types:\n"));
  1184. if (b)
  1185. {
  1186. GET_MEDIA_TYPES* pgmt = (GET_MEDIA_TYPES*)bBuf;
  1187. DEVICE_MEDIA_INFO* pMediaInfo = pgmt->MediaInfo;
  1188. DWORD cMediaInfo = pgmt->MediaInfoCount;
  1189. for (DWORD dw = 0; dw < cMediaInfo; ++dw)
  1190. {
  1191. pMediaInfo += dw;
  1192. _PrintDeviceMediaInfoReport(dwFlags, cchIndent, pMediaInfo);
  1193. _PrintCR();
  1194. }
  1195. hres = S_OK;
  1196. }
  1197. else
  1198. {
  1199. _PrintGetLastError(cchIndent);
  1200. hres = E_FAIL;
  1201. }
  1202. CloseHandle(hDevice);
  1203. }
  1204. else
  1205. {
  1206. _PrintIndent(cchIndent);
  1207. wprintf(TEXT("Cannot open device\n"));
  1208. _PrintGetLastError(cchIndent);
  1209. hres = E_DF_CANNOTOPENDEVICE;
  1210. }
  1211. return hres;
  1212. }
  1213. ///////////////////////////////////////////////////////////////////////////////
  1214. //
  1215. typedef HRESULT (*_IOCTLHANDLER)(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent);
  1216. struct _sIOCtlHandler
  1217. {
  1218. DWORD dwFlag;
  1219. _IOCTLHANDLER ioctlhandler;
  1220. };
  1221. _sIOCtlHandler _ioctlhandlers[] =
  1222. {
  1223. { IOCTL_LAYOUT, _IOCTLLayout },
  1224. { IOCTL_GEOMETRY, _IOCTLGeometry },
  1225. { IOCTL_PARTITION, _IOCTLPartition },
  1226. { IOCTL_PARTITIONSURE, _IOCTLPartition },
  1227. { IOCTL_PARTITIONGPT, _IOCTLPartitionGPT },
  1228. { IOCTL_MEDIAACCESSIBLE, _IOCTLCheckVerify },
  1229. { IOCTL_DISKISWRITABLE, _IOCTLDiskWritable },
  1230. { IOCTL_VOLUMENUMBER, _IOCTLDeviceNumber },
  1231. { IOCTL_MEDIATYPES, _IOCTLMediaTypes },
  1232. { IOCTL_MEDIATYPESEX, _IOCTLMediaTypesEx },
  1233. { IOCTL_DVD, _IOCTLDvd },
  1234. { IOCTL_EJECT, _IOCTLEject },
  1235. { IOCTL_MCNCONTROL, _IOCTLMCNControl },
  1236. { IOCTL_GETREPARSEPOINT, _FSCTLGetReparsePoint },
  1237. { IOCTL_CDROMGETCONFIGMMC2, _IOCTLCDROMGetConfig },
  1238. { IOCTL_CDROMGETCONFIGDVDRAM, _IOCTLCDROMGetConfig },
  1239. { IOCTL_CDROMGETCONFIGRW, _IOCTLCDROMGetConfig },
  1240. { IOCTL_CDROMGETCONFIGWO, _IOCTLCDROMGetConfig },
  1241. { IOCTL_CDROMGETCONFIGISW, _IOCTLCDROMGetConfig },
  1242. { IOCTL_CDROMGETCONFIGALL, _IOCTLCDROMGetConfigListAll },
  1243. };
  1244. HRESULT _ProcessIOCTL(DWORD dwFlags[], LPTSTR pszArg, DWORD cchIndent)
  1245. {
  1246. HRESULT hres = E_INVALIDARG;
  1247. for (DWORD dw = 0; dw < ARRAYSIZE(_ioctlhandlers); ++dw)
  1248. {
  1249. if (_IsFlagSet(_ioctlhandlers[dw].dwFlag, dwFlags))
  1250. {
  1251. hres = (*(_ioctlhandlers[dw].ioctlhandler))(dwFlags, pszArg,
  1252. cchIndent);
  1253. }
  1254. }
  1255. return hres;
  1256. }
  1257. /*
  1258. driveLayout->PartitionCount = MAX_PARTITIONS;
  1259. driveLayoutSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
  1260. (MAX_PARTITIONS * sizeof(PARTITION_INFORMATION));
  1261. driveLayout->Signature = 2196277081;
  1262. bytesPerTrack = diskGeometry.SectorsPerTrack *
  1263. diskGeometry.BytesPerSector;
  1264. bytesPerCylinder = diskGeometry.TracksPerCylinder *
  1265. bytesPerTrack;
  1266. partInfo = &driveLayout->PartitionEntry[0];
  1267. partLength.QuadPart = bytesPerCylinder * diskGeometry.Cylinders.QuadPart;
  1268. //
  1269. // The partition offset is 1 track (in bytes).
  1270. // Size is media_size - offset, rounded down to cylinder boundary.
  1271. //
  1272. partOffset.QuadPart = bytesPerTrack;
  1273. partSize.QuadPart = partLength.QuadPart - partOffset.QuadPart;
  1274. modulo.QuadPart = (partOffset.QuadPart + partSize.QuadPart) %
  1275. bytesPerCylinder;
  1276. partSize.QuadPart -= modulo.QuadPart;
  1277. partInfo = driveLayout->PartitionEntry;
  1278. //
  1279. // Initialize first partition entry.
  1280. //
  1281. partInfo->RewritePartition = TRUE;
  1282. partInfo->PartitionType = PARTITION_IFS;
  1283. partInfo->BootIndicator = FALSE;
  1284. partInfo->StartingOffset.QuadPart = partOffset.QuadPart;
  1285. partInfo->PartitionLength.QuadPart = partSize.QuadPart;
  1286. partInfo->HiddenSectors = 0;
  1287. partInfo->PartitionNumber = 1;
  1288. //
  1289. // For now the remaining partition entries are unused.
  1290. //
  1291. for ( index = 1; index < driveLayout->PartitionCount; index++ ) {
  1292. partInfo = &driveLayout->PartitionEntry[index];
  1293. partInfo->PartitionType = PARTITION_ENTRY_UNUSED;
  1294. partInfo->RewritePartition = TRUE;
  1295. partInfo->BootIndicator = FALSE;
  1296. partInfo->StartingOffset.QuadPart = 0;
  1297. partInfo->PartitionLength.QuadPart = 0;
  1298. partInfo->HiddenSectors = 0;
  1299. partInfo->PartitionNumber = 0;
  1300. }
  1301. */
  1302. /*
  1303. ++
  1304. Copyright (c) 1999 Microsoft Corporation
  1305. Module Name:
  1306. ntddfuji.c
  1307. --
  1308. #include "getfeatures.h"
  1309. #define NTDDFUJI_VERSION 3 // the version this file is based off of
  1310. FUJI_STRING_INFO ProfileStrings[13] = {
  1311. { ProfileInvalid, "ProfileInvalid" },
  1312. { ProfileNonRemovableDisk, "Non-Removable Disk" },
  1313. { ProfileRemovableDisk, "Removable Disk" },
  1314. { ProfileMOErasable, "Magneto-Optical Erasable" },
  1315. { ProfileMOWriteOnce, "Magneto-Optical Write-Once" },
  1316. { ProfileAS_MO, "AS Mageto-Optical" },
  1317. { ProfileCdrom, "CD-Rom" },
  1318. { ProfileCdRecordable, "CD Recordable" },
  1319. { ProfileCdRewritable, "CD Rewritable" },
  1320. { ProfileDvdRom, "DVD-Rom" },
  1321. { ProfileDvdRecordable, "DVD-Recordable" },
  1322. { ProfileDvdRam, "DVD-RAM" },
  1323. { ProfileNonStandard, "NonStandard Profile" }
  1324. };
  1325. FUJI_STRING_INFO FeatureStrings[28] = {
  1326. { FeatureProfileList , "Profile List" },
  1327. { FeatureCore , "Core" },
  1328. { FeatureMorphing , "Morphing" },
  1329. { FeatureRemovableMedium , "Removable Medium" },
  1330. { FeatureRandomReadable , "Random Readable" },
  1331. { FeatureMultiRead , "MultiRead" },
  1332. { FeatureCdRead , "CD Read" },
  1333. { FeatureDvdRead , "DVD Read" },
  1334. { FeatureRandomWritable , "Random Writable" },
  1335. { FeatureIncrementalStreamingWritable , "Incremental Stream Writing" },
  1336. { FeatureSectorErasable , "Sector Erasable" },
  1337. { FeatureFormattable , "Formattable" },
  1338. { FeatureDefectManagement , "Defect Management" },
  1339. { FeatureWriteOnce , "Write Once" },
  1340. { FeatureRestrictedOverwrite , "Restricted Overwrite" },
  1341. { FeatureCdTrackAtOnce , "CD Track-At-Once" },
  1342. { FeatureCdMastering , "CD Mastering" },
  1343. { FeatureDvdRecordableWrite , "DVD Recordable Writing" },
  1344. { FeaturePowerManagement , "Power Management" },
  1345. { FeatureSMART , "S.M.A.R.T." },
  1346. { FeatureEmbeddedChanger , "Embedded Changer" },
  1347. { FeatureCDAudioAnalogPlay , "CD Audio Analog Playback" },
  1348. { FeatureMicrocodeUpgrade , "Microcode Upgrade" },
  1349. { FeatureTimeout , "Timeout" },
  1350. { FeatureDvdCSS , "DVD CSS" },
  1351. { FeatureRealTimeStreaming , "Real-Time Streaming" },
  1352. { FeatureLogicalUnitSerialNumber , "Logical Unit Serial Number" },
  1353. { FeatureDiscControlBlocks , "Disc Control Blocks" }
  1354. };
  1355. FEATURE_PAGE_LIST RequiredFeaturePagesNonRemovableDisk = {
  1356. FeatureCore,
  1357. FeatureRandomReadable,
  1358. FeatureRandomWritable,
  1359. FeatureDefectManagement,
  1360. FeaturePowerManagement,
  1361. FeatureSMART,
  1362. FeatureProfileList
  1363. };
  1364. FEATURE_PAGE_LIST RequiredFeaturePagesRemovableDisk = {
  1365. FeatureCore,
  1366. FeatureMorphing,
  1367. FeatureRemovableMedium,
  1368. FeatureRandomReadable,
  1369. FeatureRandomWritable,
  1370. FeatureFormattable,
  1371. FeatureDefectManagement,
  1372. FeaturePowerManagement,
  1373. FeatureTimeout,
  1374. FeatureProfileList
  1375. };
  1376. FEATURE_PAGE_LIST RequiredFeaturePagesMOErasable = {
  1377. FeatureCore,
  1378. FeatureMorphing,
  1379. FeatureRemovableMedium,
  1380. FeatureRandomReadable,
  1381. FeatureRandomWritable,
  1382. FeatureSectorErasable,
  1383. FeatureFormattable,
  1384. FeatureDefectManagement,
  1385. FeaturePowerManagement,
  1386. FeatureTimeout,
  1387. FeatureProfileList
  1388. };
  1389. FEATURE_PAGE_LIST RequiredFeaturePagesMOWriteOnce = {
  1390. FeatureCore,
  1391. FeatureMorphing,
  1392. FeatureRemovableMedium,
  1393. FeatureRandomReadable,
  1394. FeatureDefectManagement,
  1395. FeatureWriteOnce,
  1396. FeaturePowerManagement,
  1397. FeatureTimeout,
  1398. FeatureProfileList
  1399. };
  1400. FEATURE_PAGE_LIST RequiredFeaturePagesAS_MO = {
  1401. FeatureCore,
  1402. FeatureMorphing,
  1403. FeatureRemovableMedium,
  1404. FeatureRandomReadable,
  1405. FeatureRandomWritable,
  1406. FeatureFormattable,
  1407. FeatureDefectManagement,
  1408. FeaturePowerManagement,
  1409. FeatureTimeout,
  1410. FeatureRealTimeStreaming,
  1411. FeatureProfileList
  1412. };
  1413. FEATURE_PAGE_LIST RequiredFeaturePagesCdrom = {
  1414. FeatureCore,
  1415. FeatureMorphing,
  1416. FeatureRemovableMedium,
  1417. FeatureRandomReadable,
  1418. FeatureCdRead,
  1419. FeaturePowerManagement,
  1420. FeatureTimeout,
  1421. FeatureProfileList
  1422. };
  1423. FEATURE_PAGE_LIST RequiredFeaturePagesCdRecordable = {
  1424. FeatureCore,
  1425. FeatureMorphing,
  1426. FeatureRemovableMedium,
  1427. FeatureRandomReadable,
  1428. FeatureCdRead,
  1429. FeatureIncrementalStreamingWritable,
  1430. FeatureCdTrackAtOnce,
  1431. FeaturePowerManagement,
  1432. FeatureTimeout,
  1433. FeatureRealTimeStreaming,
  1434. FeatureProfileList
  1435. };
  1436. FEATURE_PAGE_LIST RequiredFeaturePagesCdRewritable = {
  1437. FeatureCore,
  1438. FeatureMorphing,
  1439. FeatureRemovableMedium,
  1440. FeatureRandomReadable,
  1441. FeatureMultiRead,
  1442. FeatureCdRead,
  1443. FeatureIncrementalStreamingWritable,
  1444. FeatureFormattable,
  1445. FeatureRestrictedOverwrite,
  1446. FeatureCdTrackAtOnce,
  1447. FeaturePowerManagement,
  1448. FeatureTimeout,
  1449. FeatureRealTimeStreaming,
  1450. FeatureProfileList
  1451. };
  1452. FEATURE_PAGE_LIST RequiredFeaturePagesDvdRom = {
  1453. FeatureCore,
  1454. FeatureMorphing,
  1455. FeatureRemovableMedium,
  1456. FeatureRandomReadable,
  1457. FeatureDvdRead,
  1458. FeaturePowerManagement,
  1459. FeatureTimeout,
  1460. FeatureRealTimeStreaming,
  1461. FeatureProfileList
  1462. };
  1463. FEATURE_PAGE_LIST RequiredFeaturePagesDvdRecordable = {
  1464. FeatureCore,
  1465. FeatureMorphing,
  1466. FeatureRemovableMedium,
  1467. FeatureRandomReadable,
  1468. FeatureDvdRead,
  1469. FeatureIncrementalStreamingWritable,
  1470. FeatureDvdRecordableWrite,
  1471. FeaturePowerManagement,
  1472. FeatureTimeout,
  1473. FeatureRealTimeStreaming,
  1474. FeatureLogicalUnitSerialNumber,
  1475. FeatureProfileList
  1476. };
  1477. FEATURE_PAGE_LIST RequiredFeaturePagesDvdRam = {
  1478. FeatureCore,
  1479. FeatureMorphing,
  1480. FeatureRemovableMedium,
  1481. FeatureRandomReadable,
  1482. FeatureDvdRead,
  1483. FeatureRandomWritable,
  1484. FeatureFormattable,
  1485. FeatureDefectManagement,
  1486. FeaturePowerManagement,
  1487. FeatureTimeout,
  1488. FeatureRealTimeStreaming,
  1489. FeatureProfileList
  1490. };
  1491. FUJI_REQUIRED_FEATURE_PAGES const RequiredFeaturePages[] = {
  1492. { ProfileNonRemovableDisk, &RequiredFeaturePagesNonRemovableDisk },
  1493. { ProfileRemovableDisk, &RequiredFeaturePagesRemovableDisk },
  1494. { ProfileMOErasable, &RequiredFeaturePagesMOErasable },
  1495. { ProfileMOWriteOnce, &RequiredFeaturePagesMOWriteOnce },
  1496. { ProfileAS_MO, &RequiredFeaturePagesAS_MO },
  1497. { ProfileCdrom, &RequiredFeaturePagesCdrom },
  1498. { ProfileCdRecordable, &RequiredFeaturePagesCdRecordable },
  1499. { ProfileCdRewritable, &RequiredFeaturePagesCdRewritable },
  1500. { ProfileDvdRom, &RequiredFeaturePagesDvdRom },
  1501. { ProfileDvdRecordable, &RequiredFeaturePagesDvdRecordable },
  1502. { ProfileDvdRam, &RequiredFeaturePagesDvdRam },
  1503. { 0, NULL }
  1504. };
  1505. */