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.

1019 lines
30 KiB

  1. #include "brian.h"
  2. #define OPLOCK_VERBOSES_DEFAULT TRUE
  3. typedef struct _OPLOCK {
  4. ULONG FileHandleIndex;
  5. BOOLEAN VerboseResults;
  6. USHORT BufferIndex;
  7. } OPLOCK, *POPLOCK;
  8. //
  9. // Local procedures
  10. //
  11. VOID
  12. RequestOplockI (
  13. IN POPLOCK Oplock
  14. );
  15. VOID
  16. RequestBatchOplock (
  17. IN POPLOCK Oplock
  18. );
  19. VOID
  20. RequestFilterOplock (
  21. IN POPLOCK Oplock
  22. );
  23. VOID
  24. RequestOplockII (
  25. IN POPLOCK Oplock
  26. );
  27. VOID
  28. AcknowledgeOplockBreak (
  29. IN POPLOCK Oplock
  30. );
  31. VOID
  32. AcknowledgeOplockBreakNo2 (
  33. IN POPLOCK Oplock
  34. );
  35. VOID
  36. AcknowledgeOpBatchBreakPending (
  37. IN POPLOCK Oplock
  38. );
  39. VOID
  40. OplockBreakNotify (
  41. IN POPLOCK Oplock
  42. );
  43. VOID
  44. InputOplock(
  45. IN PCHAR ParamBuffer
  46. )
  47. {
  48. ULONG Operation;
  49. BOOLEAN VerboseResults;
  50. BOOLEAN DisplayParms;
  51. BOOLEAN ParamReceived;
  52. BOOLEAN LastInput;
  53. POPLOCK Oplock;
  54. ULONG FileHandleIndex;
  55. VerboseResults = OPLOCK_VERBOSES_DEFAULT;
  56. DisplayParms = FALSE;
  57. ParamReceived = FALSE;
  58. LastInput = TRUE;
  59. FileHandleIndex = 0;
  60. Operation = (ULONG) -1;
  61. //
  62. // While there is more input, analyze the parameter and update the
  63. // query flags.
  64. //
  65. while (TRUE) {
  66. ULONG DummyCount;
  67. //
  68. // Swallow leading white spaces.
  69. //
  70. ParamBuffer = SwallowWhite( ParamBuffer, &DummyCount );
  71. if (*ParamBuffer) {
  72. //
  73. // If the next parameter is legal then check the paramter value.
  74. // Update the parameter value.
  75. //
  76. if ((*ParamBuffer == '-'
  77. || *ParamBuffer == '/')
  78. && (ParamBuffer++, *ParamBuffer != '\0')) {
  79. BOOLEAN SwitchBool;
  80. //
  81. // Switch on the next character.
  82. //
  83. switch (*ParamBuffer) {
  84. //
  85. // Modify the operation
  86. //
  87. case 'o' :
  88. case 'O' :
  89. ParamBuffer++;
  90. SwitchBool = TRUE;
  91. while (*ParamBuffer
  92. && *ParamBuffer != ' '
  93. && *ParamBuffer != '\t') {
  94. //
  95. // Perform switch on character.
  96. //
  97. switch (*ParamBuffer) {
  98. case 'a' :
  99. case 'A' :
  100. Operation = FSCTL_REQUEST_OPLOCK_LEVEL_1;
  101. ParamReceived = TRUE;
  102. break;
  103. case 'b' :
  104. case 'B' :
  105. Operation = FSCTL_REQUEST_OPLOCK_LEVEL_2;
  106. ParamReceived = TRUE;
  107. break;
  108. case 'c' :
  109. case 'C' :
  110. Operation = FSCTL_REQUEST_BATCH_OPLOCK;
  111. ParamReceived = TRUE;
  112. break;
  113. case 'd' :
  114. case 'D' :
  115. Operation = FSCTL_REQUEST_FILTER_OPLOCK;
  116. ParamReceived = TRUE;
  117. break;
  118. case 'e' :
  119. case 'E' :
  120. Operation = FSCTL_OPLOCK_BREAK_ACKNOWLEDGE;
  121. ParamReceived = TRUE;
  122. break;
  123. case 'f' :
  124. case 'F' :
  125. Operation = FSCTL_OPBATCH_ACK_CLOSE_PENDING;
  126. ParamReceived = TRUE;
  127. break;
  128. case 'g' :
  129. case 'G' :
  130. Operation = FSCTL_OPLOCK_BREAK_NOTIFY;
  131. ParamReceived = TRUE;
  132. break;
  133. case 'h' :
  134. case 'H' :
  135. Operation = FSCTL_OPLOCK_BREAK_ACK_NO_2;
  136. ParamReceived = TRUE;
  137. break;
  138. case 'z' :
  139. case 'Z' :
  140. ParamReceived = FALSE;
  141. Operation = (ULONG) -1;
  142. break;
  143. default :
  144. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  145. SwitchBool = FALSE;
  146. }
  147. if (!SwitchBool) {
  148. break;
  149. }
  150. ParamBuffer++;
  151. }
  152. break;
  153. //
  154. // Update the file handle index.
  155. //
  156. case 'i' :
  157. case 'I' :
  158. //
  159. // Move to the next character, as long as there
  160. // are no white spaces continue analyzing letters.
  161. // On the first bad letter, skip to the next
  162. // parameter.
  163. //
  164. ParamBuffer++;
  165. FileHandleIndex = AsciiToInteger( ParamBuffer );
  166. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  167. break;
  168. case 'v' :
  169. case 'V' :
  170. //
  171. // Legal values for params are T/t or F/f.
  172. //
  173. ParamBuffer++;
  174. if (*ParamBuffer == 'T'
  175. || *ParamBuffer == 't') {
  176. VerboseResults = TRUE;
  177. ParamBuffer++;
  178. } else if (*ParamBuffer == 'F'
  179. || *ParamBuffer == 'f') {
  180. VerboseResults = FALSE;
  181. ParamBuffer++;
  182. }
  183. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  184. break;
  185. case 'y' :
  186. case 'Y' :
  187. //
  188. // Set the display parms flag and jump over this
  189. // character.
  190. //
  191. DisplayParms = TRUE;
  192. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  193. break;
  194. case 'z' :
  195. case 'Z' :
  196. //
  197. // Set flag for more input and jump over this char.
  198. //
  199. LastInput = FALSE;
  200. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  201. break;
  202. default :
  203. //
  204. // Swallow to the next white space and continue the
  205. // loop.
  206. //
  207. ParamBuffer = SwallowNonWhite( ParamBuffer, &DummyCount );
  208. }
  209. }
  210. //
  211. // Else the text is invalid, skip the entire block.
  212. //
  213. //
  214. //
  215. // Else if there is no input then exit.
  216. //
  217. } else if (LastInput) {
  218. break;
  219. //
  220. // Else try to read another line for open parameters.
  221. //
  222. } else {
  223. }
  224. }
  225. //
  226. // If no parameters were received then display the syntax message.
  227. //
  228. if (!ParamReceived) {
  229. printf( "\n Usage: oplk -i<digits> -o<char> [options]*\n" );
  230. printf( "\n Options:" );
  231. printf( "\n -i<digits> Open file handle" );
  232. printf( "\n -o<chars> Oplock operation" );
  233. printf( "\n -v[t|f] Verbose results" );
  234. printf( "\n -y Display parameters to query" );
  235. printf( "\n -z Additional input line" );
  236. printf( "\n\n" );
  237. //
  238. // Else process the call.
  239. //
  240. } else {
  241. NTSTATUS Status;
  242. SIZE_T RegionSize;
  243. ULONG TempIndex;
  244. USHORT BufferIndex;
  245. HANDLE ThreadHandle;
  246. ULONG ThreadId;
  247. RegionSize = sizeof( OPLOCK );
  248. Status = AllocateBuffer( 0, &RegionSize, &TempIndex );
  249. BufferIndex = (USHORT) TempIndex;
  250. if (!NT_SUCCESS( Status )) {
  251. printf("\n\tInputOplock: Unable to allocate async structure" );
  252. } else {
  253. Oplock = (POPLOCK) Buffers[BufferIndex].Buffer;
  254. Oplock->FileHandleIndex = FileHandleIndex;
  255. Oplock->VerboseResults = VerboseResults;
  256. Oplock->BufferIndex = BufferIndex;
  257. if (DisplayParms) {
  258. printf( "\nOplock Operation Parameters" );
  259. printf( "\n Handle index -> %ld", FileHandleIndex );
  260. printf( "\n Oplock operation -> %ld", Operation );
  261. printf( "\n Structure buffer index -> %d", BufferIndex );
  262. printf( "\n\n" );
  263. }
  264. switch (Operation) {
  265. case FSCTL_REQUEST_OPLOCK_LEVEL_1 :
  266. ThreadHandle = CreateThread( NULL,
  267. 0,
  268. RequestOplockI,
  269. Oplock,
  270. 0,
  271. &ThreadId );
  272. break;
  273. case FSCTL_REQUEST_OPLOCK_LEVEL_2 :
  274. ThreadHandle = CreateThread( NULL,
  275. 0,
  276. RequestOplockII,
  277. Oplock,
  278. 0,
  279. &ThreadId );
  280. break;
  281. case FSCTL_REQUEST_BATCH_OPLOCK :
  282. ThreadHandle = CreateThread( NULL,
  283. 0,
  284. RequestBatchOplock,
  285. Oplock,
  286. 0,
  287. &ThreadId );
  288. break;
  289. case FSCTL_REQUEST_FILTER_OPLOCK :
  290. ThreadHandle = CreateThread( NULL,
  291. 0,
  292. RequestFilterOplock,
  293. Oplock,
  294. 0,
  295. &ThreadId );
  296. break;
  297. case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE :
  298. ThreadHandle = CreateThread( NULL,
  299. 0,
  300. AcknowledgeOplockBreak,
  301. Oplock,
  302. 0,
  303. &ThreadId );
  304. break;
  305. case FSCTL_OPBATCH_ACK_CLOSE_PENDING :
  306. ThreadHandle = CreateThread( NULL,
  307. 0,
  308. AcknowledgeOpBatchBreakPending,
  309. Oplock,
  310. 0,
  311. &ThreadId );
  312. break;
  313. case FSCTL_OPLOCK_BREAK_NOTIFY :
  314. ThreadHandle = CreateThread( NULL,
  315. 0,
  316. OplockBreakNotify,
  317. Oplock,
  318. 0,
  319. &ThreadId );
  320. break;
  321. case FSCTL_OPLOCK_BREAK_ACK_NO_2 :
  322. ThreadHandle = CreateThread( NULL,
  323. 0,
  324. AcknowledgeOplockBreakNo2,
  325. Oplock,
  326. 0,
  327. &ThreadId );
  328. break;
  329. default :
  330. printf( "\nInputOplock: Invalid operation\n" );
  331. return;
  332. }
  333. if (ThreadHandle == 0) {
  334. printf( "\nInputOplock: Spawning thread fails -> %d\n", GetLastError() );
  335. }
  336. }
  337. }
  338. return;
  339. }
  340. VOID
  341. RequestOplockI (
  342. IN POPLOCK Oplock
  343. )
  344. {
  345. HANDLE Event;
  346. NTSTATUS Status;
  347. IO_STATUS_BLOCK IoSb;
  348. IoSb.Status = 0;
  349. IoSb.Information = 0;
  350. Status = NtCreateEvent( &Event,
  351. SYNCHRONIZE
  352. | GENERIC_READ
  353. | GENERIC_WRITE,
  354. NULL,
  355. NotificationEvent,
  356. FALSE );
  357. if (!NT_SUCCESS( Status )) {
  358. bprint "\nRequestOplockI: NtCreateEvent failed -> %08lx\n", Status );
  359. } else {
  360. Status = NtFsControlFile( Handles[Oplock->FileHandleIndex].Handle,
  361. Event,
  362. NULL,
  363. NULL,
  364. &IoSb,
  365. FSCTL_REQUEST_OPLOCK_LEVEL_1,
  366. NULL,
  367. 0,
  368. NULL,
  369. 0 );
  370. if (Oplock->VerboseResults) {
  371. bprint "\nRequestOplockI: Status -> %08lx\n", Status );
  372. if (NT_SUCCESS( Status )) {
  373. if ((Status = NtWaitForSingleObject( Event,
  374. FALSE,
  375. NULL )) != STATUS_SUCCESS) {
  376. bprint "\n\tRequestOplockI: Wait for event failed -> %08lx", Status );
  377. }
  378. }
  379. if (NT_SUCCESS( Status )) {
  380. bprint "\nRequestOplockI: IoSb.Status -> %08lx", IoSb.Status );
  381. bprint "\nRequestOplockI: IoSb.Information -> %08lx", IoSb.Information );
  382. }
  383. bprint "\n" );
  384. }
  385. }
  386. DeallocateBuffer( Oplock->BufferIndex );
  387. if (!SynchronousCmds) {
  388. NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS );
  389. bprint "\nRequestOplockI: Thread not terminated\n" );
  390. }
  391. }
  392. VOID
  393. RequestBatchOplock (
  394. IN POPLOCK Oplock
  395. )
  396. {
  397. HANDLE Event;
  398. NTSTATUS Status;
  399. IO_STATUS_BLOCK IoSb;
  400. IoSb.Status = 0;
  401. IoSb.Information = 0;
  402. Status = NtCreateEvent( &Event,
  403. SYNCHRONIZE
  404. | GENERIC_READ
  405. | GENERIC_WRITE,
  406. NULL,
  407. NotificationEvent,
  408. FALSE );
  409. if (!NT_SUCCESS( Status )) {
  410. bprint "\nRequestBatchOplock: NtCreateEvent failed -> %08lx\n", Status );
  411. } else {
  412. Status = NtFsControlFile( Handles[Oplock->FileHandleIndex].Handle,
  413. Event,
  414. NULL,
  415. NULL,
  416. &IoSb,
  417. FSCTL_REQUEST_BATCH_OPLOCK,
  418. NULL,
  419. 0,
  420. NULL,
  421. 0 );
  422. if (Oplock->VerboseResults) {
  423. bprint "\nRequestBatchOplock: Status -> %08lx\n", Status );
  424. if (NT_SUCCESS( Status )) {
  425. if ((Status = NtWaitForSingleObject( Event,
  426. FALSE,
  427. NULL )) != STATUS_SUCCESS) {
  428. bprint "\n\tRequestBatchOplock: Wait for event failed -> %08lx", Status );
  429. }
  430. }
  431. if (NT_SUCCESS( Status )) {
  432. bprint "\nRequestBatchOplock: IoSb.Status -> %08lx", IoSb.Status );
  433. bprint "\nRequestBatchOplock: IoSb.Information -> %08lx", IoSb.Information );
  434. }
  435. bprint "\n" );
  436. }
  437. }
  438. DeallocateBuffer( Oplock->BufferIndex );
  439. if (!SynchronousCmds) {
  440. NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS );
  441. bprint "\nRequestBatchOplock: Thread not terminated\n" );
  442. }
  443. }
  444. VOID
  445. RequestFilterOplock (
  446. IN POPLOCK Oplock
  447. )
  448. {
  449. HANDLE Event;
  450. NTSTATUS Status;
  451. IO_STATUS_BLOCK IoSb;
  452. IoSb.Status = 0;
  453. IoSb.Information = 0;
  454. Status = NtCreateEvent( &Event,
  455. SYNCHRONIZE
  456. | GENERIC_READ
  457. | GENERIC_WRITE,
  458. NULL,
  459. NotificationEvent,
  460. FALSE );
  461. if (!NT_SUCCESS( Status )) {
  462. bprint "\nRequestFilterOplock: NtCreateEvent failed -> %08lx\n", Status );
  463. } else {
  464. Status = NtFsControlFile( Handles[Oplock->FileHandleIndex].Handle,
  465. Event,
  466. NULL,
  467. NULL,
  468. &IoSb,
  469. FSCTL_REQUEST_FILTER_OPLOCK,
  470. NULL,
  471. 0,
  472. NULL,
  473. 0 );
  474. if (Oplock->VerboseResults) {
  475. bprint "\nRequestFilterOplock: Status -> %08lx\n", Status );
  476. if (NT_SUCCESS( Status )) {
  477. if ((Status = NtWaitForSingleObject( Event,
  478. FALSE,
  479. NULL )) != STATUS_SUCCESS) {
  480. bprint "\n\tRequestFilterOplock: Wait for event failed -> %08lx", Status );
  481. }
  482. if (NT_SUCCESS( Status )) {
  483. bprint "\nRequestFilterOplock: IoSb.Status -> %08lx", IoSb.Status );
  484. bprint "\nRequestFilterOplock: IoSb.Information -> %08lx", IoSb.Information );
  485. }
  486. }
  487. bprint "\n" );
  488. }
  489. }
  490. DeallocateBuffer( Oplock->BufferIndex );
  491. if (!SynchronousCmds) {
  492. NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS );
  493. bprint "\nRequestFilterOplock: Thread not terminated\n" );
  494. }
  495. }
  496. VOID
  497. RequestOplockII (
  498. IN POPLOCK Oplock
  499. )
  500. {
  501. HANDLE Event;
  502. NTSTATUS Status;
  503. IO_STATUS_BLOCK IoSb;
  504. IoSb.Status = 0;
  505. IoSb.Information = 0;
  506. Status = NtCreateEvent( &Event,
  507. SYNCHRONIZE
  508. | GENERIC_READ
  509. | GENERIC_WRITE,
  510. NULL,
  511. NotificationEvent,
  512. FALSE );
  513. if (!NT_SUCCESS( Status )) {
  514. bprint "\nRequestOplockII: NtCreateEvent failed -> %08lx\n", Status );
  515. } else {
  516. Status = NtFsControlFile( Handles[Oplock->FileHandleIndex].Handle,
  517. Event,
  518. NULL,
  519. NULL,
  520. &IoSb,
  521. FSCTL_REQUEST_OPLOCK_LEVEL_2,
  522. NULL,
  523. 0,
  524. NULL,
  525. 0 );
  526. if (Oplock->VerboseResults) {
  527. bprint "\nRequestOplockII: Status -> %08lx\n", Status );
  528. if (NT_SUCCESS( Status )) {
  529. if ((Status = NtWaitForSingleObject( Event,
  530. FALSE,
  531. NULL )) != STATUS_SUCCESS) {
  532. bprint "\n\tRequestOplockII: Wait for event failed -> %08lx", Status );
  533. }
  534. if (NT_SUCCESS( Status )) {
  535. bprint "\nRequestOplockII: IoSb.Status -> %08lx", IoSb.Status );
  536. bprint "\nRequestOplockII: IoSb.Information -> %08lx", IoSb.Information );
  537. }
  538. }
  539. bprint "\n" );
  540. }
  541. }
  542. DeallocateBuffer( Oplock->BufferIndex );
  543. if (!SynchronousCmds) {
  544. NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS );
  545. bprint "\nRequestOplockII: Thread not terminated\n" );
  546. }
  547. }
  548. VOID
  549. AcknowledgeOplockBreak (
  550. IN POPLOCK Oplock
  551. )
  552. {
  553. HANDLE Event;
  554. NTSTATUS Status;
  555. IO_STATUS_BLOCK IoSb;
  556. IoSb.Status = 0;
  557. IoSb.Information = 0;
  558. Status = NtCreateEvent( &Event,
  559. SYNCHRONIZE
  560. | GENERIC_READ
  561. | GENERIC_WRITE,
  562. NULL,
  563. NotificationEvent,
  564. FALSE );
  565. if (!NT_SUCCESS( Status )) {
  566. bprint "\nAcknowledgeOplockBreak: NtCreateEvent failed -> %08lx\n", Status );
  567. } else {
  568. Status = NtFsControlFile( Handles[Oplock->FileHandleIndex].Handle,
  569. Event,
  570. NULL,
  571. NULL,
  572. &IoSb,
  573. FSCTL_OPLOCK_BREAK_ACKNOWLEDGE,
  574. NULL,
  575. 0,
  576. NULL,
  577. 0 );
  578. if (Oplock->VerboseResults) {
  579. bprint "\nAcknowledgeOplockBreak: Status -> %08lx\n", Status );
  580. if (NT_SUCCESS( Status )) {
  581. if ((Status = NtWaitForSingleObject( Event,
  582. FALSE,
  583. NULL )) != STATUS_SUCCESS) {
  584. bprint "\n\tAcknowledgeOplockBreak: Wait for event failed -> %08lx", Status );
  585. }
  586. if (NT_SUCCESS( Status )) {
  587. bprint "\nAcknowledgeOplockBreak: IoSb.Status -> %08lx", IoSb.Status );
  588. bprint "\nAcknowledgeOplockBreak: IoSb.Information -> %08lx", IoSb.Information );
  589. }
  590. }
  591. bprint "\n" );
  592. }
  593. }
  594. DeallocateBuffer( Oplock->BufferIndex );
  595. if (!SynchronousCmds) {
  596. NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS );
  597. bprint "\nAcknowledgeOplockBreak: Thread not terminated\n" );
  598. }
  599. }
  600. VOID
  601. AcknowledgeOplockBreakNo2 (
  602. IN POPLOCK Oplock
  603. )
  604. {
  605. HANDLE Event;
  606. NTSTATUS Status;
  607. IO_STATUS_BLOCK IoSb;
  608. IoSb.Status = 0;
  609. IoSb.Information = 0;
  610. Status = NtCreateEvent( &Event,
  611. SYNCHRONIZE
  612. | GENERIC_READ
  613. | GENERIC_WRITE,
  614. NULL,
  615. NotificationEvent,
  616. FALSE );
  617. if (!NT_SUCCESS( Status )) {
  618. bprint "\nAcknowledgeOplockBreakNo2: NtCreateEvent failed -> %08lx\n", Status );
  619. } else {
  620. Status = NtFsControlFile( Handles[Oplock->FileHandleIndex].Handle,
  621. Event,
  622. NULL,
  623. NULL,
  624. &IoSb,
  625. FSCTL_OPLOCK_BREAK_ACK_NO_2,
  626. NULL,
  627. 0,
  628. NULL,
  629. 0 );
  630. if (Oplock->VerboseResults) {
  631. bprint "\nAcknowledgeOplockBreakNo2: Status -> %08lx\n", Status );
  632. if (NT_SUCCESS( Status )) {
  633. if ((Status = NtWaitForSingleObject( Event,
  634. FALSE,
  635. NULL )) != STATUS_SUCCESS) {
  636. bprint "\n\tAcknowledgeOplockBreakNo2: Wait for event failed -> %08lx", Status );
  637. }
  638. if (NT_SUCCESS( Status )) {
  639. bprint "\nAcknowledgeOplockBreakNo2: IoSb.Status -> %08lx", IoSb.Status );
  640. bprint "\nAcknowledgeOplockBreakNo2: IoSb.Information -> %08lx", IoSb.Information );
  641. }
  642. }
  643. bprint "\n" );
  644. }
  645. }
  646. DeallocateBuffer( Oplock->BufferIndex );
  647. if (!SynchronousCmds) {
  648. NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS );
  649. bprint "\nAcknowledgeOplockBreak: Thread not terminated\n" );
  650. }
  651. }
  652. VOID
  653. AcknowledgeOpBatchBreakPending (
  654. IN POPLOCK Oplock
  655. )
  656. {
  657. HANDLE Event;
  658. NTSTATUS Status;
  659. IO_STATUS_BLOCK IoSb;
  660. IoSb.Status = 0;
  661. IoSb.Information = 0;
  662. Status = NtCreateEvent( &Event,
  663. SYNCHRONIZE
  664. | GENERIC_READ
  665. | GENERIC_WRITE,
  666. NULL,
  667. NotificationEvent,
  668. FALSE );
  669. if (!NT_SUCCESS( Status )) {
  670. bprint "\nAcknowledgeOpBatchBreakPending: NtCreateEvent failed -> %08lx\n", Status );
  671. } else {
  672. Status = NtFsControlFile( Handles[Oplock->FileHandleIndex].Handle,
  673. Event,
  674. NULL,
  675. NULL,
  676. &IoSb,
  677. FSCTL_OPBATCH_ACK_CLOSE_PENDING,
  678. NULL,
  679. 0,
  680. NULL,
  681. 0 );
  682. if (Oplock->VerboseResults) {
  683. bprint "\nAcknowledgeOpBatchBreakPending: Status -> %08lx\n", Status );
  684. if (NT_SUCCESS( Status )) {
  685. if ((Status = NtWaitForSingleObject( Event,
  686. FALSE,
  687. NULL )) != STATUS_SUCCESS) {
  688. bprint "\n\tAcknowledgeOpBatchBreakPending: Wait for event failed -> %08lx", Status );
  689. }
  690. if (NT_SUCCESS( Status )) {
  691. bprint "\nAcknowledgeOpBatchBreakPending: IoSb.Status -> %08lx", IoSb.Status );
  692. bprint "\nAcknowledgeOpBatchBreakPending: IoSb.Information -> %08lx", IoSb.Information );
  693. }
  694. }
  695. bprint "\n" );
  696. }
  697. }
  698. DeallocateBuffer( Oplock->BufferIndex );
  699. if (!SynchronousCmds) {
  700. NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS );
  701. bprint "\nAcknowledgeOpBatchBreakPending: Thread not terminated\n" );
  702. }
  703. }
  704. VOID
  705. OplockBreakNotify (
  706. IN POPLOCK Oplock
  707. )
  708. {
  709. HANDLE Event;
  710. NTSTATUS Status;
  711. IO_STATUS_BLOCK IoSb;
  712. IoSb.Status = 0;
  713. IoSb.Information = 0;
  714. Status = NtCreateEvent( &Event,
  715. SYNCHRONIZE
  716. | GENERIC_READ
  717. | GENERIC_WRITE,
  718. NULL,
  719. NotificationEvent,
  720. FALSE );
  721. if (!NT_SUCCESS( Status )) {
  722. bprint "\nOplockBreakNotify: NtCreateEvent failed -> %08lx\n", Status );
  723. } else {
  724. Status = NtFsControlFile( Handles[Oplock->FileHandleIndex].Handle,
  725. Event,
  726. NULL,
  727. NULL,
  728. &IoSb,
  729. FSCTL_OPLOCK_BREAK_NOTIFY,
  730. NULL,
  731. 0,
  732. NULL,
  733. 0 );
  734. if (Oplock->VerboseResults) {
  735. bprint "\nOplockBreakNotify: Status -> %08lx\n", Status );
  736. if (NT_SUCCESS( Status )) {
  737. if ((Status = NtWaitForSingleObject( Event,
  738. FALSE,
  739. NULL )) != STATUS_SUCCESS) {
  740. bprint "\n\tOplockBreakNotify: Wait for event failed -> %08lx", Status );
  741. }
  742. if (NT_SUCCESS( Status )) {
  743. bprint "\nOplockBreakNotify: IoSb.Status -> %08lx", IoSb.Status );
  744. bprint "\nOplockBreakNotify: IoSb.Information -> %08lx", IoSb.Information );
  745. }
  746. }
  747. bprint "\n" );
  748. }
  749. }
  750. DeallocateBuffer( Oplock->BufferIndex );
  751. if (!SynchronousCmds) {
  752. NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS );
  753. bprint "\nOplockBreakNotify: Thread not terminated\n" );
  754. }
  755. }