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.

600 lines
17 KiB

  1. #include <nt.h>
  2. #include <ntddscsi.h>
  3. #include <ntdddisk.h>
  4. #include <ntddcdrm.h>
  5. #include <ntrtl.h>
  6. #include <nturtl.h>
  7. #include <windows.h>
  8. #include <stdio.h>
  9. #include <process.h>
  10. #include <memory.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #define _NTSCSI_USER_MODE_
  15. #include <scsi.h>
  16. VOID
  17. GetDriverName(
  18. IN ULONG PortNumber
  19. )
  20. {
  21. UNICODE_STRING name;
  22. UNICODE_STRING unicodeString;
  23. ANSI_STRING ansiString;
  24. HANDLE key;
  25. HANDLE portKey;
  26. OBJECT_ATTRIBUTES objectAttributes;
  27. NTSTATUS status;
  28. UCHAR buffer[64];
  29. ULONG length;
  30. PKEY_VALUE_FULL_INFORMATION keyData = (PKEY_VALUE_FULL_INFORMATION)buffer;
  31. printf("\nSCSI PORT %d\n", PortNumber);
  32. //
  33. // Obtain handle to SCSI path in device map.
  34. //
  35. RtlInitUnicodeString(&name,
  36. L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
  37. //
  38. // Initialize the object for the key.
  39. //
  40. InitializeObjectAttributes(&objectAttributes,
  41. &name,
  42. OBJ_CASE_INSENSITIVE,
  43. NULL,
  44. (PSECURITY_DESCRIPTOR) NULL);
  45. //
  46. // Open the key.
  47. //
  48. status = NtOpenKey(&key,
  49. KEY_READ,
  50. &objectAttributes);
  51. if (!NT_SUCCESS(status)) {
  52. return;
  53. }
  54. //
  55. // Create Scsi port name.
  56. //
  57. sprintf(buffer,
  58. "Scsi Port %d",
  59. PortNumber);
  60. RtlInitString(&ansiString, buffer);
  61. status = RtlAnsiStringToUnicodeString(&unicodeString,
  62. &ansiString,
  63. TRUE);
  64. if (!NT_SUCCESS(status)) {
  65. return;
  66. }
  67. InitializeObjectAttributes( &objectAttributes,
  68. &unicodeString,
  69. OBJ_CASE_INSENSITIVE,
  70. key,
  71. (PSECURITY_DESCRIPTOR) NULL );
  72. status = NtOpenKey(&portKey,
  73. KEY_READ,
  74. &objectAttributes);
  75. if (!NT_SUCCESS(status)) {
  76. return;
  77. }
  78. RtlInitUnicodeString(&name,
  79. L"Driver");
  80. status = NtQueryValueKey(portKey,
  81. &name,
  82. KeyValueFullInformation,
  83. keyData,
  84. 64,
  85. &length);
  86. if (!NT_SUCCESS(status)) {
  87. return;
  88. }
  89. printf("Driver name: %S\n",
  90. (PUCHAR)keyData + keyData->DataOffset);
  91. RtlInitUnicodeString(&name,
  92. L"Interrupt");
  93. status = NtQueryValueKey(portKey,
  94. &name,
  95. KeyValueFullInformation,
  96. keyData,
  97. 64,
  98. &length);
  99. if (!NT_SUCCESS(status)) {
  100. return;
  101. }
  102. printf("IRQ %d ",
  103. *((PUCHAR)keyData + keyData->DataOffset));
  104. RtlInitUnicodeString(&name,
  105. L"IOAddress");
  106. status = NtQueryValueKey(portKey,
  107. &name,
  108. KeyValueFullInformation,
  109. keyData,
  110. 64,
  111. &length);
  112. if (!NT_SUCCESS(status)) {
  113. printf("\n");
  114. return;
  115. }
  116. printf("IO Address %x\n",
  117. *((PULONG)keyData + keyData->DataOffset/4));
  118. return;
  119. }
  120. int __cdecl
  121. main( int argc, char **argv )
  122. {
  123. BYTE buffer[32];
  124. HANDLE volumeHandle;
  125. STRING string;
  126. UNICODE_STRING unicodeString;
  127. OBJECT_ATTRIBUTES objectAttributes;
  128. NTSTATUS ntStatus;
  129. IO_STATUS_BLOCK statusBlock;
  130. ULONG portNumber = 0;
  131. PSCSI_ADAPTER_BUS_INFO adapterInfo;
  132. PSCSI_BUS_DATA busData;
  133. PSCSI_INQUIRY_DATA inquiryData;
  134. UCHAR prevDeviceInquiryData[INQUIRYDATABUFFERSIZE];
  135. PINQUIRYDATA deviceInquiryData;
  136. ULONG bytesTransferred, i, j;
  137. ULONG deviceNumber;
  138. BOOLEAN newDisk = FALSE;
  139. BOOLEAN newCdrom = FALSE;
  140. UCHAR prevPathId;
  141. UCHAR prevTargetId;
  142. UCHAR prevLun;
  143. BOOLEAN prevDeviceClaimed;
  144. BOOLEAN listAdapters = FALSE;
  145. BOOLEAN allAdapters = TRUE;
  146. UCHAR lunExtra;
  147. if(argc == 2) {
  148. if(argv[1][0] == '*') {
  149. listAdapters = TRUE;
  150. } else {
  151. portNumber = atoi(argv[1]);
  152. allAdapters = FALSE;
  153. }
  154. }
  155. printf("\nWindows NT SCSI Bus Rescan Version 1.1\n");
  156. if(listAdapters) {
  157. printf("[only listing adapters]\n");
  158. } else if(allAdapters) {
  159. printf("[scanning all adapters]\n");
  160. } else {
  161. printf("[scanning adapter %d only]\n", portNumber);
  162. }
  163. while (TRUE) {
  164. memset( buffer, 0, sizeof( buffer ) );
  165. sprintf( buffer,
  166. "\\\\.\\Scsi%d:",
  167. portNumber);
  168. //
  169. // Open the volume with the DOS name.
  170. //
  171. volumeHandle = CreateFile( buffer,
  172. GENERIC_READ,
  173. FILE_SHARE_READ | FILE_SHARE_WRITE,
  174. NULL,
  175. OPEN_EXISTING,
  176. 0,
  177. 0 );
  178. if( volumeHandle == INVALID_HANDLE_VALUE ) {
  179. break;
  180. }
  181. if(listAdapters) {
  182. GetDriverName(portNumber);
  183. portNumber++;
  184. CloseHandle(volumeHandle);
  185. continue;
  186. }
  187. //
  188. // Issue rescan device control.
  189. //
  190. if( !DeviceIoControl( volumeHandle,
  191. IOCTL_SCSI_RESCAN_BUS,
  192. NULL,
  193. 0,
  194. NULL,
  195. 0,
  196. &bytesTransferred,
  197. NULL ) ) {
  198. printf( "Rescan SCSI port %d failed [Error %d].\n", portNumber, GetLastError() );
  199. CloseHandle( volumeHandle );
  200. exit(4);
  201. }
  202. //
  203. // Get a big chuck of memory to store the SCSI bus data.
  204. //
  205. adapterInfo = malloc( 0x1000 );
  206. if (adapterInfo == NULL) {
  207. printf( "Can't allocate memory for bus data\n" );
  208. CloseHandle( volumeHandle );
  209. exit(4);
  210. }
  211. //
  212. // Issue device control to get configuration information.
  213. //
  214. if (!DeviceIoControl( volumeHandle,
  215. IOCTL_SCSI_GET_INQUIRY_DATA,
  216. NULL,
  217. 0,
  218. adapterInfo,
  219. 0x1000,
  220. &bytesTransferred,
  221. NULL)) {
  222. printf( "Get SCSI bus data failed [Error %d].\n", GetLastError() );
  223. CloseHandle( volumeHandle );
  224. exit(4);
  225. }
  226. GetDriverName(portNumber);
  227. //
  228. // Display devices on buses.
  229. //
  230. for (i=0; i < adapterInfo->NumberOfBuses; i++) {
  231. busData = &adapterInfo->BusData[i];
  232. printf( "\nBus TID LUN In use Type Vendor FW Rev Advanced SCSI\n" );
  233. printf( "===============================================================================\n" );
  234. printf("%2d %2d %2d %2d Initiator",
  235. i,
  236. busData->InitiatorBusId & 0x7,
  237. 0,
  238. 1);
  239. inquiryData =
  240. (PSCSI_INQUIRY_DATA)((PUCHAR)adapterInfo + busData->InquiryDataOffset);
  241. memset(&prevDeviceInquiryData, 0, INQUIRYDATABUFFERSIZE);
  242. prevPathId = 0xFF;
  243. prevTargetId = 0xFF;
  244. prevLun = 0xFF;
  245. prevDeviceClaimed = 0xFF;
  246. for (j=0; j<busData->NumberOfLogicalUnits; j++) {
  247. int k;
  248. //
  249. // Make sure VendorId string is null terminated.
  250. //
  251. deviceInquiryData = (PINQUIRYDATA)&inquiryData->InquiryData[0];
  252. deviceInquiryData->VendorSpecific[0] = '\0';
  253. if (prevPathId != inquiryData->PathId ||
  254. prevTargetId != inquiryData->TargetId ||
  255. prevLun != (inquiryData->Lun-1) ||
  256. prevDeviceClaimed != inquiryData->DeviceClaimed ||
  257. memcmp( &prevDeviceInquiryData, deviceInquiryData, INQUIRYDATABUFFERSIZE)
  258. ) {
  259. lunExtra = 0;
  260. printf("\n%2d %2d %2d %2d ",
  261. inquiryData->PathId,
  262. inquiryData->TargetId,
  263. inquiryData->Lun,
  264. inquiryData->DeviceClaimed);
  265. } else {
  266. lunExtra += 1;
  267. printf("\r%2d %2d %2d-%1d %2d ",
  268. inquiryData->PathId,
  269. inquiryData->TargetId,
  270. inquiryData->Lun-lunExtra,
  271. inquiryData->Lun,
  272. inquiryData->DeviceClaimed);
  273. }
  274. prevPathId = inquiryData->PathId;
  275. prevTargetId = inquiryData->TargetId;
  276. prevLun = inquiryData->Lun;
  277. prevDeviceClaimed = inquiryData->DeviceClaimed;
  278. memmove( &prevDeviceInquiryData, deviceInquiryData, INQUIRYDATABUFFERSIZE);
  279. //
  280. // Determine the perpherial type.
  281. //
  282. switch (deviceInquiryData->DeviceType) {
  283. case DIRECT_ACCESS_DEVICE:
  284. if (!inquiryData->DeviceClaimed) {
  285. newDisk = TRUE;
  286. }
  287. printf("Disk Drive ");
  288. break;
  289. case SEQUENTIAL_ACCESS_DEVICE:
  290. printf("Tape Drive ");
  291. break;
  292. case PRINTER_DEVICE:
  293. printf("Printer ");
  294. break;
  295. case WRITE_ONCE_READ_MULTIPLE_DEVICE:
  296. printf("Worm Drive ");
  297. break;
  298. case READ_ONLY_DIRECT_ACCESS_DEVICE:
  299. if (!inquiryData->DeviceClaimed) {
  300. newCdrom = TRUE;
  301. }
  302. printf("CdRom Drive");
  303. break;
  304. case SCANNER_DEVICE:
  305. printf("Scanner ");
  306. break;
  307. case OPTICAL_DEVICE:
  308. if (!inquiryData->DeviceClaimed) {
  309. newDisk = TRUE;
  310. }
  311. printf("OpticalDisk");
  312. break;
  313. case MEDIUM_CHANGER:
  314. printf("MediumChanger");
  315. break;
  316. case COMMUNICATION_DEVICE:
  317. printf("Communication");
  318. break;
  319. default:
  320. printf("OtherPeripheral");
  321. }
  322. //
  323. // Display product information.
  324. //
  325. printf(" %s", deviceInquiryData->VendorId);
  326. //
  327. // Display SCSI capabilities.
  328. //
  329. printf(" ");
  330. if (deviceInquiryData->Synchronous) {
  331. printf(" SN");
  332. }
  333. if (deviceInquiryData->CommandQueue) {
  334. printf(" CQ");
  335. }
  336. if (deviceInquiryData->Wide16Bit) {
  337. printf(" W16");
  338. }
  339. if (deviceInquiryData->Wide32Bit) {
  340. printf(" W32");
  341. }
  342. if (deviceInquiryData->SoftReset) {
  343. printf(" SR");
  344. }
  345. if (deviceInquiryData->LinkedCommands) {
  346. printf(" LC");
  347. }
  348. if (deviceInquiryData->RelativeAddressing) {
  349. printf(" RA");
  350. }
  351. if (deviceInquiryData->DeviceTypeQualifier != DEVICE_QUALIFIER_ACTIVE) {
  352. printf(" DQ%d", deviceInquiryData->DeviceTypeQualifier);
  353. }
  354. printf("\n [ ");
  355. for(k = 0; k < 8; k++) {
  356. printf("%02x ", ((PUCHAR) deviceInquiryData)[k]);
  357. }
  358. printf("]");
  359. //
  360. // Get next device data.
  361. //
  362. inquiryData =
  363. (PSCSI_INQUIRY_DATA)((PUCHAR)adapterInfo + inquiryData->NextInquiryDataOffset);
  364. }
  365. printf("\n");
  366. }
  367. free (adapterInfo);
  368. if(allAdapters) {
  369. CloseHandle( volumeHandle );
  370. portNumber++;
  371. } else {
  372. break;
  373. }
  374. }
  375. if (newDisk) {
  376. //
  377. // Send IOCTL_DISK_FIND_NEW_DEVICES commands to each existing disk.
  378. //
  379. deviceNumber = 0;
  380. while (TRUE) {
  381. memset(buffer, 0, sizeof(buffer));
  382. sprintf(buffer,
  383. "\\Device\\Harddisk%d\\Partition0",
  384. deviceNumber);
  385. RtlInitString(&string,
  386. buffer);
  387. ntStatus = RtlAnsiStringToUnicodeString(&unicodeString,
  388. &string,
  389. TRUE);
  390. if (!NT_SUCCESS(ntStatus)) {
  391. continue;
  392. }
  393. InitializeObjectAttributes(&objectAttributes,
  394. &unicodeString,
  395. 0,
  396. NULL,
  397. NULL);
  398. ntStatus = NtOpenFile(&volumeHandle,
  399. FILE_READ_DATA |
  400. FILE_WRITE_DATA |
  401. SYNCHRONIZE,
  402. &objectAttributes,
  403. &statusBlock,
  404. FILE_SHARE_READ |
  405. FILE_SHARE_WRITE,
  406. FILE_SYNCHRONOUS_IO_ALERT);
  407. if (!NT_SUCCESS(ntStatus)) {
  408. break;
  409. }
  410. //
  411. // Issue find device device control.
  412. //
  413. if (DeviceIoControl( volumeHandle,
  414. IOCTL_DISK_FIND_NEW_DEVICES,
  415. NULL,
  416. 0,
  417. NULL,
  418. 0,
  419. &bytesTransferred,
  420. NULL ) ) {
  421. printf( "Found new disk (%d)\n", deviceNumber );
  422. }
  423. CloseHandle( volumeHandle );
  424. deviceNumber++;
  425. }
  426. }
  427. if (newCdrom) {
  428. //
  429. // Send IOCTL_CDROM_FIND_NEW_DEVICES commands to each existing cdrom.
  430. //
  431. deviceNumber = 0;
  432. while (TRUE) {
  433. memset(buffer, 0, sizeof(buffer));
  434. sprintf(buffer,
  435. "\\Device\\Cdrom%d",
  436. deviceNumber);
  437. RtlInitString(&string,
  438. buffer);
  439. ntStatus = RtlAnsiStringToUnicodeString(&unicodeString,
  440. &string,
  441. TRUE);
  442. if (!NT_SUCCESS(ntStatus)) {
  443. continue;
  444. }
  445. InitializeObjectAttributes(&objectAttributes,
  446. &unicodeString,
  447. 0,
  448. NULL,
  449. NULL);
  450. ntStatus = NtOpenFile(&volumeHandle,
  451. FILE_READ_DATA |
  452. FILE_WRITE_DATA |
  453. SYNCHRONIZE,
  454. &objectAttributes,
  455. &statusBlock,
  456. FILE_SHARE_READ |
  457. FILE_SHARE_WRITE,
  458. FILE_SYNCHRONOUS_IO_ALERT);
  459. if (!NT_SUCCESS(ntStatus)) {
  460. break;
  461. }
  462. //
  463. // Issue find device device control.
  464. //
  465. if (DeviceIoControl( volumeHandle,
  466. IOCTL_CDROM_FIND_NEW_DEVICES,
  467. NULL,
  468. 0,
  469. NULL,
  470. 0,
  471. &bytesTransferred,
  472. NULL ) ) {
  473. printf( "Found new cdrom (%d)\n", deviceNumber );
  474. }
  475. CloseHandle( volumeHandle );
  476. deviceNumber++;
  477. }
  478. }
  479. return(0);
  480. }