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.

581 lines
16 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. RequestUsn (
  17. IN PASYNC_FSCTRL Fsctrl
  18. );
  19. //
  20. // Local procedures
  21. //
  22. VOID
  23. InputUsn(
  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\tInputUsn: 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\tInputUsn: 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_ENUM_USN_DATA;
  185. HaveIoControlCode = TRUE;
  186. break;
  187. case 'b' :
  188. case 'B' :
  189. IoControlCode = FSCTL_READ_USN_JOURNAL;
  190. HaveIoControlCode = TRUE;
  191. break;
  192. case 'c' :
  193. case 'C' :
  194. IoControlCode = FSCTL_CREATE_USN_JOURNAL;
  195. HaveIoControlCode = TRUE;
  196. break;
  197. case 'd' :
  198. case 'D' :
  199. IoControlCode = FSCTL_READ_FILE_USN_DATA;
  200. HaveIoControlCode = TRUE;
  201. break;
  202. case 'e' :
  203. case 'E' :
  204. IoControlCode = FSCTL_WRITE_USN_CLOSE_RECORD;
  205. HaveIoControlCode = TRUE;
  206. break;
  207. case 'f' :
  208. case 'F' :
  209. IoControlCode = FSCTL_QUERY_USN_JOURNAL;
  210. HaveIoControlCode = TRUE;
  211. break;
  212. case 'g' :
  213. case 'G' :
  214. IoControlCode = FSCTL_DELETE_USN_JOURNAL;
  215. HaveIoControlCode = TRUE;
  216. break;
  217. default :
  218. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  219. SwitchBool = FALSE;
  220. }
  221. if (!SwitchBool) {
  222. break;
  223. }
  224. ParamBuffer++;
  225. }
  226. break;
  227. case 'v' :
  228. case 'V' :
  229. //
  230. // Legal values for params are T/t or F/f.
  231. //
  232. ParamBuffer++;
  233. if (*ParamBuffer == 'T'
  234. || *ParamBuffer == 't') {
  235. VerboseResults = TRUE;
  236. ParamBuffer++;
  237. } else if (*ParamBuffer == 'F'
  238. || *ParamBuffer == 'f') {
  239. VerboseResults = FALSE;
  240. ParamBuffer++;
  241. }
  242. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  243. break;
  244. case 'y' :
  245. case 'Y' :
  246. //
  247. // Set the display parms flag and jump over this
  248. // character.
  249. //
  250. DisplayParms = TRUE;
  251. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  252. break;
  253. case 'z' :
  254. case 'Z' :
  255. //
  256. // Set flag for more input and jump over this char.
  257. //
  258. LastInput = FALSE;
  259. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  260. break;
  261. default :
  262. //
  263. // Swallow to the next white space and continue the
  264. // loop.
  265. //
  266. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  267. }
  268. }
  269. //
  270. // Else the text is invalid, skip the entire block.
  271. //
  272. //
  273. //
  274. // Else if there is no input then exit.
  275. //
  276. } else if (LastInput) {
  277. break;
  278. //
  279. // Else try to read another line for open parameters.
  280. //
  281. } else {
  282. }
  283. }
  284. if (!HaveFileIndex || !HaveIoControlCode) {
  285. printf( "\n Usage: Usn -i<digits> -o<char> -b<i|o><digits> -l<i|o><digits>\n" );
  286. printf( "\n Options:" );
  287. printf( "\n -i<digits> Open file handle" );
  288. printf( "\n -o<chars> Usn operation" );
  289. printf( "\n -oa Enumerate Usn Data" );
  290. printf( "\n -ob Read Usn Journal" );
  291. printf( "\n -oc Create Usn Journal" );
  292. printf( "\n -od Read File Usn Data" );
  293. printf( "\n -oe Write Usn Close Record" );
  294. printf( "\n -of Query Usn Journal" );
  295. printf( "\n -og Delete Usn Journal" );
  296. printf( "\n -b[i|o]<digits> I/O buffers" );
  297. printf( "\n -l[i|o]<digits> I/O buffer lengths" );
  298. printf( "\n -e[t|f] Use event results" );
  299. printf( "\n -v[t|f] Verbose results" );
  300. printf( "\n -y Display parameters to query" );
  301. printf( "\n -z Additional input line" );
  302. printf( "\n\n" );
  303. //
  304. // Else process the call.
  305. //
  306. } else {
  307. NTSTATUS Status;
  308. SIZE_T RegionSize;
  309. ULONG TempIndex;
  310. PASYNC_FSCTRL AsyncFsctrl;
  311. HANDLE ThreadHandle;
  312. ULONG ThreadId;
  313. RegionSize = sizeof( ASYNC_FSCTRL );
  314. Status = AllocateBuffer( 0, &RegionSize, &TempIndex );
  315. AsyncIndex = (USHORT) TempIndex;
  316. if (!NT_SUCCESS( Status )) {
  317. printf("\n\tInputUsn: Unable to allocate async structure" );
  318. } else {
  319. AsyncFsctrl = (PASYNC_FSCTRL) Buffers[AsyncIndex].Buffer;
  320. AsyncFsctrl->FileIndex = FileIndex;
  321. AsyncFsctrl->UseEvent = UseEvent;
  322. AsyncFsctrl->ApcRoutine = ApcRoutine;
  323. AsyncFsctrl->ApcContext = ApcContext;
  324. AsyncFsctrl->IoControlCode = IoControlCode;
  325. AsyncFsctrl->InputBuffer = InputBuffer;
  326. AsyncFsctrl->InputBufferLength = InputBufferLength;
  327. AsyncFsctrl->OutputBuffer = OutputBuffer;
  328. AsyncFsctrl->OutputBufferLength = OutputBufferLength;
  329. AsyncFsctrl->VerboseResults = VerboseResults;
  330. AsyncFsctrl->AsyncIndex = AsyncIndex;
  331. if (DisplayParms) {
  332. printf( "\nUsn Operation Parameters" );
  333. printf( "\n Handle index -> %ld", FileIndex );
  334. printf( "\n Usn operation -> %ld", IoControlCode );
  335. printf( "\n\n" );
  336. }
  337. if (!SynchronousCmds) {
  338. ThreadHandle = CreateThread( NULL,
  339. 0,
  340. RequestUsn,
  341. AsyncFsctrl,
  342. 0,
  343. &ThreadId );
  344. if (ThreadHandle == 0) {
  345. printf( "\nInputUsn: Spawning thread fails -> %d\n", GetLastError() );
  346. }
  347. } else {
  348. RequestUsn( AsyncFsctrl );
  349. }
  350. }
  351. }
  352. return;
  353. }
  354. VOID
  355. RequestUsn (
  356. IN PASYNC_FSCTRL Fsctrl
  357. )
  358. {
  359. HANDLE ThisEvent;
  360. USHORT ThisEventIndex = 0;
  361. NTSTATUS Status = STATUS_SUCCESS;
  362. IO_STATUS_BLOCK IoSb;
  363. IoSb.Status = 0;
  364. IoSb.Information = 0;
  365. if (Fsctrl->UseEvent) {
  366. Status = ObtainEvent( &ThisEventIndex );
  367. if (!NT_SUCCESS( Status )) {
  368. bprint "\n\tRequestUsn: Unable to allocate an event" );
  369. } else {
  370. ThisEvent = Events[ThisEventIndex].Handle;
  371. }
  372. }
  373. if (NT_SUCCESS( Status )) {
  374. IoSb.Status = 0;
  375. IoSb.Information = 0;
  376. Status = NtFsControlFile( Handles[Fsctrl->FileIndex].Handle,
  377. ThisEvent,
  378. Fsctrl->ApcRoutine,
  379. Fsctrl->ApcContext,
  380. &IoSb,
  381. Fsctrl->IoControlCode,
  382. Fsctrl->InputBuffer,
  383. Fsctrl->InputBufferLength,
  384. Fsctrl->OutputBuffer,
  385. Fsctrl->OutputBufferLength );
  386. if (Fsctrl->VerboseResults) {
  387. bprint "\nRequestUsn: Status -> %08lx\n", Status );
  388. if (Fsctrl->UseEvent && NT_SUCCESS( Status )) {
  389. if ((Status = NtWaitForSingleObject( ThisEvent,
  390. FALSE,
  391. NULL )) != STATUS_SUCCESS) {
  392. bprint "\n\tRequestUsn: Wait for event failed -> %08lx", Status );
  393. }
  394. }
  395. if (NT_SUCCESS( Status )) {
  396. bprint "\nRequestUsn: IoSb.Status -> %08lx", IoSb.Status );
  397. bprint "\nRequestUsn: IoSb.Information -> %08lx", IoSb.Information );
  398. }
  399. bprint "\n" );
  400. }
  401. }
  402. if (ThisEventIndex != 0) {
  403. FreeEvent( ThisEventIndex );
  404. }
  405. DeallocateBuffer( Fsctrl->AsyncIndex );
  406. if (!SynchronousCmds) {
  407. NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS );
  408. bprint "\nRequestUsn: Thread not terminated\n" );
  409. }
  410. }