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.

688 lines
21 KiB

  1. #include "brian.h"
  2. typedef struct _ASYNC_FSCTRL {
  3. USHORT FileIndex;
  4. BOOLEAN UseEvent;
  5. PIO_APC_ROUTINE ApcRoutine;
  6. PVOID ApcContext;
  7. ULONG IoControlCode;
  8. PULONG InputBuffer;
  9. ULONG InputBufferLength;
  10. PULONG OutputBuffer;
  11. ULONG OutputBufferLength;
  12. BOOLEAN VerboseResults;
  13. USHORT AsyncIndex;
  14. } ASYNC_FSCTRL, *PASYNC_FSCTRL;
  15. VOID
  16. RequestFsctrl (
  17. IN PASYNC_FSCTRL Fsctrl
  18. );
  19. //
  20. // Local procedures
  21. //
  22. VOID
  23. InputFsctrl(
  24. IN PCHAR ParamBuffer
  25. )
  26. {
  27. BOOLEAN HaveFileIndex = FALSE;
  28. BOOLEAN HaveIoControlCode = FALSE;
  29. USHORT FileIndex;
  30. BOOLEAN UseEvent = TRUE;
  31. PIO_APC_ROUTINE ApcRoutine = NULL;
  32. PVOID ApcContext = NULL;
  33. ULONG IoControlCode = 0;
  34. PULONG InputBuffer = NULL;
  35. ULONG InputBufferLength = 0;
  36. PULONG OutputBuffer = NULL;
  37. ULONG OutputBufferLength = 0;
  38. BOOLEAN VerboseResults = FALSE;
  39. BOOLEAN DisplayParms = FALSE;
  40. USHORT AsyncIndex;
  41. BOOLEAN LastInput = TRUE;
  42. //
  43. // While there is more input, analyze the parameter and update the
  44. // query flags.
  45. //
  46. while(TRUE) {
  47. ULONG DummyCount;
  48. //
  49. // Swallow leading white spaces.
  50. //
  51. ParamBuffer = SwallowWhite( ParamBuffer, &DummyCount );
  52. if (*ParamBuffer) {
  53. ULONG TempIndex;
  54. //
  55. // If the next parameter is legal then check the paramter value.
  56. // Update the parameter value.
  57. //
  58. if((*ParamBuffer == '-'
  59. || *ParamBuffer == '/')
  60. && (ParamBuffer++, *ParamBuffer != '\0')) {
  61. //
  62. // Switch on the next character.
  63. //
  64. switch (*ParamBuffer) {
  65. BOOLEAN SwitchBool;
  66. //
  67. // Update buffers to use.
  68. //
  69. case 'b' :
  70. case 'B' :
  71. //
  72. // Move to the next character, as long as there
  73. // are no white spaces continue analyzing letters.
  74. // On the first bad letter, skip to the next
  75. // parameter.
  76. //
  77. ParamBuffer++;
  78. if (*ParamBuffer == '\0') {
  79. break;
  80. }
  81. switch (*ParamBuffer) {
  82. case 'i':
  83. case 'I':
  84. TempIndex = AsciiToInteger( ++ParamBuffer );
  85. if (TempIndex >= MAX_BUFFERS) {
  86. bprint "\n\tInputFsctrl: Invalid Input buffer" );
  87. } else {
  88. InputBuffer = (PULONG) Buffers[TempIndex].Buffer;
  89. InputBufferLength = Buffers[TempIndex].Length;
  90. }
  91. break;
  92. case 'o':
  93. case 'O':
  94. TempIndex = AsciiToInteger( ++ParamBuffer );
  95. if (TempIndex >= MAX_BUFFERS) {
  96. bprint "\n\tInputFsctrl: Invalid output buffer" );
  97. } else {
  98. OutputBuffer = (PULONG) Buffers[TempIndex].Buffer;
  99. OutputBufferLength = Buffers[TempIndex].Length;
  100. }
  101. break;
  102. }
  103. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  104. break;
  105. //
  106. // Update buffer lengths.
  107. //
  108. case 'l' :
  109. case 'L' :
  110. //
  111. // Move to the next character, as long as there
  112. // are no white spaces continue analyzing letters.
  113. // On the first bad letter, skip to the next
  114. // parameter.
  115. //
  116. ParamBuffer++;
  117. if (*ParamBuffer == '\0') {
  118. break;
  119. }
  120. switch (*ParamBuffer) {
  121. case 'i':
  122. case 'I':
  123. InputBufferLength = AsciiToInteger( ++ParamBuffer );
  124. break;
  125. case 'o':
  126. case 'O':
  127. OutputBufferLength = AsciiToInteger( ++ParamBuffer );
  128. break;
  129. }
  130. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  131. break;
  132. //
  133. // Update the file handle index.
  134. //
  135. case 'i' :
  136. case 'I' :
  137. //
  138. // Move to the next character, as long as there
  139. // are no white spaces continue analyzing letters.
  140. // On the first bad letter, skip to the next
  141. // parameter.
  142. //
  143. ParamBuffer++;
  144. FileIndex = (USHORT) (AsciiToInteger( ParamBuffer ));
  145. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  146. HaveFileIndex = TRUE;
  147. break;
  148. //
  149. // Check whether we should use an event to signal
  150. // completion.
  151. //
  152. case 'e' :
  153. case 'E' :
  154. //
  155. // Legal values for use event are T/t or F/f.
  156. //
  157. ParamBuffer++;
  158. if (*ParamBuffer == 'T'
  159. || *ParamBuffer == 't') {
  160. UseEvent = TRUE;
  161. ParamBuffer++;
  162. } else if (*ParamBuffer == 'F'
  163. || *ParamBuffer == 'f') {
  164. UseEvent = FALSE;
  165. ParamBuffer++;
  166. }
  167. break;
  168. //
  169. // Modify the operation
  170. //
  171. case 'o' :
  172. case 'O' :
  173. ParamBuffer++;
  174. SwitchBool = TRUE;
  175. while (*ParamBuffer
  176. && *ParamBuffer != ' '
  177. && *ParamBuffer != '\t') {
  178. //
  179. // Perform switch on character.
  180. //
  181. switch (*ParamBuffer) {
  182. case 'a' :
  183. case 'A' :
  184. IoControlCode = FSCTL_LOCK_VOLUME;
  185. HaveIoControlCode = TRUE;
  186. break;
  187. case 'b' :
  188. case 'B' :
  189. IoControlCode = FSCTL_UNLOCK_VOLUME;
  190. HaveIoControlCode = TRUE;
  191. break;
  192. case 'c' :
  193. case 'C' :
  194. IoControlCode = FSCTL_DISMOUNT_VOLUME;
  195. HaveIoControlCode = TRUE;
  196. break;
  197. case 'd' :
  198. case 'D' :
  199. IoControlCode = FSCTL_MARK_VOLUME_DIRTY;
  200. HaveIoControlCode = TRUE;
  201. break;
  202. case 'e' :
  203. case 'E' :
  204. IoControlCode = FSCTL_IS_PATHNAME_VALID;
  205. HaveIoControlCode = TRUE;
  206. break;
  207. case 'f' :
  208. case 'F' :
  209. IoControlCode = FSCTL_QUERY_RETRIEVAL_POINTERS;
  210. HaveIoControlCode = TRUE;
  211. break;
  212. case 'g' :
  213. case 'G' :
  214. IoControlCode = FSCTL_GET_COMPRESSION;
  215. HaveIoControlCode = TRUE;
  216. break;
  217. case 'h' :
  218. case 'H' :
  219. IoControlCode = FSCTL_SET_COMPRESSION;
  220. HaveIoControlCode = TRUE;
  221. break;
  222. case 'i' :
  223. case 'I' :
  224. IoControlCode = FSCTL_MARK_AS_SYSTEM_HIVE;
  225. HaveIoControlCode = TRUE;
  226. break;
  227. case 'j' :
  228. case 'J' :
  229. IoControlCode = FSCTL_FILESYSTEM_GET_STATISTICS;
  230. HaveIoControlCode = TRUE;
  231. break;
  232. case 'k' :
  233. case 'K' :
  234. IoControlCode = FSCTL_IS_VOLUME_DIRTY;
  235. HaveIoControlCode = TRUE;
  236. break;
  237. case 'l' :
  238. case 'L' :
  239. IoControlCode = FSCTL_GET_NTFS_VOLUME_DATA;
  240. HaveIoControlCode = TRUE;
  241. break;
  242. case 'm' :
  243. case 'M' :
  244. IoControlCode = FSCTL_GET_VOLUME_BITMAP;
  245. HaveIoControlCode = TRUE;
  246. break;
  247. case 'n' :
  248. case 'N' :
  249. IoControlCode = FSCTL_GET_NTFS_FILE_RECORD;
  250. HaveIoControlCode = TRUE;
  251. break;
  252. case 'o' :
  253. case 'O' :
  254. IoControlCode = FSCTL_MOVE_FILE;
  255. HaveIoControlCode = TRUE;
  256. break;
  257. case 'p' :
  258. case 'P' :
  259. IoControlCode = FSCTL_ALLOW_EXTENDED_DASD_IO;
  260. HaveIoControlCode = TRUE;
  261. break;
  262. case 'q' :
  263. case 'Q' :
  264. IoControlCode = FSCTL_GET_RETRIEVAL_POINTERS;
  265. HaveIoControlCode = TRUE;
  266. break;
  267. case 'r' :
  268. case 'R' :
  269. IoControlCode = FSCTL_SET_ENCRYPTION;
  270. HaveIoControlCode = TRUE;
  271. break;
  272. case 's' :
  273. case 'S' :
  274. IoControlCode = FSCTL_EXTEND_VOLUME;
  275. HaveIoControlCode = TRUE;
  276. break;
  277. case 't' :
  278. case 'T' :
  279. IoControlCode = FSCTL_FIND_FILES_BY_SID;
  280. HaveIoControlCode = TRUE;
  281. break;
  282. case 'u' :
  283. case 'U' :
  284. IoControlCode = FSCTL_MARK_HANDLE;
  285. HaveIoControlCode = TRUE;
  286. break;
  287. case 'v' :
  288. case 'V' :
  289. IoControlCode = FSCTL_FILE_PREFETCH;
  290. HaveIoControlCode = TRUE;
  291. break;
  292. default :
  293. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  294. SwitchBool = FALSE;
  295. }
  296. if (!SwitchBool) {
  297. break;
  298. }
  299. ParamBuffer++;
  300. }
  301. break;
  302. case 'v' :
  303. case 'V' :
  304. //
  305. // Legal values for params are T/t or F/f.
  306. //
  307. ParamBuffer++;
  308. if (*ParamBuffer == 'T'
  309. || *ParamBuffer == 't') {
  310. VerboseResults = TRUE;
  311. ParamBuffer++;
  312. } else if (*ParamBuffer == 'F'
  313. || *ParamBuffer == 'f') {
  314. VerboseResults = FALSE;
  315. ParamBuffer++;
  316. }
  317. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  318. break;
  319. case 'y' :
  320. case 'Y' :
  321. //
  322. // Set the display parms flag and jump over this
  323. // character.
  324. //
  325. DisplayParms = TRUE;
  326. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  327. break;
  328. case 'z' :
  329. case 'Z' :
  330. //
  331. // Set flag for more input and jump over this char.
  332. //
  333. LastInput = FALSE;
  334. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  335. break;
  336. default :
  337. //
  338. // Swallow to the next white space and continue the
  339. // loop.
  340. //
  341. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  342. }
  343. }
  344. //
  345. // Else the text is invalid, skip the entire block.
  346. //
  347. //
  348. //
  349. // Else if there is no input then exit.
  350. //
  351. } else if (LastInput) {
  352. break;
  353. //
  354. // Else try to read another line for open parameters.
  355. //
  356. } else {
  357. }
  358. }
  359. if (!HaveFileIndex || !HaveIoControlCode) {
  360. printf( "\n Usage: fsct -i<digits> -o<char> -b<i|o><digits> -l<i|o><digits>\n" );
  361. printf( "\n Options:" );
  362. printf( "\n -i<digits> Open file handle" );
  363. printf( "\n -o<chars> Fsctrl operation" );
  364. printf( "\n -oa Lock volume" );
  365. printf( "\n -ob Unlock volume" );
  366. printf( "\n -oc Dismount volume" );
  367. printf( "\n -od Mark volume dirty" );
  368. printf( "\n -oe Is pathname valid" );
  369. printf( "\n -of Query retrieval pointers" );
  370. printf( "\n -og Get compression" );
  371. printf( "\n -oh Set compression" );
  372. printf( "\n -oi Mark as system hive" );
  373. printf( "\n -oj Get statistics" );
  374. printf( "\n -ok Is volume dirty" );
  375. printf( "\n -ol Get Ntfs volume data" );
  376. printf( "\n -om Get volume bitmap" );
  377. printf( "\n -on Get Ntfs file record" );
  378. printf( "\n -oo Move file" );
  379. printf( "\n -op Set Dasd IO" );
  380. printf( "\n -oq Get retrieval pointers" );
  381. printf( "\n -or Set encryption" );
  382. printf( "\n -os Extend volume" );
  383. printf( "\n -ot Query files by SID" );
  384. printf( "\n -ou Mark handle" );
  385. printf( "\n -ov File prefetch" );
  386. printf( "\n -b[i|o]<digits> I/O buffers" );
  387. printf( "\n -l[i|o]<digits> I/O buffer lengths" );
  388. printf( "\n -e[t|f] Use event results" );
  389. printf( "\n -v[t|f] Verbose results" );
  390. printf( "\n -y Display parameters to query" );
  391. printf( "\n -z Additional input line" );
  392. printf( "\n\n" );
  393. //
  394. // Else process the call.
  395. //
  396. } else {
  397. NTSTATUS Status;
  398. SIZE_T RegionSize;
  399. ULONG TempIndex;
  400. PASYNC_FSCTRL AsyncFsctrl;
  401. HANDLE ThreadHandle;
  402. ULONG ThreadId;
  403. RegionSize = sizeof( ASYNC_FSCTRL );
  404. Status = AllocateBuffer( 0, &RegionSize, &TempIndex );
  405. AsyncIndex = (USHORT) TempIndex;
  406. if (!NT_SUCCESS( Status )) {
  407. printf("\n\tInputFsctrl: Unable to allocate async structure" );
  408. } else {
  409. AsyncFsctrl = (PASYNC_FSCTRL) Buffers[AsyncIndex].Buffer;
  410. AsyncFsctrl->FileIndex = FileIndex;
  411. AsyncFsctrl->UseEvent = UseEvent;
  412. AsyncFsctrl->ApcRoutine = ApcRoutine;
  413. AsyncFsctrl->ApcContext = ApcContext;
  414. AsyncFsctrl->IoControlCode = IoControlCode;
  415. AsyncFsctrl->InputBuffer = InputBuffer;
  416. AsyncFsctrl->InputBufferLength = InputBufferLength;
  417. AsyncFsctrl->OutputBuffer = OutputBuffer;
  418. AsyncFsctrl->OutputBufferLength = OutputBufferLength;
  419. AsyncFsctrl->VerboseResults = VerboseResults;
  420. AsyncFsctrl->AsyncIndex = AsyncIndex;
  421. if (DisplayParms) {
  422. printf( "\nFsctrl Operation Parameters" );
  423. printf( "\n Handle index -> %ld", FileIndex );
  424. printf( "\n Fsctrl operation -> %ld", IoControlCode );
  425. printf( "\n\n" );
  426. }
  427. if (!SynchronousCmds) {
  428. ThreadHandle = CreateThread( NULL,
  429. 0,
  430. RequestFsctrl,
  431. AsyncFsctrl,
  432. 0,
  433. &ThreadId );
  434. if (ThreadHandle == 0) {
  435. printf( "\nInputFsctrl: Spawning thread fails -> %d\n", GetLastError() );
  436. }
  437. } else {
  438. RequestFsctrl( AsyncFsctrl );
  439. }
  440. }
  441. }
  442. return;
  443. }
  444. VOID
  445. RequestFsctrl (
  446. IN PASYNC_FSCTRL Fsctrl
  447. )
  448. {
  449. HANDLE ThisEvent;
  450. USHORT ThisEventIndex = 0;
  451. NTSTATUS Status = STATUS_SUCCESS;
  452. IO_STATUS_BLOCK IoSb;
  453. IoSb.Status = 0;
  454. IoSb.Information = 0;
  455. if (Fsctrl->UseEvent) {
  456. Status = ObtainEvent( &ThisEventIndex );
  457. if (!NT_SUCCESS( Status )) {
  458. bprint "\n\tRequestFsctrl: Unable to allocate an event" );
  459. } else {
  460. ThisEvent = Events[ThisEventIndex].Handle;
  461. }
  462. }
  463. if (NT_SUCCESS( Status )) {
  464. IoSb.Status = 0;
  465. IoSb.Information = 0;
  466. Status = NtFsControlFile( Handles[Fsctrl->FileIndex].Handle,
  467. ThisEvent,
  468. Fsctrl->ApcRoutine,
  469. Fsctrl->ApcContext,
  470. &IoSb,
  471. Fsctrl->IoControlCode,
  472. Fsctrl->InputBuffer,
  473. Fsctrl->InputBufferLength,
  474. Fsctrl->OutputBuffer,
  475. Fsctrl->OutputBufferLength );
  476. if (Fsctrl->VerboseResults) {
  477. bprint "\nRequestFsctrl: Status -> %08lx\n", Status );
  478. if (Fsctrl->UseEvent && NT_SUCCESS( Status )) {
  479. if ((Status = NtWaitForSingleObject( ThisEvent,
  480. FALSE,
  481. NULL )) != STATUS_SUCCESS) {
  482. bprint "\n\tFsctrl: Wait for event failed -> %08lx", Status );
  483. }
  484. }
  485. if (!NT_ERROR( Status )) {
  486. bprint "\nRequestFsctrl: IoSb.Status -> %08lx", IoSb.Status );
  487. bprint "\nRequestFsctrl: IoSb.Information -> %08lx", IoSb.Information );
  488. }
  489. bprint "\n" );
  490. }
  491. }
  492. if (ThisEventIndex != 0) {
  493. FreeEvent( ThisEventIndex );
  494. }
  495. DeallocateBuffer( Fsctrl->AsyncIndex );
  496. if (!SynchronousCmds) {
  497. NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS );
  498. bprint "\nRequestFsctrl: Thread not terminated\n" );
  499. }
  500. }