Leaked source code of windows server 2003
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.

189 lines
4.9 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 NUM_DRIVES 26 // 26 drive letters
  18. #define MAX_FLOPPY_OFFSET 1
  19. #define DRIVE_NAME_BUFFER_SIZE 32
  20. enum {UNKNOWN = 0, FLOPPY, SCSI, IDE};
  21. void processDevice(DWORD driveLetterOffset);
  22. int __cdecl main(int argc, char *argv[]) {
  23. DWORD dwT, i, Index;
  24. dwT = GetLogicalDrives();
  25. if(dwT == 0) {
  26. printf("Error getting device letters (%d)\n", GetLastError());
  27. exit(-2);
  28. }
  29. Index = 1;
  30. for( i = 0; i < NUM_DRIVES; i++ ) {
  31. if(Index & dwT) {
  32. processDevice(i);
  33. }
  34. Index <<= 1;
  35. }
  36. return 0;
  37. }
  38. //
  39. // processDevice(driveLetterOffset);
  40. // in: driveLetterOffset - offset of the drive letter relative to 'A'
  41. //
  42. void processDevice(DWORD driveLetterOffset) {
  43. LPTSTR next;
  44. char chBuf[ DRIVE_NAME_BUFFER_SIZE ];
  45. HANDLE hDevice = INVALID_HANDLE_VALUE;
  46. SCSI_ADDRESS scsiAddress;
  47. DISK_CONTROLLER_NUMBER atAddress;
  48. DWORD dwSize;
  49. UCHAR diskType = UNKNOWN;
  50. DWORD offset = driveLetterOffset;
  51. // only do processing on drive letters
  52. try {
  53. _snprintf(
  54. chBuf, (sizeof(chBuf) / sizeof(chBuf[0])),
  55. "\\\\.\\%c:", ('A' + offset)
  56. );
  57. // Check if drive letter is 'A' or 'B'
  58. if(offset <= MAX_FLOPPY_OFFSET) {
  59. diskType = FLOPPY;
  60. hDevice = INVALID_HANDLE_VALUE;
  61. goto typeKnown;
  62. }
  63. hDevice = CreateFile(chBuf,
  64. GENERIC_READ,
  65. FILE_SHARE_READ | FILE_SHARE_WRITE,
  66. NULL,
  67. OPEN_EXISTING,
  68. FILE_ATTRIBUTE_NORMAL,
  69. NULL);
  70. if(hDevice == INVALID_HANDLE_VALUE) {
  71. // printf("Error opening device %s (%d)\n",
  72. // chBuf, GetLastError());
  73. leave;
  74. }
  75. // send down the scsi query first (yes, i'm biased)
  76. if(!DeviceIoControl(hDevice,
  77. IOCTL_SCSI_GET_ADDRESS,
  78. NULL,
  79. 0,
  80. &scsiAddress,
  81. sizeof(SCSI_ADDRESS),
  82. &dwSize,
  83. NULL)) {
  84. // if the ioctl was invalid, then we don't know the disk type yet,
  85. // so just keep going
  86. // if there was another error, skip to the next device
  87. if(GetLastError() != ERROR_INVALID_FUNCTION) {
  88. leave;
  89. }
  90. } else {
  91. // if the ioctl was valid, then we're a scsi device (or a scsiport
  92. // controlled device in the case of atapi) - go on to the end
  93. diskType = SCSI;
  94. goto typeKnown;
  95. }
  96. if(!DeviceIoControl(hDevice,
  97. IOCTL_DISK_CONTROLLER_NUMBER,
  98. NULL,
  99. 0,
  100. &atAddress,
  101. sizeof(DISK_CONTROLLER_NUMBER),
  102. &dwSize,
  103. NULL)) {
  104. // if the ioctl was invalid, then we still don't know the
  105. // disk type - continue on.
  106. if(GetLastError() != ERROR_INVALID_FUNCTION) leave;
  107. } else {
  108. // if the ioctl was valid, then we're an IDE device
  109. diskType = IDE;
  110. goto typeKnown;
  111. }
  112. diskType = UNKNOWN;
  113. typeKnown:
  114. printf("%s -> ", chBuf);
  115. switch(diskType) {
  116. case FLOPPY:
  117. printf("Floppy drive\n");
  118. break;
  119. case SCSI:
  120. printf("Port %d, Path %d, Target %d, Lun %d\n",
  121. scsiAddress.PortNumber,
  122. scsiAddress.PathId,
  123. scsiAddress.TargetId,
  124. scsiAddress.Lun);
  125. break;
  126. case IDE:
  127. printf("Controller %d, Disk %d\n",
  128. atAddress.ControllerNumber,
  129. atAddress.DiskNumber);
  130. break;
  131. default:
  132. printf("Unknown\n");
  133. break;
  134. }
  135. } finally {
  136. // close the file handle if we've opened it
  137. if(hDevice != INVALID_HANDLE_VALUE) CloseHandle(hDevice);
  138. }
  139. return;
  140. }