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.

374 lines
9.4 KiB

  1. #include <nt.h>
  2. #include <ntddft.h>
  3. #include <ntdddisk.h>
  4. #include <ntrtl.h>
  5. #include <nturtl.h>
  6. #include <windows.h>
  7. #include <stdio.h>
  8. #include <process.h>
  9. #include <memory.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #define SECTOR_SIZE 512
  14. #define COMPARE_BUFFER_SIZE 0x4000
  15. BYTE PrimaryBuffer[COMPARE_BUFFER_SIZE];
  16. BYTE SecondaryBuffer[COMPARE_BUFFER_SIZE];
  17. BYTE OutputBuffer[1024];
  18. void
  19. DumpMiscompare(
  20. IN PBYTE PrimarySector,
  21. IN PBYTE SecondarySector
  22. )
  23. {
  24. BYTE ch;
  25. int i, j, offset;
  26. i = 0;
  27. while( i < SECTOR_SIZE && PrimarySector[i] == SecondarySector[i] ) {
  28. i++;
  29. }
  30. offset = i & ~7;
  31. while( offset < SECTOR_SIZE ) {
  32. printf( "%03X: ", offset );
  33. // display primary as hex.
  34. for( j = offset; j < offset + 8; j++ ) {
  35. if( j < i ) {
  36. printf( " " );
  37. } else {
  38. printf( " %02X", PrimarySector[j] );
  39. }
  40. }
  41. printf( " " );
  42. // display primary as character.
  43. for( j = offset; j < offset + 8; j++ ) {
  44. if( j < i ) {
  45. printf( " " );
  46. } else {
  47. ch = PrimarySector[j];
  48. if( !isprint(ch) ) {
  49. ch = '.';
  50. }
  51. printf( "%c", ch );
  52. }
  53. }
  54. printf( " -- " );
  55. // Display secondary as hex.
  56. for( j = offset; j < offset + 8; j++ ) {
  57. if( j < i ) {
  58. printf( " " );
  59. } else {
  60. printf( " %02X", SecondarySector[j] );
  61. }
  62. }
  63. printf( " " );
  64. // display primary as character.
  65. for( j = offset; j < offset + 8; j++ ) {
  66. if( j < i ) {
  67. printf( " " );
  68. } else {
  69. ch = SecondarySector[j];
  70. if( !isprint(ch) ) {
  71. ch = '.';
  72. }
  73. printf( "%c", ch );
  74. }
  75. }
  76. printf( "\n" );
  77. offset += 8;
  78. }
  79. // Add a blank line.
  80. //
  81. printf( "\n" );
  82. }
  83. BOOL
  84. ReadSectors(
  85. IN HANDLE VolumeHandle,
  86. IN ULONG SectorNumber,
  87. IN ULONG NumberOfSectors,
  88. IN PBYTE Buffer,
  89. IN BOOL Secondary
  90. )
  91. {
  92. FT_SPECIAL_READ SpecialReadBuffer;
  93. ULONG BytesRead;
  94. SpecialReadBuffer.ByteOffset = RtlEnlargedIntegerMultiply( SectorNumber, SECTOR_SIZE );
  95. SpecialReadBuffer.Length = NumberOfSectors * SECTOR_SIZE;
  96. // Issue the IOCTL
  97. //
  98. return( DeviceIoControl( VolumeHandle,
  99. Secondary ? FT_SECONDARY_READ : FT_PRIMARY_READ,
  100. &SpecialReadBuffer,
  101. sizeof( SpecialReadBuffer ),
  102. Buffer,
  103. NumberOfSectors * SECTOR_SIZE,
  104. &BytesRead,
  105. NULL ) &&
  106. BytesRead == NumberOfSectors * SECTOR_SIZE );
  107. }
  108. VOID
  109. ShowUsage()
  110. {
  111. printf( "usage: parcomp DosDriveName: [-d] [-b:StartingSector] [-e:EndingSector]\n" );
  112. exit(4);
  113. }
  114. int __cdecl
  115. main( int argc, char **argv )
  116. {
  117. PARTITION_INFORMATION PartitionInfo;
  118. BYTE DriveNameBuffer[32];
  119. HANDLE VolumeHandle;
  120. LARGE_INTEGER BigSectorsOnVolume;
  121. ULONG SectorsOnVolume, SectorOffset, SectorsToRead, i, Errors;
  122. LONG k;
  123. BOOL PrimaryRead, SecondaryRead, DumpErrors = FALSE;
  124. ULONG BytesTransferred;
  125. ULONG StartSector = 0, EndSector = 0;
  126. if( argc < 2 ) {
  127. ShowUsage();
  128. }
  129. memset( DriveNameBuffer, 0, sizeof( DriveNameBuffer ) );
  130. strcat( DriveNameBuffer, "\\\\.\\" );
  131. strcat( DriveNameBuffer, argv[1] );
  132. for( k = 2;
  133. k < argc;
  134. k++ ) {
  135. if( argv[k][0] == '-' ||
  136. argv[k][0] == '/' ) {
  137. switch (argv[k][1]) {
  138. case 'd':
  139. //
  140. // Display miscompares.
  141. //
  142. DumpErrors = TRUE;
  143. break;
  144. case 'b':
  145. //
  146. // Specify beginning sector number.
  147. //
  148. if (sscanf( argv[k]+2, ":%x", &StartSector ) != 1)
  149. ShowUsage();
  150. break;
  151. case 'e':
  152. //
  153. // Specify beginning sector number.
  154. //
  155. if (sscanf( argv[k]+2, ":%x", &EndSector ) != 1)
  156. ShowUsage();
  157. break;
  158. default:
  159. ShowUsage();
  160. break;
  161. }
  162. } else {
  163. ShowUsage();
  164. }
  165. }
  166. // Open the volume with the DOS name.
  167. //
  168. VolumeHandle = CreateFile( DriveNameBuffer,
  169. GENERIC_READ,
  170. FILE_SHARE_READ | FILE_SHARE_WRITE,
  171. NULL,
  172. OPEN_EXISTING,
  173. 0,
  174. 0 );
  175. if( VolumeHandle == INVALID_HANDLE_VALUE ) {
  176. printf( "Unable to open %s [Error %d]\n", argv[1], GetLastError() );
  177. exit(4);
  178. }
  179. // GetFile information.
  180. //
  181. if( !DeviceIoControl( VolumeHandle,
  182. IOCTL_DISK_GET_PARTITION_INFO,
  183. NULL,
  184. 0,
  185. &PartitionInfo,
  186. sizeof( PartitionInfo ),
  187. &BytesTransferred,
  188. NULL ) ) {
  189. printf( "Unable to get volume size [Error %d].\n", GetLastError() );
  190. CloseHandle( VolumeHandle );
  191. exit(4);
  192. }
  193. if( !(PartitionInfo.PartitionType & VALID_NTFT) ) {
  194. printf( "%s is not a Fault-Tolerant volume.\n", argv[1] );
  195. exit(4);
  196. }
  197. BigSectorsOnVolume = RtlExtendedLargeIntegerDivide( PartitionInfo.PartitionLength, SECTOR_SIZE, NULL );
  198. SectorsOnVolume = BigSectorsOnVolume.LowPart;
  199. if( EndSector == 0 ) {
  200. EndSector = SectorsOnVolume;
  201. }
  202. sprintf( OutputBuffer, "Sectors on volume = %x\n", SectorsOnVolume );
  203. printf( OutputBuffer );
  204. OutputDebugString( OutputBuffer );
  205. sprintf( OutputBuffer, "Starting Sector = %x\n", StartSector );
  206. printf( OutputBuffer );
  207. OutputDebugString( OutputBuffer );
  208. sprintf( OutputBuffer, "Ending Sector = %x\n", EndSector );
  209. printf( OutputBuffer );
  210. OutputDebugString( OutputBuffer );
  211. SectorsToRead = 0;
  212. Errors = 0;
  213. printf( "Sectors read %8x\b\b\b\b\b\b\b\b", StartSector );
  214. for( SectorOffset = StartSector;
  215. SectorOffset < EndSector;
  216. SectorOffset += SectorsToRead ) {
  217. SectorsToRead = __min( COMPARE_BUFFER_SIZE / SECTOR_SIZE,
  218. EndSector - SectorOffset );
  219. // zero out the buffers.
  220. //
  221. memset( PrimaryBuffer, 0, COMPARE_BUFFER_SIZE );
  222. memset( SecondaryBuffer, 0, COMPARE_BUFFER_SIZE );
  223. // Read the primary:
  224. //
  225. PrimaryRead = ReadSectors( VolumeHandle,
  226. SectorOffset,
  227. SectorsToRead,
  228. PrimaryBuffer,
  229. FALSE );
  230. // Read the secondary:
  231. //
  232. SecondaryRead = ReadSectors( VolumeHandle,
  233. SectorOffset,
  234. SectorsToRead,
  235. SecondaryBuffer,
  236. TRUE );
  237. if( PrimaryRead && SecondaryRead ) {
  238. for( i = 0; i < SectorsToRead; i++ ) {
  239. if( memcmp( PrimaryBuffer + SECTOR_SIZE * i,
  240. SecondaryBuffer + SECTOR_SIZE * i,
  241. SECTOR_SIZE ) ) {
  242. sprintf( OutputBuffer, "\rPrimary and Secondary miscompare at sector %x\n", SectorOffset + i );
  243. printf( OutputBuffer );
  244. OutputDebugString( OutputBuffer );
  245. if( DumpErrors ) {
  246. DumpMiscompare( PrimaryBuffer + SECTOR_SIZE * i,
  247. SecondaryBuffer + SECTOR_SIZE * i );
  248. }
  249. printf( "Sectors read %8x\b\b\b\b\b\b\b\b", SectorOffset );
  250. Errors++;
  251. }
  252. }
  253. } else if( PrimaryRead ) {
  254. sprintf( OutputBuffer, "\rSecondary read failed at sector %x, length %x (Error %d)\n", SectorOffset, SectorsToRead, GetLastError() );
  255. printf( OutputBuffer );
  256. OutputDebugString( OutputBuffer );
  257. printf( "Sectors read %8x\b\b\b\b\b\b\b\b", SectorOffset );
  258. } else if( SecondaryRead ) {
  259. sprintf( OutputBuffer, "\rPrimary read failed at sector %x, length %x (Error %d)\n", SectorOffset, SectorsToRead, GetLastError() );
  260. printf( OutputBuffer );
  261. OutputDebugString( OutputBuffer );
  262. printf( "Sectors read %8x\b\b\b\b\b\b\b\b", SectorOffset );
  263. } else {
  264. sprintf( OutputBuffer, "\rPrimary and Secondary reads failed at sector %x, length %x (Error %d)\n", SectorOffset, SectorsToRead, GetLastError() );
  265. printf( OutputBuffer );
  266. OutputDebugString( OutputBuffer );
  267. printf( "Sectors read %8x\b\b\b\b\b\b\b\b", SectorOffset );
  268. }
  269. printf( "%8x\b\b\b\b\b\b\b\b", SectorOffset );
  270. }
  271. printf( "%8x\b\b\b\b\b\b\b\b", SectorOffset );
  272. printf( "\n%x Errors\n", Errors );
  273. CloseHandle( VolumeHandle );
  274. return( 0 );
  275. }