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.

2059 lines
54 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 = FILE_SYNCHRONOUS_IO_ALERT;
  39. #define simprintf(X,Y) {if (!Silent) {DbgPrint(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. DbgPrint("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*1;
  193. DbgPrint( "Wait 1 second for all thread to get ready .....");
  194. NtDelayExecution(FALSE, &DelayTime);
  195. DbgPrint( "Notifying %d threads to go.\n", Threads);
  196. NtSetEvent( StartSignal, NULL );
  197. NtTerminateThread(NtCurrentThread(), STATUS_SUCCESS);
  198. // DbgPrint( "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. DbgPrint("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. DbgPrint(LoopStr);
  234. DbgPrint("\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. DbgPrint( "%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. DbgPrint( "%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. DbgPrint( "%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. DbgPrint( "%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. DbgPrint( "%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. DbgPrint("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,
  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,
  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. //
  446. // Check how the read turned out
  447. //
  448. if (IoStatus.Status == STATUS_END_OF_FILE) {
  449. break;
  450. }
  451. CheckIoStatus( &IoStatus, BUFFERSIZE, TRUE );
  452. if (!NT_SUCCESS(IoStatus.Status)) {
  453. break;
  454. }
  455. //
  456. // Append the sectors to the To file
  457. //
  458. ReadLength = IoStatus.Information;
  459. if (!NT_SUCCESS(Status = NtWriteFile( ToFileHandle,
  460. (HANDLE)NULL,
  461. (PIO_APC_ROUTINE)NULL,
  462. (PVOID)NULL,
  463. &IoStatus,
  464. Buffer,
  465. IoStatus.Information,
  466. &EofOffset,
  467. (PULONG) NULL ))) {
  468. WriteFileError( Status, ToName );
  469. return;
  470. }
  471. //
  472. // Check how the write turned out
  473. //
  474. CheckIoStatus( &IoStatus, ReadLength, FALSE );
  475. if (!NT_SUCCESS(IoStatus.Status)) {
  476. IoStatusError( IoStatus.Status );
  477. break;
  478. }
  479. //
  480. // If we didn't read or write a full buffer then the copy is done
  481. //
  482. if (IoStatus.Information < BUFFERSIZE) {
  483. break;
  484. }
  485. }
  486. if (!NT_SUCCESS(IoStatus.Status) && (IoStatus.Status != STATUS_END_OF_FILE)) {
  487. IoStatusError( IoStatus.Status );
  488. }
  489. //
  490. // Close both files
  491. //
  492. if (!NT_SUCCESS(Status = NtClose( FromFileHandle ))) {
  493. CloseError( Status, FromName );
  494. }
  495. if (!NT_SUCCESS(Status = NtClose( ToFileHandle ))) {
  496. CloseError( Status, ToName );
  497. }
  498. //
  499. // And return to our caller
  500. //
  501. return;
  502. }
  503. VOID Chmode(
  504. IN PCHAR Attrib,
  505. IN PCHAR String
  506. )
  507. {
  508. CHAR Buffer[BUFFERSIZE];
  509. NTSTATUS Status;
  510. HANDLE FileHandle;
  511. OBJECT_ATTRIBUTES ObjectAttributes;
  512. UNICODE_STRING NameString;
  513. IO_STATUS_BLOCK IoStatus;
  514. ULONG FileAttribute;
  515. //
  516. // Get the attribute
  517. //
  518. Upcase( (PUCHAR)Attrib );
  519. //
  520. // Get the filename
  521. //
  522. simprintf("Chmode", 0);
  523. simprintf(String, 0);
  524. simprintf(" ", 0);
  525. simprintf(Attrib, 0);
  526. simprintf("\n", 0);
  527. //
  528. // Decode the attributes
  529. //
  530. FileAttribute = 0;
  531. if (strpbrk(Attrib,"N") != NULL) {FileAttribute |= FILE_ATTRIBUTE_NORMAL;}
  532. if (strpbrk(Attrib,"R") != NULL) {FileAttribute |= FILE_ATTRIBUTE_READONLY;}
  533. if (strpbrk(Attrib,"H") != NULL) {FileAttribute |= FILE_ATTRIBUTE_HIDDEN;}
  534. if (strpbrk(Attrib,"S") != NULL) {FileAttribute |= FILE_ATTRIBUTE_SYSTEM;}
  535. if (strpbrk(Attrib,"A") != NULL) {FileAttribute |= FILE_ATTRIBUTE_ARCHIVE;}
  536. //
  537. // Open the file for write attributes access
  538. //
  539. // RtlInitString( &NameString, String );
  540. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  541. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  542. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  543. FILE_WRITE_ATTRIBUTES,
  544. &ObjectAttributes,
  545. &IoStatus,
  546. 0L,
  547. WriteThrough ))) {
  548. OpenFileError( Status, String );
  549. return;
  550. }
  551. //
  552. // Change the file attributes
  553. //
  554. ((PFILE_BASIC_INFORMATION)&Buffer[0])->CreationTime.HighPart = 0;
  555. ((PFILE_BASIC_INFORMATION)&Buffer[0])->CreationTime.LowPart = 0;
  556. ((PFILE_BASIC_INFORMATION)&Buffer[0])->LastAccessTime.HighPart = 0;
  557. ((PFILE_BASIC_INFORMATION)&Buffer[0])->LastAccessTime.LowPart = 0;
  558. ((PFILE_BASIC_INFORMATION)&Buffer[0])->LastWriteTime.HighPart = 0;
  559. ((PFILE_BASIC_INFORMATION)&Buffer[0])->LastWriteTime.LowPart = 0;
  560. ((PFILE_BASIC_INFORMATION)&Buffer[0])->FileAttributes = FileAttribute;
  561. if (!NT_SUCCESS(Status = NtSetInformationFile( FileHandle,
  562. &IoStatus,
  563. Buffer,
  564. sizeof(FILE_BASIC_INFORMATION),
  565. FileBasicInformation))) {
  566. SetInformationFileError( Status );
  567. }
  568. //
  569. // Now close the file
  570. //
  571. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  572. CloseError( Status, String );
  573. }
  574. //
  575. // And return to our caller
  576. //
  577. RtlFreeUnicodeString( &NameString );
  578. return;
  579. }
  580. VOID Copy(
  581. IN PCHAR FromName,
  582. IN PCHAR ToName
  583. )
  584. {
  585. CHAR Buffer[BUFFERSIZE];
  586. NTSTATUS Status;
  587. HANDLE FromFileHandle;
  588. HANDLE ToFileHandle;
  589. OBJECT_ATTRIBUTES ObjectAttributes;
  590. UNICODE_STRING NameString;
  591. IO_STATUS_BLOCK IoStatus;
  592. LARGE_INTEGER FromFileAllocation;
  593. LARGE_INTEGER ByteOffset;
  594. ULONG LogLsn;
  595. //
  596. // Get both file names
  597. //
  598. simprintf("Copy ", 0);
  599. simprintf(FromName, 0);
  600. simprintf(" ", 0);
  601. simprintf(ToName, 0);
  602. simprintf("\n", 0);
  603. //
  604. // Open the From file for read access
  605. //
  606. // RtlInitString( &NameString, FromName );
  607. RtlDosPathNameToNtPathName( FromName, &NameString, NULL, NULL );
  608. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  609. if (!NT_SUCCESS(Status = NtOpenFile( &FromFileHandle,
  610. FILE_READ_DATA | FILE_READ_ATTRIBUTES,
  611. &ObjectAttributes,
  612. &IoStatus,
  613. 0L,
  614. WriteThrough ))) {
  615. OpenFileError( Status, FromName );
  616. return;
  617. }
  618. RtlFreeUnicodeString( &NameString );
  619. //
  620. // Get the size of the from file
  621. //
  622. if (!NT_SUCCESS(Status = NtQueryInformationFile( FromFileHandle,
  623. &IoStatus,
  624. Buffer,
  625. BUFFERSIZE,
  626. FileStandardInformation))) {
  627. QueryInformationFileError( Status );
  628. return;
  629. }
  630. FromFileAllocation = ((PFILE_STANDARD_INFORMATION)Buffer)->AllocationSize;
  631. //
  632. // Create the To file
  633. //
  634. // RtlInitString( &NameString, ToName );
  635. RtlDosPathNameToNtPathName( ToName, &NameString, NULL, NULL );
  636. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  637. if (!NT_SUCCESS(Status = NtCreateFile( &ToFileHandle,
  638. FILE_WRITE_DATA,
  639. &ObjectAttributes,
  640. &IoStatus,
  641. &FromFileAllocation,
  642. FILE_ATTRIBUTE_NORMAL,
  643. 0L,
  644. FILE_SUPERSEDE,
  645. WriteThrough,
  646. (PVOID)NULL,
  647. 0L ))) {
  648. CreateFileError( Status, ToName );
  649. return;
  650. }
  651. RtlFreeUnicodeString( &NameString );
  652. //
  653. // Now copy the files
  654. //
  655. ByteOffset = LiFromLong( 0 );
  656. for (LogLsn = 0; TRUE; LogLsn += BUFFERSIZE/512) {
  657. ULONG ReadLength;
  658. //
  659. // Read the next logical sectors in
  660. //
  661. ByteOffset.LowPart = LogLsn * 512;
  662. if (!NT_SUCCESS(Status = NtReadFile( FromFileHandle,
  663. (HANDLE)NULL,
  664. (PIO_APC_ROUTINE)NULL,
  665. (PVOID)NULL,
  666. &IoStatus,
  667. Buffer,
  668. BUFFERSIZE,
  669. &ByteOffset,
  670. (PULONG) NULL ))) {
  671. if (Status == STATUS_END_OF_FILE) {
  672. break;
  673. }
  674. ReadFileError( Status, FromName );
  675. break;
  676. }
  677. //
  678. // Check how the read turned out
  679. //
  680. if (IoStatus.Status == STATUS_END_OF_FILE) {
  681. break;
  682. }
  683. CheckIoStatus( &IoStatus, BUFFERSIZE, TRUE );
  684. if (!NT_SUCCESS(IoStatus.Status)) {
  685. break;
  686. }
  687. //
  688. // Write the sectors out
  689. //
  690. ReadLength = IoStatus.Information;
  691. if (!NT_SUCCESS(Status = NtWriteFile( ToFileHandle,
  692. (HANDLE)NULL,
  693. (PIO_APC_ROUTINE)NULL,
  694. (PVOID)NULL,
  695. &IoStatus,
  696. Buffer,
  697. IoStatus.Information,
  698. &ByteOffset,
  699. (PULONG) NULL ))) {
  700. WriteFileError( Status, ToName );
  701. return;
  702. }
  703. //
  704. // Check how the write turned out
  705. //
  706. CheckIoStatus( &IoStatus, ReadLength, FALSE );
  707. if (!NT_SUCCESS(IoStatus.Status)) {
  708. IoStatusError( IoStatus.Status );
  709. break;
  710. }
  711. //
  712. // If we didn't read or write a full buffer then the copy is done
  713. //
  714. if (IoStatus.Information < BUFFERSIZE) {
  715. break;
  716. }
  717. }
  718. if (!NT_SUCCESS(IoStatus.Status) && (IoStatus.Status != STATUS_END_OF_FILE)) {
  719. IoStatusError( IoStatus.Status );
  720. }
  721. //
  722. // Close both files
  723. //
  724. if (!NT_SUCCESS(Status = NtClose( FromFileHandle ))) {
  725. CloseError( Status, FromName );
  726. }
  727. if (!NT_SUCCESS(Status = NtClose( ToFileHandle ))) {
  728. CloseError( Status, ToName );
  729. }
  730. //
  731. // And return to our caller
  732. //
  733. return;
  734. }
  735. VOID Create(
  736. IN PCHAR String,
  737. IN ULONG Size
  738. )
  739. {
  740. CHAR Buffer[BUFFERSIZE];
  741. NTSTATUS Status;
  742. HANDLE FileHandle;
  743. OBJECT_ATTRIBUTES ObjectAttributes;
  744. UNICODE_STRING NameString;
  745. IO_STATUS_BLOCK IoStatus;
  746. LARGE_INTEGER AllocationSize;
  747. LARGE_INTEGER ByteOffset;
  748. ULONG BufferLength;
  749. ULONG i;
  750. static CHAR FoxString[] = "The quick brown fox jumped over the lazy dog.\r\n";
  751. ULONG FoxLength;
  752. //
  753. // Get the filename
  754. //
  755. simprintf("Create ", 0);
  756. simprintf(String, 0);
  757. simprintf("\n", 0);
  758. //
  759. // Create the new file
  760. //
  761. AllocationSize = LiFromUlong( Size );
  762. // RtlInitString( &NameString, String );
  763. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  764. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  765. if (!NT_SUCCESS(Status = NtCreateFile( &FileHandle,
  766. FILE_WRITE_DATA,
  767. &ObjectAttributes,
  768. &IoStatus,
  769. &AllocationSize,
  770. FILE_ATTRIBUTE_NORMAL,
  771. 0L,
  772. FILE_SUPERSEDE,
  773. WriteThrough,
  774. (PVOID)NULL,
  775. 0L ))) {
  776. CreateFileError( Status, String );
  777. return;
  778. }
  779. //
  780. // create a test buffer to output
  781. //
  782. FoxLength = strlen(FoxString);
  783. for (i = FoxLength; i < BUFFERSIZE; i += FoxLength) {
  784. strcpy((PCHAR)&Buffer[i-FoxLength], FoxString);
  785. }
  786. BufferLength = i - FoxLength;
  787. //
  788. // The main loop writes out the test buffer a BufferLength amount
  789. // at a time
  790. //
  791. ByteOffset = LiFromLong( 0 );
  792. for (i = BufferLength; i < Size; i += BufferLength) {
  793. //
  794. // Write the next buffer
  795. //
  796. ByteOffset.LowPart = i-BufferLength;
  797. if (!NT_SUCCESS(Status = NtWriteFile( FileHandle,
  798. (HANDLE)NULL,
  799. (PIO_APC_ROUTINE)NULL,
  800. (PVOID)NULL,
  801. &IoStatus,
  802. Buffer,
  803. BufferLength,
  804. &ByteOffset,
  805. (PULONG) NULL ))) {
  806. WriteFileError( Status, String );
  807. return;
  808. }
  809. //
  810. // check how the write turned out
  811. //
  812. CheckIoStatus( &IoStatus, BufferLength, FALSE );
  813. if (!NT_SUCCESS(IoStatus.Status)) {
  814. IoStatusError( IoStatus.Status );
  815. break;
  816. }
  817. }
  818. //
  819. // Check for a residual to output
  820. //
  821. if (i - BufferLength < Size) {
  822. //
  823. // Write out the residual buffer
  824. //
  825. ByteOffset.LowPart = i-BufferLength;
  826. if (!NT_SUCCESS(Status = NtWriteFile( FileHandle,
  827. (HANDLE)NULL,
  828. (PIO_APC_ROUTINE)NULL,
  829. (PVOID)NULL,
  830. &IoStatus,
  831. Buffer,
  832. Size - (i - BufferLength),
  833. &ByteOffset,
  834. (PULONG) NULL ))) {
  835. WriteFileError( Status, String );
  836. return;
  837. }
  838. //
  839. // check how the write turned out
  840. //
  841. CheckIoStatus( &IoStatus, Size - (i - BufferLength), FALSE );
  842. if (!NT_SUCCESS(IoStatus.Status)) {
  843. IoStatusError( IoStatus.Status );
  844. }
  845. }
  846. //
  847. // Now close the file
  848. //
  849. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  850. CloseError( Status, String );
  851. }
  852. //
  853. // And return to our caller
  854. //
  855. RtlFreeUnicodeString( &NameString );
  856. return;
  857. }
  858. VOID DebugLevel()
  859. {
  860. #ifdef FATDBG
  861. //simprintf("Debug Trace Level %x\n", FatDebugTraceLevel);
  862. #else
  863. //simprintf("System not compiled for debug tracing\n", 0);
  864. #endif // FATDBG
  865. return;
  866. }
  867. VOID Delete(
  868. IN PCHAR String
  869. )
  870. {
  871. CHAR Buffer[BUFFERSIZE];
  872. NTSTATUS Status;
  873. HANDLE FileHandle;
  874. OBJECT_ATTRIBUTES ObjectAttributes;
  875. UNICODE_STRING NameString;
  876. IO_STATUS_BLOCK IoStatus;
  877. //
  878. // Get the filename
  879. //
  880. simprintf("Delete ", 0);
  881. simprintf(String, 0);
  882. simprintf("\n", 0);
  883. //
  884. // Open the file for delete access
  885. //
  886. // RtlInitString( &NameString, String );
  887. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  888. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  889. if (!NT_SUCCESS(Status = NtCreateFile( &FileHandle,
  890. DELETE,
  891. &ObjectAttributes,
  892. &IoStatus,
  893. (PLARGE_INTEGER)NULL,
  894. 0L,
  895. 0L,
  896. FILE_OPEN,
  897. WriteThrough,
  898. (PVOID)NULL,
  899. 0L ))) {
  900. CreateFileError( Status, String );
  901. return;
  902. }
  903. //
  904. // Mark the file for delete
  905. //
  906. ((PFILE_DISPOSITION_INFORMATION)&Buffer[0])->DeleteFile = TRUE;
  907. if (!NT_SUCCESS(Status = NtSetInformationFile( FileHandle,
  908. &IoStatus,
  909. Buffer,
  910. sizeof(FILE_DISPOSITION_INFORMATION),
  911. FileDispositionInformation))) {
  912. SetInformationFileError( Status );
  913. return;
  914. }
  915. //
  916. // Now close the file
  917. //
  918. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  919. CloseError( Status, String );
  920. }
  921. //
  922. // And return to our caller
  923. //
  924. RtlFreeUnicodeString( &NameString );
  925. return;
  926. }
  927. VOID Directory(
  928. IN PCHAR String
  929. )
  930. {
  931. CHAR Buffer[BUFFERSIZE];
  932. NTSTATUS Status;
  933. HANDLE FileHandle;
  934. OBJECT_ATTRIBUTES ObjectAttributes;
  935. UNICODE_STRING NameString;
  936. IO_STATUS_BLOCK IoStatus;
  937. NTSTATUS NtStatus;
  938. PFILE_ADIRECTORY_INFORMATION FileInfo;
  939. // ULONG i;
  940. //
  941. // Get the filename
  942. //
  943. simprintf("Directory ", 0);
  944. simprintf(String, 0);
  945. simprintf("\n", 0);
  946. //
  947. // Open the file for list directory access
  948. //
  949. // RtlInitString( &NameString, String );
  950. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  951. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  952. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  953. FILE_LIST_DIRECTORY,
  954. &ObjectAttributes,
  955. &IoStatus,
  956. FILE_SHARE_READ,
  957. WriteThrough | FILE_DIRECTORY_FILE ))) {
  958. OpenFileError( Status, String );
  959. return;
  960. }
  961. //
  962. // zero out the buffer so next time we'll recognize the end of data
  963. //
  964. RtlZeroMemory(Buffer, BUFFERSIZE);
  965. //
  966. // Do the directory loop
  967. //
  968. for (NtStatus = NtQueryDirectoryFile( FileHandle,
  969. (HANDLE)NULL,
  970. (PIO_APC_ROUTINE)NULL,
  971. (PVOID)NULL,
  972. &IoStatus,
  973. Buffer,
  974. BUFFERSIZE,
  975. FileADirectoryInformation,
  976. FALSE,
  977. (PSTRING)NULL,
  978. TRUE);
  979. NT_SUCCESS(NtStatus);
  980. NtStatus = NtQueryDirectoryFile( FileHandle,
  981. (HANDLE)NULL,
  982. (PIO_APC_ROUTINE)NULL,
  983. (PVOID)NULL,
  984. &IoStatus,
  985. Buffer,
  986. BUFFERSIZE,
  987. FileADirectoryInformation,
  988. FALSE,
  989. (PSTRING)NULL,
  990. FALSE) ) {
  991. //
  992. // Check the Irp for success
  993. //
  994. if (!NT_SUCCESS(IoStatus.Status)) {
  995. break;
  996. }
  997. //
  998. // For every record in the buffer type out the directory information
  999. //
  1000. //
  1001. // Point to the first record in the buffer, we are guaranteed to have
  1002. // one otherwise IoStatus would have been No More Files
  1003. //
  1004. FileInfo = (PFILE_ADIRECTORY_INFORMATION)&Buffer[0];
  1005. while (TRUE) {
  1006. //
  1007. // Lets put in some checks to make sure these are ok.
  1008. //
  1009. ASSERT(FileInfo->FileNameLength < MAXIMUM_FILENAME_LENGTH);
  1010. ASSERT(FileInfo->NextEntryOffset < MAXIMUM_FILENAME_LENGTH+sizeof(FILE_ADIRECTORY_INFORMATION)+4);
  1011. //
  1012. // Print out information about the file
  1013. //
  1014. simprintf("%8lx ", FileInfo->FileAttributes);
  1015. simprintf("%8lx/", FileInfo->EndOfFile.LowPart);
  1016. simprintf("%8lx ", FileInfo->AllocationSize.LowPart);
  1017. {
  1018. CHAR Saved;
  1019. Saved = FileInfo->FileName[FileInfo->FileNameLength];
  1020. FileInfo->FileName[FileInfo->FileNameLength] = 0;
  1021. simprintf(FileInfo->FileName, 0);
  1022. FileInfo->FileName[FileInfo->FileNameLength] = Saved;
  1023. }
  1024. simprintf("\n", 0);
  1025. //
  1026. // Check if there is another record, if there isn't then we
  1027. // simply get out of this loop
  1028. //
  1029. if (FileInfo->NextEntryOffset == 0) {
  1030. break;
  1031. }
  1032. //
  1033. // There is another record so advance FileInfo to the next
  1034. // record
  1035. //
  1036. FileInfo = (PFILE_ADIRECTORY_INFORMATION)(((PUCHAR)FileInfo) + FileInfo->NextEntryOffset);
  1037. }
  1038. //
  1039. // zero out the buffer so next time we'll recognize the end of data
  1040. //
  1041. RtlZeroMemory(Buffer, BUFFERSIZE);
  1042. }
  1043. //
  1044. // Now close the file
  1045. //
  1046. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1047. CloseError( Status, String );
  1048. }
  1049. //
  1050. // And return to our caller
  1051. //
  1052. RtlFreeUnicodeString( &NameString );
  1053. return;
  1054. }
  1055. VOID Mkdir(
  1056. IN PCHAR String
  1057. )
  1058. {
  1059. NTSTATUS Status;
  1060. HANDLE FileHandle;
  1061. OBJECT_ATTRIBUTES ObjectAttributes;
  1062. UNICODE_STRING NameString;
  1063. IO_STATUS_BLOCK IoStatus;
  1064. LARGE_INTEGER AllocationSize;
  1065. //
  1066. // Get the filename
  1067. //
  1068. simprintf("Mkdir ", 0);
  1069. simprintf(String, 0);
  1070. simprintf("\n", 0);
  1071. //
  1072. // Create the new directory
  1073. //
  1074. AllocationSize = LiFromLong( 4 );
  1075. // RtlInitString( &NameString, String );
  1076. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  1077. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  1078. if (!NT_SUCCESS(Status = NtCreateFile( &FileHandle,
  1079. 0,
  1080. &ObjectAttributes,
  1081. &IoStatus,
  1082. &AllocationSize,
  1083. 0L,
  1084. 0L,
  1085. FILE_CREATE,
  1086. WriteThrough | FILE_DIRECTORY_FILE,
  1087. (PVOID)NULL,
  1088. 0L ))) {
  1089. CreateFileError( Status, String );
  1090. return;
  1091. }
  1092. //
  1093. // Now close the directory
  1094. //
  1095. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1096. CloseError( Status, String );
  1097. }
  1098. //
  1099. // And return to our caller
  1100. //
  1101. RtlFreeUnicodeString( &NameString );
  1102. return;
  1103. }
  1104. VOID Query(
  1105. IN PCHAR String
  1106. )
  1107. {
  1108. CHAR Buffer[BUFFERSIZE];
  1109. NTSTATUS Status;
  1110. HANDLE FileHandle;
  1111. OBJECT_ATTRIBUTES ObjectAttributes;
  1112. UNICODE_STRING NameString;
  1113. IO_STATUS_BLOCK IoStatus;
  1114. ULONG i;
  1115. PFILE_AALL_INFORMATION AllInfo;
  1116. PFILE_BASIC_INFORMATION BasicInfo;
  1117. PFILE_STANDARD_INFORMATION StandardInfo;
  1118. PFILE_INTERNAL_INFORMATION InternalInfo;
  1119. PFILE_EA_INFORMATION EaInfo;
  1120. PFILE_ACCESS_INFORMATION AccessInfo;
  1121. PFILE_ANAME_INFORMATION NameInfo;
  1122. //
  1123. // zero out the buffer so next time we'll recognize the end of data
  1124. //
  1125. for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; }
  1126. //
  1127. // Set up some local pointers
  1128. //
  1129. AllInfo = (PFILE_AALL_INFORMATION)Buffer;
  1130. BasicInfo = &AllInfo->BasicInformation;
  1131. StandardInfo = &AllInfo->StandardInformation;
  1132. InternalInfo = &AllInfo->InternalInformation;
  1133. EaInfo = &AllInfo->EaInformation;
  1134. AccessInfo = &AllInfo->AccessInformation;
  1135. NameInfo = &AllInfo->NameInformation;
  1136. //
  1137. // Get the filename
  1138. //
  1139. simprintf("Query ", 0);
  1140. simprintf(String, 0);
  1141. simprintf("\n", 0);
  1142. //
  1143. // Open the file for read attributes, read ea, and read control access
  1144. //
  1145. // RtlInitString( &NameString, String );
  1146. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  1147. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  1148. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  1149. FILE_READ_ATTRIBUTES | FILE_READ_EA | READ_CONTROL,
  1150. &ObjectAttributes,
  1151. &IoStatus,
  1152. 0L,
  1153. WriteThrough ))) {
  1154. OpenFileError( Status, String );
  1155. return;
  1156. }
  1157. //
  1158. // Query the file
  1159. //
  1160. if (!NT_SUCCESS(Status = NtQueryInformationFile( FileHandle,
  1161. &IoStatus,
  1162. Buffer,
  1163. BUFFERSIZE,
  1164. FileAAllInformation))) {
  1165. QueryInformationFileError( Status );
  1166. return;
  1167. }
  1168. //
  1169. // Output file name information
  1170. //
  1171. simprintf("\"", 0);
  1172. simprintf(NameInfo->FileName, 0);
  1173. simprintf("\"\n", 0);
  1174. //
  1175. // Output the times
  1176. //
  1177. simprintf(" Create = ", 0); PrintTime( &BasicInfo->CreationTime ); simprintf("\n", 0);
  1178. simprintf(" Access = ", 0); PrintTime( &BasicInfo->LastAccessTime ); simprintf("\n", 0);
  1179. simprintf(" Write = ", 0); PrintTime( &BasicInfo->LastWriteTime ); simprintf("\n", 0);
  1180. //
  1181. // Output File size, and allocation size
  1182. //
  1183. simprintf(" Size = %8lx\n", StandardInfo->EndOfFile.LowPart);
  1184. simprintf(" Alloc = %8lx\n", StandardInfo->AllocationSize.LowPart);
  1185. //
  1186. // Output File attributes, Device type, link count, and flags
  1187. //
  1188. simprintf(" Attrib = %8lx\n", BasicInfo->FileAttributes);
  1189. // simprintf(" DevType = %8lx\n", StandardInfo->DeviceType);
  1190. simprintf(" Links = %8lx\n", StandardInfo->NumberOfLinks);
  1191. simprintf(" Dir = %8lx\n", StandardInfo->Directory);
  1192. simprintf(" Delete = %8lx\n", StandardInfo->DeletePending);
  1193. //
  1194. // Output the index number and ea size
  1195. //
  1196. simprintf(" Index = %8lx\n", InternalInfo->IndexNumber.LowPart);
  1197. simprintf(" EaSize = %8lx\n", EaInfo->EaSize);
  1198. //
  1199. // Output the file access flags
  1200. //
  1201. simprintf(" Flags = %8lx\n", AccessInfo->AccessFlags);
  1202. //
  1203. // Now close the file
  1204. //
  1205. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1206. CloseError( Status, String );
  1207. }
  1208. //
  1209. // And return to our caller
  1210. //
  1211. RtlFreeUnicodeString( &NameString );
  1212. return;
  1213. }
  1214. VOID QVolume(
  1215. IN PCHAR String
  1216. )
  1217. {
  1218. CHAR Buffer[BUFFERSIZE];
  1219. NTSTATUS Status;
  1220. HANDLE FileHandle;
  1221. OBJECT_ATTRIBUTES ObjectAttributes;
  1222. UNICODE_STRING NameString;
  1223. IO_STATUS_BLOCK IoStatus;
  1224. ULONG i;
  1225. PFILE_FS_AVOLUME_INFORMATION VolumeInfo;
  1226. //
  1227. // zero out the buffer so next time we'll recognize the end of data
  1228. //
  1229. for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; }
  1230. //
  1231. // Set up some local pointers
  1232. //
  1233. VolumeInfo = (PFILE_FS_AVOLUME_INFORMATION)Buffer;
  1234. //
  1235. // Get the volume name
  1236. //
  1237. simprintf("QVolume ", 0);
  1238. simprintf(String, 0);
  1239. simprintf("\n", 0);
  1240. //
  1241. // Open the Volume for no access
  1242. //
  1243. // RtlInitString( &NameString, String );
  1244. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  1245. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  1246. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  1247. FILE_READ_ATTRIBUTES,
  1248. &ObjectAttributes,
  1249. &IoStatus,
  1250. 0L,
  1251. WriteThrough ))) {
  1252. OpenFileError( Status, String );
  1253. return;
  1254. }
  1255. //
  1256. // zero out the buffer so next time we'll recognize the end of data
  1257. //
  1258. for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; }
  1259. //
  1260. // Query the volume info
  1261. //
  1262. if (!NT_SUCCESS(Status = NtQueryVolumeInformationFile( FileHandle,
  1263. &IoStatus,
  1264. Buffer,
  1265. BUFFERSIZE,
  1266. FileAFsVolumeInformation))) {
  1267. QueryVolumeInformationFileError( Status );
  1268. return;
  1269. }
  1270. //
  1271. // Output Volume name information
  1272. //
  1273. simprintf("\"", 0);
  1274. simprintf(VolumeInfo->VolumeLabel, 0);
  1275. simprintf("\"\n", 0);
  1276. //
  1277. // Output the volume serial number
  1278. //
  1279. simprintf(" SerialNum = %8lx\n", VolumeInfo->VolumeSerialNumber);
  1280. //
  1281. // Now close the Volume
  1282. //
  1283. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1284. CloseError( Status, String );
  1285. }
  1286. //
  1287. // And return to our caller
  1288. //
  1289. RtlFreeUnicodeString( &NameString );
  1290. return;
  1291. }
  1292. VOID Rename()
  1293. {
  1294. //simprintf("Rename not implemented\n", 0);
  1295. }
  1296. VOID SVolume(
  1297. IN PCHAR String,
  1298. IN PCHAR Label
  1299. )
  1300. {
  1301. CHAR Buffer[BUFFERSIZE];
  1302. NTSTATUS Status;
  1303. HANDLE FileHandle;
  1304. OBJECT_ATTRIBUTES ObjectAttributes;
  1305. UNICODE_STRING NameString;
  1306. IO_STATUS_BLOCK IoStatus;
  1307. ULONG i;
  1308. PFILE_FS_ALABEL_INFORMATION LabelInfo;
  1309. //
  1310. // zero out the buffer so next time we'll recognize the end of data
  1311. //
  1312. for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; }
  1313. //
  1314. // Set up some local pointers
  1315. //
  1316. LabelInfo = (PFILE_FS_ALABEL_INFORMATION)Buffer;
  1317. //
  1318. // Get the volume name, and new label name
  1319. //
  1320. strcpy( LabelInfo->VolumeLabel, Label );
  1321. LabelInfo->VolumeLabelLength = strlen(LabelInfo->VolumeLabel);
  1322. if ((LabelInfo->VolumeLabelLength == 1) &&
  1323. (LabelInfo->VolumeLabel[0] == '.')) {
  1324. LabelInfo->VolumeLabelLength = 0;
  1325. }
  1326. simprintf("SVolume ", 0);
  1327. simprintf(String, 0);
  1328. simprintf(" ", 0);
  1329. simprintf(LabelInfo->VolumeLabel, 0);
  1330. simprintf("\n", 0);
  1331. //
  1332. // Open the Volume for no access
  1333. //
  1334. // RtlInitString( &NameString, String );
  1335. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  1336. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  1337. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  1338. FILE_WRITE_ATTRIBUTES,
  1339. &ObjectAttributes,
  1340. &IoStatus,
  1341. 0L,
  1342. WriteThrough ))) {
  1343. OpenFileError( Status, String );
  1344. return;
  1345. }
  1346. //
  1347. // Set the volume info
  1348. //
  1349. if (!NT_SUCCESS(Status = NtSetVolumeInformationFile( FileHandle,
  1350. &IoStatus,
  1351. LabelInfo,
  1352. BUFFERSIZE,
  1353. FileAFsLabelInformation))) {
  1354. SetVolumeInformationFileError( Status );
  1355. return;
  1356. }
  1357. //
  1358. // Now close the Volume
  1359. //
  1360. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1361. CloseError( Status, String );
  1362. }
  1363. //
  1364. // And return to our caller
  1365. //
  1366. RtlFreeUnicodeString( &NameString );
  1367. return;
  1368. }
  1369. VOID Type(
  1370. IN PCHAR String
  1371. )
  1372. {
  1373. CHAR Buffer[BUFFERSIZE];
  1374. NTSTATUS Status;
  1375. HANDLE FileHandle;
  1376. OBJECT_ATTRIBUTES ObjectAttributes;
  1377. UNICODE_STRING NameString;
  1378. IO_STATUS_BLOCK IoStatus;
  1379. LARGE_INTEGER ByteOffset;
  1380. ULONG LogLsn;
  1381. ULONG i;
  1382. //
  1383. // Get the filename
  1384. //
  1385. simprintf("Type ", 0);
  1386. simprintf(String, 0);
  1387. simprintf("\n", 0);
  1388. //
  1389. // Open the file for read
  1390. //
  1391. // RtlInitString( &NameString, String );
  1392. RtlDosPathNameToNtPathName( String, &NameString, NULL, NULL );
  1393. InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL );
  1394. if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle,
  1395. FILE_READ_DATA,
  1396. &ObjectAttributes,
  1397. &IoStatus,
  1398. 0L,
  1399. WriteThrough ))) {
  1400. OpenFileError( Status, String );
  1401. return;
  1402. }
  1403. //
  1404. // While there is data to be read we'll read a buffer and write it out
  1405. //
  1406. ByteOffset = LiFromLong( 0 );
  1407. for (LogLsn = 0; TRUE; LogLsn += BUFFERSIZE/512) {
  1408. //
  1409. // Read the next logical sector
  1410. //
  1411. ByteOffset.LowPart = LogLsn * 512;
  1412. if (!NT_SUCCESS(Status = NtReadFile( FileHandle,
  1413. (HANDLE)NULL,
  1414. (PIO_APC_ROUTINE)NULL,
  1415. (PVOID)NULL,
  1416. &IoStatus,
  1417. Buffer,
  1418. BUFFERSIZE,
  1419. &ByteOffset,
  1420. (PULONG) NULL ))) {
  1421. if (Status == STATUS_END_OF_FILE) {
  1422. break;
  1423. }
  1424. ReadFileError( Status, String );
  1425. break;
  1426. }
  1427. //
  1428. // check how the read turned out
  1429. //
  1430. if (IoStatus.Status == STATUS_END_OF_FILE) {
  1431. break;
  1432. }
  1433. CheckIoStatus( &IoStatus, BUFFERSIZE, TRUE );
  1434. if (!NT_SUCCESS(IoStatus.Status)) {
  1435. IoStatusError( IoStatus.Status );
  1436. break;
  1437. }
  1438. //
  1439. // Write out the buffer
  1440. //
  1441. for (i = 0; i < IoStatus.Information; i += 1) {
  1442. simprintf("%c", Buffer[i]);
  1443. }
  1444. //
  1445. // If we didn't read in a complete buffer then we're all done reading
  1446. // and can get out of here
  1447. //
  1448. if (IoStatus.Information < BUFFERSIZE) {
  1449. break;
  1450. }
  1451. }
  1452. //
  1453. // Now close the file
  1454. //
  1455. if (!NT_SUCCESS(Status = NtClose( FileHandle ))) {
  1456. CloseError( Status, String );
  1457. }
  1458. //
  1459. // And return to our caller
  1460. //
  1461. RtlFreeUnicodeString( &NameString );
  1462. return;
  1463. }
  1464. VOID
  1465. Quit()
  1466. {
  1467. simprintf("FatTest Exiting.\n", 0);
  1468. return;
  1469. }
  1470. VOID
  1471. PrintTime (
  1472. IN PLARGE_INTEGER Time
  1473. )
  1474. {
  1475. TIME_FIELDS TimeFields;
  1476. static PCHAR Months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
  1477. "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  1478. static PCHAR Days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  1479. RtlTimeToTimeFields( Time, &TimeFields );
  1480. simprintf(" %4d-", TimeFields.Year);
  1481. simprintf(Months[TimeFields.Month-1], 0);
  1482. simprintf("-%2d", TimeFields.Day);
  1483. simprintf(" %2d", TimeFields.Hour);
  1484. simprintf(":%2d", TimeFields.Minute);
  1485. simprintf(":%2d", TimeFields.Second);
  1486. simprintf(".%3d (", TimeFields.Milliseconds);
  1487. simprintf(Days[TimeFields.Weekday], 0);
  1488. simprintf(")", 0);
  1489. return;
  1490. }
  1491. VOID
  1492. WaitForSingleObjectError(
  1493. IN NTSTATUS Status
  1494. )
  1495. {
  1496. DbgPrint(" WaitForSingleObject Error %X\n", Status);
  1497. }
  1498. VOID
  1499. CreateFileError(
  1500. IN NTSTATUS Status,
  1501. IN PUCHAR File
  1502. )
  1503. {
  1504. DbgPrint(" CreateFile Error %X on %s\n", Status, File);
  1505. }
  1506. VOID
  1507. OpenFileError(
  1508. IN NTSTATUS Status,
  1509. IN PUCHAR File
  1510. )
  1511. {
  1512. DbgPrint(" OpenFile Error %X on %s\n", Status, File);
  1513. }
  1514. VOID
  1515. ReadFileError(
  1516. IN NTSTATUS Status,
  1517. IN PUCHAR File
  1518. )
  1519. {
  1520. DbgPrint(" ReadFile Error %X on %s\n", Status, File);
  1521. }
  1522. VOID
  1523. WriteFileError(
  1524. IN NTSTATUS Status,
  1525. IN PUCHAR File
  1526. )
  1527. {
  1528. DbgPrint(" WriteFile Error %X on %s\n", Status, File);
  1529. }
  1530. VOID
  1531. CheckIoStatus(
  1532. IN PIO_STATUS_BLOCK IoStatus,
  1533. IN ULONG Length,
  1534. IN BOOLEAN Read
  1535. )
  1536. {
  1537. if (!NT_SUCCESS(IoStatus->Status)) {
  1538. DbgPrint(" IoStatus->Status Error %08lx\n", IoStatus->Status);
  1539. }
  1540. if ((!Read && (IoStatus->Information != Length))
  1541. ||
  1542. (Read && (IoStatus->Information > Length))) {
  1543. DbgPrint(" IoStatus->Information Error %08lx\n", IoStatus->Information);
  1544. }
  1545. }
  1546. VOID
  1547. SetInformationFileError(
  1548. IN NTSTATUS Status
  1549. )
  1550. {
  1551. DbgPrint(" SetInfoFile Error %X\n", Status);
  1552. }
  1553. VOID
  1554. QueryInformationFileError(
  1555. IN NTSTATUS Status
  1556. )
  1557. {
  1558. DbgPrint(" QueryInfoFile Error %X\n", Status);
  1559. }
  1560. VOID
  1561. SetVolumeInformationFileError(
  1562. IN NTSTATUS Status
  1563. )
  1564. {
  1565. DbgPrint(" SetVolumeInfoFile Error %X\n", Status);
  1566. }
  1567. VOID
  1568. QueryVolumeInformationFileError(
  1569. IN NTSTATUS Status
  1570. )
  1571. {
  1572. DbgPrint(" QueryVolumeInfoFile Error %X\n", Status);
  1573. }
  1574. VOID
  1575. CloseError(
  1576. IN NTSTATUS Status,
  1577. IN PUCHAR File
  1578. )
  1579. {
  1580. DbgPrint(" Close Error %8lx on %s\n", Status, File);
  1581. }
  1582. VOID
  1583. IoStatusError(
  1584. IN NTSTATUS Status
  1585. )
  1586. {
  1587. DbgPrint(" IoStatus Error %8lx\n", Status);
  1588. }
  1589. VOID
  1590. CreateThreadError(
  1591. IN NTSTATUS Status
  1592. )
  1593. {
  1594. DbgPrint(" CreateThread Error %8lx\n", Status);
  1595. }