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.

198 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. drivemap.c
  5. Abstract:
  6. User mode program to determine which ide/scsi device each drive letter is
  7. connected to.
  8. Author:
  9. 01-Nov-1995 Peter Wieland (peterwie)
  10. Revision History:
  11. --*/
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <windows.h>
  15. #include <winioctl.h>
  16. #include <ntddscsi.h>
  17. #define BUFSIZE 6 // <drive letter>:<NULL>
  18. #define NUM_DRIVES 26 // 26 drive letters
  19. #define MAX_FLOPPY_OFFSET 1
  20. enum {UNKNOWN = 0, FLOPPY, SCSI, IDE};
  21. typedef struct devent {
  22. char *dosName; // dosdevices name
  23. char devName[64];
  24. int type;
  25. void *desc;
  26. } devent;
  27. void splitDosQuery(LPTSTR queryString, devent *list);
  28. void checkDeviceType(devent *dev);
  29. void processDevice(DWORD driveLetterOffset);
  30. ULONG NumberOfDriveLetters;
  31. int __cdecl main(int argc, char *argv[]) {
  32. DWORD dwT, i, Index;
  33. TCHAR strDriveLetter[BUFSIZE];
  34. dwT = GetLogicalDrives();
  35. if(dwT == 0) {
  36. printf("Error getting device letters (%d)\n", GetLastError());
  37. exit(-2);
  38. }
  39. Index = 1;
  40. for( i = 0; i < NUM_DRIVES; i++ ) {
  41. if(Index & dwT) {
  42. processDevice(i);
  43. }
  44. Index <<= 1;
  45. }
  46. return 0;
  47. }
  48. //
  49. // processDevice(driveLetterOffset);
  50. // in: driveLetterOffset - offset of the drive letter relative to 'A'
  51. //
  52. void processDevice(DWORD driveLetterOffset) {
  53. LPTSTR next;
  54. char chBuf[32];
  55. HANDLE hDevice = INVALID_HANDLE_VALUE;
  56. DWORD ioctlData[2];
  57. PSCSI_ADDRESS scsiAddress = (PSCSI_ADDRESS) ioctlData;
  58. PDISK_CONTROLLER_NUMBER atAddress = (PDISK_CONTROLLER_NUMBER) ioctlData;
  59. DWORD dwSize;
  60. UCHAR diskType = UNKNOWN;
  61. DWORD offset = driveLetterOffset;
  62. // only do processing on drive letters
  63. try {
  64. sprintf(chBuf, "\\\\.\\%c:", ('A' + offset));
  65. // Check if drive letter is 'A' or 'B'
  66. if(offset <= MAX_FLOPPY_OFFSET) {
  67. diskType = FLOPPY;
  68. hDevice = INVALID_HANDLE_VALUE;
  69. goto typeKnown;
  70. }
  71. hDevice = CreateFile(chBuf,
  72. GENERIC_READ,
  73. FILE_SHARE_READ | FILE_SHARE_WRITE,
  74. NULL,
  75. OPEN_EXISTING,
  76. FILE_ATTRIBUTE_NORMAL,
  77. NULL);
  78. if(hDevice == INVALID_HANDLE_VALUE) {
  79. // printf("Error opening device %s (%d)\n",
  80. // chBuf, GetLastError());
  81. return;
  82. }
  83. // send down the scsi query first (yes, i'm biased)
  84. if(!DeviceIoControl(hDevice,
  85. IOCTL_SCSI_GET_ADDRESS,
  86. NULL,
  87. 0,
  88. scsiAddress,
  89. sizeof(SCSI_ADDRESS),
  90. &dwSize,
  91. NULL)) {
  92. // if the ioctl was invalid, then we don't know the disk type yet,
  93. // so just keep going
  94. // if there was another error, skip to the next device
  95. if(GetLastError() != ERROR_INVALID_FUNCTION) {
  96. return;
  97. }
  98. } else {
  99. // if the ioctl was valid, then we're a scsi device (or a scsiport
  100. // controlled device in the case of atapi) - go on to the end
  101. diskType = SCSI;
  102. goto typeKnown;
  103. }
  104. if(!DeviceIoControl(hDevice,
  105. IOCTL_DISK_CONTROLLER_NUMBER,
  106. NULL,
  107. 0,
  108. atAddress,
  109. sizeof(DISK_CONTROLLER_NUMBER),
  110. &dwSize,
  111. NULL)) {
  112. // if the ioctl was invalid, then we still don't know the
  113. // disk type - continue on.
  114. if(GetLastError() != ERROR_INVALID_FUNCTION) return;
  115. } else {
  116. // if the ioctl was valid, then we're an IDE device
  117. diskType = IDE;
  118. goto typeKnown;
  119. }
  120. diskType = UNKNOWN;
  121. typeKnown:
  122. printf("%s -> ", chBuf);
  123. switch(diskType) {
  124. case FLOPPY:
  125. printf("Floppy drive\n");
  126. break;
  127. case SCSI:
  128. printf("Port %d, Path %d, Target %d, Lun %d\n",
  129. scsiAddress->PortNumber,
  130. scsiAddress->PathId,
  131. scsiAddress->TargetId,
  132. scsiAddress->Lun);
  133. break;
  134. case IDE:
  135. printf("Controller %d, Disk %d\n",
  136. atAddress->ControllerNumber,
  137. atAddress->DiskNumber);
  138. break;
  139. default:
  140. printf("Unknown\n");
  141. break;
  142. }
  143. } finally {
  144. // close the file handle if we've opened it
  145. if(hDevice != INVALID_HANDLE_VALUE) CloseHandle(hDevice);
  146. }
  147. return;
  148. }