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.

156 lines
5.4 KiB

  1. #include <windows.h>
  2. #include <winioctl.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #define MBR_DISK_SIGNATURE_BYTE_OFFSET 0x1B8
  7. BYTE TemporaryBuffer[4096*16];
  8. int _cdecl
  9. main(
  10. int argc,
  11. char *argv[]
  12. )
  13. {
  14. HANDLE hFile;
  15. DWORD Size;
  16. DWORD Signature;
  17. BOOL rVal;
  18. DWORD i;
  19. DWORD ErrorCode = ERROR_SUCCESS;
  20. SetErrorMode(SEM_FAILCRITICALERRORS);
  21. if( (argc == 2) && !_strcmpi( argv[1], "-dump" ) ) {
  22. //
  23. // Just dump the signatures.
  24. //
  25. for (i=0; i<999; i++) {
  26. sprintf( (LPSTR)TemporaryBuffer, "\\\\.\\PhysicalDrive%d", i );
  27. hFile = CreateFile( (LPSTR)TemporaryBuffer,
  28. GENERIC_READ,
  29. FILE_SHARE_READ,
  30. NULL,
  31. OPEN_EXISTING,
  32. 0,
  33. NULL );
  34. if (hFile != INVALID_HANDLE_VALUE) {
  35. //
  36. // NOTE: We don't use IOCTL_DISK_GET_DRIVE_LAYOUT_EX
  37. // since it returns cached signature value.
  38. //
  39. if (DeviceIoControl( hFile,
  40. IOCTL_DISK_GET_DRIVE_GEOMETRY,
  41. NULL,
  42. 0,
  43. TemporaryBuffer,
  44. sizeof(TemporaryBuffer),
  45. &Size,
  46. NULL)) {
  47. DWORD SectorSize = ((PDISK_GEOMETRY)(TemporaryBuffer))->BytesPerSector;
  48. PUCHAR Sector = (PUCHAR)TemporaryBuffer;
  49. DWORD BytesRead = 0;
  50. LARGE_INTEGER Offset = {0};
  51. //
  52. // Read the boot sector (NOTE : This code doesn't handle MBR INT13 hookers)
  53. //
  54. if (ReadFile(hFile, Sector, SectorSize, &BytesRead, NULL)) {
  55. PDWORD OldSignature = (PDWORD)(Sector + MBR_DISK_SIGNATURE_BYTE_OFFSET);
  56. printf( "PhysicalDrive%d=0x%08x\n", i, *OldSignature);
  57. } else {
  58. ErrorCode = GetLastError();
  59. }
  60. } else {
  61. ErrorCode = GetLastError();
  62. }
  63. CloseHandle( hFile );
  64. } else {
  65. ErrorCode = GetLastError();
  66. }
  67. }
  68. } else if( (argc == 4) && !_strcmpi( argv[1], "-set" ) ) {
  69. //
  70. // Get the disk number.
  71. //
  72. i = strtoul( argv[2], NULL, 16 );
  73. //
  74. // Get the Signature.
  75. //
  76. Signature = strtoul( argv[3], NULL, 16 );
  77. sprintf( (LPSTR)TemporaryBuffer, "\\\\.\\PhysicalDrive%d", i );
  78. hFile = CreateFile( (LPSTR)TemporaryBuffer,
  79. GENERIC_READ | GENERIC_WRITE,
  80. 0,
  81. NULL,
  82. OPEN_EXISTING,
  83. FILE_ATTRIBUTE_NORMAL,
  84. INVALID_HANDLE_VALUE );
  85. if (hFile != INVALID_HANDLE_VALUE) {
  86. if (DeviceIoControl( hFile,
  87. IOCTL_DISK_GET_DRIVE_GEOMETRY,
  88. NULL,
  89. 0,
  90. TemporaryBuffer,
  91. sizeof(TemporaryBuffer),
  92. &Size,
  93. NULL)) {
  94. DWORD SectorSize = ((PDISK_GEOMETRY)(TemporaryBuffer))->BytesPerSector;
  95. PUCHAR Sector = (PUCHAR)TemporaryBuffer;
  96. DWORD BytesRead = 0;
  97. LARGE_INTEGER Offset = {0};
  98. //
  99. // Read the boot sector (NOTE : This code doesn't handle MBR INT13 hookers)
  100. //
  101. if (ReadFile(hFile, Sector, SectorSize, &BytesRead, NULL) &&
  102. (BytesRead == SectorSize) &&
  103. SetFilePointerEx(hFile, Offset, NULL, FILE_BEGIN)) {
  104. DWORD BytesWritten = 0;
  105. PDWORD OldSignature = (PDWORD)(Sector + MBR_DISK_SIGNATURE_BYTE_OFFSET);
  106. printf( "Setting PhysicalDrive%d Signature=0x%08x\n", i, Signature );
  107. *OldSignature = Signature;
  108. if (!WriteFile(hFile, Sector, SectorSize, &BytesWritten, NULL)) {
  109. ErrorCode = GetLastError();
  110. } else if (BytesWritten != SectorSize) {
  111. ErrorCode = ERROR_IO_DEVICE;
  112. }
  113. } else {
  114. ErrorCode = GetLastError();
  115. if (ErrorCode == ERROR_SUCCESS) {
  116. ErrorCode = ERROR_IO_DEVICE;
  117. }
  118. }
  119. } else {
  120. ErrorCode = GetLastError();
  121. }
  122. CloseHandle( hFile );
  123. } else {
  124. ErrorCode = GetLastError();
  125. }
  126. } else {
  127. printf( "Usage: %s <parameters>\n", argv[0] );
  128. printf( " Where <parameters> are:\n" );
  129. printf( " -dump dumps signatures for all disks\n" );
  130. printf( " -set <disk num> <hex signature> sets signature for specified disk\n" );
  131. }
  132. return ErrorCode;
  133. }