#include #include #include #include #include #include #include #include #include #include #include #include #include #define _NTSCSI_USER_MODE_ #include VOID GetDriverName( IN ULONG PortNumber ) { UNICODE_STRING name; UNICODE_STRING unicodeString; ANSI_STRING ansiString; HANDLE key; HANDLE portKey; OBJECT_ATTRIBUTES objectAttributes; NTSTATUS status; UCHAR buffer[64]; ULONG length; PKEY_VALUE_FULL_INFORMATION keyData = (PKEY_VALUE_FULL_INFORMATION)buffer; printf("\nSCSI PORT %d\n", PortNumber); // // Obtain handle to SCSI path in device map. // RtlInitUnicodeString(&name, L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi"); // // Initialize the object for the key. // InitializeObjectAttributes(&objectAttributes, &name, OBJ_CASE_INSENSITIVE, NULL, (PSECURITY_DESCRIPTOR) NULL); // // Open the key. // status = NtOpenKey(&key, KEY_READ, &objectAttributes); if (!NT_SUCCESS(status)) { return; } // // Create Scsi port name. // sprintf(buffer, "Scsi Port %d", PortNumber); RtlInitString(&ansiString, buffer); status = RtlAnsiStringToUnicodeString(&unicodeString, &ansiString, TRUE); if (!NT_SUCCESS(status)) { return; } InitializeObjectAttributes( &objectAttributes, &unicodeString, OBJ_CASE_INSENSITIVE, key, (PSECURITY_DESCRIPTOR) NULL ); status = NtOpenKey(&portKey, KEY_READ, &objectAttributes); if (!NT_SUCCESS(status)) { return; } RtlInitUnicodeString(&name, L"Driver"); status = NtQueryValueKey(portKey, &name, KeyValueFullInformation, keyData, 64, &length); if (!NT_SUCCESS(status)) { return; } printf("Driver name: %S\n", (PUCHAR)keyData + keyData->DataOffset); RtlInitUnicodeString(&name, L"Interrupt"); status = NtQueryValueKey(portKey, &name, KeyValueFullInformation, keyData, 64, &length); if (!NT_SUCCESS(status)) { return; } printf("IRQ %d ", *((PUCHAR)keyData + keyData->DataOffset)); RtlInitUnicodeString(&name, L"IOAddress"); status = NtQueryValueKey(portKey, &name, KeyValueFullInformation, keyData, 64, &length); if (!NT_SUCCESS(status)) { printf("\n"); return; } printf("IO Address %x\n", *((PULONG)keyData + keyData->DataOffset/4)); return; } int __cdecl main( int argc, char **argv ) { BYTE buffer[32]; HANDLE volumeHandle; STRING string; UNICODE_STRING unicodeString; OBJECT_ATTRIBUTES objectAttributes; NTSTATUS ntStatus; IO_STATUS_BLOCK statusBlock; ULONG portNumber = 0; PSCSI_ADAPTER_BUS_INFO adapterInfo; PSCSI_BUS_DATA busData; PSCSI_INQUIRY_DATA inquiryData; UCHAR prevDeviceInquiryData[INQUIRYDATABUFFERSIZE]; PINQUIRYDATA deviceInquiryData; ULONG bytesTransferred, i, j; ULONG deviceNumber; BOOLEAN newDisk = FALSE; BOOLEAN newCdrom = FALSE; UCHAR prevPathId; UCHAR prevTargetId; UCHAR prevLun; BOOLEAN prevDeviceClaimed; BOOLEAN listAdapters = FALSE; BOOLEAN allAdapters = TRUE; UCHAR lunExtra; if(argc == 2) { if(argv[1][0] == '*') { listAdapters = TRUE; } else { portNumber = atoi(argv[1]); allAdapters = FALSE; } } printf("\nWindows NT SCSI Bus Rescan Version 1.1\n"); if(listAdapters) { printf("[only listing adapters]\n"); } else if(allAdapters) { printf("[scanning all adapters]\n"); } else { printf("[scanning adapter %d only]\n", portNumber); } while (TRUE) { memset( buffer, 0, sizeof( buffer ) ); sprintf( buffer, "\\\\.\\Scsi%d:", portNumber); // // Open the volume with the DOS name. // volumeHandle = CreateFile( buffer, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); if( volumeHandle == INVALID_HANDLE_VALUE ) { break; } if(listAdapters) { GetDriverName(portNumber); portNumber++; CloseHandle(volumeHandle); continue; } // // Issue rescan device control. // if( !DeviceIoControl( volumeHandle, IOCTL_SCSI_RESCAN_BUS, NULL, 0, NULL, 0, &bytesTransferred, NULL ) ) { printf( "Rescan SCSI port %d failed [Error %d].\n", portNumber, GetLastError() ); CloseHandle( volumeHandle ); exit(4); } // // Get a big chuck of memory to store the SCSI bus data. // adapterInfo = malloc( 0x1000 ); if (adapterInfo == NULL) { printf( "Can't allocate memory for bus data\n" ); CloseHandle( volumeHandle ); exit(4); } // // Issue device control to get configuration information. // if (!DeviceIoControl( volumeHandle, IOCTL_SCSI_GET_INQUIRY_DATA, NULL, 0, adapterInfo, 0x1000, &bytesTransferred, NULL)) { printf( "Get SCSI bus data failed [Error %d].\n", GetLastError() ); CloseHandle( volumeHandle ); exit(4); } GetDriverName(portNumber); // // Display devices on buses. // for (i=0; i < adapterInfo->NumberOfBuses; i++) { busData = &adapterInfo->BusData[i]; printf( "\nBus TID LUN In use Type Vendor FW Rev Advanced SCSI\n" ); printf( "===============================================================================\n" ); printf("%2d %2d %2d %2d Initiator", i, busData->InitiatorBusId & 0x7, 0, 1); inquiryData = (PSCSI_INQUIRY_DATA)((PUCHAR)adapterInfo + busData->InquiryDataOffset); memset(&prevDeviceInquiryData, 0, INQUIRYDATABUFFERSIZE); prevPathId = 0xFF; prevTargetId = 0xFF; prevLun = 0xFF; prevDeviceClaimed = 0xFF; for (j=0; jNumberOfLogicalUnits; j++) { int k; // // Make sure VendorId string is null terminated. // deviceInquiryData = (PINQUIRYDATA)&inquiryData->InquiryData[0]; deviceInquiryData->VendorSpecific[0] = '\0'; if (prevPathId != inquiryData->PathId || prevTargetId != inquiryData->TargetId || prevLun != (inquiryData->Lun-1) || prevDeviceClaimed != inquiryData->DeviceClaimed || memcmp( &prevDeviceInquiryData, deviceInquiryData, INQUIRYDATABUFFERSIZE) ) { lunExtra = 0; printf("\n%2d %2d %2d %2d ", inquiryData->PathId, inquiryData->TargetId, inquiryData->Lun, inquiryData->DeviceClaimed); } else { lunExtra += 1; printf("\r%2d %2d %2d-%1d %2d ", inquiryData->PathId, inquiryData->TargetId, inquiryData->Lun-lunExtra, inquiryData->Lun, inquiryData->DeviceClaimed); } prevPathId = inquiryData->PathId; prevTargetId = inquiryData->TargetId; prevLun = inquiryData->Lun; prevDeviceClaimed = inquiryData->DeviceClaimed; memmove( &prevDeviceInquiryData, deviceInquiryData, INQUIRYDATABUFFERSIZE); // // Determine the perpherial type. // switch (deviceInquiryData->DeviceType) { case DIRECT_ACCESS_DEVICE: if (!inquiryData->DeviceClaimed) { newDisk = TRUE; } printf("Disk Drive "); break; case SEQUENTIAL_ACCESS_DEVICE: printf("Tape Drive "); break; case PRINTER_DEVICE: printf("Printer "); break; case WRITE_ONCE_READ_MULTIPLE_DEVICE: printf("Worm Drive "); break; case READ_ONLY_DIRECT_ACCESS_DEVICE: if (!inquiryData->DeviceClaimed) { newCdrom = TRUE; } printf("CdRom Drive"); break; case SCANNER_DEVICE: printf("Scanner "); break; case OPTICAL_DEVICE: if (!inquiryData->DeviceClaimed) { newDisk = TRUE; } printf("OpticalDisk"); break; case MEDIUM_CHANGER: printf("MediumChanger"); break; case COMMUNICATION_DEVICE: printf("Communication"); break; default: printf("OtherPeripheral"); } // // Display product information. // printf(" %s", deviceInquiryData->VendorId); // // Display SCSI capabilities. // printf(" "); if (deviceInquiryData->Synchronous) { printf(" SN"); } if (deviceInquiryData->CommandQueue) { printf(" CQ"); } if (deviceInquiryData->Wide16Bit) { printf(" W16"); } if (deviceInquiryData->Wide32Bit) { printf(" W32"); } if (deviceInquiryData->SoftReset) { printf(" SR"); } if (deviceInquiryData->LinkedCommands) { printf(" LC"); } if (deviceInquiryData->RelativeAddressing) { printf(" RA"); } if (deviceInquiryData->DeviceTypeQualifier != DEVICE_QUALIFIER_ACTIVE) { printf(" DQ%d", deviceInquiryData->DeviceTypeQualifier); } printf("\n [ "); for(k = 0; k < 8; k++) { printf("%02x ", ((PUCHAR) deviceInquiryData)[k]); } printf("]"); // // Get next device data. // inquiryData = (PSCSI_INQUIRY_DATA)((PUCHAR)adapterInfo + inquiryData->NextInquiryDataOffset); } printf("\n"); } free (adapterInfo); if(allAdapters) { CloseHandle( volumeHandle ); portNumber++; } else { break; } } if (newDisk) { // // Send IOCTL_DISK_FIND_NEW_DEVICES commands to each existing disk. // deviceNumber = 0; while (TRUE) { memset(buffer, 0, sizeof(buffer)); sprintf(buffer, "\\Device\\Harddisk%d\\Partition0", deviceNumber); RtlInitString(&string, buffer); ntStatus = RtlAnsiStringToUnicodeString(&unicodeString, &string, TRUE); if (!NT_SUCCESS(ntStatus)) { continue; } InitializeObjectAttributes(&objectAttributes, &unicodeString, 0, NULL, NULL); ntStatus = NtOpenFile(&volumeHandle, FILE_READ_DATA | FILE_WRITE_DATA | SYNCHRONIZE, &objectAttributes, &statusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT); if (!NT_SUCCESS(ntStatus)) { break; } // // Issue find device device control. // if (DeviceIoControl( volumeHandle, IOCTL_DISK_FIND_NEW_DEVICES, NULL, 0, NULL, 0, &bytesTransferred, NULL ) ) { printf( "Found new disk (%d)\n", deviceNumber ); } CloseHandle( volumeHandle ); deviceNumber++; } } if (newCdrom) { // // Send IOCTL_CDROM_FIND_NEW_DEVICES commands to each existing cdrom. // deviceNumber = 0; while (TRUE) { memset(buffer, 0, sizeof(buffer)); sprintf(buffer, "\\Device\\Cdrom%d", deviceNumber); RtlInitString(&string, buffer); ntStatus = RtlAnsiStringToUnicodeString(&unicodeString, &string, TRUE); if (!NT_SUCCESS(ntStatus)) { continue; } InitializeObjectAttributes(&objectAttributes, &unicodeString, 0, NULL, NULL); ntStatus = NtOpenFile(&volumeHandle, FILE_READ_DATA | FILE_WRITE_DATA | SYNCHRONIZE, &objectAttributes, &statusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT); if (!NT_SUCCESS(ntStatus)) { break; } // // Issue find device device control. // if (DeviceIoControl( volumeHandle, IOCTL_CDROM_FIND_NEW_DEVICES, NULL, 0, NULL, 0, &bytesTransferred, NULL ) ) { printf( "Found new cdrom (%d)\n", deviceNumber ); } CloseHandle( volumeHandle ); deviceNumber++; } } return(0); }