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.

1008 lines
24 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. Ea.c
  5. Abstract:
  6. This module implements the EA, security and quota routines for Rx called by
  7. the dispatch driver.
  8. Author:
  9. Joe Linn [JoeLi] 1-Jan-95
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. //
  15. // The local debug trace level
  16. //
  17. #define Dbg (DEBUG_TRACE_EA)
  18. #ifdef ALLOC_PRAGMA
  19. #pragma alloc_text(PAGE, RxCommonQueryEa)
  20. #pragma alloc_text(PAGE, RxCommonSetEa)
  21. #pragma alloc_text(PAGE, RxCommonQuerySecurity)
  22. #pragma alloc_text(PAGE, RxCommonSetSecurity)
  23. #endif
  24. typedef
  25. NTSTATUS
  26. (NTAPI *PRX_MISC_OP_ROUTINE) (
  27. IN PRX_CONTEXT RxContext,
  28. IN PIRP Irp,
  29. IN PFCB Fcb
  30. );
  31. NTSTATUS
  32. RxpCommonMiscOp (
  33. IN PRX_CONTEXT RxContext,
  34. IN PIRP Irp,
  35. IN PFCB Fcb,
  36. IN PRX_MISC_OP_ROUTINE MiscOpRoutine
  37. )
  38. /*++
  39. Routine Description:
  40. Main stub that all the common routines below use - this does the common work
  41. such as acquiring the fcb, parameter validation and posting if necc.
  42. Arguments:
  43. RxContext - the rxcontext
  44. Fcb - the fcb being used
  45. MiscOpRoutine - The callback that does the real work
  46. Return Value:
  47. Notes:
  48. --*/
  49. {
  50. NTSTATUS Status;
  51. NODE_TYPE_CODE TypeOfOpen = NodeType( Fcb );
  52. if ((TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_FILE) &&
  53. (TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_DIRECTORY)) {
  54. RxDbgTrace( -1, Dbg, ("RxpCommonMiscOp -> %08lx\n", STATUS_INVALID_PARAMETER) );
  55. return STATUS_INVALID_PARAMETER;
  56. }
  57. if (!FlagOn( RxContext->Flags, RX_CONTEXT_FLAG_WAIT )) {
  58. RxDbgTrace( 0, Dbg, ("RxpCommonMiscOp: Set Ea must be waitable....posting\n", 0) );
  59. Status = RxFsdPostRequest( RxContext );
  60. RxDbgTrace(-1, Dbg, ("RxpCommonMiscOp -> %08lx\n", Status ));
  61. return Status;
  62. }
  63. Status = RxAcquireExclusiveFcb( RxContext, Fcb );
  64. if (Status != STATUS_SUCCESS) {
  65. RxDbgTrace( -1, Dbg, ("RxpCommonMiscOp -> Error Acquiring Fcb %08lx\n", Status) );
  66. return Status;
  67. }
  68. try {
  69. Status = (*MiscOpRoutine)( RxContext, Irp, Fcb );
  70. } finally {
  71. DebugUnwind( *MiscOpRoutine );
  72. RxReleaseFcb( RxContext, Fcb );
  73. RxDbgTrace( -1, Dbg, ("RxpCommonMiscOp -> %08lx\n", Status ));
  74. }
  75. return Status;
  76. }
  77. NTSTATUS
  78. RxpCommonQuerySecurity (
  79. IN PRX_CONTEXT RxContext,
  80. IN PIRP Irp,
  81. IN PFCB Fcb
  82. )
  83. /*++
  84. Routine Description:
  85. Callback that implements the query security call
  86. Arguments:
  87. RxContext -
  88. Irp -
  89. Fcb -
  90. Return Value:
  91. Note:
  92. --*/
  93. {
  94. NTSTATUS Status;
  95. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  96. PUCHAR Buffer;
  97. ULONG UserBufferLength;
  98. UserBufferLength = IrpSp->Parameters.QuerySecurity.Length;
  99. RxContext->QuerySecurity.SecurityInformation = IrpSp->Parameters.QuerySecurity.SecurityInformation;
  100. RxLockUserBuffer( RxContext,
  101. Irp,
  102. IoModifyAccess,
  103. UserBufferLength );
  104. //
  105. // Lock before map so that map will get userbuffer instead of assoc buffer
  106. //
  107. Buffer = RxMapUserBuffer( RxContext, Irp );
  108. RxDbgTrace( 0, Dbg, ("RxCommonQuerySecurity -> Buffer = %08lx\n", Buffer) );
  109. if ((Buffer != NULL) ||
  110. (UserBufferLength == 0)) {
  111. RxContext->Info.Buffer = Buffer;
  112. RxContext->Info.LengthRemaining = UserBufferLength;
  113. MINIRDR_CALL( Status,
  114. RxContext,
  115. Fcb->MRxDispatch,
  116. MRxQuerySdInfo,
  117. (RxContext) );
  118. Irp->IoStatus.Information = RxContext->InformationToReturn;
  119. } else {
  120. Irp->IoStatus.Information = 0;
  121. Status = STATUS_INSUFFICIENT_RESOURCES;
  122. }
  123. return Status;
  124. }
  125. NTSTATUS
  126. RxCommonQuerySecurity (
  127. IN PRX_CONTEXT RxContext,
  128. IN PIRP Irp
  129. )
  130. /*++
  131. Routine Description:
  132. This is the common routine for querying File ea called by both
  133. the fsd and fsp threads.
  134. Arguments:
  135. Irp - Supplies the Irp being processed
  136. Return Value:
  137. RXSTATUS - The return status for the operation
  138. STATUS_NO_MORE_EAS(warning):
  139. If the index of the last Ea + 1 == EaIndex.
  140. STATUS_NONEXISTENT_EA_ENTRY(error):
  141. EaIndex > index of last Ea + 1.
  142. STATUS_EAS_NOT_SUPPORTED(error):
  143. Attempt to do an operation to a server that did not negotiate
  144. "KNOWS_EAS".
  145. STATUS_BUFFER_OVERFLOW(warning):
  146. User did not supply an EaList, at least one but not all Eas
  147. fit in the buffer.
  148. STATUS_BUFFER_TOO_SMALL(error):
  149. Could not fit a single Ea in the buffer.
  150. User supplied an EaList and not all Eas fit in the buffer.
  151. STATUS_NO_EAS_ON_FILE(error):
  152. There were no eas on the file.
  153. STATUS_SUCCESS:
  154. All Eas fit in the buffer.
  155. If STATUS_BUFFER_TOO_SMALL is returned then IoStatus.Information is set
  156. to 0.
  157. Note:
  158. This code assumes that this is a buffered I/O operation. If it is ever
  159. implemented as a non buffered operation, then we have to put code to map
  160. in the users buffer here.
  161. --*/
  162. {
  163. NTSTATUS Status;
  164. PFCB Fcb;
  165. PFOBX Fobx;
  166. NODE_TYPE_CODE TypeOfOpen;
  167. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  168. PAGED_CODE();
  169. RxDbgTrace(+1, Dbg, ("RxCommonQuerySecurity...\n", 0));
  170. RxDbgTrace( 0, Dbg, (" Wait = %08lx\n", FlagOn( RxContext->Flags, RX_CONTEXT_FLAG_WAIT )));
  171. RxDbgTrace( 0, Dbg, (" Irp = %08lx\n", Irp ));
  172. RxDbgTrace( 0, Dbg, (" ->UserBuffer = %08lx\n", Irp->UserBuffer ));
  173. RxDbgTrace( 0, Dbg, (" ->Length = %08lx\n", IrpSp->Parameters.QuerySecurity.Length ));
  174. RxDbgTrace( 0, Dbg, (" ->SecurityInfo = %08lx\n", IrpSp->Parameters.QuerySecurity.SecurityInformation ));
  175. TypeOfOpen = RxDecodeFileObject( IrpSp->FileObject, &Fcb, &Fobx );
  176. if ((TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_FILE) &&
  177. (TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_DIRECTORY)) {
  178. RxDbgTrace( -1, Dbg, ("RxpCommonQuerySecurity -> %08lx\n", STATUS_INVALID_PARAMETER) );
  179. return STATUS_INVALID_PARAMETER;
  180. }
  181. Status = RxpCommonMiscOp( RxContext,
  182. Irp,
  183. Fcb,
  184. RxpCommonQuerySecurity );
  185. RxDbgTrace(-1, Dbg, ("RxCommonQuerySecurity -> %08lx\n", Status));
  186. return Status;
  187. }
  188. NTSTATUS
  189. RxpCommonSetSecurity (
  190. IN PRX_CONTEXT RxContext,
  191. IN PIRP Irp,
  192. IN PFCB Fcb
  193. )
  194. /*++
  195. Routine Description:
  196. Callback that implements the set security call
  197. Arguments:
  198. RxContext -
  199. Irp -
  200. Fcb -
  201. Return Value:
  202. Note:
  203. --*/
  204. {
  205. NTSTATUS Status;
  206. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  207. RxContext->SetSecurity.SecurityInformation = IrpSp->Parameters.SetSecurity.SecurityInformation;
  208. RxContext->SetSecurity.SecurityDescriptor = IrpSp->Parameters.SetSecurity.SecurityDescriptor;
  209. RxDbgTrace(0, Dbg, ("RxCommonSetSecurity -> Descr/Info = %08lx/%08lx\n",
  210. RxContext->SetSecurity.SecurityDescriptor,
  211. RxContext->SetSecurity.SecurityInformation ));
  212. MINIRDR_CALL( Status,
  213. RxContext,
  214. Fcb->MRxDispatch,
  215. MRxSetSdInfo,
  216. (RxContext) );
  217. return Status;
  218. }
  219. NTSTATUS
  220. RxCommonSetSecurity (
  221. IN PRX_CONTEXT RxContext,
  222. IN PIRP Irp
  223. )
  224. /*++
  225. Routine Description:
  226. This routine implements the common Set Ea File Api called by the
  227. the Fsd and Fsp threads
  228. Arguments:
  229. Irp - Supplies the Irp to process
  230. Return Value:
  231. RXSTATUS - The appropriate status for the Irp
  232. --*/
  233. {
  234. NTSTATUS Status;
  235. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  236. PFCB Fcb;
  237. PFOBX Fobx;
  238. NODE_TYPE_CODE TypeOfOpen;
  239. PAGED_CODE();
  240. TypeOfOpen = RxDecodeFileObject( IrpSp->FileObject, &Fcb, &Fobx );
  241. if ((TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_FILE) &&
  242. (TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_DIRECTORY)) {
  243. RxDbgTrace( -1, Dbg, ("RxpCommonSetSecurity -> %08lx\n", STATUS_INVALID_PARAMETER) );
  244. return STATUS_INVALID_PARAMETER;
  245. }
  246. RxDbgTrace(+1, Dbg, ("RxCommonSetSecurity...\n", 0));
  247. RxDbgTrace( 0, Dbg, (" Wait = %08lx\n", FlagOn( RxContext->Flags, RX_CONTEXT_FLAG_WAIT )));
  248. RxDbgTrace( 0, Dbg, (" Irp = %08lx\n", RxContext->CurrentIrp ));
  249. Status = RxpCommonMiscOp( RxContext, RxContext->CurrentIrp, Fcb, RxpCommonSetSecurity );
  250. RxDbgTrace(-1, Dbg, ("RxCommonSetSecurity -> %08lx\n", Status));
  251. return Status;
  252. }
  253. NTSTATUS
  254. RxpCommonQueryEa (
  255. IN PRX_CONTEXT RxContext,
  256. IN PIRP Irp,
  257. IN PFCB Fcb
  258. )
  259. /*++
  260. Routine Description:
  261. Callback that implements the query ea call
  262. Arguments:
  263. RxContext -
  264. Irp -
  265. Fcb -
  266. Return Value:
  267. Note:
  268. --*/
  269. {
  270. NTSTATUS Status;
  271. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  272. PUCHAR Buffer;
  273. ULONG UserBufferLength;
  274. UserBufferLength = IrpSp->Parameters.QueryEa.Length;
  275. RxContext->QueryEa.UserEaList = IrpSp->Parameters.QueryEa.EaList;
  276. RxContext->QueryEa.UserEaListLength = IrpSp->Parameters.QueryEa.EaListLength;
  277. RxContext->QueryEa.UserEaIndex = IrpSp->Parameters.QueryEa.EaIndex;
  278. RxContext->QueryEa.RestartScan = BooleanFlagOn(IrpSp->Flags, SL_RESTART_SCAN);
  279. RxContext->QueryEa.ReturnSingleEntry = BooleanFlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
  280. RxContext->QueryEa.IndexSpecified = BooleanFlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED);
  281. RxLockUserBuffer( RxContext, Irp, IoModifyAccess, UserBufferLength );
  282. //
  283. // lock before map so that map will get userbuffer instead of assoc buffer
  284. //
  285. Buffer = RxMapUserBuffer( RxContext, Irp );
  286. if ((Buffer != NULL) ||
  287. (UserBufferLength == 0)) {
  288. RxDbgTrace( 0, Dbg, ("RxCommonQueryEa -> Buffer = %08lx\n", Buffer ));
  289. RxContext->Info.Buffer = Buffer;
  290. RxContext->Info.LengthRemaining = UserBufferLength;
  291. MINIRDR_CALL( Status,
  292. RxContext,
  293. Fcb->MRxDispatch,
  294. MRxQueryEaInfo,
  295. (RxContext) );
  296. //
  297. // In addition to manipulating the LengthRemaining and filling the buffer,
  298. // the minirdr also updates the fileindex (Fobx->OffsetOfNextEaToReturn)
  299. //
  300. Irp->IoStatus.Information = IrpSp->Parameters.QueryEa.Length - RxContext->Info.LengthRemaining;
  301. } else {
  302. Irp->IoStatus.Information = 0;
  303. Status = STATUS_INSUFFICIENT_RESOURCES;
  304. }
  305. return Status;
  306. }
  307. NTSTATUS
  308. RxCommonQueryEa (
  309. IN PRX_CONTEXT RxContext,
  310. IN PIRP Irp
  311. )
  312. /*++
  313. Routine Description:
  314. This is the common routine for querying File ea called by both
  315. the fsd and fsp threads.
  316. Arguments:
  317. Irp - Supplies the Irp being processed
  318. Return Value:
  319. RXSTATUS - The return status for the operation
  320. STATUS_NO_MORE_EAS(warning):
  321. If the index of the last Ea + 1 == EaIndex.
  322. STATUS_NONEXISTENT_EA_ENTRY(error):
  323. EaIndex > index of last Ea + 1.
  324. STATUS_EAS_NOT_SUPPORTED(error):
  325. Attempt to do an operation to a server that did not negotiate
  326. "KNOWS_EAS".
  327. STATUS_BUFFER_OVERFLOW(warning):
  328. User did not supply an EaList, at least one but not all Eas
  329. fit in the buffer.
  330. STATUS_BUFFER_TOO_SMALL(error):
  331. Could not fit a single Ea in the buffer.
  332. User supplied an EaList and not all Eas fit in the buffer.
  333. STATUS_NO_EAS_ON_FILE(error):
  334. There were no eas on the file.
  335. STATUS_SUCCESS:
  336. All Eas fit in the buffer.
  337. If STATUS_BUFFER_TOO_SMALL is returned then IoStatus.Information is set
  338. to 0.
  339. Note:
  340. This code assumes that this is a buffered I/O operation. If it is ever
  341. implemented as a non buffered operation, then we have to put code to map
  342. in the users buffer here.
  343. --*/
  344. {
  345. NTSTATUS Status;
  346. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  347. PFCB Fcb;
  348. PFOBX Fobx;
  349. NODE_TYPE_CODE TypeOfOpen;
  350. PAGED_CODE();
  351. RxDbgTrace( +1, Dbg, ("RxCommonQueryEa...\n", 0 ));
  352. RxDbgTrace( 0, Dbg, (" Wait = %08lx\n", FlagOn( RxContext->Flags, RX_CONTEXT_FLAG_WAIT )));
  353. RxDbgTrace( 0, Dbg, (" Irp = %08lx\n", Irp ));
  354. RxDbgTrace( 0, Dbg, (" ->SystemBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer ));
  355. RxDbgTrace( 0, Dbg, (" ->UserBuffer = %08lx\n", Irp->UserBuffer ));
  356. RxDbgTrace( 0, Dbg, (" ->Length = %08lx\n", IrpSp->Parameters.QueryEa.Length ));
  357. RxDbgTrace( 0, Dbg, (" ->EaList = %08lx\n", IrpSp->Parameters.QueryEa.EaList ));
  358. RxDbgTrace( 0, Dbg, (" ->EaListLength = %08lx\n", IrpSp->Parameters.QueryEa.EaListLength ));
  359. RxDbgTrace( 0, Dbg, (" ->EaIndex = %08lx\n", IrpSp->Parameters.QueryEa.EaIndex ));
  360. RxDbgTrace( 0, Dbg, (" ->RestartScan = %08lx\n", FlagOn( IrpSp->Flags, SL_RESTART_SCAN )));
  361. RxDbgTrace( 0, Dbg, (" ->ReturnSingleEntry = %08lx\n", FlagOn( IrpSp->Flags, SL_RETURN_SINGLE_ENTRY )));
  362. RxDbgTrace( 0, Dbg, (" ->IndexSpecified = %08lx\n", FlagOn( IrpSp->Flags, SL_INDEX_SPECIFIED )));
  363. TypeOfOpen = RxDecodeFileObject( IrpSp->FileObject, &Fcb, &Fobx );
  364. Status = RxpCommonMiscOp( RxContext,
  365. Irp,
  366. Fcb,
  367. RxpCommonQueryEa );
  368. RxDbgTrace(-1, Dbg, ("RxCommonQueryEa -> %08lx\n", Status));
  369. return Status;
  370. }
  371. NTSTATUS
  372. RxpCommonSetEa (
  373. IN PRX_CONTEXT RxContext,
  374. IN PIRP Irp,
  375. IN PFCB Fcb
  376. )
  377. /*++
  378. Routine Description:
  379. Callback that implements the set ea call
  380. Arguments:
  381. RxContext -
  382. Irp -
  383. Fcb -
  384. Return Value:
  385. Note:
  386. --*/
  387. {
  388. NTSTATUS Status;
  389. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  390. PFILE_OBJECT FileObject = IrpSp->FileObject;
  391. PUCHAR Buffer;
  392. ULONG UserBufferLength;
  393. //
  394. // Reference our input parameters to make things easier
  395. //
  396. UserBufferLength = IrpSp->Parameters.SetEa.Length;
  397. SetFlag( FileObject->Flags, FO_FILE_MODIFIED );
  398. RxLockUserBuffer( RxContext,
  399. Irp,
  400. IoModifyAccess,
  401. UserBufferLength );
  402. //
  403. // unless we lock first, rxmap actually gets the systembuffer!
  404. //
  405. Buffer = RxMapUserBuffer( RxContext, Irp );
  406. if ((Buffer != NULL) ||
  407. (UserBufferLength == 0)) {
  408. ULONG ErrorOffset;
  409. RxDbgTrace( 0, Dbg, ("RxCommonSetEa -> Buffer = %08lx\n", Buffer ));
  410. //
  411. // Check the validity of the buffer with the new eas.
  412. //
  413. Status = IoCheckEaBufferValidity( (PFILE_FULL_EA_INFORMATION)Buffer,
  414. UserBufferLength,
  415. &ErrorOffset );
  416. if (!NT_SUCCESS( Status )) {
  417. Irp->IoStatus.Information = ErrorOffset;
  418. return Status;
  419. }
  420. } else {
  421. Irp->IoStatus.Information = 0;
  422. return STATUS_INSUFFICIENT_RESOURCES;
  423. }
  424. Irp->IoStatus.Information = 0;
  425. RxContext->Info.Buffer = Buffer;
  426. RxContext->Info.Length = UserBufferLength;
  427. MINIRDR_CALL( Status,
  428. RxContext,
  429. Fcb->MRxDispatch,
  430. MRxSetEaInfo,
  431. (RxContext) );
  432. return Status;
  433. }
  434. NTSTATUS
  435. RxCommonSetEa (
  436. IN PRX_CONTEXT RxContext,
  437. IN PIRP Irp
  438. )
  439. /*++
  440. Routine Description:
  441. This routine implements the common Set Ea File Api called by the
  442. the Fsd and Fsp threads
  443. Arguments:
  444. Irp - Supplies the Irp to process
  445. Return Value:
  446. RXSTATUS - The appropriate status for the Irp
  447. --*/
  448. {
  449. NTSTATUS Status;
  450. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  451. PFCB Fcb;
  452. PFOBX Fobx;
  453. NODE_TYPE_CODE TypeOfOpen;
  454. PAGED_CODE();
  455. RxDbgTrace( +1, Dbg, ("RxCommonSetEa...\n", 0) );
  456. RxDbgTrace( 0, Dbg, (" Wait = %08lx\n", FlagOn( RxContext->Flags, RX_CONTEXT_FLAG_WAIT )));
  457. RxDbgTrace( 0, Dbg, (" Irp = %08lx\n", Irp ));
  458. RxDbgTrace( 0, Dbg, (" ->SystemBuffer = %08lx\n", Irp->UserBuffer ));
  459. RxDbgTrace( 0, Dbg, (" ->Length = %08lx\n", IrpSp->Parameters.SetEa.Length ));
  460. TypeOfOpen = RxDecodeFileObject( IrpSp->FileObject, &Fcb, &Fobx );
  461. if ((TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_FILE) &&
  462. (TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_DIRECTORY)) {
  463. RxDbgTrace( -1, Dbg, ("RxpCommonSetSecurity -> %08lx\n", STATUS_INVALID_PARAMETER) );
  464. return STATUS_INVALID_PARAMETER;
  465. }
  466. Status = RxpCommonMiscOp( RxContext, Irp, Fcb, RxpCommonSetEa );
  467. RxDbgTrace(-1, Dbg, ("RxCommonSetEa -> %08lx\n", Status));
  468. return Status;
  469. }
  470. NTSTATUS
  471. RxpCommonQueryQuotaInformation (
  472. IN PRX_CONTEXT RxContext,
  473. IN PIRP Irp,
  474. IN PFCB Fcb
  475. )
  476. /*++
  477. Routine Description:
  478. Callback that implements the query quota call
  479. Arguments:
  480. RxContext -
  481. Irp -
  482. Fcb -
  483. Return Value:
  484. Note:
  485. --*/
  486. {
  487. NTSTATUS Status;
  488. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  489. PUCHAR Buffer;
  490. ULONG UserBufferLength;
  491. UserBufferLength = IrpSp->Parameters.QueryQuota.Length;
  492. RxContext->QueryQuota.SidList = IrpSp->Parameters.QueryQuota.SidList;
  493. RxContext->QueryQuota.SidListLength = IrpSp->Parameters.QueryQuota.SidListLength;
  494. RxContext->QueryQuota.StartSid = IrpSp->Parameters.QueryQuota.StartSid;
  495. RxContext->QueryQuota.Length = IrpSp->Parameters.QueryQuota.Length;
  496. RxContext->QueryQuota.RestartScan = BooleanFlagOn( IrpSp->Flags, SL_RESTART_SCAN );
  497. RxContext->QueryQuota.ReturnSingleEntry = BooleanFlagOn( IrpSp->Flags, SL_RETURN_SINGLE_ENTRY );
  498. RxContext->QueryQuota.IndexSpecified = BooleanFlagOn( IrpSp->Flags, SL_INDEX_SPECIFIED );
  499. RxLockUserBuffer( RxContext,
  500. Irp,
  501. IoModifyAccess,
  502. UserBufferLength );
  503. //
  504. // lock before map so that map will get userbuffer instead of assoc buffer
  505. //
  506. Buffer = RxMapUserBuffer( RxContext, Irp );
  507. if ((Buffer != NULL) ||
  508. (UserBufferLength == 0)) {
  509. RxDbgTrace( 0, Dbg, ("RxCommonQueryQuota -> Buffer = %08lx\n", Buffer) );
  510. RxContext->Info.Buffer = Buffer;
  511. RxContext->Info.LengthRemaining = UserBufferLength;
  512. MINIRDR_CALL( Status,
  513. RxContext,
  514. Fcb->MRxDispatch,
  515. MRxQueryQuotaInfo,
  516. (RxContext) );
  517. Irp->IoStatus.Information = RxContext->Info.LengthRemaining;
  518. } else {
  519. Irp->IoStatus.Information = 0;
  520. Status = STATUS_INSUFFICIENT_RESOURCES;
  521. }
  522. return Status;
  523. }
  524. NTSTATUS
  525. RxCommonQueryQuotaInformation (
  526. IN PRX_CONTEXT RxContext,
  527. IN PIRP Irp
  528. )
  529. /*++
  530. Routine Description:
  531. Main entry point for IRP_MJ_QUERY_QUOTA_INFORMATION
  532. Arguments:
  533. RxContext -
  534. Return Value:
  535. Note:
  536. --*/
  537. {
  538. NTSTATUS Status;
  539. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  540. PFCB Fcb;
  541. PFOBX Fobx;
  542. NODE_TYPE_CODE TypeOfOpen;
  543. PAGED_CODE();
  544. RxDbgTrace( +1, Dbg, ("RxCommonQueryQueryQuotaInformation...\n", 0) );
  545. RxDbgTrace( 0, Dbg, (" Wait = %08lx\n", FlagOn( RxContext->Flags, RX_CONTEXT_FLAG_WAIT )));
  546. RxDbgTrace( 0, Dbg, (" Irp = %08lx\n", Irp ));
  547. RxDbgTrace( 0, Dbg, (" ->SystemBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer ));
  548. RxDbgTrace( 0, Dbg, (" ->UserBuffer = %08lx\n", Irp->UserBuffer ));
  549. RxDbgTrace( 0, Dbg, (" ->Length = %08lx\n", IrpSp->Parameters.QueryQuota.Length ));
  550. RxDbgTrace( 0, Dbg, (" ->StartSid = %08lx\n", IrpSp->Parameters.QueryQuota.StartSid ));
  551. RxDbgTrace( 0, Dbg, (" ->SidList = %08lx\n", IrpSp->Parameters.QueryQuota.SidList ));
  552. RxDbgTrace( 0, Dbg, (" ->SidListLength = %08lx\n", IrpSp->Parameters.QueryQuota.SidListLength ));
  553. RxDbgTrace( 0, Dbg, (" ->RestartScan = %08lx\n", FlagOn( IrpSp->Flags, SL_RESTART_SCAN )));
  554. RxDbgTrace( 0, Dbg, (" ->ReturnSingleEntry = %08lx\n", FlagOn( IrpSp->Flags, SL_RETURN_SINGLE_ENTRY )));
  555. RxDbgTrace( 0, Dbg, (" ->IndexSpecified = %08lx\n", FlagOn( IrpSp->Flags, SL_INDEX_SPECIFIED )));
  556. TypeOfOpen = RxDecodeFileObject( IrpSp->FileObject, &Fcb, &Fobx );
  557. if ((TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_FILE) &&
  558. (TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_DIRECTORY)) {
  559. RxDbgTrace( -1, Dbg, ("RxpCommonQueryQuotaInformation -> %08lx\n", STATUS_INVALID_PARAMETER) );
  560. return STATUS_INVALID_PARAMETER;
  561. }
  562. Status = RxpCommonMiscOp( RxContext, Irp, Fcb, RxpCommonQueryQuotaInformation );
  563. return Status;
  564. }
  565. NTSTATUS
  566. RxpCommonSetQuotaInformation (
  567. IN PRX_CONTEXT RxContext,
  568. IN PIRP Irp,
  569. IN PFCB Fcb
  570. )
  571. /*++
  572. Routine Description:
  573. Callback that implements the set quota call
  574. Arguments:
  575. RxContext -
  576. Irp -
  577. Fcb -
  578. Return Value:
  579. Note:
  580. --*/
  581. {
  582. NTSTATUS Status;
  583. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  584. PUCHAR Buffer;
  585. ULONG UserBufferLength;
  586. PAGED_CODE();
  587. UserBufferLength = IrpSp->Parameters.SetQuota.Length;
  588. RxLockUserBuffer( RxContext,
  589. Irp,
  590. IoModifyAccess,
  591. UserBufferLength );
  592. //
  593. // lock before map so that map will get userbuffer instead of assoc buffer
  594. //
  595. Buffer = RxMapUserBuffer( RxContext, Irp );
  596. if ((Buffer != NULL) ||
  597. (UserBufferLength == 0)) {
  598. RxDbgTrace(0, Dbg, ("RxCommonQueryQuota -> Buffer = %08lx\n", Buffer));
  599. RxContext->Info.Buffer = Buffer;
  600. RxContext->Info.LengthRemaining = UserBufferLength;
  601. MINIRDR_CALL( Status,
  602. RxContext,
  603. Fcb->MRxDispatch,
  604. MRxSetQuotaInfo,
  605. (RxContext) );
  606. } else {
  607. Status = STATUS_INSUFFICIENT_RESOURCES;
  608. }
  609. return Status;
  610. }
  611. NTSTATUS
  612. RxCommonSetQuotaInformation (
  613. IN PRX_CONTEXT RxContext,
  614. IN PIRP Irp
  615. )
  616. /*++
  617. Routine Description:
  618. Main entry point for IRP_MJ_SET_QUOTA_INFORMATION
  619. Arguments:
  620. RxContext -
  621. Return Value:
  622. Note:
  623. --*/
  624. {
  625. NTSTATUS Status;
  626. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
  627. PFCB Fcb;
  628. PFOBX Fobx;
  629. NODE_TYPE_CODE TypeOfOpen;
  630. PAGED_CODE();
  631. RxDbgTrace( +1, Dbg, ("RxCommonSetQuotaInformation...\n", 0) );
  632. RxDbgTrace( 0, Dbg, (" Wait = %08lx\n", FlagOn( RxContext->Flags, RX_CONTEXT_FLAG_WAIT )));
  633. RxDbgTrace( 0, Dbg, (" Irp = %08lx\n", Irp ));
  634. TypeOfOpen = RxDecodeFileObject( IrpSp->FileObject, &Fcb, &Fobx );
  635. if ((TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_FILE) &&
  636. (TypeOfOpen != RDBSS_NTC_STORAGE_TYPE_DIRECTORY)) {
  637. RxDbgTrace( -1, Dbg, ("RxpCommonSetQuotaInformation -> %08lx\n", STATUS_INVALID_PARAMETER) );
  638. return STATUS_INVALID_PARAMETER;
  639. }
  640. Status = RxpCommonMiscOp( RxContext, Irp, Fcb, RxpCommonSetQuotaInformation );
  641. return Status;
  642. }
  643.