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.

1129 lines
23 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. fileinfo.c
  5. Abstract:
  6. This module implements the get / set file information routines for
  7. MSFS called by the dispatch driver.
  8. Author:
  9. Manny Weiser (mannyw) 31-Jan-1991
  10. Revision History:
  11. --*/
  12. #include "mailslot.h"
  13. //
  14. // The debug trace level
  15. //
  16. #define Dbg (DEBUG_TRACE_FILEINFO)
  17. //
  18. // local procedure prototypes
  19. //
  20. NTSTATUS
  21. MsCommonQueryInformation (
  22. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  23. IN PIRP Irp
  24. );
  25. NTSTATUS
  26. MsCommonSetInformation (
  27. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  28. IN PIRP Irp
  29. );
  30. VOID
  31. MsQueryBasicInfo (
  32. IN PFCB Fcb,
  33. IN PFILE_BASIC_INFORMATION Buffer
  34. );
  35. VOID
  36. MsQueryStandardInfo (
  37. IN PFCB Fcb,
  38. IN PFILE_STANDARD_INFORMATION Buffer
  39. );
  40. VOID
  41. MsQueryInternalInfo (
  42. IN PFCB Fcb,
  43. IN PFILE_INTERNAL_INFORMATION Buffer
  44. );
  45. VOID
  46. MsQueryEaInfo (
  47. IN PFILE_EA_INFORMATION Buffer
  48. );
  49. NTSTATUS
  50. MsQueryNameInfo (
  51. IN PFCB Fcb,
  52. IN PFILE_NAME_INFORMATION Buffer,
  53. IN OUT PULONG Length
  54. );
  55. VOID
  56. MsQueryPositionInfo (
  57. IN PFCB Fcb,
  58. IN PFILE_POSITION_INFORMATION Buffer
  59. );
  60. VOID
  61. MsQueryMailslotInfo (
  62. IN PFCB Fcb,
  63. IN PFILE_MAILSLOT_QUERY_INFORMATION Buffer
  64. );
  65. NTSTATUS
  66. MsSetBasicInfo (
  67. IN PFCB Fcb,
  68. IN PFILE_BASIC_INFORMATION Buffer
  69. );
  70. NTSTATUS
  71. MsSetMailslotInfo (
  72. IN PIRP Irp,
  73. IN PFCB Fcb,
  74. IN PFILE_MAILSLOT_SET_INFORMATION Buffer
  75. );
  76. #ifdef ALLOC_PRAGMA
  77. #pragma alloc_text( PAGE, MsCommonQueryInformation )
  78. #pragma alloc_text( PAGE, MsCommonSetInformation )
  79. #pragma alloc_text( PAGE, MsFsdQueryInformation )
  80. #pragma alloc_text( PAGE, MsFsdSetInformation )
  81. #pragma alloc_text( PAGE, MsQueryBasicInfo )
  82. #pragma alloc_text( PAGE, MsQueryEaInfo )
  83. #pragma alloc_text( PAGE, MsQueryInternalInfo )
  84. #pragma alloc_text( PAGE, MsQueryMailslotInfo )
  85. #pragma alloc_text( PAGE, MsQueryNameInfo )
  86. #pragma alloc_text( PAGE, MsQueryPositionInfo )
  87. #pragma alloc_text( PAGE, MsQueryStandardInfo )
  88. #pragma alloc_text( PAGE, MsSetBasicInfo )
  89. #pragma alloc_text( PAGE, MsSetMailslotInfo )
  90. #endif
  91. NTSTATUS
  92. MsFsdQueryInformation (
  93. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  94. IN PIRP Irp
  95. )
  96. /*++
  97. Routine Description:
  98. This routine implements the FSD part of the NtQueryInformationFile API
  99. calls.
  100. Arguments:
  101. MsfsDeviceObject - Supplies a pointer to the device object to use.
  102. Irp - Supplies a pointer to the Irp to process.
  103. Return Value:
  104. NTSTATUS - The Fsd status for the Irp
  105. --*/
  106. {
  107. NTSTATUS status;
  108. PAGED_CODE();
  109. DebugTrace(+1, Dbg, "MsFsdQueryInformation\n", 0);
  110. //
  111. // Call the common query information routine.
  112. //
  113. FsRtlEnterFileSystem();
  114. status = MsCommonQueryInformation( MsfsDeviceObject, Irp );
  115. FsRtlExitFileSystem();
  116. //
  117. // Return to the caller.
  118. //
  119. DebugTrace(-1, Dbg, "MsFsdQueryInformation -> %08lx\n", status );
  120. return status;
  121. }
  122. NTSTATUS
  123. MsFsdSetInformation (
  124. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  125. IN PIRP Irp
  126. )
  127. /*++
  128. Routine Description:
  129. This routine implements the FSD part of the NtSetInformationFile API
  130. calls.
  131. Arguments:
  132. MsfsDeviceObject - Supplies the device object to use.
  133. Irp - Supplies the Irp being processed
  134. Return Value:
  135. NTSTATUS - The Fsd status for the Irp
  136. --*/
  137. {
  138. NTSTATUS status;
  139. PAGED_CODE();
  140. DebugTrace(+1, Dbg, "MsFsdSetInformation\n", 0);
  141. //
  142. // Call the common Set Information routine.
  143. //
  144. FsRtlEnterFileSystem();
  145. status = MsCommonSetInformation( MsfsDeviceObject, Irp );
  146. FsRtlExitFileSystem();
  147. //
  148. // Return to the caller.
  149. //
  150. DebugTrace(-1, Dbg, "MsFsdSetInformation -> %08lx\n", status );
  151. return status;
  152. }
  153. NTSTATUS
  154. MsCommonQueryInformation (
  155. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  156. IN PIRP Irp
  157. )
  158. /*++
  159. Routine Description:
  160. This is the common routine for querying information on a file.
  161. Arguments:
  162. MsfsDeviceObject - The device object to use.
  163. Irp - Supplies the Irp to process
  164. Return Value:
  165. NTSTATUS - the return status for the operation.
  166. --*/
  167. {
  168. PIO_STACK_LOCATION irpSp;
  169. NTSTATUS status;
  170. ULONG length;
  171. FILE_INFORMATION_CLASS fileInformationClass;
  172. PVOID buffer;
  173. NODE_TYPE_CODE nodeTypeCode;
  174. PFCB fcb;
  175. PVOID fsContext, fsContext2;
  176. PFILE_ALL_INFORMATION AllInfo;
  177. PAGED_CODE();
  178. //
  179. // Get the current stack location.
  180. //
  181. irpSp = IoGetCurrentIrpStackLocation( Irp );
  182. DebugTrace(+1, Dbg, "MsCommonQueryInformation...\n", 0);
  183. DebugTrace( 0, Dbg, " Irp = %08lx\n", (ULONG)Irp);
  184. DebugTrace( 0, Dbg, " ->Length = %08lx\n", irpSp->Parameters.QueryFile.Length);
  185. DebugTrace( 0, Dbg, " ->FileInformationClass = %08lx\n", irpSp->Parameters.QueryFile.FileInformationClass);
  186. DebugTrace( 0, Dbg, " ->Buffer = %08lx\n", (ULONG)Irp->AssociatedIrp.SystemBuffer);
  187. //
  188. // Find out who are.
  189. //
  190. if ((nodeTypeCode = MsDecodeFileObject( irpSp->FileObject,
  191. &fsContext,
  192. &fsContext2 )) == NTC_UNDEFINED) {
  193. DebugTrace(0, Dbg, "Mailslot is disconnected from us\n", 0);
  194. MsCompleteRequest( Irp, STATUS_FILE_FORCED_CLOSED );
  195. status = STATUS_FILE_FORCED_CLOSED;
  196. DebugTrace(-1, Dbg, "MsCommonQueryInformation -> %08lx\n", status );
  197. return status;
  198. }
  199. //
  200. // Decide how to handle this request. A user can query information
  201. // on a DCB, ROOT_DCB, FCB, or CCB only.
  202. //
  203. switch (nodeTypeCode) {
  204. case MSFS_NTC_FCB: // This is a server side handle to a mailslot file
  205. case MSFS_NTC_ROOT_DCB: // This is the MSFS root directory
  206. fcb = (PFCB)fsContext;
  207. break;
  208. default: // This is an illegal file object to query
  209. DebugTrace(0, Dbg, "Node type code is not incorrect\n", 0);
  210. MsDereferenceNode( (PNODE_HEADER)fsContext );
  211. MsCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
  212. DebugTrace(-1, Dbg, "MsCommonQueryInformation -> STATUS_INVALID_PARAMETER\n", 0);
  213. return STATUS_INVALID_PARAMETER;
  214. }
  215. //
  216. // Make local copies of the input parameters.
  217. //
  218. length = irpSp->Parameters.QueryFile.Length;
  219. fileInformationClass = irpSp->Parameters.QueryFile.FileInformationClass;
  220. buffer = Irp->AssociatedIrp.SystemBuffer;
  221. //
  222. // Now acquire shared access to the FCB
  223. //
  224. MsAcquireSharedFcb( fcb );
  225. try {
  226. //
  227. // Based on the information class we'll do different actions. Each
  228. // of the procedure that we're calling fill up as much of the
  229. // buffer as possible and return the remaining length, and status
  230. // This is done so that we can use them to build up the
  231. // FileAllInformation request. These procedures do not complete the
  232. // IRP, instead this procedure must complete the IRP.
  233. //
  234. status = STATUS_SUCCESS;
  235. switch (fileInformationClass) {
  236. case FileAllInformation:
  237. AllInfo = buffer;
  238. MsQueryBasicInfo( fcb, &AllInfo->BasicInformation );
  239. MsQueryStandardInfo( fcb, &AllInfo->StandardInformation );
  240. MsQueryInternalInfo( fcb, &AllInfo->InternalInformation );
  241. MsQueryEaInfo( &AllInfo->EaInformation );
  242. MsQueryPositionInfo( fcb, &AllInfo->PositionInformation );
  243. length -= FIELD_OFFSET( FILE_ALL_INFORMATION, NameInformation );
  244. status = MsQueryNameInfo( fcb, &AllInfo->NameInformation, &length );
  245. break;
  246. case FileBasicInformation:
  247. MsQueryBasicInfo( fcb, buffer );
  248. length -= sizeof( FILE_BASIC_INFORMATION );
  249. break;
  250. case FileStandardInformation:
  251. MsQueryStandardInfo( fcb, buffer );
  252. length -= sizeof( FILE_STANDARD_INFORMATION );
  253. break;
  254. case FileInternalInformation:
  255. MsQueryInternalInfo( fcb, buffer );
  256. length -= sizeof( FILE_INTERNAL_INFORMATION );
  257. break;
  258. case FileEaInformation:
  259. MsQueryEaInfo( buffer );
  260. length -= sizeof( FILE_EA_INFORMATION );
  261. break;
  262. case FilePositionInformation:
  263. MsQueryPositionInfo( fcb, buffer );
  264. length -= sizeof( FILE_POSITION_INFORMATION );
  265. break;
  266. case FileNameInformation:
  267. status = MsQueryNameInfo( fcb, buffer, &length );
  268. break;
  269. case FileMailslotQueryInformation:
  270. if( nodeTypeCode == MSFS_NTC_FCB ) {
  271. MsQueryMailslotInfo( fcb, buffer );
  272. length -= sizeof( FILE_MAILSLOT_QUERY_INFORMATION );
  273. } else {
  274. status = STATUS_INVALID_PARAMETER;
  275. }
  276. break;
  277. default:
  278. status = STATUS_INVALID_PARAMETER;
  279. break;
  280. }
  281. } finally {
  282. MsReleaseFcb( fcb );
  283. MsDereferenceFcb( fcb );
  284. //
  285. // Set the information field to the number of bytes actually
  286. // filled in and then complete the request.
  287. //
  288. Irp->IoStatus.Information =
  289. irpSp->Parameters.QueryFile.Length - length;
  290. MsCompleteRequest( Irp, status );
  291. DebugTrace(-1, Dbg, "MsCommonQueryInformation -> %08lx\n", status );
  292. }
  293. return status;
  294. }
  295. NTSTATUS
  296. MsCommonSetInformation (
  297. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  298. IN PIRP Irp
  299. )
  300. /*++
  301. Routine Description:
  302. This is the common routine for setting information on a mailslot file.
  303. Arguments:
  304. Irp - Supplies the Irp to process
  305. Return Value:
  306. NTSTATUS - the return status for the operation
  307. --*/
  308. {
  309. PIO_STACK_LOCATION irpSp;
  310. NTSTATUS status;
  311. ULONG length;
  312. FILE_INFORMATION_CLASS fileInformationClass;
  313. PVOID buffer;
  314. NODE_TYPE_CODE nodeTypeCode;
  315. PFCB fcb;
  316. PVOID fsContext2;
  317. PAGED_CODE();
  318. //
  319. // Get the current Irp stack location.
  320. //
  321. irpSp = IoGetCurrentIrpStackLocation( Irp );
  322. DebugTrace(+1, Dbg, "MsCommonSetInformation...\n", 0);
  323. DebugTrace( 0, Dbg, " Irp = %08lx\n", (ULONG)Irp);
  324. DebugTrace( 0, Dbg, " ->Length = %08lx\n", irpSp->Parameters.SetFile.Length);
  325. DebugTrace( 0, Dbg, " ->FileInformationClass = %08lx\n", irpSp->Parameters.SetFile.FileInformationClass);
  326. DebugTrace( 0, Dbg, " ->Buffer = %08lx\n", (ULONG)Irp->AssociatedIrp.SystemBuffer);
  327. //
  328. // Get a pointer to the FCB and ensure that this is a server side
  329. // handler to a mailslot file.
  330. //
  331. if ((nodeTypeCode = MsDecodeFileObject( irpSp->FileObject,
  332. (PVOID *)&fcb,
  333. &fsContext2 )) == NTC_UNDEFINED) {
  334. DebugTrace(0, Dbg, "The mailslot is disconnected from us\n", 0);
  335. MsCompleteRequest( Irp, STATUS_FILE_FORCED_CLOSED );
  336. status = STATUS_FILE_FORCED_CLOSED;
  337. DebugTrace(-1, Dbg, "MsCommonSetInformation -> %08lx\n", status );
  338. return status;
  339. }
  340. //
  341. // Case on the type of the context, We can only set information
  342. // on an FCB.
  343. //
  344. if (nodeTypeCode != MSFS_NTC_FCB) {
  345. MsDereferenceNode( &fcb->Header );
  346. MsCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
  347. DebugTrace(-1, Dbg, "MsCommonQueryInformation -> STATUS_INVALID_PARAMETER\n", 0);
  348. return STATUS_INVALID_PARAMETER;
  349. }
  350. //
  351. // Make local copies of the input parameters.
  352. //
  353. length = irpSp->Parameters.SetFile.Length;
  354. fileInformationClass = irpSp->Parameters.SetFile.FileInformationClass;
  355. buffer = Irp->AssociatedIrp.SystemBuffer;
  356. //
  357. // Acquire exclusive access to the FCB.
  358. //
  359. MsAcquireExclusiveFcb( fcb );
  360. try {
  361. //
  362. // Based on the information class we'll do different actions. Each
  363. // procedure that we're calling will complete the request.
  364. //
  365. switch (fileInformationClass) {
  366. case FileBasicInformation:
  367. status = MsSetBasicInfo( fcb, buffer );
  368. break;
  369. case FileMailslotSetInformation:
  370. status = MsSetMailslotInfo( Irp, fcb, buffer );
  371. break;
  372. default:
  373. status = STATUS_INVALID_PARAMETER;
  374. break;
  375. }
  376. //
  377. // Directory information has changed. Complete any notify change
  378. // directory requests.
  379. //
  380. MsCheckForNotify( fcb->ParentDcb, FALSE, STATUS_SUCCESS );
  381. } finally {
  382. MsReleaseFcb( fcb );
  383. MsDereferenceFcb( fcb );
  384. //
  385. // Complete the request.
  386. //
  387. MsCompleteRequest( Irp, status );
  388. DebugTrace(-1, Dbg, "MsCommonSetInformation -> %08lx\n", status);
  389. }
  390. return status;
  391. }
  392. VOID
  393. MsQueryBasicInfo (
  394. IN PFCB Fcb,
  395. IN PFILE_BASIC_INFORMATION Buffer
  396. )
  397. /*++
  398. Routine Description:
  399. This routine performs the query basic information operation.
  400. Arguments:
  401. Fcb - Supplies a pointer the FCB of mailslot being queried.
  402. Buffer - Supplies a pointer to the buffer where the information is
  403. to be returned.
  404. Return Value:
  405. VOID
  406. --*/
  407. {
  408. PAGED_CODE();
  409. DebugTrace(0, Dbg, "QueryBasicInfo...\n", 0);
  410. //
  411. // Zero out the buffer.
  412. //
  413. RtlZeroMemory( Buffer, sizeof(FILE_BASIC_INFORMATION) );
  414. //
  415. // Set the various fields in the record. These times are not maintained for the root DCB0
  416. //
  417. if( Fcb->Header.NodeTypeCode == MSFS_NTC_FCB ) {
  418. Buffer->CreationTime = Fcb->Specific.Fcb.CreationTime;
  419. Buffer->LastAccessTime = Fcb->Specific.Fcb.LastAccessTime;
  420. Buffer->LastWriteTime = Fcb->Specific.Fcb.LastModificationTime;
  421. Buffer->ChangeTime = Fcb->Specific.Fcb.LastChangeTime;
  422. }
  423. Buffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
  424. return;
  425. }
  426. VOID
  427. MsQueryStandardInfo (
  428. IN PFCB Fcb,
  429. IN PFILE_STANDARD_INFORMATION Buffer
  430. )
  431. /*++
  432. Routine Description:
  433. This routine performs the query standard information operation.
  434. Arguments:
  435. Fcb - Supplies the FCB of the mailslot being queried
  436. Buffer - Supplies a pointer to the buffer where the information is
  437. to be returned
  438. Return Value:
  439. VOID
  440. --*/
  441. {
  442. PDATA_QUEUE dataQueue;
  443. PAGED_CODE();
  444. DebugTrace(0, Dbg, "MsQueryStandardInfo...\n", 0);
  445. //
  446. // Zero out the buffer.
  447. //
  448. RtlZeroMemory( Buffer, sizeof(FILE_STANDARD_INFORMATION) );
  449. //
  450. // The allocation size is the amount of quota we've charged the mailslot
  451. // creator.
  452. //
  453. if( Fcb->Header.NodeTypeCode == MSFS_NTC_FCB ) {
  454. dataQueue = &Fcb->DataQueue;
  455. Buffer->AllocationSize.QuadPart = dataQueue->Quota;
  456. //
  457. // The EOF is the number of written bytes ready to be read from the
  458. // mailslot.
  459. //
  460. Buffer->EndOfFile.QuadPart = dataQueue->BytesInQueue;
  461. Buffer->Directory = FALSE;
  462. } else {
  463. Buffer->Directory = TRUE;
  464. }
  465. Buffer->NumberOfLinks = 1;
  466. Buffer->DeletePending = TRUE;
  467. return;
  468. }
  469. VOID
  470. MsQueryInternalInfo (
  471. IN PFCB Fcb,
  472. IN PFILE_INTERNAL_INFORMATION Buffer
  473. )
  474. /*++
  475. Routine Description:
  476. This routine performs the query internal information operation.
  477. Arguments:
  478. Fcb - Supplies the FCB of the mailslot being queried.
  479. Buffer - Supplies a pointer to the buffer where the information is
  480. to be returned.
  481. Return Value:
  482. VOID
  483. --*/
  484. {
  485. PAGED_CODE();
  486. DebugTrace(0, Dbg, "QueryInternalInfo...\n", 0);
  487. //
  488. // Zero out the buffer.
  489. //
  490. RtlZeroMemory( Buffer, sizeof(FILE_INTERNAL_INFORMATION) );
  491. //
  492. // Set the internal index number to be the address of the FCB.
  493. //
  494. Buffer->IndexNumber.QuadPart = (ULONG_PTR)Fcb;
  495. return;
  496. }
  497. VOID
  498. MsQueryEaInfo (
  499. IN PFILE_EA_INFORMATION Buffer
  500. )
  501. /*++
  502. Routine Description:
  503. This routine performs the query Ea information operation.
  504. Arguments:
  505. Buffer - Supplies a pointer to the buffer where the information is
  506. to be returned
  507. Return Value:
  508. VOID - The result of this query
  509. --*/
  510. {
  511. PAGED_CODE();
  512. DebugTrace(0, Dbg, "QueryEaInfo...\n", 0);
  513. //
  514. // Zero out the buffer.
  515. //
  516. RtlZeroMemory(Buffer, sizeof(FILE_EA_INFORMATION));
  517. return;
  518. }
  519. NTSTATUS
  520. MsQueryNameInfo (
  521. IN PFCB Fcb,
  522. IN PFILE_NAME_INFORMATION Buffer,
  523. IN PULONG Length
  524. )
  525. /*++
  526. Routine Description:
  527. This routine performs the query name information operation.
  528. Arguments:
  529. Fcb - Supplies the FCB of the mailslot to query.
  530. Buffer - Supplies a pointer to the buffer where the information is
  531. to be returned
  532. Length - Supplies and receives the length of the buffer in bytes.
  533. Return Value:
  534. NTSTATUS - The result of this query.
  535. --*/
  536. {
  537. ULONG bytesToCopy;
  538. ULONG fileNameSize;
  539. NTSTATUS status;
  540. PAGED_CODE();
  541. DebugTrace(0, Dbg, "QueryNameInfo...\n", 0);
  542. //
  543. // See if the buffer is large enough, and decide how many bytes to copy.
  544. //
  545. *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName[0] );
  546. fileNameSize = Fcb->FullFileName.Length;
  547. if ( *Length >= fileNameSize ) {
  548. status = STATUS_SUCCESS;
  549. bytesToCopy = fileNameSize;
  550. } else {
  551. status = STATUS_BUFFER_OVERFLOW;
  552. bytesToCopy = *Length;
  553. }
  554. //
  555. // Copy over the file name and its length.
  556. //
  557. RtlCopyMemory (Buffer->FileName,
  558. Fcb->FullFileName.Buffer,
  559. bytesToCopy);
  560. Buffer->FileNameLength = bytesToCopy;
  561. *Length -= bytesToCopy;
  562. return status;
  563. }
  564. VOID
  565. MsQueryPositionInfo (
  566. IN PFCB Fcb,
  567. IN PFILE_POSITION_INFORMATION Buffer
  568. )
  569. /*++
  570. Routine Description:
  571. This routine performs the query position information operation.
  572. Arguments:
  573. Fcb - Supplies the FCB of the mailslot being queried.
  574. Buffer - Supplies a pointer to the buffer where the information is
  575. to be returned.
  576. Return Value:
  577. VOID
  578. --*/
  579. {
  580. PDATA_QUEUE dataQueue;
  581. PAGED_CODE();
  582. DebugTrace(0, Dbg, "QueryPositionInfo...\n", 0);
  583. //
  584. // The current byte offset is the number of bytes available to read
  585. // in the mailslot buffer.
  586. //
  587. if( Fcb->Header.NodeTypeCode == MSFS_NTC_FCB ) {
  588. dataQueue = &Fcb->DataQueue;
  589. Buffer->CurrentByteOffset.QuadPart = dataQueue->BytesInQueue;
  590. } else {
  591. Buffer->CurrentByteOffset.QuadPart = 0;
  592. }
  593. return;
  594. }
  595. VOID
  596. MsQueryMailslotInfo (
  597. IN PFCB Fcb,
  598. IN PFILE_MAILSLOT_QUERY_INFORMATION Buffer
  599. )
  600. /*++
  601. Routine Description:
  602. This routine performs the query mailslot information operation.
  603. Arguments:
  604. Fcb - Supplies the Fcb of the mailslot to query.
  605. Buffer - Supplies a pointer to the buffer where the information is
  606. to be returned.
  607. Return Value:
  608. VOID
  609. --*/
  610. {
  611. PDATA_QUEUE dataQueue;
  612. PDATA_ENTRY dataEntry;
  613. PAGED_CODE();
  614. DebugTrace(0, Dbg, "QueryMailslotInfo...\n", 0);
  615. //
  616. // Set the fields in the record.
  617. //
  618. dataQueue = &Fcb->DataQueue;
  619. Buffer->MaximumMessageSize = dataQueue->MaximumMessageSize;
  620. Buffer->MailslotQuota = dataQueue->Quota;
  621. Buffer->MessagesAvailable = dataQueue->EntriesInQueue;
  622. Buffer->ReadTimeout = Fcb->Specific.Fcb.ReadTimeout;
  623. if ( dataQueue->EntriesInQueue == 0 ) {
  624. Buffer->NextMessageSize = MAILSLOT_NO_MESSAGE;
  625. } else {
  626. dataEntry = CONTAINING_RECORD( dataQueue->DataEntryList.Flink,
  627. DATA_ENTRY,
  628. ListEntry );
  629. Buffer->NextMessageSize = dataEntry->DataSize;
  630. }
  631. return;
  632. }
  633. NTSTATUS
  634. MsSetBasicInfo (
  635. IN PFCB Fcb,
  636. IN PFILE_BASIC_INFORMATION Buffer
  637. )
  638. /*++
  639. Routine Description:
  640. This routine sets the basic information for a mailslot.
  641. Arguments:
  642. Fcb - Supplies the FCB for the mailslot being modified.
  643. Buffer - Supplies the buffer containing the data being set.
  644. Return Value:
  645. NTSTATUS - Returns our completion status.
  646. --*/
  647. {
  648. PAGED_CODE();
  649. DebugTrace(0, Dbg, "SetBasicInfo...\n", 0);
  650. if (((PLARGE_INTEGER)&Buffer->CreationTime)->QuadPart != 0) {
  651. //
  652. // Modify the creation time
  653. //
  654. Fcb->Specific.Fcb.CreationTime = Buffer->CreationTime;
  655. }
  656. if (((PLARGE_INTEGER)&Buffer->LastAccessTime)->QuadPart != 0) {
  657. //
  658. // Modify the last access time
  659. //
  660. Fcb->Specific.Fcb.LastAccessTime = Buffer->LastAccessTime;
  661. }
  662. if (((PLARGE_INTEGER)&Buffer->LastWriteTime)->QuadPart != 0) {
  663. //
  664. // Modify the last write time
  665. //
  666. Fcb->Specific.Fcb.LastModificationTime = Buffer->LastWriteTime;
  667. }
  668. if (((PLARGE_INTEGER)&Buffer->ChangeTime)->QuadPart != 0) {
  669. //
  670. // Modify the change time
  671. //
  672. Fcb->Specific.Fcb.LastChangeTime = Buffer->ChangeTime;
  673. }
  674. //
  675. // And return to our caller
  676. //
  677. return STATUS_SUCCESS;
  678. }
  679. NTSTATUS
  680. MsSetMailslotInfo (
  681. IN PIRP Irp,
  682. IN PFCB Fcb,
  683. IN PFILE_MAILSLOT_SET_INFORMATION Buffer
  684. )
  685. /*++
  686. Routine Description:
  687. This routine sets the mailslot information for a mailslot.
  688. Arguments:
  689. Irp - Pointer to an irp that contains the requestor's mode.
  690. Fcb - Supplies the FCB for the mailslot being modified.
  691. Buffer - Supplies the buffer containing the data being set.
  692. Return Value:
  693. NTSTATUS - Returns our completion status.
  694. --*/
  695. {
  696. BOOLEAN fileUpdated;
  697. PAGED_CODE();
  698. DebugTrace(0, Dbg, "SetMaislotInfo...\n", 0);
  699. fileUpdated = FALSE;
  700. //
  701. // Check whether or not the DefaultTimeout parameter was specified. If
  702. // so, then set it in the FCB.
  703. //
  704. if (ARGUMENT_PRESENT( Buffer->ReadTimeout )) {
  705. //
  706. // A read timeout parameter was specified. Check to see whether
  707. // the caller's mode is kernel and if not capture the parameter inside
  708. // of a try...except clause.
  709. //
  710. if (Irp->RequestorMode != KernelMode) {
  711. try {
  712. ProbeForRead( Buffer->ReadTimeout,
  713. sizeof( LARGE_INTEGER ),
  714. sizeof( ULONG ) );
  715. Fcb->Specific.Fcb.ReadTimeout = *(Buffer->ReadTimeout);
  716. } except(EXCEPTION_EXECUTE_HANDLER) {
  717. //
  718. // Something went awry attempting to access the parameter.
  719. // Get the reason for the error and return it as the status
  720. // value from this service.
  721. //
  722. return GetExceptionCode();
  723. }
  724. } else {
  725. //
  726. // The caller's mode was kernel so simply store the parameter.
  727. //
  728. Fcb->Specific.Fcb.ReadTimeout = *(Buffer->ReadTimeout);
  729. }
  730. fileUpdated = TRUE;
  731. }
  732. //
  733. // Update the last change time, if necessary
  734. //
  735. if ( fileUpdated ) {
  736. KeQuerySystemTime( &Fcb->Specific.Fcb.LastChangeTime);
  737. }
  738. //
  739. // And return to our caller
  740. //
  741. return STATUS_SUCCESS;
  742. }