Source code of Windows XP (NT5)
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.

767 lines
24 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. InnerIo.c
  5. Abstract:
  6. This module implements the read, write, and lockctrl routines for the proxy minirdr
  7. Author:
  8. Joe Linn [JoeLinn] 11-Oct-1994
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. //
  14. // The local debug trace level
  15. //
  16. #define Dbg (DEBUG_TRACE_READ)
  17. #ifdef ALLOC_PRAGMA
  18. #endif
  19. NTSTATUS
  20. MRxProxyBuildAsynchronousRequest(
  21. IN PRX_CONTEXT RxContext,
  22. IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL
  23. )
  24. /*++
  25. Routine Description:
  26. This routine builds an I/O Request Packet (IRP) suitable for a File System
  27. Driver (FSD) to use in requesting an I/O operation from a device driver.
  28. The request (RxContext->MajorFunction) must be one of the following request codes:
  29. IRP_MJ_READ
  30. IRP_MJ_WRITE
  31. IRP_MJ_DIRECTORY_CONTROL
  32. IRP_MJ_FLUSH_BUFFERS
  33. //IRP_MJ_SHUTDOWN (not yet implemented)
  34. Arguments:
  35. CompletionRoutine - the IrpCompletionRoutine
  36. Return Value:
  37. The function value is a pointer to the IRP representing the specified
  38. request.
  39. --*/
  40. {
  41. PIRP irp;
  42. PIO_STACK_LOCATION irpSp;
  43. ULONG MajorFunction = RxContext->MajorFunction;
  44. RxCaptureFcb; RxCaptureFobx;
  45. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  46. PMRXPROXY_RX_CONTEXT pMRxProxyContext = MRxProxyGetMinirdrContext(RxContext);
  47. PMRXPROXY_ASYNCENGINE_CONTEXT AsyncEngineContext =
  48. (PMRXPROXY_ASYNCENGINE_CONTEXT)(pMRxProxyContext->AsyncEngineContext);
  49. PMRX_SRV_OPEN SrvOpen = capFobx->pSrvOpen;
  50. PMRX_PROXY_SRV_OPEN proxySrvOpen = MRxProxyGetSrvOpenExtension(capFobx->pSrvOpen);
  51. //PMRX_PROXY_FCB proxyFcb = MRxProxyGetFcbExtension(capFcb);
  52. PDEVICE_OBJECT DeviceObject = proxySrvOpen->UnderlyingDeviceObject;
  53. PFILE_OBJECT FileObject = proxySrvOpen->UnderlyingFileObject;
  54. LARGE_INTEGER ZeroAsLI;
  55. ULONG MdlLength = 0;
  56. PAGED_CODE();
  57. ASSERT (proxySrvOpen->UnderlyingFileObject);
  58. if (DeviceObject->Flags & DO_BUFFERED_IO) {
  59. //i cannot handled buffered_io devices....sigh
  60. return STATUS_INVALID_DEVICE_REQUEST;
  61. }
  62. RxDbgTrace(0, Dbg, ("MRxProxyBuildAsynchronousRequest %08lx %08lx len/off=%08lx %08lx\n",
  63. RxContext,SrvOpen,
  64. LowIoContext->ParamsFor.ReadWrite.ByteCount,
  65. (ULONG)LowIoContext->ParamsFor.ReadWrite.ByteOffset));
  66. RxLog(("BuildAsyncIrp %lx %lx %lx %lx",
  67. RxContext,SrvOpen,
  68. LowIoContext->ParamsFor.ReadWrite.ByteCount,
  69. (ULONG)LowIoContext->ParamsFor.ReadWrite.ByteOffset));
  70. ZeroAsLI.QuadPart = 0;
  71. // irp = IoBuildAsynchronousFsdRequest(
  72. // MajorFunction,
  73. // DeviceObject,
  74. // NULL,
  75. // 0,
  76. // &ZeroAsLI,
  77. // NULL
  78. // );
  79. //
  80. // if (!irp) {
  81. // return STATUS_INSUFFICIENT_RESOURCES;
  82. // }
  83. irp = IoAllocateIrp( DeviceObject->StackSize, FALSE ); //why not charge???
  84. if (!irp) {
  85. return STATUS_INSUFFICIENT_RESOURCES;
  86. }
  87. //
  88. // Set current thread for IoSetHardErrorOrVerifyDevice.
  89. //
  90. irp->Tail.Overlay.Thread = PsGetCurrentThread();
  91. //
  92. // Get a pointer to the stack location of the first driver which will be
  93. // invoked. This is where the function codes and the parameters are set.
  94. //
  95. irpSp = IoGetNextIrpStackLocation( irp ); //ok4ioget
  96. irpSp->MajorFunction = (UCHAR) MajorFunction;
  97. irpSp->FileObject = FileObject; //ok4->FileObj
  98. RxLog(("BuildAsyncIrpFo %lx %lx",RxContext,FileObject));
  99. { BOOLEAN EnableCalls = CompletionRoutine!=NULL;
  100. IoSetCompletionRoutine(irp, CompletionRoutine, RxContext,
  101. EnableCalls,EnableCalls,EnableCalls);
  102. }
  103. if ( (MajorFunction == IRP_MJ_READ) || (MajorFunction == IRP_MJ_WRITE) ) {
  104. // never paging io
  105. BOOLEAN PagingIo = FALSE;
  106. //BOOLEAN PagingIo =
  107. // BooleanFlagOn(LowIoContext->ParamsFor.ReadWrite.Flags,LOWIO_READWRITEFLAG_PAGING_IO);
  108. irp->Flags |= IRP_NOCACHE;
  109. //
  110. // Set the parameters according to whether this is a read or a write
  111. // operation. Notice that these parameters must be set even if the
  112. // driver has not specified buffered or direct I/O.
  113. //
  114. ASSERT (&irpSp->Parameters.Write.Key == &irpSp->Parameters.Read.Key);
  115. ASSERT (&irpSp->Parameters.Write.Length == &irpSp->Parameters.Read.Length);
  116. ASSERT (&irpSp->Parameters.Write.ByteOffset == &irpSp->Parameters.Read.ByteOffset);
  117. irpSp->Parameters.Read.Key = LowIoContext->ParamsFor.ReadWrite.Key;
  118. irpSp->Parameters.Read.ByteOffset.QuadPart = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
  119. irp->RequestorMode = KernelMode;
  120. irp->UserBuffer = RxLowIoGetBufferAddress(RxContext);
  121. MdlLength = RxContext->CurrentIrp->MdlAddress->ByteCount;
  122. if (PagingIo) {
  123. irpSp->Parameters.Read.Length = MdlLength;
  124. } else {
  125. irpSp->Parameters.Read.Length = LowIoContext->ParamsFor.ReadWrite.ByteCount;
  126. }
  127. } else if (MajorFunction == IRP_MJ_FLUSH_BUFFERS) {
  128. MdlLength = 0;
  129. //nothing else to do!!!
  130. } else {
  131. FILE_INFORMATION_CLASS FileInformationClass = RxContext->Info.FileInformationClass;
  132. PVOID Buffer = RxContext->Info.Buffer;
  133. PULONG pLengthRemaining = &RxContext->Info.LengthRemaining;
  134. BOOLEAN Wait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
  135. ASSERT( MajorFunction == IRP_MJ_DIRECTORY_CONTROL );
  136. irpSp->MinorFunction = IRP_MN_QUERY_DIRECTORY;
  137. //CODE.IMPROVEMENT it would be better to actually get the stuff out of the context.info
  138. irpSp->Parameters.QueryDirectory = RxContext->CurrentIrpSp->Parameters.QueryDirectory;
  139. ASSERT (
  140. (irpSp->Parameters.QueryDirectory.FileInformationClass == FileInformationClass)
  141. && (irpSp->Parameters.QueryDirectory.Length == *pLengthRemaining)
  142. );
  143. irpSp->Flags = RxContext->CurrentIrpSp->Flags;
  144. irp->UserBuffer = Buffer;
  145. MdlLength = *pLengthRemaining;
  146. if (Wait) {
  147. irp->Flags |= IRP_SYNCHRONOUS_API;
  148. }
  149. }
  150. // Build an mdl if necessary....
  151. if (MdlLength != 0) {
  152. irp->MdlAddress = IoAllocateMdl(irp->UserBuffer,MdlLength,
  153. FALSE,FALSE,NULL);
  154. if (!irp->MdlAddress) {
  155. //whoops.......sorry..........
  156. IoFreeIrp(irp);
  157. return(STATUS_INSUFFICIENT_RESOURCES);
  158. }
  159. MmBuildMdlForNonPagedPool(irp->MdlAddress);
  160. }
  161. //
  162. // Finally, return a pointer to the IRP.
  163. //
  164. AsyncEngineContext->CalldownIrp = irp;
  165. RxLog(("BAsyIrpX %lx %lx %lx %lx %lx %lx %lx",
  166. RxContext,
  167. irpSp->MajorFunction,
  168. irpSp->Flags,
  169. irpSp->Parameters.Others.Argument1,
  170. irpSp->Parameters.Others.Argument2,
  171. irpSp->Parameters.Others.Argument3,
  172. irpSp->Parameters.Others.Argument4));
  173. return STATUS_SUCCESS;
  174. }
  175. //----------------------------------------------------------------------------------------------
  176. //----------------------------------------------------------------------------------------------
  177. //----------------------------------------------------------------------------------------------
  178. //----------------------------------------------------------------------------------------------
  179. //----------------------------------------------------------------------------------------------
  180. //----------------------------------------------------------------------------------------------
  181. //----------------------------------------------------------------------------------------------
  182. //----------------------------------------------------------------------------------------------
  183. //----------------------------------------------------------------------------------------------
  184. //----------------------------------------------------------------------------------------------
  185. //----------------------------------------------------------------------------------------------
  186. //----------------------------------------------------------------------------------------------
  187. //
  188. // The local debug trace level
  189. //
  190. #undef Dbg
  191. #define Dbg (DEBUG_TRACE_WRITE)
  192. //everything else in here is ifdef'd out....also CODE.IMPROVEMENT we should change over
  193. //to a common irp building routine in Rx. the code is already in the csc driver
  194. #if 0
  195. NTSTATUS
  196. MRxProxyBuildInnerIoAsyncWrite (
  197. IN PRX_CONTEXT RxContext,
  198. IN PBYTE Buffer,
  199. IN ULONG WriteByteCount,
  200. IN PLARGE_INTEGER FileOffset,
  201. IN OUT PIRP *CalldownIrp
  202. )
  203. /*++
  204. Routine Description:
  205. This routine fills in the calldown irp for a proxy read
  206. Arguments:
  207. RxContext,
  208. PBYTE Buffer - the write buffer
  209. ULONG Count - amount of data to written
  210. PLARGE_INTEGER FileOffset - fileoffset where the write begins
  211. PIRP *CallDownIrp - where the Irp is to be stored
  212. Return Value:
  213. NTSTATUS - Returns the status for the write
  214. --*/
  215. {
  216. NTSTATUS Status = STATUS_SUCCESS;
  217. RxCaptureFcb; RxCaptureFobx;
  218. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  219. PMRX_SRV_OPEN SrvOpen = capFobx->pSrvOpen;
  220. PMRX_PROXY_SRV_OPEN proxySrvOpen = MRxProxyGetSrvOpenExtension(SrvOpen);
  221. RxDbgTrace(+1, Dbg, ("MRxProxyInnerIoWrite.... ByteCount = %08lx, ByteOffset = %08lx %08lx\n",
  222. LowIoContext->ParamsFor.ReadWrite.ByteCount,
  223. FileOffset->LowPart, FileOffset->HighPart));
  224. RxLog(("MRxProxyInnerIoWrite %lx %lx %lx",
  225. SrvOpen,
  226. LowIoContext->ParamsFor.ReadWrite.ByteCount,
  227. FileOffset->LowPart));
  228. RxDbgTrace ( 0, Dbg, ( "MRxProxyInnerIoWrite.... ->Buffer = %8lx\n", Buffer));
  229. *CalldownIrp = MRxProxyBuildAsynchronousReadWriteRequest(
  230. RxContext, // IN PVOID Context
  231. MRxProxyAsyncEngineCalldownIrpCompletion // IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
  232. );
  233. if (!*CalldownIrp){
  234. Status = (STATUS_INSUFFICIENT_RESOURCES);
  235. }
  236. RxDbgTrace(-1, Dbg, ("MRxProxyInnerIoWrite.... exit\n"));
  237. return(Status);
  238. }
  239. //----------------------------------------------------------------------------------------------
  240. //----------------------------------------------------------------------------------------------
  241. //----------------------------------------------------------------------------------------------
  242. //----------------------------------------------------------------------------------------------
  243. //----------------------------------------------------------------------------------------------
  244. //----------------------------------------------------------------------------------------------
  245. //----------------------------------------------------------------------------------------------
  246. //----------------------------------------------------------------------------------------------
  247. //----------------------------------------------------------------------------------------------
  248. //----------------------------------------------------------------------------------------------
  249. //----------------------------------------------------------------------------------------------
  250. //----------------------------------------------------------------------------------------------
  251. //
  252. // The local debug trace level
  253. //
  254. #undef Dbg
  255. #define Dbg (DEBUG_TRACE_LOCKCTRL)
  256. PIRP
  257. MRxBuildLockRequest (
  258. IN PIRP irp OPTIONAL,
  259. IN PFILE_OBJECT fileObject,
  260. IN PETHREAD UsersThread,
  261. IN UCHAR MinorCode,
  262. IN RXVBO ByteOffset,
  263. IN PLARGE_INTEGER Length,
  264. IN ULONG Key,
  265. IN UCHAR Flags,
  266. IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
  267. IN PVOID Context OPTIONAL
  268. )
  269. /*++
  270. Routine Description:
  271. This function builds an I/O request packet for a lock request.
  272. Arguments:
  273. Irp - Supplies a pointer to an IRP; allocates one if one is not provided.
  274. FileObject - Supplies a pointer the file object to which this
  275. request is directed. This pointer is copied into the IRP, so
  276. that the called driver can find its file-based context. NOTE
  277. THAT THIS IS NOT A REFERENCED POINTER. The caller must ensure
  278. that the file object is not deleted while the I/O operation is
  279. in progress. The proxy minirdr accomplishes this by holding a pointer
  280. (a REFERENCED ptr) to the fileobject in its srvopen while the fileobject is
  281. open.
  282. Context - Supplies a PVOID value that is passed to the completion
  283. routine.
  284. StartingBlock - the block number of the beginning of the locked
  285. range.
  286. ByteOffset - the offset within block of the beginning of the locked
  287. range.
  288. Length - the length of the locked range.
  289. Key - the key value to be associated with the lock.
  290. Return Value:
  291. None.
  292. --*/
  293. {
  294. PDEVICE_OBJECT deviceObject;
  295. PIO_STACK_LOCATION irpSp;
  296. PAGED_CODE( );
  297. deviceObject = IoGetRelatedDeviceObject( fileObject );
  298. //
  299. // Allocate and initialize the I/O Request Packet (IRP) for this operation.
  300. // The allocation is performed with an exception handler in case the
  301. // caller does not have enough quota to allocate the packet.
  302. if (irp) {
  303. ASSERT( irp->StackCount >= deviceObject->StackSize );
  304. } else {
  305. irp = IoAllocateIrp( deviceObject->StackSize, TRUE ); //joejoe should i charge quota??
  306. }
  307. if (!irp) {
  308. //
  309. // An IRP could not be allocated.
  310. return NULL;
  311. }
  312. // we have to make sure that the thread that takes the lock is the same as the one that reads
  313. irp->Tail.Overlay.Thread = UsersThread;
  314. irp->RequestorMode = KernelMode;
  315. //
  316. // Get a pointer to the stack location for the first driver. This will be
  317. // used to pass the original function codes and parameters.
  318. //
  319. irpSp = IoGetNextIrpStackLocation( irp );
  320. { BOOLEAN EnableCalls = CompletionRoutine!=NULL;
  321. IoSetCompletionRoutine(irp, CompletionRoutine, Context,
  322. EnableCalls,EnableCalls,EnableCalls);
  323. }
  324. irpSp->MajorFunction = IRP_MJ_LOCK_CONTROL;
  325. irpSp->MinorFunction = MinorCode;
  326. irpSp->FileObject = fileObject; //ok4->FileObj
  327. irpSp->DeviceObject = deviceObject;
  328. irpSp->Flags = Flags;
  329. irpSp->Parameters.LockControl.Length = Length;
  330. irpSp->Parameters.LockControl.Key = Key;
  331. irpSp->Parameters.LockControl.ByteOffset.QuadPart = ByteOffset;
  332. return irp;
  333. }
  334. NTSTATUS
  335. MRxProxyCalldownLockCompletion (
  336. IN PDEVICE_OBJECT DeviceObject,
  337. IN PIRP CalldownIrp,
  338. IN PVOID Context
  339. )
  340. /*++
  341. Routine Description:
  342. This is the I/O completion routine for calldown lock requests. we just call the lowio completion
  343. and exit
  344. Arguments:
  345. DeviceObject - Pointer to target device object for the request.
  346. CalldownIrp - Pointer to I/O request packet used to call down to the underlying filesystem
  347. Context - Irpcontext of the original request to the rdbss
  348. Return Value:
  349. NTSTATUS - (STATUS_MORE_PROCESSING_REQUIRED) is returned.
  350. --*/
  351. {
  352. PRX_CONTEXT RxContext = Context;
  353. RxDbgTrace ( 0, Dbg, ("MRxProxyCalldownLockCompletion = %08lx\n", 0));
  354. //DbgBreakPoint();
  355. if (CalldownIrp->PendingReturned){
  356. RxContext->CurrentIrp->IoStatus = CalldownIrp->IoStatus;
  357. RxContext->StoredStatus = CalldownIrp->IoStatus.Status;
  358. }
  359. RxLowIoCompletion(RxContext);
  360. IoFreeIrp(CalldownIrp);
  361. return((STATUS_MORE_PROCESSING_REQUIRED));
  362. }
  363. NTSTATUS
  364. MRxProxyLocks (
  365. IN PRX_CONTEXT RxContext
  366. )
  367. /*++
  368. Routine Description:
  369. This routine implements proxy read call. we fill in the info and stuff here BUT we
  370. do not complete the Irp.
  371. Arguments:
  372. Return Value:
  373. NTSTATUS - Returns the status for the read
  374. --*/
  375. {
  376. NTSTATUS Status;
  377. RxCaptureRequestPacket;
  378. PIRP CalldownIrp;
  379. RxCaptureFcb; RxCaptureFobx; RxCaptureParamBlock;
  380. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  381. PSRV_OPEN SrvOpen = capFobx->SrvOpen;
  382. PMRX_LOCAL_SRV_OPEN proxySrvOpen = (PMRX_LOCAL_SRV_OPEN)SrvOpen;
  383. BOOLEAN Wait = FlagOn(RxContext->Flags,RX_CONTEXT_FLAG_WAIT)!=0;
  384. PLARGE_INTEGER LengthAsLI = (PLARGE_INTEGER)&LowIoContext->ParamsFor.Locks.Length;
  385. PLARGE_INTEGER OffsetAsLI = (PLARGE_INTEGER)&LowIoContext->ParamsFor.Locks.ByteOffset;
  386. char *whichop;
  387. switch (LowIoContext->Operation) {
  388. case LOWIO_OP_SHAREDLOCK: whichop = "SHAREDLOCK"; break;
  389. case LOWIO_OP_EXCLUSIVELOCK: whichop = "EXCLUSIVELOCK"; break;
  390. case LOWIO_OP_UNLOCK: whichop = "UNLOCK"; break;
  391. case LOWIO_OP_UNLOCKALL: whichop = "UNLOCKALL"; break;
  392. case LOWIO_OP_UNLOCKALLBYKEY: whichop = "UNLOCKALLBYKEY"; break;
  393. }
  394. RxDbgTrace (+1, Dbg, ("MRxExclusiveLock...%s, Flags = %08lx, Key = %08lx\n", whichop,
  395. LowIoContext->ParamsFor.Locks.Flags,
  396. LowIoContext->ParamsFor.Locks.Key));
  397. RxDbgTrace( 0, Dbg, (" ->Length = %08lx %08lx\n",
  398. LengthAsLI->LowPart,
  399. LengthAsLI->HighPart));
  400. RxDbgTrace( 0, Dbg, (" ->ByteOffset = %08lx %08lx\n",
  401. OffsetAsLI->LowPart,
  402. OffsetAsLI->HighPart));
  403. RxLog(('kLz',3,SrvOpen, LengthAsLI->LowPart, OffsetAsLI->LowPart));
  404. ASSERT (proxySrvOpen->UnderlyingFileObject);
  405. CalldownIrp = MRxBuildLockRequest (
  406. NULL ,//IN PIRP irp OPTIONAL,
  407. proxySrvOpen->UnderlyingFileObject ,//IN PFILE_OBJECT fileObject,
  408. capReqPacket->Tail.Overlay.Thread ,//IN PTHREAD UsersThread,
  409. capPARAMS->MinorFunction ,//IN UCHAR MinorCode,
  410. LowIoContext->ParamsFor.Locks.ByteOffset,//IN RXVBO ByteOffset,
  411. LengthAsLI ,//IN PLARGE_INTEGER Length,
  412. LowIoContext->ParamsFor.Locks.Key ,//IN ULONG Key,
  413. (UCHAR)LowIoContext->ParamsFor.Locks.Flags ,//IN UCHAR Flags,
  414. MRxProxyCalldownLockCompletion ,//IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
  415. RxContext //IN PVOID Context OPTIONAL
  416. );
  417. if (!CalldownIrp){
  418. Status = RxContext->StoredStatus = (STATUS_INSUFFICIENT_RESOURCES);
  419. return(Status);
  420. }
  421. Status = RxContext->StoredStatus =
  422. IoCallDriver(
  423. proxySrvOpen->UnderlyingDeviceObject,
  424. CalldownIrp
  425. );
  426. if (Status != (STATUS_PENDING)) {
  427. //copy up the status
  428. capReqPacket->IoStatus = CalldownIrp->IoStatus;
  429. }
  430. RxDbgTrace ( 0, Dbg, (" ---->Initial Status = %08lx\n", Status));
  431. RxDbgTrace(-1, Dbg, (" ------> Initial Block status/Info = %08lx %08lx\n",
  432. capReqPacket->IoStatus.Status, capReqPacket->IoStatus.Information));
  433. return(Status);
  434. }
  435. NTSTATUS
  436. MRxProxyAssertLockCompletion (
  437. IN PDEVICE_OBJECT DeviceObject,
  438. IN PIRP CalldownIrp,
  439. IN PVOID Context
  440. )
  441. /*++
  442. Routine Description:
  443. This is the I/O completion routine for calldown ios like querydirectory. the rub is that we
  444. turned synchronous opens into async opens. what we do here is set an event (in the case of a pended
  445. packet for a sync that we turned async) OR copyup the status;complete;free in the case of a call
  446. that was always async.
  447. Arguments:
  448. DeviceObject - Pointer to target device object for the request.
  449. CalldownIrp - Pointer to I/O request packet used to call down to the underlying filesystem
  450. Context - Irpcontext of the original request to the rdbss
  451. Return Value:
  452. NTSTATUS - If (STATUS_MORE_PROCESSING_REQUIRED) is returned.
  453. --*/
  454. {
  455. PKEVENT Event = Context;
  456. RxDbgTrace ( 0, Dbg, (" MRxProxyAssertLockCompletion = %08lx\n", 0));
  457. if (CalldownIrp->PendingReturned){
  458. KeSetEvent( Event, 0, FALSE );
  459. }
  460. return((STATUS_MORE_PROCESSING_REQUIRED));
  461. }
  462. NTSTATUS
  463. MRxProxyAssertBufferedFileLocks (
  464. IN PSRV_OPEN SrvOpen
  465. )
  466. /*++
  467. Routine Description:
  468. This routine is called to assert all buffered file locks on a srvopen.
  469. Arguments:
  470. SrvOpen - Supplies the file whose locks are to be asserted.
  471. Return Value:
  472. NTSTATUS - Status of operation.
  473. --*/
  474. {
  475. NTSTATUS Status;
  476. PFILE_LOCK_INFO FileLock;
  477. PFCB Fcb = SrvOpen->Fcb;
  478. PIRP CalldownIrp = NULL;
  479. PMRX_LOCAL_SRV_OPEN proxySrvOpen = (PMRX_LOCAL_SRV_OPEN)SrvOpen;
  480. UCHAR Flags;
  481. BOOLEAN Wait = TRUE;
  482. PKEVENT Event;
  483. PAGED_CODE();
  484. RxDbgTrace (+1, Dbg, ("MRxProxyAssertBufferedFileLocks SrvOpen = %08lx", SrvOpen));
  485. ASSERT (proxySrvOpen->UnderlyingFileObject);
  486. Event = RxAllocatePoolWithTag( NonPagedPool, sizeof(KEVENT), 'LAxR' );
  487. if (!CalldownIrp){
  488. Status = (STATUS_INSUFFICIENT_RESOURCES);
  489. return(Status);
  490. }
  491. try {
  492. for (FileLock = FsRtlGetNextFileLock(&Fcb->Specific.Fcb.FileLock, TRUE);
  493. FileLock != NULL;
  494. FileLock = FsRtlGetNextFileLock(&Fcb->Specific.Fcb.FileLock, FALSE)) {
  495. RxDbgTrace (0, Dbg, ("MRxProxyAssertBufferedFileLocks Exclusive = %08lx, Key = %08lx\n",
  496. FileLock->ExclusiveLock,
  497. FileLock->Key));
  498. RxDbgTrace( 0, Dbg, (" ->Length = %08lx %08lx\n",
  499. FileLock->Length.LowPart,
  500. FileLock->Length.HighPart));
  501. RxDbgTrace( 0, Dbg, (" ->ByteOffset = %08lx %08lx\n",
  502. FileLock->StartingByte.LowPart,
  503. FileLock->StartingByte.HighPart));
  504. if (FileLock->ExclusiveLock) {
  505. Flags = SL_EXCLUSIVE_LOCK | SL_FAIL_IMMEDIATELY;
  506. } else {
  507. Flags = SL_FAIL_IMMEDIATELY;
  508. }
  509. //joejoe we should reuse the irp.........
  510. CalldownIrp = MRxBuildLockRequest (
  511. NULL ,//IN PIRP irp OPTIONAL,
  512. proxySrvOpen->UnderlyingFileObject ,//IN PFILE_OBJECT fileObject,
  513. proxySrvOpen->OriginalThread ,//IN PTHREAD UsersThread,
  514. IRP_MN_LOCK ,//IN UCHAR MinorCode,
  515. FileLock->StartingByte.QuadPart ,//IN RXVBO ByteOffset,
  516. &FileLock->Length ,//IN PLARGE_INTEGER Length,
  517. FileLock->Key ,//IN ULONG Key,
  518. Flags ,//IN UCHAR Flags,
  519. MRxProxyAssertLockCompletion ,//IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
  520. &Event //IN PVOID Context OPTIONAL
  521. );
  522. if (!CalldownIrp){
  523. Status = (STATUS_INSUFFICIENT_RESOURCES);
  524. try_return(Status);
  525. }
  526. CalldownIrp->Flags |= IRP_SYNCHRONOUS_API;
  527. KeInitializeEvent( Event, SynchronizationEvent, FALSE );
  528. Status = IoCallDriver(
  529. proxySrvOpen->UnderlyingDeviceObject,
  530. CalldownIrp
  531. );
  532. if (Status == (STATUS_PENDING)) {
  533. KeWaitForSingleObject(Event, UserRequest, KernelMode, FALSE, NULL);
  534. Status = CalldownIrp->IoStatus.Status;
  535. }
  536. RxDbgTrace ( 0, Dbg, (" ---->PerLock Status = %08lx\n", Status));
  537. }
  538. try_exit:
  539. NOTHING;
  540. } finally {
  541. ExFreePool(Event);
  542. if (CalldownIrp) {
  543. IoFreeIrp(CalldownIrp);
  544. }
  545. }
  546. RxDbgTrace (-1, Dbg, ("--------->Final Status = %08lx\n", Status));
  547. return Status;
  548. }
  549. #endif
  550.