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.

1237 lines
40 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. RxInit.c
  5. Abstract:
  6. This module implements the FSD-level dispatch routine for the RDBSS.
  7. Author:
  8. Joe Linn [JoeLinn] 2-dec-1994
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include <ntddnfs.h>
  14. #include <dfsfsctl.h>
  15. #include "NtDspVec.h"
  16. //
  17. // The debug trace level
  18. //
  19. #define Dbg (DEBUG_TRACE_DISPATCH)
  20. // the difference between dispatch problem and unimplemented is my judgement as to whether
  21. // this represents a likely application error or not. in a free build, there's no difference.
  22. NTSTATUS
  23. RxCommonDispatchProblem ( RXCOMMON_SIGNATURE );
  24. NTSTATUS
  25. RxCommonUnimplemented ( RXCOMMON_SIGNATURE );
  26. NTSTATUS
  27. RxCommonUnsupported ( RXCOMMON_SIGNATURE );
  28. VOID
  29. RxInitializeTopLevelIrpPackage(
  30. void
  31. );
  32. RX_FSD_DISPATCH_VECTOR RxFsdDispatchVector[IRP_MJ_MAXIMUM_FUNCTION + 1] = {
  33. DISPVECENTRY_NEW(CREATE, TRUE, Create, 0x10), // 0x00
  34. DISPVECENTRY_NEW(CREATE_NAMED_PIPE, TRUE, Unimplemented, 0x10), // 0x01
  35. DISPVECENTRY_NEW(CLOSE, TRUE, Close, 0x10), // 0x02
  36. DISPVECENTRY_NEW(READ, TRUE, Read, 0x10), // 0x03
  37. DISPVECENTRY_NEW(WRITE, TRUE, Write, 0x10), // 0x04
  38. DISPVECENTRY_NEW(QUERY_INFORMATION, TRUE, QueryInformation, 0x10), // 0x05
  39. DISPVECENTRY_NEW(SET_INFORMATION, TRUE, SetInformation, 0x10), // 0x06
  40. DISPVECENTRY_NEW(QUERY_EA, TRUE, QueryEa, 0x10), // 0x07
  41. DISPVECENTRY_NEW(SET_EA, TRUE, SetEa, 0x10), // 0x08
  42. DISPVECENTRY_NEW(FLUSH_BUFFERS, TRUE, FlushBuffers, 0x10), // 0x09
  43. DISPVECENTRY_NEW(QUERY_VOLUME_INFORMATION, TRUE, QueryVolumeInformation, 0x10), // 0x0a
  44. DISPVECENTRY_NEW(SET_VOLUME_INFORMATION, TRUE, SetVolumeInformation, 0x10), // 0x0b
  45. DISPVECENTRY_NEW(DIRECTORY_CONTROL, TRUE, DirectoryControl, 0x10), // 0x0c
  46. DISPVECENTRY_NEW(FILE_SYSTEM_CONTROL, TRUE, FileSystemControl, 0x10), // 0x0d
  47. DISPVECENTRY_NEW(DEVICE_CONTROL, TRUE, DeviceControl, 0x10), // 0x0e
  48. DISPVECENTRY_NEW(INTERNAL_DEVICE_CONTROL, TRUE, DeviceControl, 0x10), // 0x0f
  49. DISPVECENTRY_NEW(SHUTDOWN, TRUE, Unimplemented, 0x10), // 0x10
  50. DISPVECENTRY_NEW(LOCK_CONTROL, TRUE, LockControl, 0x10), // 0x11
  51. DISPVECENTRY_NEW(CLEANUP, TRUE, Cleanup, 0x10), // 0x12
  52. DISPVECENTRY_NEW(CREATE_MAILSLOT, TRUE, Unimplemented, 0x10), // 0x13
  53. DISPVECENTRY_NEW(QUERY_SECURITY, TRUE, QuerySecurity, 0x10), // 0x14
  54. DISPVECENTRY_NEW(SET_SECURITY, TRUE, SetSecurity, 0x10), // 0x15
  55. DISPVECENTRY_NEW(POWER, TRUE, Unimplemented, 0x10), // 0x16
  56. DISPVECENTRY_NEW(WMI, TRUE, Unimplemented, 0x10), // 0x17
  57. DISPVECENTRY_NEW(DEVICE_CHANGE, TRUE, Unimplemented, 0x10), // 0x18
  58. DISPVECENTRY_NEW(QUERY_QUOTA, TRUE, QueryQuotaInformation, 0x10), // 0x19
  59. DISPVECENTRY_NEW(SET_QUOTA, TRUE, SetQuotaInformation, 0x10), // 0x1a
  60. DISPVECENTRY_NEW(PNP, TRUE, Unimplemented, 0x10) // 0x1b
  61. };
  62. RX_FSD_DISPATCH_VECTOR RxDeviceFCBVector[IRP_MJ_MAXIMUM_FUNCTION + 1] = {
  63. DISPVECENTRY_NEW(CREATE, TRUE, DispatchProblem, 0x10),
  64. DISPVECENTRY_NEW(CREATE_NAMED_PIPE, TRUE, DispatchProblem, 0x10),
  65. DISPVECENTRY_NEW(CLOSE, TRUE, DevFCBClose, 0x10),
  66. DISPVECENTRY_NEW(READ, TRUE, DispatchProblem, 0x10),
  67. DISPVECENTRY_NEW(WRITE, TRUE, DispatchProblem, 0x10),
  68. DISPVECENTRY_NEW(QUERY_INFORMATION, TRUE, DispatchProblem, 0x10),
  69. DISPVECENTRY_NEW(SET_INFORMATION, TRUE, DispatchProblem, 0x10),
  70. DISPVECENTRY_NEW(QUERY_EA, TRUE, DispatchProblem, 0x10),
  71. DISPVECENTRY_NEW(SET_EA, TRUE, DispatchProblem, 0x10),
  72. DISPVECENTRY_NEW(FLUSH_BUFFERS, TRUE, DispatchProblem, 0x10),
  73. DISPVECENTRY_NEW(QUERY_VOLUME_INFORMATION, TRUE, DevFCBQueryVolInfo, 0x10),
  74. DISPVECENTRY_NEW(SET_VOLUME_INFORMATION, TRUE, DispatchProblem, 0x10),
  75. DISPVECENTRY_NEW(DIRECTORY_CONTROL, TRUE, DispatchProblem, 0x10),
  76. DISPVECENTRY_NEW(FILE_SYSTEM_CONTROL, TRUE, DevFCBFsCtl, 0x10),
  77. DISPVECENTRY_NEW(DEVICE_CONTROL, TRUE, DevFCBIoCtl, 0x10),
  78. DISPVECENTRY_NEW(INTERNAL_DEVICE_CONTROL, TRUE, DevFCBIoCtl, 0x10),
  79. DISPVECENTRY_NEW(SHUTDOWN, TRUE, DispatchProblem, 0x10),
  80. DISPVECENTRY_NEW(LOCK_CONTROL, TRUE, DispatchProblem, 0x10),
  81. DISPVECENTRY_NEW(CLEANUP, TRUE, DevFCBCleanup, 0x10),
  82. DISPVECENTRY_NEW(CREATE_MAILSLOT, TRUE, DispatchProblem, 0x10),
  83. DISPVECENTRY_NEW(QUERY_SECURITY, TRUE, DispatchProblem, 0x10),
  84. DISPVECENTRY_NEW(SET_SECURITY, TRUE, DispatchProblem, 0x10),
  85. DISPVECENTRY_NEW(POWER, TRUE, Unimplemented, 0x10), // 0x16
  86. DISPVECENTRY_NEW(WMI, TRUE, Unimplemented, 0x10), // 0x17
  87. DISPVECENTRY_NEW(DEVICE_CHANGE, TRUE, Unimplemented, 0x10), // 0x18
  88. DISPVECENTRY_NEW(QUERY_QUOTA, TRUE, Unimplemented, 0x10), // 0x19
  89. DISPVECENTRY_NEW(SET_QUOTA, TRUE, Unimplemented, 0x10), // 0x1a
  90. DISPVECENTRY_NEW(PNP, TRUE, Unimplemented, 0x10) // 0x1b
  91. };
  92. FAST_IO_DISPATCH RxFastIoDispatch;
  93. NTSTATUS
  94. RxFsdCommonDispatch (
  95. PRX_FSD_DISPATCH_VECTOR DispatchVector,
  96. IN UCHAR MajorFunctionCode,
  97. IN PIO_STACK_LOCATION IrpSp,
  98. IN PFILE_OBJECT FileObject,
  99. IN PIRP Irp,
  100. IN PRDBSS_DEVICE_OBJECT RxObject
  101. );
  102. VOID
  103. RxInitializeDispatchVectors(
  104. OUT PDRIVER_OBJECT DriverObject
  105. );
  106. #ifdef ALLOC_PRAGMA
  107. #pragma alloc_text(INIT, RxInitializeDispatchVectors)
  108. //not pageable SPINLOCK #pragma alloc_text(PAGE, RxFsdCommonDispatch)
  109. #pragma alloc_text(PAGE, RxCommonDispatchProblem)
  110. #pragma alloc_text(PAGE, RxCommonUnimplemented)
  111. #pragma alloc_text(PAGE, RxCommonUnsupported)
  112. #pragma alloc_text(PAGE, RxFsdDispatch)
  113. #pragma alloc_text(PAGE, RxTryToBecomeTheTopLevelIrp)
  114. #endif
  115. VOID
  116. RxInitializeDispatchVectors(
  117. OUT PDRIVER_OBJECT DriverObject
  118. )
  119. /*++
  120. Routine Description:
  121. This routine initializes the dispatch table for the driver object
  122. Arguments:
  123. DriverObject - Supplies the driver object
  124. --*/
  125. {
  126. ULONG i;
  127. PAGED_CODE();
  128. for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {
  129. DriverObject->MajorFunction[i] = (PDRIVER_DISPATCH)RxFsdDispatch;
  130. }
  131. // Set Dispatch Vector for the DevFCB
  132. RxDeviceFCB.PrivateDispatchVector = &RxDeviceFCBVector[0];
  133. ASSERT (RxFsdDispatchVector[IRP_MJ_MAXIMUM_FUNCTION].CommonRoutine != NULL);
  134. ASSERT (RxDeviceFCBVector[IRP_MJ_MAXIMUM_FUNCTION].CommonRoutine != NULL);
  135. DriverObject->FastIoDispatch = &RxFastIoDispatch; //this is dangerous!!!
  136. RxFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
  137. RxFastIoDispatch.FastIoCheckIfPossible = RxFastIoCheckIfPossible; // CheckForFastIo
  138. RxFastIoDispatch.FastIoRead = RxFastIoRead; // Read
  139. RxFastIoDispatch.FastIoWrite = RxFastIoWrite; // Write
  140. RxFastIoDispatch.FastIoQueryBasicInfo = NULL; //RxFastQueryBasicInfo; // QueryBasicInfo
  141. RxFastIoDispatch.FastIoQueryStandardInfo = NULL; //RxFastQueryStdInfo; // QueryStandardInfo
  142. RxFastIoDispatch.FastIoLock = NULL; //RxFastLock; // Lock
  143. RxFastIoDispatch.FastIoUnlockSingle = NULL; //RxFastUnlockSingle; // UnlockSingle
  144. RxFastIoDispatch.FastIoUnlockAll = NULL; //RxFastUnlockAll; // UnlockAll
  145. RxFastIoDispatch.FastIoUnlockAllByKey = NULL; //RxFastUnlockAllByKey; // UnlockAllByKey
  146. RxFastIoDispatch.FastIoDeviceControl = RxFastIoDeviceControl; // IoDeviceControl
  147. RxFastIoDispatch.AcquireForCcFlush = RxAcquireForCcFlush;
  148. RxFastIoDispatch.ReleaseForCcFlush = RxReleaseForCcFlush;
  149. RxFastIoDispatch.AcquireFileForNtCreateSection = RxAcquireFileForNtCreateSection;
  150. RxFastIoDispatch.ReleaseFileForNtCreateSection = RxReleaseFileForNtCreateSection;
  151. // Initialize stuff for the toplevelirp package
  152. RxInitializeTopLevelIrpPackage();
  153. // Initialize the cache manager callback routines
  154. RxData.CacheManagerCallbacks.AcquireForLazyWrite = &RxAcquireFcbForLazyWrite;
  155. RxData.CacheManagerCallbacks.ReleaseFromLazyWrite = &RxReleaseFcbFromLazyWrite;
  156. RxData.CacheManagerCallbacks.AcquireForReadAhead = &RxAcquireFcbForReadAhead;
  157. RxData.CacheManagerCallbacks.ReleaseFromReadAhead = &RxReleaseFcbFromReadAhead;
  158. RxData.CacheManagerNoOpCallbacks.AcquireForLazyWrite = &RxNoOpAcquire;
  159. RxData.CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &RxNoOpRelease;
  160. RxData.CacheManagerNoOpCallbacks.AcquireForReadAhead = &RxNoOpAcquire;
  161. RxData.CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &RxNoOpRelease;
  162. }
  163. NTSTATUS
  164. RxCommonDispatchProblem ( RXCOMMON_SIGNATURE )
  165. {
  166. // if we get here then something is awry. this is used to initialize fields that SHOULD
  167. // not be accessed....like the create field in any vector but the highest level
  168. PAGED_CODE();
  169. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("RxFsdDispatchPROBLEM: IrpC =%08lx,Code=", RxContext, RxContext->MajorFunction ));
  170. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("---------------------PROBLEM-----%s\n", "" ));
  171. RxLog(("%s %lx %ld\n","pDX", RxContext, RxContext->MajorFunction));
  172. RxWmiLog(LOG,
  173. RxCommonDispatchProblem,
  174. LOGPTR(RxContext)
  175. LOGUCHAR(RxContext->MajorFunction));
  176. // RxCompleteContextAndReturn( RxStatus(NOT_IMPLEMENTED) );
  177. return STATUS_NOT_IMPLEMENTED;
  178. }
  179. NTSTATUS
  180. RxCommonUnimplemented ( RXCOMMON_SIGNATURE )
  181. {
  182. PAGED_CODE();
  183. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("RxFsdDispatRxFsdUnImplementedchPROBLEM: IrpC =%08lx,Code=",
  184. RxContext, RxContext->MajorFunction ));
  185. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("---------------------UNIMLEMENTED-----%s\n", "" ));
  186. return STATUS_NOT_IMPLEMENTED;
  187. }
  188. NTSTATUS
  189. RxCommonUnsupported ( RXCOMMON_SIGNATURE )
  190. {
  191. PAGED_CODE();
  192. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("RxFsdDispatRxFsdUnSupportedchPROBLEM: IrpC =%08lx,Code=",
  193. RxContext, RxContext->MajorFunction ));
  194. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("---------------------UNSUPPORTED-----%s\n", "" ));
  195. return STATUS_NOT_SUPPORTED;
  196. }
  197. RxDbgTraceDoit(ULONG RxDbgTraceEnableCommand = 0xffff;)
  198. WML_CONTROL_GUID_REG Rdbss_ControlGuids[] = {
  199. { // cddc01e2-fdce-479a-b8ee-3c87053fb55e Rdbss
  200. 0xcddc01e2,0xfdce,0x479a,{0xb8,0xee,0x3c,0x87,0x05,0x3f,0xb5,0x5e},
  201. { // 529ae497-0a1f-43a5-8cb5-2aa60b497831
  202. {0x529ae497,0x0a1f,0x43a5,{0x8c,0xb5,0x2a,0xa6,0x0b,0x49,0x78,0x31},},
  203. // b7e3da1d-67f4-49bd-b9c0-1e61ce7417a8
  204. {0xb7e3da1d,0x67f4,0x49bd,{0xb9,0xc0,0x1e,0x61,0xce,0x74,0x17,0xa8},},
  205. // c966bef5-21c5-4630-84a0-4334875f41b8
  206. {0xc966bef5,0x21c5,0x4630,{0x84,0xa0,0x43,0x34,0x87,0x5f,0x41,0xb8},}
  207. },
  208. },
  209. };
  210. #define Rdbss_ControlGuids_len 1
  211. extern BOOLEAN EnableWmiLog;
  212. NTSTATUS
  213. RxSystemControl(
  214. IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
  215. IN PIRP Irp)
  216. /*++
  217. Routine Description:
  218. This is the common routine for doing System control operations called
  219. by both the fsd and fsp threads
  220. Arguments:
  221. Irp - Supplies the Irp to process
  222. InFsp - Indicates if this is the fsp thread or someother thread
  223. Return Value:
  224. RXSTATUS - The return status for the operation
  225. --*/
  226. {
  227. NTSTATUS Status;
  228. WML_TINY_INFO Info;
  229. UNICODE_STRING RegPath;
  230. PAGED_CODE();
  231. if (EnableWmiLog) {
  232. RtlInitUnicodeString (&RegPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Rdbss");
  233. RtlZeroMemory (&Info, sizeof(Info));
  234. Info.ControlGuids = Rdbss_ControlGuids;
  235. Info.GuidCount = Rdbss_ControlGuids_len;
  236. Info.DriverRegPath = &RegPath;
  237. Status = WmlTinySystemControl(&Info,
  238. (PDEVICE_OBJECT)RxDeviceObject,
  239. Irp);
  240. if (Status != STATUS_SUCCESS) {
  241. //DbgPrint("Rdbss WMI control return %lx\n", Status);
  242. }
  243. } else {
  244. Status = STATUS_INVALID_DEVICE_REQUEST;
  245. Irp->IoStatus.Status = Status;
  246. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  247. }
  248. return Status;
  249. }
  250. NTSTATUS
  251. RxFsdDispatch (
  252. IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
  253. IN PIRP Irp
  254. )
  255. /*++
  256. Routine Description:
  257. This routine implements the FSD dispatch for the RDBSS.
  258. Arguments:
  259. RxDeviceObject - Supplies the device object for the packet being processed.
  260. Irp - Supplies the Irp being processed
  261. Return Value:
  262. RXSTATUS - The Fsd status for the Irp
  263. --*/
  264. {
  265. NTSTATUS status;
  266. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); //ok4ioget
  267. UCHAR MajorFunctionCode = IrpSp->MajorFunction;
  268. PFILE_OBJECT FileObject = IrpSp->FileObject; //ok4->fileobj
  269. PRX_FSD_DISPATCH_VECTOR DispatchVector;
  270. PAGED_CODE();
  271. RxDbgTraceDoit(
  272. if (MajorFunctionCode == RxDbgTraceEnableCommand) {
  273. RxNextGlobalTraceSuppress = RxGlobalTraceSuppress = FALSE;
  274. }
  275. if (0) {
  276. RxNextGlobalTraceSuppress = RxGlobalTraceSuppress = FALSE;
  277. }
  278. );
  279. RxDbgTrace( 0, Dbg, ("RxFsdDispatch: Code =%02lx (%lu) ----------%s-----------\n",
  280. MajorFunctionCode,
  281. ++RxIrpCodeCount[IrpSp->MajorFunction],
  282. RxIrpCodeToName[MajorFunctionCode] ));
  283. if (IrpSp->MajorFunction == IRP_MJ_SYSTEM_CONTROL) {
  284. return RxSystemControl(RxDeviceObject,Irp);
  285. }
  286. if ((MajorFunctionCode == IRP_MJ_CREATE_MAILSLOT) ||
  287. (MajorFunctionCode == IRP_MJ_CREATE_NAMED_PIPE)) {
  288. DispatchVector = NULL;
  289. status = STATUS_OBJECT_NAME_INVALID;
  290. } else {
  291. // get a private dispatch table if there is one
  292. if (MajorFunctionCode == IRP_MJ_CREATE) {
  293. DispatchVector = RxFsdDispatchVector;
  294. } else if (FileObject != NULL && FileObject->FsContext != NULL) {
  295. if ((NodeTypeIsFcb((PFCB)(FileObject->FsContext))) &&
  296. (((PFCB)(FileObject->FsContext))->PrivateDispatchVector != NULL)) { //ok4fscontext
  297. RxDbgTraceLV( 0, Dbg, 2500, ("Using Private Dispatch Vector\n"));
  298. DispatchVector = ((PFCB)(FileObject->FsContext))->PrivateDispatchVector;
  299. } else {
  300. DispatchVector = RxFsdDispatchVector;
  301. }
  302. if ((RxDeviceObject == RxFileSystemDeviceObject) &&
  303. ((MajorFunctionCode != IRP_MJ_CLOSE) ||
  304. (MajorFunctionCode != IRP_MJ_DEVICE_CONTROL))
  305. ) {
  306. DispatchVector = NULL;
  307. status = STATUS_INVALID_DEVICE_REQUEST;
  308. }
  309. } else {
  310. DispatchVector = NULL;
  311. status = STATUS_INVALID_DEVICE_REQUEST;
  312. RxDbgTrace(
  313. 0,
  314. Dbg,
  315. ("RxFsdDispatch: Code =%02lx (%lu) ----------%s-----------\n",
  316. MajorFunctionCode,
  317. ++RxIrpCodeCount[IrpSp->MajorFunction],
  318. RxIrpCodeToName[MajorFunctionCode]));
  319. }
  320. }
  321. if (DispatchVector != NULL) {
  322. status = RxFsdCommonDispatch( DispatchVector,
  323. MajorFunctionCode,
  324. IrpSp,
  325. FileObject,
  326. Irp,
  327. RxDeviceObject );
  328. RxDbgTrace( 0, Dbg, ("RxFsdDispatch: Status =%02lx %s....\n",
  329. status,
  330. RxIrpCodeToName[MajorFunctionCode] ));
  331. RxDbgTraceDoit(
  332. if (RxGlobalTraceIrpCount > 0) {
  333. RxGlobalTraceIrpCount -= 1;
  334. RxGlobalTraceSuppress = FALSE;
  335. } else {
  336. RxGlobalTraceSuppress = RxNextGlobalTraceSuppress;
  337. }
  338. );
  339. } else {
  340. IoMarkIrpPending(Irp);
  341. Irp->IoStatus.Status = status;
  342. Irp->IoStatus.Information = 0;
  343. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  344. status = STATUS_PENDING;
  345. }
  346. return status;
  347. }
  348. NTSTATUS
  349. RxFsdCommonDispatch (
  350. PRX_FSD_DISPATCH_VECTOR DispatchVector,
  351. IN UCHAR MajorFunctionCode,
  352. IN PIO_STACK_LOCATION IrpSp,
  353. IN PFILE_OBJECT FileObject,
  354. IN PIRP Irp,
  355. IN PRDBSS_DEVICE_OBJECT RxDeviceObject
  356. )
  357. /*++
  358. Routine Description:
  359. This routine implements the FSD part of dispatch for IRP's
  360. Arguments:
  361. DispatchVector - the dispatch vector
  362. MajorFunctionCode - the IRP major function
  363. IrpSp - the IRP stack
  364. FileObject - the file object
  365. Irp - the IRP
  366. Return Value:
  367. RXSTATUS - The FSD status for the IRP
  368. Notes:
  369. --*/
  370. { //not currently pageable.......
  371. NTSTATUS Status = STATUS_SUCCESS;
  372. PRX_CONTEXT RxContext = NULL;
  373. RX_TOPLEVELIRP_CONTEXT TopLevelContext;
  374. UCHAR MinorFunctionCode = IrpSp->MinorFunction;
  375. BOOLEAN TopLevel = FALSE;
  376. ULONG ContextFlags = 0;
  377. BOOLEAN Wait;
  378. BOOLEAN Cancellable;
  379. BOOLEAN ModWriter = FALSE;
  380. BOOLEAN fCleanupOrClose = FALSE;
  381. BOOLEAN fContinueOperation = TRUE;
  382. KIRQL SavedIrql;
  383. BOOLEAN PostRequest = FALSE;
  384. PRX_DISPATCH DispatchRoutine = NULL;
  385. PDRIVER_CANCEL CancelRoutine = NULL;
  386. //RxDbgTraceLV(+1, Dbg, 1500, ("RxFsd[%s]\n", RxIrpCodeToName[MajorFunctionCode]));
  387. //TimerStart(Dbg);
  388. FsRtlEnterFileSystem();
  389. TopLevel = RxTryToBecomeTheTopLevelIrp( &TopLevelContext, Irp, RxDeviceObject, FALSE ); //dont force
  390. try {
  391. // Treat all operations as being cancellable and waitable.
  392. Wait = RX_CONTEXT_FLAG_WAIT;
  393. Cancellable = TRUE;
  394. CancelRoutine = RxCancelRoutine;
  395. // Retract the capability based upon the operation
  396. switch (MajorFunctionCode) {
  397. case IRP_MJ_FILE_SYSTEM_CONTROL:
  398. // Call the common FileSystem Control routine, with blocking allowed if
  399. // synchronous. This opeation needs to special case the mount
  400. // and verify suboperations because we know they are allowed to block.
  401. // We identify these suboperations by looking at the file object field
  402. // and seeing if its null.
  403. Wait = (FileObject == NULL) ? TRUE : CanFsdWait( Irp );
  404. break;
  405. case IRP_MJ_READ:
  406. case IRP_MJ_LOCK_CONTROL:
  407. case IRP_MJ_DIRECTORY_CONTROL:
  408. case IRP_MJ_QUERY_VOLUME_INFORMATION:
  409. case IRP_MJ_WRITE:
  410. case IRP_MJ_QUERY_INFORMATION:
  411. case IRP_MJ_SET_INFORMATION:
  412. case IRP_MJ_QUERY_EA:
  413. case IRP_MJ_SET_EA:
  414. case IRP_MJ_QUERY_SECURITY:
  415. case IRP_MJ_SET_SECURITY:
  416. case IRP_MJ_FLUSH_BUFFERS:
  417. case IRP_MJ_DEVICE_CONTROL:
  418. case IRP_MJ_SET_VOLUME_INFORMATION:
  419. Wait = CanFsdWait( Irp );
  420. break;
  421. case IRP_MJ_CLEANUP:
  422. case IRP_MJ_CLOSE:
  423. Cancellable = FALSE;
  424. fCleanupOrClose = TRUE;
  425. break;
  426. default:
  427. break;
  428. }
  429. KeAcquireSpinLock(&RxStrucSupSpinLock,&SavedIrql);
  430. fContinueOperation = TRUE;
  431. switch (RxDeviceObject->StartStopContext.State) {
  432. case RDBSS_STARTABLE: //here only device creates and device operations can go thru
  433. {
  434. if ((DispatchVector == RxDeviceFCBVector) ||
  435. ((FileObject->FileName.Length == 0) &&
  436. (FileObject->RelatedFileObject == NULL))) {
  437. NOTHING;
  438. } else {
  439. fContinueOperation = FALSE;
  440. Status = STATUS_REDIRECTOR_NOT_STARTED;
  441. }
  442. }
  443. break;
  444. case RDBSS_STOP_IN_PROGRESS:
  445. if (!fCleanupOrClose) {
  446. fContinueOperation = FALSE;
  447. Status = STATUS_REDIRECTOR_NOT_STARTED;
  448. }
  449. break;
  450. //case RDBSS_STOPPED:
  451. // {
  452. // if ((MajorFunctionCode == IRP_MJ_FILE_SYSTEM_CONTROL) &&
  453. // (MinorFunctionCode == IRP_MN_USER_FS_REQUEST) &&
  454. // (IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_LMR_START)) {
  455. // RxDeviceObject->StartStopContext.State = RDBSS_START_IN_PROGRESS;
  456. // RxDeviceObject->StartStopContext.Version++;
  457. // fContinueOperation = TRUE;
  458. // } else {
  459. // fContinueOperation = FALSE;
  460. // Status = STATUS_REDIRECTOR_NOT_STARTED);
  461. // }
  462. // }
  463. case RDBSS_STARTED:
  464. // intentional break;
  465. default:
  466. break;
  467. }
  468. KeReleaseSpinLock(&RxStrucSupSpinLock,SavedIrql);
  469. if ((IrpSp->FileObject != NULL) &&
  470. (IrpSp->FileObject->FsContext != NULL)) {
  471. PFCB pFcb = (PFCB)IrpSp->FileObject->FsContext;
  472. BOOLEAN fOrphaned = FALSE;
  473. if ((IrpSp->FileObject->FsContext2 != UIntToPtr(DFS_OPEN_CONTEXT)) &&
  474. (IrpSp->FileObject->FsContext2 != UIntToPtr(DFS_DOWNLEVEL_OPEN_CONTEXT)))
  475. {
  476. fOrphaned = (FlagOn(pFcb->FcbState,FCB_STATE_ORPHANED) != 0);
  477. if (!fOrphaned && IrpSp->FileObject->FsContext2)
  478. {
  479. PFOBX pFobx = (PFOBX)IrpSp->FileObject->FsContext2;
  480. fOrphaned = (FlagOn(pFobx->SrvOpen->Flags, SRVOPEN_FLAG_ORPHANED) != 0);
  481. }
  482. }
  483. if (fOrphaned) {
  484. if (!fCleanupOrClose) {
  485. RxDbgTrace(
  486. 0,
  487. Dbg,
  488. ("Ignoring operation on ORPHANED FCB %lx %lx %lx\n",
  489. pFcb,MajorFunctionCode,MinorFunctionCode));
  490. fContinueOperation = FALSE;
  491. Status = STATUS_UNEXPECTED_NETWORK_ERROR;
  492. RxLog(("#### Orphaned FCB op %lx\n",pFcb));
  493. RxWmiLog(LOG,
  494. RxFsdCommonDispatch_OF,
  495. LOGPTR(pFcb));
  496. } else {
  497. RxDbgTrace(
  498. 0,
  499. Dbg,
  500. ("Delayed Close/Cleanup on ORPHANED FCB %lx\n",pFcb));
  501. fContinueOperation = TRUE;
  502. }
  503. }
  504. }
  505. if (RxDeviceObject->StartStopContext.State == RDBSS_STOP_IN_PROGRESS) {
  506. if (fCleanupOrClose) {
  507. PFILE_OBJECT pFileObject = IrpSp->FileObject;
  508. PFCB pFcb = (PFCB)pFileObject->FsContext;
  509. RxDbgPrint(("RDBSS -- Close after Stop"));
  510. RxDbgPrint(("RDBSS: Irp(%lx) MJ %ld MN %ld FileObject(%lx) FCB(%lx) \n",
  511. Irp,IrpSp->MajorFunction,IrpSp->MinorFunction,pFileObject,pFcb));
  512. if ((pFileObject != NULL)
  513. && (pFcb != NULL)
  514. && (pFcb != &RxDeviceFCB)
  515. && NodeTypeIsFcb(pFcb)) {
  516. RxDbgPrint((
  517. "RDBSS: OpenCount(%ld) UncleanCount(%ld) Name(%wZ)\n",
  518. pFcb->OpenCount,
  519. pFcb->UncleanCount,
  520. &pFcb->FcbTableEntry.Path));
  521. }
  522. }
  523. }
  524. if (!fContinueOperation) {
  525. if ((MajorFunctionCode != IRP_MJ_DIRECTORY_CONTROL)||
  526. (MinorFunctionCode !=IRP_MN_NOTIFY_CHANGE_DIRECTORY))
  527. {
  528. IoMarkIrpPending(Irp);
  529. Irp->IoStatus.Status = Status;
  530. Irp->IoStatus.Information = 0;
  531. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  532. Status = STATUS_PENDING;
  533. }
  534. else
  535. {
  536. // this is a changenotify directory control
  537. // Fail the operation
  538. // The usermode API cannot get the error in the IO status block
  539. // correctly, due to the way FindFirstChangeNotify/FindNextChangeNotify
  540. // APIs are designed
  541. Irp->IoStatus.Status = Status;
  542. Irp->IoStatus.Information = 0;
  543. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  544. }
  545. try_return(Status);
  546. }
  547. if (Wait) {
  548. SetFlag(ContextFlags,RX_CONTEXT_FLAG_WAIT);
  549. }
  550. RxContext = RxCreateRxContext( Irp, RxDeviceObject, ContextFlags );
  551. if (RxContext == NULL) {
  552. Status = STATUS_INSUFFICIENT_RESOURCES;
  553. RxCompleteRequest_OLD( RxNull, Irp, Status );
  554. try_return( Status );
  555. }
  556. // Assume ownership of the Irp by setting the cancelling routine.
  557. if (Cancellable) {
  558. RxSetCancelRoutine(Irp,CancelRoutine);
  559. } else {
  560. // Ensure that those operations regarded as non cancellable will
  561. // not be cancelled.
  562. RxSetCancelRoutine(Irp,NULL);
  563. }
  564. ASSERT(MajorFunctionCode <= IRP_MJ_MAXIMUM_FUNCTION);
  565. Irp->IoStatus.Information = 0;
  566. Irp->IoStatus.Status = STATUS_SUCCESS;
  567. DispatchRoutine = DispatchVector[MajorFunctionCode].CommonRoutine;
  568. switch (MajorFunctionCode) {
  569. case IRP_MJ_READ:
  570. case IRP_MJ_WRITE:
  571. // If this is an Mdl complete request, don't go through
  572. // common read.
  573. if ( FlagOn(MinorFunctionCode, IRP_MN_COMPLETE) ) {
  574. DispatchRoutine = RxCompleteMdl;
  575. } else if ( FlagOn(MinorFunctionCode, IRP_MN_DPC) ) {
  576. // Post all DPC calls.
  577. RxDbgTrace(0, Dbg, ("Passing DPC call to Fsp\n", 0 ));
  578. PostRequest = TRUE;
  579. } else if ((MajorFunctionCode == IRP_MJ_READ) &&
  580. (IoGetRemainingStackSize() < 0xe00)) {
  581. //
  582. // Check if we have enough stack space to process this request. If there
  583. // isn't enough then we will pass the request off to the stack overflow thread.
  584. //
  585. // NTBUG 61951 Shishirp 2/23/2000 where did the number come from......
  586. // this number should come from the minirdr....only he knows how much he needs
  587. // and in my configuration it should definitely be bigger than for FAT!
  588. // plus......i can't go to the net on the hypercrtical thread!!! this will have to be
  589. // reworked! maybe we should have our own hypercritical thread............
  590. RxDbgTrace(0, Dbg, ("Passing StackOverflowRead off\n", 0 ));
  591. RxContext->PendingReturned = TRUE;
  592. Status = RxPostStackOverflowRead( RxContext);
  593. if (Status != STATUS_PENDING) {
  594. RxContext->PendingReturned = FALSE;
  595. RxCompleteRequest(RxContext,Status);
  596. }
  597. try_return(Status);
  598. }
  599. break;
  600. default:
  601. NOTHING;
  602. }
  603. //
  604. // set the resume routine for the fsp to be the dispatch routine and then either post immediately
  605. // or calldow to the common dispatch as appropriate
  606. RxContext->ResumeRoutine = DispatchRoutine;
  607. if( DispatchRoutine != NULL ) {
  608. RxContext->PendingReturned = TRUE;
  609. if (PostRequest) {
  610. Status = RxFsdPostRequest(RxContext);
  611. } else {
  612. do {
  613. Status = DispatchRoutine( RXCOMMON_ARGUMENTS );
  614. } while (Status == STATUS_RETRY);
  615. if (Status != STATUS_PENDING) {
  616. if (! ((RxContext->CurrentIrp == Irp) &&
  617. (RxContext->CurrentIrpSp == IrpSp) &&
  618. (RxContext->MajorFunction == MajorFunctionCode) &&
  619. (RxContext->MinorFunction == MinorFunctionCode) )
  620. ) {
  621. DbgPrint("RXCONTEXT CONTAMINATED!!!! rxc=%08lx\n", RxContext);
  622. DbgPrint("-irp> %08lx %08lx\n",RxContext->CurrentIrp,Irp);
  623. DbgPrint("--sp> %08lx %08lx\n",RxContext->CurrentIrpSp,IrpSp);
  624. DbgPrint("--mj> %08lx %08lx\n",RxContext->MajorFunction,MajorFunctionCode);
  625. DbgPrint("--mn> %08lx %08lx\n",RxContext->MinorFunction,MinorFunctionCode);
  626. //DbgBreakPoint();
  627. }
  628. RxContext->PendingReturned = FALSE;
  629. Status = RxCompleteRequest( RxContext, Status );
  630. }
  631. }
  632. } else {
  633. Status = STATUS_NOT_IMPLEMENTED;
  634. }
  635. try_exit: NOTHING;
  636. } except(RxExceptionFilter( RxContext, GetExceptionInformation() )) {
  637. // The I/O request was not handled successfully, abort the I/O request with
  638. // the error status that we get back from the execption code
  639. if (RxContext != NULL) {
  640. RxContext->PendingReturned = FALSE;
  641. }
  642. Status = RxProcessException( RxContext, GetExceptionCode() );
  643. }
  644. if (TopLevel) {
  645. RxUnwindTopLevelIrp( &TopLevelContext );
  646. }
  647. FsRtlExitFileSystem();
  648. //RxDbgTraceLV(-1, Dbg, 1500, ("RxFsd[%s] Status-> %08lx\n", RxIrpCodeToName[MajorFunctionCode],Status));
  649. //TimerStop(Dbg,"RxFsdCreate");
  650. return Status;
  651. #if DBG
  652. NOTHING;
  653. #else
  654. UNREFERENCED_PARAMETER( IrpSp );
  655. #endif
  656. }
  657. #ifdef RX_PRIVATE_BUILD
  658. #undef IoGetTopLevelIrp
  659. #undef IoSetTopLevelIrp
  660. #endif //ifdef RX_PRIVATE_BUILD
  661. #define RX_TOPLEVELCTX_FLAG_FROM_POOL (0x00000001)
  662. KSPIN_LOCK TopLevelIrpSpinLock;
  663. LIST_ENTRY TopLevelIrpAllocatedContextsList;
  664. VOID
  665. RxInitializeTopLevelIrpPackage(
  666. void
  667. )
  668. {
  669. KeInitializeSpinLock( &TopLevelIrpSpinLock );
  670. InitializeListHead(&TopLevelIrpAllocatedContextsList);
  671. }
  672. VOID
  673. RxAddToTopLevelIrpAllocatedContextsList(
  674. IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext
  675. )
  676. /*++
  677. Routine Description:
  678. This the passed context is added to the allocatedcontexts list. THIS
  679. ROUTINE TAKES A SPINLOCK...CANNOT BE PAGED.
  680. Arguments:
  681. TopLevelContext - the context to be removed
  682. Return Value:
  683. --*/
  684. {
  685. KIRQL SavedIrql;
  686. ASSERT(TopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE);
  687. ASSERT(FlagOn(TopLevelContext->Flags,RX_TOPLEVELCTX_FLAG_FROM_POOL));
  688. KeAcquireSpinLock(&TopLevelIrpSpinLock,&SavedIrql);
  689. InsertHeadList(&TopLevelIrpAllocatedContextsList,
  690. &TopLevelContext->ListEntry);
  691. KeReleaseSpinLock(&TopLevelIrpSpinLock,SavedIrql);
  692. }
  693. VOID
  694. RxRemoveFromTopLevelIrpAllocatedContextsList(
  695. IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext
  696. )
  697. /*++
  698. Routine Description:
  699. This the passed context is removed from the allocatedcontexts list. THIS
  700. ROUTINE TAKES A SPINLOCK...CANNOT BE PAGED.
  701. Arguments:
  702. TopLevelContext - the context to be removed
  703. Return Value:
  704. --*/
  705. {
  706. KIRQL SavedIrql;
  707. ASSERT(TopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE);
  708. ASSERT(FlagOn(TopLevelContext->Flags,RX_TOPLEVELCTX_FLAG_FROM_POOL));
  709. KeAcquireSpinLock(&TopLevelIrpSpinLock,&SavedIrql);
  710. RemoveEntryList(&TopLevelContext->ListEntry);
  711. KeReleaseSpinLock(&TopLevelIrpSpinLock,SavedIrql);
  712. }
  713. BOOLEAN
  714. RxIsMemberOfTopLevelIrpAllocatedContextsList(
  715. IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext
  716. )
  717. /*++
  718. Routine Description:
  719. This looks to see if the passed context is on the allocatedcontexts list.
  720. THIS ROUTINE TAKES A SPINLOCK...CANNOT BE PAGED.
  721. Arguments:
  722. TopLevelContext - the context to be looked up
  723. Return Value:
  724. TRUE if TopLevelContext is on the list, FALSE otherwise
  725. --*/
  726. {
  727. KIRQL SavedIrql;
  728. PLIST_ENTRY pListEntry;
  729. BOOLEAN Found = FALSE;
  730. KeAcquireSpinLock(&TopLevelIrpSpinLock,&SavedIrql);
  731. pListEntry = TopLevelIrpAllocatedContextsList.Flink;
  732. while (pListEntry != &TopLevelIrpAllocatedContextsList) {
  733. PRX_TOPLEVELIRP_CONTEXT ListTopLevelContext
  734. = CONTAINING_RECORD(pListEntry,RX_TOPLEVELIRP_CONTEXT,ListEntry);
  735. ASSERT(ListTopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE);
  736. ASSERT(FlagOn(ListTopLevelContext->Flags,RX_TOPLEVELCTX_FLAG_FROM_POOL));
  737. if (ListTopLevelContext == TopLevelContext) {
  738. Found = TRUE;
  739. break;
  740. } else {
  741. pListEntry = pListEntry->Flink;
  742. }
  743. }
  744. KeReleaseSpinLock(&TopLevelIrpSpinLock,SavedIrql);
  745. return(Found);
  746. }
  747. BOOLEAN
  748. RxIsThisAnRdbssTopLevelContext (
  749. IN PRX_TOPLEVELIRP_CONTEXT TopLevelContext
  750. )
  751. {
  752. ULONG_PTR StackBottom;
  753. ULONG_PTR StackTop;
  754. // if it's a magic value....then no
  755. if ((ULONG_PTR)TopLevelContext <= FSRTL_MAX_TOP_LEVEL_IRP_FLAG) {
  756. return(FALSE);
  757. }
  758. //if it's on the stack...check the signature
  759. IoGetStackLimits( &StackTop, &StackBottom);
  760. if (((ULONG_PTR) TopLevelContext <= StackBottom - sizeof( RX_TOPLEVELIRP_CONTEXT )) &&
  761. ((ULONG_PTR) TopLevelContext >= StackTop)) {
  762. //it's on the stack check it
  763. if (!FlagOn( (ULONG_PTR) TopLevelContext, 0x3 ) &&
  764. (TopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE) ) {
  765. return TRUE;
  766. } else {
  767. return(FALSE);
  768. }
  769. }
  770. return RxIsMemberOfTopLevelIrpAllocatedContextsList(TopLevelContext);
  771. }
  772. BOOLEAN
  773. RxTryToBecomeTheTopLevelIrp (
  774. IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext,
  775. IN PIRP Irp,
  776. IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
  777. IN BOOLEAN ForceTopLevel
  778. )
  779. /*++
  780. Routine Description:
  781. This routine detects if an Irp is the Top level requestor, ie. if it os OK
  782. to do a verify or pop-up now. If TRUE is returned, then no file system
  783. resources are held above us. Also, we have left a context in TLS that will
  784. allow us to tell if we are the top level...even if we are entered recursively.
  785. Arguments:
  786. TopLevelContext - the toplevelirp context to use. if NULL, allocate one
  787. Irp - the irp. could be a magic value
  788. RxDeviceObject - the associated deviceobject
  789. ForceTopLevel - if true, we force ourselves onto the TLS
  790. Return Value:
  791. BOOLEAN tells whether we became the toplevel.
  792. --*/
  793. {
  794. ULONG ContextFlags = 0;
  795. PAGED_CODE();
  796. if ( (IoGetTopLevelIrp() != NULL ) && !ForceTopLevel ) {
  797. return(FALSE);
  798. }
  799. // i hate doing this allocate....toplevelirp is the world's biggest kludge
  800. if (TopLevelContext == NULL) {
  801. TopLevelContext = RxAllocatePool( NonPagedPool, sizeof(RX_TOPLEVELIRP_CONTEXT) );
  802. if (TopLevelContext == NULL) {
  803. return(FALSE);
  804. }
  805. ContextFlags = RX_TOPLEVELCTX_FLAG_FROM_POOL;
  806. }
  807. __RxInitializeTopLevelIrpContext(TopLevelContext,
  808. Irp,
  809. RxDeviceObject,
  810. ContextFlags);
  811. ASSERT(TopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE);
  812. if (ContextFlags!=0) {
  813. ASSERT(FlagOn(TopLevelContext->Flags,RX_TOPLEVELCTX_FLAG_FROM_POOL));
  814. }
  815. IoSetTopLevelIrp( (PIRP)TopLevelContext );
  816. return TRUE;
  817. }
  818. VOID
  819. __RxInitializeTopLevelIrpContext (
  820. IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext,
  821. IN PIRP Irp,
  822. IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
  823. IN ULONG Flags
  824. )
  825. /*++
  826. Routine Description:
  827. This routine initalizes a toplevelirp context.
  828. Arguments:
  829. TopLevelContext - the toplevelirp context to use.
  830. Irp - the irp. could be a magic value
  831. RxDeviceObject - the associated deviceobject
  832. Flags - could be various...currently just tells if context is allocated or not
  833. Return Value:
  834. None.
  835. --*/
  836. {
  837. RtlZeroMemory(TopLevelContext,sizeof(RX_TOPLEVELIRP_CONTEXT));
  838. TopLevelContext->Signature = RX_TOPLEVELIRP_CONTEXT_SIGNATURE;
  839. TopLevelContext->Irp = Irp;
  840. TopLevelContext->Flags = Flags;
  841. TopLevelContext->RxDeviceObject = RxDeviceObject;
  842. TopLevelContext->Previous = IoGetTopLevelIrp();
  843. TopLevelContext->Thread = PsGetCurrentThread();
  844. //if this is an allocated context, add it to the allocatedcontextslist
  845. if (FlagOn(TopLevelContext->Flags,RX_TOPLEVELCTX_FLAG_FROM_POOL)) {
  846. RxAddToTopLevelIrpAllocatedContextsList(TopLevelContext);
  847. }
  848. }
  849. VOID
  850. RxUnwindTopLevelIrp (
  851. IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext
  852. )
  853. /*++
  854. Routine Description:
  855. This routine removes us from the TLC....replacing by the previous.
  856. Arguments:
  857. TopLevelContext - the toplevelirp context to use. if NULL, use the one from TLS
  858. Return Value:
  859. None.
  860. --*/
  861. {
  862. if (TopLevelContext==NULL) {
  863. //get the one off the thread and do some asserts to make sure it's me
  864. TopLevelContext = (PRX_TOPLEVELIRP_CONTEXT)(IoGetTopLevelIrp());
  865. // depending on a race condition, this context could be NULL.
  866. // we chkec it before hand and bail if so.
  867. // In this case the Irp was completed by another thread.
  868. if (!TopLevelContext)
  869. {
  870. return;
  871. }
  872. ASSERT(RxIsThisAnRdbssTopLevelContext(TopLevelContext));
  873. ASSERT(FlagOn(TopLevelContext->Flags,RX_TOPLEVELCTX_FLAG_FROM_POOL));
  874. }
  875. ASSERT(TopLevelContext->Signature == RX_TOPLEVELIRP_CONTEXT_SIGNATURE);
  876. ASSERT(TopLevelContext->Thread == PsGetCurrentThread());
  877. IoSetTopLevelIrp( TopLevelContext->Previous );
  878. if (FlagOn(TopLevelContext->Flags,RX_TOPLEVELCTX_FLAG_FROM_POOL)) {
  879. RxRemoveFromTopLevelIrpAllocatedContextsList(TopLevelContext);
  880. RxFreePool(TopLevelContext);
  881. }
  882. }
  883. BOOLEAN
  884. RxIsThisTheTopLevelIrp (
  885. IN PIRP Irp
  886. )
  887. /*++
  888. Routine Description:
  889. This determines if the irp at hand is the toplevel irp.
  890. Arguments:
  891. Irp - the one to find out if it's toplevel...btw, it works for NULL.
  892. Return Value:
  893. TRUE if irp is the toplevelirp.
  894. --*/
  895. {
  896. PIRP TopIrp = IoGetTopLevelIrp();
  897. PRX_TOPLEVELIRP_CONTEXT TopLevelContext;
  898. TopLevelContext = (PRX_TOPLEVELIRP_CONTEXT)TopIrp;
  899. if (RxIsThisAnRdbssTopLevelContext(TopLevelContext)) {
  900. TopIrp = TopLevelContext->Irp;
  901. }
  902. return ( TopIrp == Irp );
  903. }
  904. PIRP
  905. RxGetTopIrpIfRdbssIrp (
  906. void
  907. )
  908. /*++
  909. Routine Description:
  910. This gets the toplevelirp if it belongs to the rdbss.
  911. Arguments:
  912. Return Value:
  913. topirp if topirp is rdbss-irp and NULL otherwise.
  914. --*/
  915. {
  916. PRX_TOPLEVELIRP_CONTEXT TopLevelContext;
  917. TopLevelContext = (PRX_TOPLEVELIRP_CONTEXT)(IoGetTopLevelIrp());
  918. if (RxIsThisAnRdbssTopLevelContext(TopLevelContext)) {
  919. return TopLevelContext->Irp;
  920. } else {
  921. return NULL;
  922. }
  923. }
  924. PRDBSS_DEVICE_OBJECT
  925. RxGetTopDeviceObjectIfRdbssIrp (
  926. void
  927. )
  928. /*++
  929. Routine Description:
  930. This gets the deviceobject assoc'd w/ toplevelirp if topirp belongs to the rdbss.
  931. Arguments:
  932. Return Value:
  933. deviceobject for topirp if topirp is rdbss-irp and NULL otherwise.
  934. --*/
  935. {
  936. PRX_TOPLEVELIRP_CONTEXT TopLevelContext;
  937. TopLevelContext = (PRX_TOPLEVELIRP_CONTEXT)(IoGetTopLevelIrp());
  938. if (RxIsThisAnRdbssTopLevelContext(TopLevelContext)) {
  939. return TopLevelContext->RxDeviceObject;
  940. } else {
  941. return NULL;
  942. }
  943. }