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.

2102 lines
56 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. tfat.c
  5. Abstract:
  6. Test program for the Fat File system
  7. Author:
  8. Gary Kimura [GaryKi] 24-May-1989
  9. Revision History:
  10. --*/
  11. //#define BIG
  12. #include <stdio.h>
  13. #include <string.h>
  14. //#include <ctype.h>
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <nturtl.h>
  18. #define toupper(C) ((C) >= 'a' && (C) <= 'z' ? (C) - ('a' - 'A') : (C))
  19. #define isdigit(C) ((C) >= '0' && (C) <= '9')
  20. #define RtlDosPathNameToNtPathName(IN_STR,OUT_STR,FOO,BAR) { \
  21. STRING TmpStr; \
  22. UNICODE_STRING TmpUStr; \
  23. \
  24. RtlInitString( &TmpStr, (IN_STR) ); \
  25. TmpStr.Length++; \
  26. RtlAnsiStringToUnicodeString( &TmpUStr, &TmpStr, TRUE ); \
  27. RtlDosPathNameToNtPathName_U( (PWSTR)TmpUStr.Buffer, (OUT_STR), \
  28. (FOO),(BAR) ); \
  29. \
  30. RtlFreeUnicodeString( &TmpUStr ); \
  31. }
  32. #ifndef SIMULATOR
  33. ULONG IoInitIncludeDevices;
  34. #endif // SIMULATOR
  35. ULONG Threads;
  36. HANDLE StartSignal;
  37. ULONG Id;
  38. ULONG WriteThrough = 0;
  39. #define simprintf(X,Y) {if (!Silent) {printf(X,Y);} }
  40. BOOLEAN Silent;
  41. //
  42. // The buffer size must be a multiple of 512
  43. //
  44. #define BUFFERSIZE 1024
  45. HANDLE CurrentProcessHandle;
  46. ULONG LoopCount;
  47. CHAR RootDir[32];
  48. STRING NtRootDir;
  49. VOID
  50. PrintTime (
  51. IN PLARGE_INTEGER Time
  52. );
  53. VOID
  54. WaitForSingleObjectError(
  55. IN NTSTATUS Status
  56. );
  57. VOID
  58. CreateFileError(
  59. IN NTSTATUS Status,
  60. IN PUCHAR File
  61. );
  62. VOID
  63. OpenFileError(
  64. IN NTSTATUS Status,
  65. IN PUCHAR File
  66. );
  67. VOID
  68. ReadFileError(
  69. IN NTSTATUS Status,
  70. IN PUCHAR File
  71. );
  72. VOID
  73. WriteFileError(
  74. IN NTSTATUS Status,
  75. IN PUCHAR File
  76. );
  77. VOID
  78. CheckIoStatus(
  79. IN PIO_STATUS_BLOCK IoStatus,
  80. IN ULONG Length,
  81. IN BOOLEAN Read
  82. );
  83. VOID
  84. SetInformationFileError(
  85. IN NTSTATUS Status
  86. );
  87. VOID
  88. QueryInformationFileError(
  89. IN NTSTATUS Status
  90. );
  91. VOID
  92. SetVolumeInformationFileError(
  93. IN NTSTATUS Status
  94. );
  95. VOID
  96. QueryVolumeInformationFileError(
  97. IN NTSTATUS Status
  98. );
  99. VOID
  100. CloseError(
  101. IN NTSTATUS Status,
  102. IN PUCHAR File
  103. );
  104. VOID
  105. IoStatusError(
  106. IN NTSTATUS Status
  107. );
  108. VOID
  109. CreateThreadError(
  110. IN NTSTATUS Status
  111. );
  112. VOID
  113. main(
  114. int argc,
  115. char *argv[],
  116. char *envp[]
  117. )
  118. {
  119. NTSTATUS Status;
  120. ULONG i;
  121. VOID FatMain();
  122. LARGE_INTEGER DelayTime;
  123. LARGE_INTEGER Time;
  124. TIME_FIELDS TimeFields;
  125. NtQuerySystemTime(&Time);
  126. RtlTimeToTimeFields( &Time, &TimeFields );
  127. Id = 100 * (TimeFields.Minute +
  128. 100 * (TimeFields.Hour +
  129. 100 * TimeFields.Day));
  130. CurrentProcessHandle = NtCurrentProcess();
  131. Status = STATUS_SUCCESS;
  132. if (argc > 1) {
  133. strcpy( RootDir, argv[1]);
  134. } else {
  135. printf("usage: %s RootDir [itterations] [threads] [writethrough]\n", argv[0]);
  136. return;
  137. }
  138. if (argc > 2) {
  139. LoopCount = 0;
  140. for (i = 0; isdigit(argv[2][i]); i += 1) {
  141. LoopCount = LoopCount * 10 + (ULONG)(argv[2][i] - '0');
  142. }
  143. } else {
  144. LoopCount = 1;
  145. }
  146. if (argc > 3) {
  147. Threads = 0;
  148. for (i = 0; isdigit(argv[3][i]); i += 1) {
  149. Threads = Threads * 10 + (ULONG)(argv[3][i] - '0');
  150. }
  151. } else {
  152. Threads = 1;
  153. }
  154. if (argc > 4) {
  155. WriteThrough = FILE_WRITE_THROUGH;
  156. }
  157. if (toupper(RootDir[0]) != RootDir[0]) {
  158. RootDir[0] = (CHAR)toupper(RootDir[0]);
  159. Silent = TRUE;
  160. } else {
  161. Silent = FALSE;
  162. }
  163. //
  164. // Initialize my starting signal
  165. //
  166. NtCreateEvent(
  167. &StartSignal,
  168. EVENT_ALL_ACCESS,
  169. NULL,
  170. NotificationEvent,
  171. FALSE);
  172. //
  173. // Create a bunch of threads to run FatMain
  174. //
  175. for (i=0; i< Threads; i++) {
  176. if (!NT_SUCCESS(Status = RtlCreateUserThread(
  177. CurrentProcessHandle,
  178. NULL,
  179. FALSE,
  180. 0,
  181. 0,
  182. 0,
  183. (PUSER_THREAD_START_ROUTINE)FatMain,
  184. NULL,
  185. NULL,
  186. NULL))) {
  187. CreateThreadError( Status );
  188. return;
  189. }
  190. }
  191. DelayTime.HighPart = -1;
  192. DelayTime.LowPart = -10*1000*1000*5;
  193. printf( "Wait 5 seconds for all thread to get ready .....");
  194. NtDelayExecution(FALSE, &DelayTime);
  195. printf( "Notifying %d threads to go.\n", Threads);
  196. NtSetEvent( StartSignal, NULL );
  197. NtTerminateThread(NtCurrentThread(), STATUS_SUCCESS);
  198. // printf( "Exiting User Mode Test Program with Status = %lx\n", Status );
  199. // NtTerminateProcess( CurrentProcessHandle, Status );
  200. }
  201. VOID
  202. FatMain()
  203. {
  204. VOID Upcase();
  205. VOID Append(),Chmode(),Copy(),Create(),DebugLevel(),Delete();
  206. VOID Directory(),Mkdir(),Query(),QVolume(),Rename();
  207. VOID SVolume(),Type(),Quit();
  208. CHAR Str[64];
  209. CHAR Str2[64];
  210. CHAR LoopStr[64];
  211. CHAR Prefix[64];
  212. ULONG i, MyId;
  213. NTSTATUS Status;
  214. //
  215. // Get our id and wait for wakeup
  216. //
  217. MyId = Id++;
  218. if (!NT_SUCCESS(Status = NtWaitForSingleObject( StartSignal, TRUE, NULL))) {
  219. WaitForSingleObjectError( Status );
  220. return;
  221. }
  222. strcpy( Prefix, RootDir ); // "\\A:\\";
  223. RtlIntegerToChar( MyId, 10, -8, &Str[0] );
  224. Str[8] = 0;
  225. strcat( Prefix, Str );
  226. printf("FatMain %s:%d %08l \n\n", Prefix, LoopCount, MyId);
  227. Mkdir( Prefix );
  228. Directory( Prefix );
  229. for (i = 0; i < LoopCount; i += 1) {
  230. strcpy(LoopStr, "Start loop xxxxxxxx ");
  231. RtlIntegerToChar(i, 16, -8, &LoopStr[11]);
  232. strcat( LoopStr, Prefix );
  233. printf(LoopStr);
  234. printf("\n");
  235. //
  236. // Create new log
  237. //
  238. strcpy( Str2, "\\" ); RtlIntegerToChar(i, 16, -8, &Str2[1]); Str2[9] = 0;
  239. strcpy( Str, Prefix ); Create( strcat( Str, Str2 ), i);
  240. //
  241. // Delete last log file if i > 0
  242. //
  243. if (i > 0) {
  244. strcpy( Str2, "\\" ); RtlIntegerToChar(i-1, 16, -8, &Str2[1]); Str2[9] = 0;
  245. strcpy( Str, Prefix ); Delete( strcat( Str, Str2 ) );
  246. }
  247. //
  248. // Create some new files
  249. //
  250. printf( "%s: Creating ....\n", Prefix );
  251. strcpy( Str, Prefix ); Create( strcat( Str, "\\0.tmp" ), 0 );
  252. strcpy( Str, Prefix ); Create( strcat( Str, "\\1.tmp" ), 1 );
  253. strcpy( Str, Prefix ); Create( strcat( Str, "\\511.tmp" ), 511 );
  254. strcpy( Str, Prefix ); Create( strcat( Str, "\\512.tmp" ), 512 );
  255. strcpy( Str, Prefix ); Create( strcat( Str, "\\513.tmp" ), 513 );
  256. strcpy( Str, Prefix ); Create( strcat( Str, "\\1023.tmp" ), 1023 );
  257. strcpy( Str, Prefix ); Create( strcat( Str, "\\1024.tmp" ), 1024 );
  258. strcpy( Str, Prefix ); Create( strcat( Str, "\\1025.tmp" ), 1025 );
  259. strcpy( Str, Prefix ); Create( strcat( Str, "\\4095.tmp" ), 4095 );
  260. strcpy( Str, Prefix ); Create( strcat( Str, "\\4096.tmp" ), 4096 );
  261. strcpy( Str, Prefix ); Create( strcat( Str, "\\4097.tmp" ), 4097 );
  262. strcpy( Str, Prefix ); Create( strcat( Str, "\\8191.tmp" ), 8191 );
  263. strcpy( Str, Prefix ); Create( strcat( Str, "\\8192.tmp" ), 8192 );
  264. strcpy( Str, Prefix ); Create( strcat( Str, "\\8193.tmp" ), 8193 );
  265. #ifdef BIG
  266. strcpy( Str, Prefix ); Create( strcat( Str, "\\40970.tmp" ), 40970 );
  267. strcpy( Str, Prefix ); Create( strcat( Str, "\\81910.tmp" ), 81910 );
  268. strcpy( Str, Prefix ); Create( strcat( Str, "\\409700.tmp" ), 409700 );
  269. #endif
  270. Directory( Prefix );
  271. printf( "%s: Copying ....\n", Prefix );
  272. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\0.tmp" ), strcat( Str2, "\\0.tmq" ) );
  273. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\1.tmp" ), strcat( Str2, "\\1.tmq" ) );
  274. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\511.tmp" ), strcat( Str2, "\\511.tmq" ) );
  275. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\512.tmp" ), strcat( Str2, "\\512.tmq" ) );
  276. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\513.tmp" ), strcat( Str2, "\\513.tmq" ) );
  277. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\1023.tmp" ), strcat( Str2, "\\1023.tmq" ) );
  278. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\1024.tmp" ), strcat( Str2, "\\1024.tmq" ) );
  279. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\1025.tmp" ), strcat( Str2, "\\1025.tmq" ) );
  280. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\4095.tmp" ), strcat( Str2, "\\4095.tmq" ) );
  281. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\4096.tmp" ), strcat( Str2, "\\4096.tmq" ) );
  282. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\4097.tmp" ), strcat( Str2, "\\4097.tmq" ) );
  283. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\8191.tmp" ), strcat( Str2, "\\8191.tmq" ) );
  284. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\8192.tmp" ), strcat( Str2, "\\8192.tmq" ) );
  285. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\8193.tmp" ), strcat( Str2, "\\8193.tmq" ) );
  286. #ifdef BIG
  287. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\40970.tmp" ), strcat( Str2, "\\40970.tmq" ) );
  288. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\81910.tmp" ), strcat( Str2, "\\81910.tmq" ) );
  289. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Copy( strcat( Str, "\\409700.tmp" ), strcat( Str2, "\\409700.tmq" ) );
  290. #endif
  291. Directory( Prefix );
  292. printf( "%s: Appending ....\n", Prefix );
  293. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\0.tmp" ), strcat( Str2, "\\0.tmq" ) );
  294. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\1.tmp" ), strcat( Str2, "\\1.tmq" ) );
  295. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\511.tmp" ), strcat( Str2, "\\511.tmq" ) );
  296. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\512.tmp" ), strcat( Str2, "\\512.tmq" ) );
  297. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\513.tmp" ), strcat( Str2, "\\513.tmq" ) );
  298. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\1023.tmp" ), strcat( Str2, "\\1023.tmq" ) );
  299. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\1024.tmp" ), strcat( Str2, "\\1024.tmq" ) );
  300. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\1025.tmp" ), strcat( Str2, "\\1025.tmq" ) );
  301. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\4095.tmp" ), strcat( Str2, "\\4095.tmq" ) );
  302. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\4096.tmp" ), strcat( Str2, "\\4096.tmq" ) );
  303. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\4097.tmp" ), strcat( Str2, "\\4097.tmq" ) );
  304. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\8191.tmp" ), strcat( Str2, "\\8191.tmq" ) );
  305. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\8192.tmp" ), strcat( Str2, "\\8192.tmq" ) );
  306. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\8193.tmp" ), strcat( Str2, "\\8193.tmq" ) );
  307. #ifdef BIG
  308. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\40970.tmp" ), strcat( Str2, "\\40970.tmq" ) );
  309. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\81910.tmp" ), strcat( Str2, "\\81910.tmq" ) );
  310. strcpy( Str, Prefix ); strcpy( Str2, Prefix ); Append( strcat( Str, "\\409700.tmp" ), strcat( Str2, "\\409700.tmq" ) );
  311. #endif
  312. Directory( Prefix );
  313. printf( "%s: Deleteing ....\n", Prefix );
  314. strcpy( Str, Prefix ); Delete( strcat( Str, "\\0.tmp" ) );
  315. strcpy( Str, Prefix ); Delete( strcat( Str, "\\1.tmp" ) );
  316. strcpy( Str, Prefix ); Delete( strcat( Str, "\\511.tmp" ) );
  317. strcpy( Str, Prefix ); Delete( strcat( Str, "\\512.tmp" ) );
  318. strcpy( Str, Prefix ); Delete( strcat( Str, "\\513.tmp" ) );
  319. strcpy( Str, Prefix ); Delete( strcat( Str, "\\1023.tmp" ) );
  320. strcpy( Str, Prefix ); Delete( strcat( Str, "\\1024.tmp" ) );
  321. strcpy( Str, Prefix ); Delete( strcat( Str, "\\1025.tmp" ) );
  322. strcpy( Str, Prefix ); Delete( strcat( Str, "\\4095.tmp" ) );
  323. strcpy( Str, Prefix ); Delete( strcat( Str, "\\4096.tmp" ) );
  324. strcpy( Str, Prefix ); Delete( strcat( Str, "\\4097.tmp" ) );
  325. strcpy( Str, Prefix ); Delete( strcat( Str, "\\8191.tmp" ) );
  326. strcpy( Str, Prefix ); Delete( strcat( Str, "\\8192.tmp" ) );
  327. strcpy( Str, Prefix ); Delete( strcat( Str, "\\8193.tmp" ) );
  328. #ifdef BIG
  329. strcpy( Str, Prefix ); Delete( strcat( Str, "\\40970.tmp" ) );
  330. strcpy( Str, Prefix ); Delete( strcat( Str, "\\81910.tmp" ) );
  331. strcpy( Str, Prefix ); Delete( strcat( Str, "\\409700.tmp" ) );
  332. #endif
  333. Directory( Prefix );
  334. }
  335. printf( "%s: Done.\n", Prefix );
  336. Quit();
  337. NtTerminateThread(NtCurrentThread(), STATUS_SUCCESS);
  338. return; // TRUE;
  339. }
  340. #ifdef undef
  341. VOID
  342. FatMain()
  343. {
  344. NTSTATUS Status;
  345. //
  346. // Wait for wakeup
  347. //
  348. if (!NT_SUCCESS(Status = NtWaitForSingleObject( StartSignal, TRUE, NULL))) {
  349. WaitForSingleObjectError( Status );
  350. return;
  351. }
  352. printf("Here Captain, number 0x%x.\n",
  353. (ULONG)NtCurrentTeb()->ClientId.UniqueThread);
  354. NtTerminateThread(NtCurrentThread(), STATUS_SUCCESS);
  355. }
  356. #endif
  357. VOID
  358. Upcase (
  359. IN OUT PUCHAR String
  360. )
  361. {
  362. while (*String != '\0') {
  363. *String = (UCHAR)toupper(*String);
  364. String += 1;
  365. }
  366. }
  367. VOID Append(
  368. IN PCHAR FromName,
  369. IN PCHAR ToName
  370. )
  371. {
  372. NTSTATUS Status;
  373. CHAR Buffer[BUFFERSIZE];
  374. HANDLE FromFileHandle;
  375. HANDLE ToFileHandle;
  376. OBJECT_ATTRIBUTES ObjectAttributes;
  377. UNICODE_STRING NameString;
  378. IO_STATUS_BLOCK IoStatus;
  379. LARGE_INTEGER ByteOffset;
  380. LARGE_INTEGER EofOffset;
  381. ULONG LogLsn;
  382. simprintf("Append ", 0);
  383. simprintf(FromName, 0);
  384. simprintf(" ", 0);
  385. simprintf(ToName, 0);
  386. simprintf("\n", 0);
  387. //
  388. // Open the From file for read access
  389. //
  390. // RtlInitString( &NameString, FromName );
  391. RtlDosPathNameToNtPathName( FromName, &NameString, NULL, NULL );
  392. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  393. if (!NT_SUCCESS(Status = NtOpenFile( &FromFileHandle,
  394. FILE_READ_DATA | SYNCHRONIZE,
  395. &ObjectAttributes,
  396. &IoStatus,
  397. 0L,
  398. WriteThrough ))) {
  399. OpenFileError( Status, FromName );
  400. return;
  401. }
  402. RtlFreeUnicodeString( &NameString );
  403. //
  404. // Open the To file for write access
  405. //
  406. // RtlInitString( &NameString, ToName );
  407. RtlDosPathNameToNtPathName( ToName, &NameString, NULL, NULL );
  408. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  409. if (!NT_SUCCESS(Status = NtOpenFile( &ToFileHandle,
  410. FILE_WRITE_DATA | SYNCHRONIZE,
  411. &ObjectAttributes,
  412. &IoStatus,
  413. 0L,
  414. WriteThrough ))) {
  415. OpenFileError( Status, ToName );
  416. return;
  417. }
  418. RtlFreeUnicodeString( &NameString );
  419. //
  420. // Now append the files
  421. //
  422. ByteOffset = LiFromLong( 0 );
  423. EofOffset = LiFromLong( FILE_WRITE_TO_END_OF_FILE );
  424. for (LogLsn = 0; TRUE; LogLsn += BUFFERSIZE/512) {
  425. ULONG ReadLength;
  426. //
  427. // Read the next logical sectors in
  428. //
  429. ByteOffset.LowPart = LogLsn * 512;
  430. if (!NT_SUCCESS(Status = NtReadFile( FromFileHandle,
  431. (HANDLE)NULL,
  432. (PIO_APC_ROUTINE)NULL,
  433. (PVOID)NULL,
  434. &IoStatus,
  435. Buffer,
  436. BUFFERSIZE,
  437. &ByteOffset,
  438. (PULONG) NULL ))) {
  439. if (Status == STATUS_END_OF_FILE) {
  440. break;
  441. }
  442. ReadFileError( Status, FromName );
  443. break;
  444. }
  445. if (!NT_SUCCESS( Status = NtWaitForSingleObject( FromFileHandle, TRUE, NULL))) {
  446. // NtPartyByNumber(50);
  447. WaitForSingleObjectError( Status );
  448. return;
  449. }
  450. //
  451. // Check how the read turned out
  452. //
  453. if (IoStatus.Status == STATUS_END_OF_FILE) {
  454. break;
  455. }
  456. CheckIoStatus( &IoStatus, BUFFERSIZE, TRUE );
  457. if (!NT_SUCCESS(IoStatus.Status)) {
  458. break;
  459. }
  460. //
  461. // Append the sectors to the To file
  462. //
  463. ReadLength = IoStatus.Information;
  464. if (!NT_SUCCESS(Status = NtWriteFile( ToFileHandle,
  465. (HANDLE)NULL,
  466. (PIO_APC_ROUTINE)NULL,
  467. (PVOID)NULL,
  468. &IoStatus,
  469. Buffer,
  470. IoStatus.Information,
  471. &EofOffset,
  472. (PULONG) NULL ))) {
  473. WriteFileError( Status, ToName );
  474. return;
  475. }
  476. if (!NT_SUCCESS(Status = NtWaitForSingleObject( ToFileHandle, TRUE, NULL))) {
  477. // NtPartyByNumber(50);
  478. WaitForSingleObjectError( Status );
  479. return;
  480. }
  481. //
  482. // Check how the write turned out
  483. //
  484. CheckIoStatus( &IoStatus, ReadLength, FALSE );
  485. if (!NT_SUCCESS(IoStatus.Status)) {
  486. IoStatusError( IoStatus.Status );
  487. break;
  488. }
  489. //
  490. // If we didn't read or write a full buffer then the copy is done
  491. //
  492. if (IoStatus.Information < BUFFERSIZE) {
  493. break;
  494. }
  495. }
  496. if (!NT_SUCCESS(IoStatus.Status) && (IoStatus.Status != STATUS_END_OF_FILE)) {
  497. IoStatusError( IoStatus.Status );
  498. }
  499. //
  500. // Close both files
  501. //
  502. if (!NT_SUCCESS(Status = NtClose( FromFileHandle ))) {
  503. CloseError( Status, FromName );
  504. }
  505. if (!NT_SUCCESS(Status = NtClose( ToFileHandle ))) {
  506. CloseError( Status, ToName );
  507. }
  508. //
  509. // And return to our caller
  510. //
  511. return;
  512. }
  513. VOID Chmode(
  514. IN PCHAR Attrib,
  515. IN PCHAR String
  516. )
  517. {
  518. CHAR Buffer[BUFFERSIZE];
  519. NTSTATUS Status;
  520. HANDLE FileHandle;
  521. OBJECT_ATTRIBUTES ObjectAttributes;
  522. UNICODE_STRING NameString;
  523. IO_STATUS_BLOCK IoStatus;
  524. ULONG FileAttribute;
  525. //
  526. // Get the attribute
  527. //
  528. Upcase( (PUCHAR)Attrib );
  529. //
  530. // Get the filename
  531. //
  532. simprintf("Chmode", 0);
  533. simprintf(String, 0);
  534. simprintf(" ", 0);
  535. simprintf(Attrib, 0);
  536. simprintf("\n", 0);
  537. //
  538. // Decode the attributes
  539. //
  540. FileAttribute = 0;
  541. if (strpbrk(Attrib,"N") != NULL) {FileAttribute |= FILE_ATTRIBUTE_NORMAL;}
  542. if (strpbrk(Attrib,"R") != NULL) {FileAttribute |= FILE_ATTRIBUTE_READONLY;}
  543. if (strpbrk(Attrib,"H") != NULL) {FileAttribute |= FILE_ATTRIBUTE_HIDDEN;}
  544. if (strpbrk(Attrib,"S") != NULL) {FileAttribute |= FILE_ATTRIBUTE_SYSTEM;}
  545. if (strpbrk(Attrib,"A") != NULL) {FileAttribute |= FILE_ATTRIBUTE_ARCHIVE;}
  546. //
  547. // Open the file for write attributes access
  548. //
  549. // RtlInitString( &NameString, String );
  550. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  551. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  552. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  553. FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
  554. &ObjectAttributes,
  555. &IoStatus,
  556. 0L,
  557. WriteThrough ))) {
  558. OpenFileError( Status, String );
  559. return;
  560. }
  561. //
  562. // Change the file attributes
  563. //
  564. ((PFILE_BASIC_INFORMATION)&Buffer[0])->CreationTime.HighPart = 0;
  565. ((PFILE_BASIC_INFORMATION)&Buffer[0])->CreationTime.LowPart = 0;
  566. ((PFILE_BASIC_INFORMATION)&Buffer[0])->LastAccessTime.HighPart = 0;
  567. ((PFILE_BASIC_INFORMATION)&Buffer[0])->LastAccessTime.LowPart = 0;
  568. ((PFILE_BASIC_INFORMATION)&Buffer[0])->LastWriteTime.HighPart = 0;
  569. ((PFILE_BASIC_INFORMATION)&Buffer[0])->LastWriteTime.LowPart = 0;
  570. ((PFILE_BASIC_INFORMATION)&Buffer[0])->FileAttributes = FileAttribute;
  571. if (!NT_SUCCESS(Status = NtSetInformationFile( FileHandle,
  572. &IoStatus,
  573. Buffer,
  574. sizeof(FILE_BASIC_INFORMATION),
  575. FileBasicInformation))) {
  576. SetInformationFileError( Status );
  577. }
  578. //
  579. // Now close the file
  580. //
  581. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  582. CloseError( Status, String );
  583. }
  584. //
  585. // And return to our caller
  586. //
  587. RtlFreeUnicodeString( &NameString );
  588. return;
  589. }
  590. VOID Copy(
  591. IN PCHAR FromName,
  592. IN PCHAR ToName
  593. )
  594. {
  595. CHAR Buffer[BUFFERSIZE];
  596. NTSTATUS Status;
  597. HANDLE FromFileHandle;
  598. HANDLE ToFileHandle;
  599. OBJECT_ATTRIBUTES ObjectAttributes;
  600. UNICODE_STRING NameString;
  601. IO_STATUS_BLOCK IoStatus;
  602. LARGE_INTEGER FromFileAllocation;
  603. LARGE_INTEGER ByteOffset;
  604. ULONG LogLsn;
  605. //
  606. // Get both file names
  607. //
  608. simprintf("Copy ", 0);
  609. simprintf(FromName, 0);
  610. simprintf(" ", 0);
  611. simprintf(ToName, 0);
  612. simprintf("\n", 0);
  613. //
  614. // Open the From file for read access
  615. //
  616. // RtlInitString( &NameString, FromName );
  617. RtlDosPathNameToNtPathName( FromName, &NameString, NULL, NULL );
  618. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  619. if (!NT_SUCCESS(Status = NtOpenFile( &FromFileHandle,
  620. FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
  621. &ObjectAttributes,
  622. &IoStatus,
  623. 0L,
  624. WriteThrough ))) {
  625. OpenFileError( Status, FromName );
  626. return;
  627. }
  628. RtlFreeUnicodeString( &NameString );
  629. //
  630. // Get the size of the from file
  631. //
  632. if (!NT_SUCCESS(Status = NtQueryInformationFile( FromFileHandle,
  633. &IoStatus,
  634. Buffer,
  635. BUFFERSIZE,
  636. FileStandardInformation))) {
  637. QueryInformationFileError( Status );
  638. return;
  639. }
  640. FromFileAllocation = ((PFILE_STANDARD_INFORMATION)Buffer)->AllocationSize;
  641. //
  642. // Create the To file
  643. //
  644. // RtlInitString( &NameString, ToName );
  645. RtlDosPathNameToNtPathName( ToName, &NameString, NULL, NULL );
  646. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  647. if (!NT_SUCCESS(Status = NtCreateFile( &ToFileHandle,
  648. FILE_WRITE_DATA | SYNCHRONIZE,
  649. &ObjectAttributes,
  650. &IoStatus,
  651. &FromFileAllocation,
  652. FILE_ATTRIBUTE_NORMAL,
  653. 0L,
  654. FILE_SUPERSEDE,
  655. WriteThrough,
  656. (PVOID)NULL,
  657. 0L ))) {
  658. CreateFileError( Status, ToName );
  659. return;
  660. }
  661. RtlFreeUnicodeString( &NameString );
  662. //
  663. // Now copy the files
  664. //
  665. ByteOffset = LiFromLong( 0 );
  666. for (LogLsn = 0; TRUE; LogLsn += BUFFERSIZE/512) {
  667. ULONG ReadLength;
  668. //
  669. // Read the next logical sectors in
  670. //
  671. ByteOffset.LowPart = LogLsn * 512;
  672. if (!NT_SUCCESS(Status = NtReadFile( FromFileHandle,
  673. (HANDLE)NULL,
  674. (PIO_APC_ROUTINE)NULL,
  675. (PVOID)NULL,
  676. &IoStatus,
  677. Buffer,
  678. BUFFERSIZE,
  679. &ByteOffset,
  680. (PULONG) NULL ))) {
  681. if (Status == STATUS_END_OF_FILE) {
  682. break;
  683. }
  684. ReadFileError( Status, FromName );
  685. break;
  686. }
  687. if (!NT_SUCCESS(Status = NtWaitForSingleObject( FromFileHandle, TRUE, NULL))) {
  688. // NtPartyByNumber(50);
  689. WaitForSingleObjectError( Status );
  690. return;
  691. }
  692. //
  693. // Check how the read turned out
  694. //
  695. if (IoStatus.Status == STATUS_END_OF_FILE) {
  696. break;
  697. }
  698. CheckIoStatus( &IoStatus, BUFFERSIZE, TRUE );
  699. if (!NT_SUCCESS(IoStatus.Status)) {
  700. break;
  701. }
  702. //
  703. // Write the sectors out
  704. //
  705. ReadLength = IoStatus.Information;
  706. if (!NT_SUCCESS(Status = NtWriteFile( ToFileHandle,
  707. (HANDLE)NULL,
  708. (PIO_APC_ROUTINE)NULL,
  709. (PVOID)NULL,
  710. &IoStatus,
  711. Buffer,
  712. IoStatus.Information,
  713. &ByteOffset,
  714. (PULONG) NULL ))) {
  715. WriteFileError( Status, ToName );
  716. return;
  717. }
  718. if (!NT_SUCCESS(Status = NtWaitForSingleObject( ToFileHandle, TRUE, NULL))) {
  719. // NtPartyByNumber(50);
  720. WaitForSingleObjectError( Status );
  721. return;
  722. }
  723. //
  724. // Check how the write turned out
  725. //
  726. CheckIoStatus( &IoStatus, ReadLength, FALSE );
  727. if (!NT_SUCCESS(IoStatus.Status)) {
  728. IoStatusError( IoStatus.Status );
  729. break;
  730. }
  731. //
  732. // If we didn't read or write a full buffer then the copy is done
  733. //
  734. if (IoStatus.Information < BUFFERSIZE) {
  735. break;
  736. }
  737. }
  738. if (!NT_SUCCESS(IoStatus.Status) && (IoStatus.Status != STATUS_END_OF_FILE)) {
  739. IoStatusError( IoStatus.Status );
  740. }
  741. //
  742. // Close both files
  743. //
  744. if (!NT_SUCCESS(Status = NtClose( FromFileHandle ))) {
  745. CloseError( Status, FromName );
  746. }
  747. if (!NT_SUCCESS(Status = NtClose( ToFileHandle ))) {
  748. CloseError( Status, ToName );
  749. }
  750. //
  751. // And return to our caller
  752. //
  753. return;
  754. }
  755. VOID Create(
  756. IN PCHAR String,
  757. IN ULONG Size
  758. )
  759. {
  760. CHAR Buffer[BUFFERSIZE];
  761. NTSTATUS Status;
  762. HANDLE FileHandle;
  763. OBJECT_ATTRIBUTES ObjectAttributes;
  764. UNICODE_STRING NameString;
  765. IO_STATUS_BLOCK IoStatus;
  766. LARGE_INTEGER AllocationSize;
  767. LARGE_INTEGER ByteOffset;
  768. ULONG BufferLength;
  769. ULONG i;
  770. static CHAR FoxString[] = "The quick brown fox jumped over the lazy dog.\r\n";
  771. ULONG FoxLength;
  772. //
  773. // Get the filename
  774. //
  775. simprintf("Create ", 0);
  776. simprintf(String, 0);
  777. simprintf("\n", 0);
  778. //
  779. // Create the new file
  780. //
  781. AllocationSize = LiFromUlong( Size );
  782. // RtlInitString( &NameString, String );
  783. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  784. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  785. if (!NT_SUCCESS(Status = NtCreateFile( &FileHandle,
  786. FILE_WRITE_DATA | SYNCHRONIZE,
  787. &ObjectAttributes,
  788. &IoStatus,
  789. &AllocationSize,
  790. FILE_ATTRIBUTE_NORMAL,
  791. 0L,
  792. FILE_SUPERSEDE,
  793. WriteThrough,
  794. (PVOID)NULL,
  795. 0L ))) {
  796. CreateFileError( Status, String );
  797. return;
  798. }
  799. //
  800. // create a test buffer to output
  801. //
  802. FoxLength = strlen(FoxString);
  803. for (i = FoxLength; i < BUFFERSIZE; i += FoxLength) {
  804. strcpy((PCHAR)&Buffer[i-FoxLength], FoxString);
  805. }
  806. BufferLength = i - FoxLength;
  807. //
  808. // The main loop writes out the test buffer a BufferLength amount
  809. // at a time
  810. //
  811. ByteOffset = LiFromLong( 0 );
  812. for (i = BufferLength; i < Size; i += BufferLength) {
  813. //
  814. // Write the next buffer
  815. //
  816. ByteOffset.LowPart = i-BufferLength;
  817. if (!NT_SUCCESS(Status = NtWriteFile( FileHandle,
  818. (HANDLE)NULL,
  819. (PIO_APC_ROUTINE)NULL,
  820. (PVOID)NULL,
  821. &IoStatus,
  822. Buffer,
  823. BufferLength,
  824. &ByteOffset,
  825. (PULONG) NULL ))) {
  826. WriteFileError( Status, String );
  827. return;
  828. }
  829. if (!NT_SUCCESS(Status = NtWaitForSingleObject( FileHandle, TRUE, NULL))) {
  830. // NtPartyByNumber(50);
  831. WaitForSingleObjectError( Status );
  832. return;
  833. }
  834. //
  835. // check how the write turned out
  836. //
  837. CheckIoStatus( &IoStatus, BufferLength, FALSE );
  838. if (!NT_SUCCESS(IoStatus.Status)) {
  839. IoStatusError( IoStatus.Status );
  840. break;
  841. }
  842. }
  843. //
  844. // Check for a residual to output
  845. //
  846. if (i - BufferLength < Size) {
  847. //
  848. // Write out the residual buffer
  849. //
  850. ByteOffset.LowPart = i-BufferLength;
  851. if (!NT_SUCCESS(Status = NtWriteFile( FileHandle,
  852. (HANDLE)NULL,
  853. (PIO_APC_ROUTINE)NULL,
  854. (PVOID)NULL,
  855. &IoStatus,
  856. Buffer,
  857. Size - (i - BufferLength),
  858. &ByteOffset,
  859. (PULONG) NULL ))) {
  860. WriteFileError( Status, String );
  861. return;
  862. }
  863. if (!NT_SUCCESS(Status = NtWaitForSingleObject( FileHandle, TRUE, NULL))) {
  864. // NtPartyByNumber(50);
  865. WaitForSingleObjectError( Status );
  866. return;
  867. }
  868. //
  869. // check how the write turned out
  870. //
  871. CheckIoStatus( &IoStatus, Size - (i - BufferLength), FALSE );
  872. if (!NT_SUCCESS(IoStatus.Status)) {
  873. IoStatusError( IoStatus.Status );
  874. }
  875. }
  876. //
  877. // Now close the file
  878. //
  879. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  880. CloseError( Status, String );
  881. }
  882. //
  883. // And return to our caller
  884. //
  885. RtlFreeUnicodeString( &NameString );
  886. return;
  887. }
  888. VOID DebugLevel()
  889. {
  890. #ifdef FATDBG
  891. //simprintf("Debug Trace Level %x\n", FatDebugTraceLevel);
  892. #else
  893. //simprintf("System not compiled for debug tracing\n", 0);
  894. #endif // FATDBG
  895. return;
  896. }
  897. VOID Delete(
  898. IN PCHAR String
  899. )
  900. {
  901. CHAR Buffer[BUFFERSIZE];
  902. NTSTATUS Status;
  903. HANDLE FileHandle;
  904. OBJECT_ATTRIBUTES ObjectAttributes;
  905. UNICODE_STRING NameString;
  906. IO_STATUS_BLOCK IoStatus;
  907. //
  908. // Get the filename
  909. //
  910. simprintf("Delete ", 0);
  911. simprintf(String, 0);
  912. simprintf("\n", 0);
  913. //
  914. // Open the file for delete access
  915. //
  916. // RtlInitString( &NameString, String );
  917. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  918. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  919. if (!NT_SUCCESS(Status = NtCreateFile( &FileHandle,
  920. DELETE | SYNCHRONIZE,
  921. &ObjectAttributes,
  922. &IoStatus,
  923. (PLARGE_INTEGER)NULL,
  924. 0L,
  925. 0L,
  926. FILE_OPEN,
  927. WriteThrough,
  928. (PVOID)NULL,
  929. 0L ))) {
  930. CreateFileError( Status, String );
  931. return;
  932. }
  933. //
  934. // Mark the file for delete
  935. //
  936. ((PFILE_DISPOSITION_INFORMATION)&Buffer[0])->DeleteFile = TRUE;
  937. if (!NT_SUCCESS(Status = NtSetInformationFile( FileHandle,
  938. &IoStatus,
  939. Buffer,
  940. sizeof(FILE_DISPOSITION_INFORMATION),
  941. FileDispositionInformation))) {
  942. SetInformationFileError( Status );
  943. return;
  944. }
  945. //
  946. // Now close the file
  947. //
  948. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  949. CloseError( Status, String );
  950. }
  951. //
  952. // And return to our caller
  953. //
  954. RtlFreeUnicodeString( &NameString );
  955. return;
  956. }
  957. VOID Directory(
  958. IN PCHAR String
  959. )
  960. {
  961. CHAR Buffer[BUFFERSIZE];
  962. NTSTATUS Status;
  963. HANDLE FileHandle;
  964. OBJECT_ATTRIBUTES ObjectAttributes;
  965. UNICODE_STRING NameString;
  966. IO_STATUS_BLOCK IoStatus;
  967. NTSTATUS NtStatus;
  968. PFILE_ADIRECTORY_INFORMATION FileInfo;
  969. // ULONG i;
  970. //
  971. // Get the filename
  972. //
  973. simprintf("Directory ", 0);
  974. simprintf(String, 0);
  975. simprintf("\n", 0);
  976. //
  977. // Open the file for list directory access
  978. //
  979. // RtlInitString( &NameString, String );
  980. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  981. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  982. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  983. FILE_LIST_DIRECTORY | SYNCHRONIZE,
  984. &ObjectAttributes,
  985. &IoStatus,
  986. FILE_SHARE_READ,
  987. WriteThrough | FILE_DIRECTORY_FILE ))) {
  988. OpenFileError( Status, String );
  989. return;
  990. }
  991. //
  992. // zero out the buffer so next time we'll recognize the end of data
  993. //
  994. RtlZeroMemory(Buffer, BUFFERSIZE);
  995. //
  996. // Do the directory loop
  997. //
  998. for (NtStatus = NtQueryDirectoryFile( FileHandle,
  999. (HANDLE)NULL,
  1000. (PIO_APC_ROUTINE)NULL,
  1001. (PVOID)NULL,
  1002. &IoStatus,
  1003. Buffer,
  1004. BUFFERSIZE,
  1005. FileADirectoryInformation,
  1006. FALSE,
  1007. (PSTRING)NULL,
  1008. TRUE);
  1009. NT_SUCCESS(NtStatus);
  1010. NtStatus = NtQueryDirectoryFile( FileHandle,
  1011. (HANDLE)NULL,
  1012. (PIO_APC_ROUTINE)NULL,
  1013. (PVOID)NULL,
  1014. &IoStatus,
  1015. Buffer,
  1016. BUFFERSIZE,
  1017. FileADirectoryInformation,
  1018. FALSE,
  1019. (PSTRING)NULL,
  1020. FALSE) ) {
  1021. if (!NT_SUCCESS(Status = NtWaitForSingleObject(FileHandle, TRUE, NULL))) {
  1022. // NtPartyByNumber(50);
  1023. WaitForSingleObjectError( Status );
  1024. return;
  1025. }
  1026. //
  1027. // Check the Irp for success
  1028. //
  1029. if (!NT_SUCCESS(IoStatus.Status)) {
  1030. break;
  1031. }
  1032. //
  1033. // For every record in the buffer type out the directory information
  1034. //
  1035. //
  1036. // Point to the first record in the buffer, we are guaranteed to have
  1037. // one otherwise IoStatus would have been No More Files
  1038. //
  1039. FileInfo = (PFILE_ADIRECTORY_INFORMATION)&Buffer[0];
  1040. while (TRUE) {
  1041. //
  1042. // Lets put in some checks to make sure these are ok.
  1043. //
  1044. ASSERT(FileInfo->FileNameLength < MAXIMUM_FILENAME_LENGTH);
  1045. ASSERT(FileInfo->NextEntryOffset < MAXIMUM_FILENAME_LENGTH+sizeof(FILE_ADIRECTORY_INFORMATION)+4);
  1046. //
  1047. // Print out information about the file
  1048. //
  1049. simprintf("%8lx ", FileInfo->FileAttributes);
  1050. simprintf("%8lx/", FileInfo->EndOfFile.LowPart);
  1051. simprintf("%8lx ", FileInfo->AllocationSize.LowPart);
  1052. {
  1053. CHAR Saved;
  1054. Saved = FileInfo->FileName[FileInfo->FileNameLength];
  1055. FileInfo->FileName[FileInfo->FileNameLength] = 0;
  1056. simprintf(FileInfo->FileName, 0);
  1057. FileInfo->FileName[FileInfo->FileNameLength] = Saved;
  1058. }
  1059. simprintf("\n", 0);
  1060. //
  1061. // Check if there is another record, if there isn't then we
  1062. // simply get out of this loop
  1063. //
  1064. if (FileInfo->NextEntryOffset == 0) {
  1065. break;
  1066. }
  1067. //
  1068. // There is another record so advance FileInfo to the next
  1069. // record
  1070. //
  1071. FileInfo = (PFILE_ADIRECTORY_INFORMATION)(((PUCHAR)FileInfo) + FileInfo->NextEntryOffset);
  1072. }
  1073. //
  1074. // zero out the buffer so next time we'll recognize the end of data
  1075. //
  1076. RtlZeroMemory(Buffer, BUFFERSIZE);
  1077. }
  1078. //
  1079. // Now close the file
  1080. //
  1081. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1082. CloseError( Status, String );
  1083. }
  1084. //
  1085. // And return to our caller
  1086. //
  1087. RtlFreeUnicodeString( &NameString );
  1088. return;
  1089. }
  1090. VOID Mkdir(
  1091. IN PCHAR String
  1092. )
  1093. {
  1094. NTSTATUS Status;
  1095. HANDLE FileHandle;
  1096. OBJECT_ATTRIBUTES ObjectAttributes;
  1097. UNICODE_STRING NameString;
  1098. IO_STATUS_BLOCK IoStatus;
  1099. LARGE_INTEGER AllocationSize;
  1100. //
  1101. // Get the filename
  1102. //
  1103. simprintf("Mkdir ", 0);
  1104. simprintf(String, 0);
  1105. simprintf("\n", 0);
  1106. //
  1107. // Create the new directory
  1108. //
  1109. AllocationSize = LiFromLong( 4 );
  1110. // RtlInitString( &NameString, String );
  1111. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  1112. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  1113. if (!NT_SUCCESS(Status = NtCreateFile( &FileHandle,
  1114. SYNCHRONIZE,
  1115. &ObjectAttributes,
  1116. &IoStatus,
  1117. &AllocationSize,
  1118. 0L,
  1119. 0L,
  1120. FILE_CREATE,
  1121. WriteThrough | FILE_DIRECTORY_FILE,
  1122. (PVOID)NULL,
  1123. 0L ))) {
  1124. CreateFileError( Status, String );
  1125. return;
  1126. }
  1127. //
  1128. // Now close the directory
  1129. //
  1130. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1131. CloseError( Status, String );
  1132. }
  1133. //
  1134. // And return to our caller
  1135. //
  1136. RtlFreeUnicodeString( &NameString );
  1137. return;
  1138. }
  1139. VOID Query(
  1140. IN PCHAR String
  1141. )
  1142. {
  1143. CHAR Buffer[BUFFERSIZE];
  1144. NTSTATUS Status;
  1145. HANDLE FileHandle;
  1146. OBJECT_ATTRIBUTES ObjectAttributes;
  1147. UNICODE_STRING NameString;
  1148. IO_STATUS_BLOCK IoStatus;
  1149. ULONG i;
  1150. PFILE_AALL_INFORMATION AllInfo;
  1151. PFILE_BASIC_INFORMATION BasicInfo;
  1152. PFILE_STANDARD_INFORMATION StandardInfo;
  1153. PFILE_INTERNAL_INFORMATION InternalInfo;
  1154. PFILE_EA_INFORMATION EaInfo;
  1155. PFILE_ACCESS_INFORMATION AccessInfo;
  1156. PFILE_ANAME_INFORMATION NameInfo;
  1157. //
  1158. // zero out the buffer so next time we'll recognize the end of data
  1159. //
  1160. for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; }
  1161. //
  1162. // Set up some local pointers
  1163. //
  1164. AllInfo = (PFILE_AALL_INFORMATION)Buffer;
  1165. BasicInfo = &AllInfo->BasicInformation;
  1166. StandardInfo = &AllInfo->StandardInformation;
  1167. InternalInfo = &AllInfo->InternalInformation;
  1168. EaInfo = &AllInfo->EaInformation;
  1169. AccessInfo = &AllInfo->AccessInformation;
  1170. NameInfo = &AllInfo->NameInformation;
  1171. //
  1172. // Get the filename
  1173. //
  1174. simprintf("Query ", 0);
  1175. simprintf(String, 0);
  1176. simprintf("\n", 0);
  1177. //
  1178. // Open the file for read attributes, read ea, and read control access
  1179. //
  1180. // RtlInitString( &NameString, String );
  1181. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  1182. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  1183. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  1184. FILE_READ_ATTRIBUTES | FILE_READ_EA | READ_CONTROL | SYNCHRONIZE,
  1185. &ObjectAttributes,
  1186. &IoStatus,
  1187. 0L,
  1188. WriteThrough ))) {
  1189. OpenFileError( Status, String );
  1190. return;
  1191. }
  1192. //
  1193. // Query the file
  1194. //
  1195. if (!NT_SUCCESS(Status = NtQueryInformationFile( FileHandle,
  1196. &IoStatus,
  1197. Buffer,
  1198. BUFFERSIZE,
  1199. FileAAllInformation))) {
  1200. QueryInformationFileError( Status );
  1201. return;
  1202. }
  1203. //
  1204. // Output file name information
  1205. //
  1206. simprintf("\"", 0);
  1207. simprintf(NameInfo->FileName, 0);
  1208. simprintf("\"\n", 0);
  1209. //
  1210. // Output the times
  1211. //
  1212. simprintf(" Create = ", 0); PrintTime( &BasicInfo->CreationTime ); simprintf("\n", 0);
  1213. simprintf(" Access = ", 0); PrintTime( &BasicInfo->LastAccessTime ); simprintf("\n", 0);
  1214. simprintf(" Write = ", 0); PrintTime( &BasicInfo->LastWriteTime ); simprintf("\n", 0);
  1215. //
  1216. // Output File size, and allocation size
  1217. //
  1218. simprintf(" Size = %8lx\n", StandardInfo->EndOfFile.LowPart);
  1219. simprintf(" Alloc = %8lx\n", StandardInfo->AllocationSize.LowPart);
  1220. //
  1221. // Output File attributes, Device type, link count, and flags
  1222. //
  1223. simprintf(" Attrib = %8lx\n", BasicInfo->FileAttributes);
  1224. // simprintf(" DevType = %8lx\n", StandardInfo->DeviceType);
  1225. simprintf(" Links = %8lx\n", StandardInfo->NumberOfLinks);
  1226. simprintf(" Dir = %8lx\n", StandardInfo->Directory);
  1227. simprintf(" Delete = %8lx\n", StandardInfo->DeletePending);
  1228. //
  1229. // Output the index number and ea size
  1230. //
  1231. simprintf(" Index = %8lx\n", InternalInfo->IndexNumber.LowPart);
  1232. simprintf(" EaSize = %8lx\n", EaInfo->EaSize);
  1233. //
  1234. // Output the file access flags
  1235. //
  1236. simprintf(" Flags = %8lx\n", AccessInfo->AccessFlags);
  1237. //
  1238. // Now close the file
  1239. //
  1240. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1241. CloseError( Status, String );
  1242. }
  1243. //
  1244. // And return to our caller
  1245. //
  1246. RtlFreeUnicodeString( &NameString );
  1247. return;
  1248. }
  1249. VOID QVolume(
  1250. IN PCHAR String
  1251. )
  1252. {
  1253. CHAR Buffer[BUFFERSIZE];
  1254. NTSTATUS Status;
  1255. HANDLE FileHandle;
  1256. OBJECT_ATTRIBUTES ObjectAttributes;
  1257. UNICODE_STRING NameString;
  1258. IO_STATUS_BLOCK IoStatus;
  1259. ULONG i;
  1260. PFILE_FS_AVOLUME_INFORMATION VolumeInfo;
  1261. //
  1262. // zero out the buffer so next time we'll recognize the end of data
  1263. //
  1264. for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; }
  1265. //
  1266. // Set up some local pointers
  1267. //
  1268. VolumeInfo = (PFILE_FS_AVOLUME_INFORMATION)Buffer;
  1269. //
  1270. // Get the volume name
  1271. //
  1272. simprintf("QVolume ", 0);
  1273. simprintf(String, 0);
  1274. simprintf("\n", 0);
  1275. //
  1276. // Open the Volume for no access
  1277. //
  1278. // RtlInitString( &NameString, String );
  1279. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  1280. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  1281. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  1282. FILE_READ_ATTRIBUTES | SYNCHRONIZE,
  1283. &ObjectAttributes,
  1284. &IoStatus,
  1285. 0L,
  1286. WriteThrough ))) {
  1287. OpenFileError( Status, String );
  1288. return;
  1289. }
  1290. //
  1291. // zero out the buffer so next time we'll recognize the end of data
  1292. //
  1293. for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; }
  1294. //
  1295. // Query the volume info
  1296. //
  1297. if (!NT_SUCCESS(Status = NtQueryVolumeInformationFile( FileHandle,
  1298. &IoStatus,
  1299. Buffer,
  1300. BUFFERSIZE,
  1301. FileAFsVolumeInformation))) {
  1302. QueryVolumeInformationFileError( Status );
  1303. return;
  1304. }
  1305. //
  1306. // Output Volume name information
  1307. //
  1308. simprintf("\"", 0);
  1309. simprintf(VolumeInfo->VolumeLabel, 0);
  1310. simprintf("\"\n", 0);
  1311. //
  1312. // Output the volume serial number
  1313. //
  1314. simprintf(" SerialNum = %8lx\n", VolumeInfo->VolumeSerialNumber);
  1315. //
  1316. // Now close the Volume
  1317. //
  1318. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1319. CloseError( Status, String );
  1320. }
  1321. //
  1322. // And return to our caller
  1323. //
  1324. RtlFreeUnicodeString( &NameString );
  1325. return;
  1326. }
  1327. VOID Rename()
  1328. {
  1329. //simprintf("Rename not implemented\n", 0);
  1330. }
  1331. VOID SVolume(
  1332. IN PCHAR String,
  1333. IN PCHAR Label
  1334. )
  1335. {
  1336. CHAR Buffer[BUFFERSIZE];
  1337. NTSTATUS Status;
  1338. HANDLE FileHandle;
  1339. OBJECT_ATTRIBUTES ObjectAttributes;
  1340. UNICODE_STRING NameString;
  1341. IO_STATUS_BLOCK IoStatus;
  1342. ULONG i;
  1343. PFILE_FS_ALABEL_INFORMATION LabelInfo;
  1344. //
  1345. // zero out the buffer so next time we'll recognize the end of data
  1346. //
  1347. for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; }
  1348. //
  1349. // Set up some local pointers
  1350. //
  1351. LabelInfo = (PFILE_FS_ALABEL_INFORMATION)Buffer;
  1352. //
  1353. // Get the volume name, and new label name
  1354. //
  1355. strcpy( LabelInfo->VolumeLabel, Label );
  1356. LabelInfo->VolumeLabelLength = strlen(LabelInfo->VolumeLabel);
  1357. if ((LabelInfo->VolumeLabelLength == 1) &&
  1358. (LabelInfo->VolumeLabel[0] == '.')) {
  1359. LabelInfo->VolumeLabelLength = 0;
  1360. }
  1361. simprintf("SVolume ", 0);
  1362. simprintf(String, 0);
  1363. simprintf(" ", 0);
  1364. simprintf(LabelInfo->VolumeLabel, 0);
  1365. simprintf("\n", 0);
  1366. //
  1367. // Open the Volume for no access
  1368. //
  1369. // RtlInitString( &NameString, String );
  1370. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  1371. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  1372. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  1373. FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
  1374. &ObjectAttributes,
  1375. &IoStatus,
  1376. 0L,
  1377. WriteThrough ))) {
  1378. OpenFileError( Status, String );
  1379. return;
  1380. }
  1381. //
  1382. // Set the volume info
  1383. //
  1384. if (!NT_SUCCESS(Status = NtSetVolumeInformationFile( FileHandle,
  1385. &IoStatus,
  1386. LabelInfo,
  1387. BUFFERSIZE,
  1388. FileAFsLabelInformation))) {
  1389. SetVolumeInformationFileError( Status );
  1390. return;
  1391. }
  1392. //
  1393. // Now close the Volume
  1394. //
  1395. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1396. CloseError( Status, String );
  1397. }
  1398. //
  1399. // And return to our caller
  1400. //
  1401. RtlFreeUnicodeString( &NameString );
  1402. return;
  1403. }
  1404. VOID Type(
  1405. IN PCHAR String
  1406. )
  1407. {
  1408. CHAR Buffer[BUFFERSIZE];
  1409. NTSTATUS Status;
  1410. HANDLE FileHandle;
  1411. OBJECT_ATTRIBUTES ObjectAttributes;
  1412. UNICODE_STRING NameString;
  1413. IO_STATUS_BLOCK IoStatus;
  1414. LARGE_INTEGER ByteOffset;
  1415. ULONG LogLsn;
  1416. ULONG i;
  1417. //
  1418. // Get the filename
  1419. //
  1420. simprintf("Type ", 0);
  1421. simprintf(String, 0);
  1422. simprintf("\n", 0);
  1423. //
  1424. // Open the file for read
  1425. //
  1426. // RtlInitString( &NameString, String );
  1427. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  1428. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  1429. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  1430. FILE_READ_DATA | SYNCHRONIZE,
  1431. &ObjectAttributes,
  1432. &IoStatus,
  1433. 0L,
  1434. WriteThrough ))) {
  1435. OpenFileError( Status, String );
  1436. return;
  1437. }
  1438. //
  1439. // While there is data to be read we'll read a buffer and write it out
  1440. //
  1441. ByteOffset = LiFromLong( 0 );
  1442. for (LogLsn = 0; TRUE; LogLsn += BUFFERSIZE/512) {
  1443. //
  1444. // Read the next logical sector
  1445. //
  1446. ByteOffset.LowPart = LogLsn * 512;
  1447. if (!NT_SUCCESS(Status = NtReadFile( FileHandle,
  1448. (HANDLE)NULL,
  1449. (PIO_APC_ROUTINE)NULL,
  1450. (PVOID)NULL,
  1451. &IoStatus,
  1452. Buffer,
  1453. BUFFERSIZE,
  1454. &ByteOffset,
  1455. (PULONG) NULL ))) {
  1456. if (Status == STATUS_END_OF_FILE) {
  1457. break;
  1458. }
  1459. ReadFileError( Status, String );
  1460. break;
  1461. }
  1462. if (!NT_SUCCESS(Status = NtWaitForSingleObject( FileHandle, TRUE, NULL))) {
  1463. // NtPartyByNumber(50);
  1464. WaitForSingleObjectError( Status );
  1465. return;
  1466. }
  1467. //
  1468. // check how the read turned out
  1469. //
  1470. if (IoStatus.Status == STATUS_END_OF_FILE) {
  1471. break;
  1472. }
  1473. CheckIoStatus( &IoStatus, BUFFERSIZE, TRUE );
  1474. if (!NT_SUCCESS(IoStatus.Status)) {
  1475. IoStatusError( IoStatus.Status );
  1476. break;
  1477. }
  1478. //
  1479. // Write out the buffer
  1480. //
  1481. for (i = 0; i < IoStatus.Information; i += 1) {
  1482. simprintf("%c", Buffer[i]);
  1483. }
  1484. //
  1485. // If we didn't read in a complete buffer then we're all done reading
  1486. // and can get out of here
  1487. //
  1488. if (IoStatus.Information < BUFFERSIZE) {
  1489. break;
  1490. }
  1491. }
  1492. //
  1493. // Now close the file
  1494. //
  1495. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1496. CloseError( Status, String );
  1497. }
  1498. //
  1499. // And return to our caller
  1500. //
  1501. RtlFreeUnicodeString( &NameString );
  1502. return;
  1503. }
  1504. VOID
  1505. Quit()
  1506. {
  1507. simprintf("FatTest Exiting.\n", 0);
  1508. return;
  1509. }
  1510. VOID
  1511. PrintTime (
  1512. IN PLARGE_INTEGER Time
  1513. )
  1514. {
  1515. TIME_FIELDS TimeFields;
  1516. static PCHAR Months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
  1517. "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  1518. static PCHAR Days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  1519. RtlTimeToTimeFields( Time, &TimeFields );
  1520. simprintf(" %4d-", TimeFields.Year);
  1521. simprintf(Months[TimeFields.Month-1], 0);
  1522. simprintf("-%2d", TimeFields.Day);
  1523. simprintf(" %2d", TimeFields.Hour);
  1524. simprintf(":%2d", TimeFields.Minute);
  1525. simprintf(":%2d", TimeFields.Second);
  1526. simprintf(".%3d (", TimeFields.Milliseconds);
  1527. simprintf(Days[TimeFields.Weekday], 0);
  1528. simprintf(")", 0);
  1529. return;
  1530. }
  1531. VOID
  1532. WaitForSingleObjectError(
  1533. IN NTSTATUS Status
  1534. )
  1535. {
  1536. printf(" WaitForSingleObject Error %X\n", Status);
  1537. }
  1538. VOID
  1539. CreateFileError(
  1540. IN NTSTATUS Status,
  1541. IN PUCHAR File
  1542. )
  1543. {
  1544. printf(" CreateFile Error %X on %s\n", Status, File);
  1545. }
  1546. VOID
  1547. OpenFileError(
  1548. IN NTSTATUS Status,
  1549. IN PUCHAR File
  1550. )
  1551. {
  1552. printf(" OpenFile Error %X on %s\n", Status, File);
  1553. }
  1554. VOID
  1555. ReadFileError(
  1556. IN NTSTATUS Status,
  1557. IN PUCHAR File
  1558. )
  1559. {
  1560. printf(" ReadFile Error %X on %s\n", Status, File);
  1561. }
  1562. VOID
  1563. WriteFileError(
  1564. IN NTSTATUS Status,
  1565. IN PUCHAR File
  1566. )
  1567. {
  1568. printf(" WriteFile Error %X on %s\n", Status, File);
  1569. }
  1570. VOID
  1571. CheckIoStatus(
  1572. IN PIO_STATUS_BLOCK IoStatus,
  1573. IN ULONG Length,
  1574. IN BOOLEAN Read
  1575. )
  1576. {
  1577. if (!NT_SUCCESS(IoStatus->Status)) {
  1578. printf(" IoStatus->Status Error %08lx\n", IoStatus->Status);
  1579. }
  1580. if ((!Read && (IoStatus->Information != Length))
  1581. ||
  1582. (Read && (IoStatus->Information > Length))) {
  1583. printf(" IoStatus->Information Error %08lx\n", IoStatus->Information);
  1584. }
  1585. }
  1586. VOID
  1587. SetInformationFileError(
  1588. IN NTSTATUS Status
  1589. )
  1590. {
  1591. printf(" SetInfoFile Error %X\n", Status);
  1592. }
  1593. VOID
  1594. QueryInformationFileError(
  1595. IN NTSTATUS Status
  1596. )
  1597. {
  1598. printf(" QueryInfoFile Error %X\n", Status);
  1599. }
  1600. VOID
  1601. SetVolumeInformationFileError(
  1602. IN NTSTATUS Status
  1603. )
  1604. {
  1605. printf(" SetVolumeInfoFile Error %X\n", Status);
  1606. }
  1607. VOID
  1608. QueryVolumeInformationFileError(
  1609. IN NTSTATUS Status
  1610. )
  1611. {
  1612. printf(" QueryVolumeInfoFile Error %X\n", Status);
  1613. }
  1614. VOID
  1615. CloseError(
  1616. IN NTSTATUS Status,
  1617. IN PUCHAR File
  1618. )
  1619. {
  1620. printf(" Close Error %8lx on %s\n", Status, File);
  1621. }
  1622. VOID
  1623. IoStatusError(
  1624. IN NTSTATUS Status
  1625. )
  1626. {
  1627. printf(" IoStatus Error %8lx\n", Status);
  1628. }
  1629. VOID
  1630. CreateThreadError(
  1631. IN NTSTATUS Status
  1632. )
  1633. {
  1634. printf(" CreateThread Error %8lx\n", Status);
  1635. }