2 * PROJECT: ReactOS Named Pipe FileSystem
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/filesystems/npfs/fileinfo.c
5 * PURPOSE: Pipes Information
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
13 // File ID number for NPFS bugchecking support
14 #define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_FILEINFO)
16 /* FUNCTIONS ******************************************************************/
20 NpSetBasicInfo(IN PNP_CCB Ccb
,
21 IN PFILE_BASIC_INFORMATION Buffer
)
24 return STATUS_SUCCESS
;
29 NpSetPipeInfo(IN PNP_FCB Fcb
,
31 IN PFILE_PIPE_INFORMATION Buffer
,
32 IN ULONG NamedPipeEnd
,
36 PNP_DATA_QUEUE ReadQueue
, WriteQueue
;
39 if (Buffer
->ReadMode
== FILE_PIPE_MESSAGE_MODE
&& Fcb
->NamedPipeType
== FILE_PIPE_BYTE_STREAM_TYPE
)
41 return STATUS_INVALID_PARAMETER
;
44 if (NamedPipeEnd
!= FILE_PIPE_CLIENT_END
)
46 if (NamedPipeEnd
!= FILE_PIPE_SERVER_END
)
48 NpBugCheck(NamedPipeEnd
, 0, 0);
50 ReadQueue
= &Ccb
->DataQueue
[FILE_PIPE_INBOUND
];
51 WriteQueue
= &Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
];
55 ReadQueue
= &Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
];
56 WriteQueue
= &Ccb
->DataQueue
[FILE_PIPE_INBOUND
];
59 if (Buffer
->CompletionMode
!= FILE_PIPE_COMPLETE_OPERATION
||
60 Ccb
->CompletionMode
[NamedPipeEnd
] == FILE_PIPE_COMPLETE_OPERATION
||
61 (ReadQueue
->QueueState
== ReadEntries
&&
62 WriteQueue
->QueueState
!= WriteEntries
))
64 Ccb
->ReadMode
[NamedPipeEnd
] = Buffer
->ReadMode
& 0xFF;
65 Ccb
->CompletionMode
[NamedPipeEnd
] = Buffer
->CompletionMode
& 0xFF;
67 NpCheckForNotify(Fcb
->ParentDcb
, FALSE
, List
);
68 Status
= STATUS_SUCCESS
;
72 Status
= STATUS_PIPE_BUSY
;
80 NpCommonSetInformation(IN PDEVICE_OBJECT DeviceObject
,
84 NODE_TYPE_CODE NodeTypeCode
;
85 PIO_STACK_LOCATION IoStack
;
93 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
95 NodeTypeCode
= NpDecodeFileObject(IoStack
->FileObject
,
99 if (!NodeTypeCode
) return STATUS_PIPE_DISCONNECTED
;
100 if (NodeTypeCode
!= NPFS_NTC_CCB
) return STATUS_INVALID_PARAMETER
;
102 InfoClass
= IoStack
->Parameters
.QueryFile
.FileInformationClass
;
103 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
105 if (InfoClass
== FileBasicInformation
) return NpSetBasicInfo(Ccb
, Buffer
);
107 if (InfoClass
!= FilePipeInformation
) return STATUS_INVALID_PARAMETER
;
109 return NpSetPipeInfo(Fcb
, Ccb
, Buffer
, NamedPipeEnd
, List
);
114 NpFsdSetInformation(IN PDEVICE_OBJECT DeviceObject
,
118 LIST_ENTRY DeferredList
;
121 InitializeListHead(&DeferredList
);
123 FsRtlEnterFileSystem();
124 NpAcquireExclusiveVcb();
126 Status
= NpCommonSetInformation(DeviceObject
, Irp
, &DeferredList
);
129 NpCompleteDeferredIrps(&DeferredList
);
130 FsRtlExitFileSystem();
132 if (Status
!= STATUS_PENDING
)
134 Irp
->IoStatus
.Status
= Status
;
135 IoCompleteRequest(Irp
, IO_NAMED_PIPE_INCREMENT
);
143 NpQueryBasicInfo(IN PNP_CCB Ccb
,
145 IN OUT PULONG Length
)
147 PFILE_BASIC_INFORMATION InfoBuffer
= Buffer
;
149 *Length
-= sizeof(*InfoBuffer
);
151 RtlZeroMemory(InfoBuffer
, sizeof(*InfoBuffer
));
152 InfoBuffer
->FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
154 return STATUS_SUCCESS
;
159 NpQueryStandardInfo(IN PNP_CCB Ccb
,
161 IN OUT PULONG Length
,
162 IN ULONG NamedPipeEnd
)
164 PNP_DATA_QUEUE DataQueue
;
165 PFILE_STANDARD_INFORMATION InfoBuffer
= Buffer
;
167 *Length
-= sizeof(*InfoBuffer
);
169 RtlZeroMemory(InfoBuffer
, sizeof(*InfoBuffer
));
171 if (NamedPipeEnd
== FILE_PIPE_SERVER_END
)
173 DataQueue
= &Ccb
->DataQueue
[FILE_PIPE_INBOUND
];
177 DataQueue
= &Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
];
180 InfoBuffer
->AllocationSize
.LowPart
= Ccb
->DataQueue
[FILE_PIPE_INBOUND
].Quota
+
181 Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
].Quota
;
182 InfoBuffer
->AllocationSize
.HighPart
= 0;
184 if (DataQueue
->QueueState
== WriteEntries
)
186 InfoBuffer
->EndOfFile
.HighPart
= 0;
187 InfoBuffer
->EndOfFile
.LowPart
= DataQueue
->BytesInQueue
-
188 DataQueue
->ByteOffset
;
191 InfoBuffer
->Directory
= FALSE
;
192 InfoBuffer
->NumberOfLinks
= 1;
193 InfoBuffer
->DeletePending
= TRUE
;
195 return STATUS_SUCCESS
;
200 NpQueryEaInfo(IN PNP_CCB Ccb
,
202 IN OUT PULONG Length
)
204 PFILE_EA_INFORMATION InfoBuffer
= Buffer
;
206 *Length
-= sizeof(*InfoBuffer
);
208 RtlZeroMemory(InfoBuffer
, sizeof(*InfoBuffer
));
210 return STATUS_SUCCESS
;
215 NpQueryNameInfo(IN PNP_CCB Ccb
,
217 IN OUT PULONG Length
)
219 PFILE_NAME_INFORMATION InfoBuffer
= Buffer
;
224 *Length
-= sizeof(*InfoBuffer
);
226 if (Ccb
->NodeType
== NPFS_NTC_ROOT_DCB_CCB
)
228 NameLength
= NpVcb
->RootDcb
->FullName
.Length
;
229 Name
= NpVcb
->RootDcb
->FullName
.Buffer
;
233 NameLength
= Ccb
->Fcb
->FullName
.Length
;
234 Name
= Ccb
->Fcb
->FullName
.Buffer
;
237 if (*Length
< NameLength
)
239 Status
= STATUS_BUFFER_OVERFLOW
;
240 NameLength
= (USHORT
)*Length
;
244 Status
= STATUS_SUCCESS
;
247 RtlCopyMemory(InfoBuffer
->FileName
, Name
, NameLength
);
248 InfoBuffer
->FileNameLength
= NameLength
;
250 *Length
-= NameLength
;
256 NpQueryInternalInfo(IN PNP_CCB Ccb
,
258 IN OUT PULONG Length
)
260 PFILE_INTERNAL_INFORMATION InfoBuffer
= Buffer
;
262 *Length
-= sizeof(*InfoBuffer
);
264 RtlZeroMemory(InfoBuffer
, sizeof(*InfoBuffer
));
266 return STATUS_SUCCESS
;
271 NpQueryPositionInfo(IN PNP_CCB Ccb
,
273 IN OUT PULONG Length
,
274 IN ULONG NamedPipeEnd
)
276 PNP_DATA_QUEUE DataQueue
;
277 PFILE_POSITION_INFORMATION InfoBuffer
= Buffer
;
279 *Length
-= sizeof(*InfoBuffer
);
281 RtlZeroMemory(InfoBuffer
, sizeof(*InfoBuffer
));
283 if (NamedPipeEnd
== FILE_PIPE_SERVER_END
)
285 DataQueue
= &Ccb
->DataQueue
[FILE_PIPE_INBOUND
];
289 DataQueue
= &Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
];
292 if (DataQueue
->QueueState
== WriteEntries
)
294 InfoBuffer
->CurrentByteOffset
.QuadPart
= DataQueue
->BytesInQueue
-
295 DataQueue
->ByteOffset
;
298 return STATUS_SUCCESS
;
303 NpQueryPipeLocalInfo(IN PNP_FCB Fcb
,
306 IN OUT PULONG Length
,
307 IN ULONG NamedPipeEnd
)
309 PFILE_PIPE_LOCAL_INFORMATION InfoBuffer
= Buffer
;
310 PNP_DATA_QUEUE InQueue
, OutQueue
;
312 *Length
-= sizeof(*InfoBuffer
);
314 RtlZeroMemory(InfoBuffer
, sizeof(*InfoBuffer
));
316 InQueue
= &Ccb
->DataQueue
[FILE_PIPE_INBOUND
];
317 OutQueue
= &Ccb
->DataQueue
[FILE_PIPE_OUTBOUND
];
319 InfoBuffer
->NamedPipeType
= Fcb
->NamedPipeType
;
320 InfoBuffer
->NamedPipeConfiguration
= Fcb
->NamedPipeConfiguration
;
321 InfoBuffer
->MaximumInstances
= Fcb
->MaximumInstances
;
322 InfoBuffer
->CurrentInstances
= Fcb
->CurrentInstances
;
323 InfoBuffer
->InboundQuota
= InQueue
->Quota
;
324 InfoBuffer
->OutboundQuota
= OutQueue
->Quota
;
325 InfoBuffer
->NamedPipeState
= Ccb
->NamedPipeState
;
326 InfoBuffer
->NamedPipeEnd
= NamedPipeEnd
;
328 if (NamedPipeEnd
== FILE_PIPE_SERVER_END
)
330 if (InQueue
->QueueState
== WriteEntries
)
332 InfoBuffer
->ReadDataAvailable
= InQueue
->BytesInQueue
- InQueue
->ByteOffset
;
334 InfoBuffer
->WriteQuotaAvailable
= OutQueue
->Quota
- OutQueue
->QuotaUsed
;
338 if (OutQueue
->QueueState
== WriteEntries
)
340 InfoBuffer
->ReadDataAvailable
= OutQueue
->BytesInQueue
- OutQueue
->ByteOffset
;
342 InfoBuffer
->WriteQuotaAvailable
= OutQueue
->Quota
- InQueue
->QuotaUsed
;
345 return STATUS_SUCCESS
;
350 NpQueryPipeInfo(IN PNP_FCB Fcb
,
353 IN OUT PULONG Length
,
354 IN ULONG NamedPipeEnd
)
356 PFILE_PIPE_INFORMATION InfoBuffer
= Buffer
;
358 *Length
-= sizeof(*InfoBuffer
);
360 RtlZeroMemory(InfoBuffer
, sizeof(*InfoBuffer
));
362 InfoBuffer
->ReadMode
= Ccb
->ReadMode
[NamedPipeEnd
];
363 InfoBuffer
->CompletionMode
= Ccb
->CompletionMode
[NamedPipeEnd
];
365 return STATUS_SUCCESS
;
370 NpCommonQueryInformation(IN PDEVICE_OBJECT DeviceObject
,
373 PIO_STACK_LOCATION IoStack
;
374 NODE_TYPE_CODE NodeTypeCode
;
378 FILE_INFORMATION_CLASS InfoClass
;
381 PFILE_ALL_INFORMATION AllInfo
;
385 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
386 NodeTypeCode
= NpDecodeFileObject(IoStack
->FileObject
,
390 if (!NodeTypeCode
) return STATUS_PIPE_DISCONNECTED
;
392 Buffer
= Irp
->AssociatedIrp
.SystemBuffer
;
393 Length
= IoStack
->Parameters
.QueryFile
.Length
;
394 InfoClass
= IoStack
->Parameters
.QueryFile
.FileInformationClass
;
396 if (NodeTypeCode
!= NPFS_NTC_CCB
)
398 if (NodeTypeCode
!= NPFS_NTC_ROOT_DCB
|| InfoClass
!= FileNameInformation
)
400 return STATUS_INVALID_PARAMETER
;
406 case FileNameInformation
:
407 Status
= NpQueryNameInfo(Ccb
, Buffer
, &Length
);
410 case FilePositionInformation
:
411 Status
= NpQueryPositionInfo(Ccb
, Buffer
, &Length
, NamedPipeEnd
);
414 case FilePipeInformation
:
415 Status
= NpQueryPipeInfo(Fcb
, Ccb
, Buffer
, &Length
, NamedPipeEnd
);
418 case FilePipeLocalInformation
:
419 Status
= NpQueryPipeLocalInfo(Fcb
, Ccb
, Buffer
, &Length
, NamedPipeEnd
);
422 case FileBasicInformation
:
423 Status
= NpQueryBasicInfo(Ccb
, Buffer
, &Length
);
426 case FileStandardInformation
:
427 Status
= NpQueryStandardInfo(Ccb
, Buffer
, &Length
, NamedPipeEnd
);
430 case FileInternalInformation
:
431 Status
= NpQueryInternalInfo(Ccb
, Buffer
, &Length
);
434 case FileAllInformation
:
437 AllInfo
= (PFILE_ALL_INFORMATION
)Buffer
;
438 NpQueryBasicInfo(Ccb
, &AllInfo
->BasicInformation
, &Length
);
439 NpQueryStandardInfo(Ccb
, &AllInfo
->StandardInformation
, &Length
, NamedPipeEnd
);
440 NpQueryInternalInfo(Ccb
, &AllInfo
->InternalInformation
, &Length
);
441 NpQueryEaInfo(Ccb
, &AllInfo
->EaInformation
, &Length
);
442 NpQueryPositionInfo(Ccb
, &AllInfo
->PositionInformation
, &Length
, NamedPipeEnd
);
446 case FileEaInformation
:
447 Status
= NpQueryEaInfo(Ccb
, Buffer
, &Length
);
451 Status
= STATUS_INVALID_PARAMETER
;
455 Irp
->IoStatus
.Information
= IoStack
->Parameters
.Read
.Length
- Length
;
461 NpFsdQueryInformation(IN PDEVICE_OBJECT DeviceObject
,
467 FsRtlEnterFileSystem();
468 NpAcquireSharedVcb();
470 Status
= NpCommonQueryInformation(DeviceObject
, Irp
);
473 FsRtlExitFileSystem();
475 if (Status
!= STATUS_PENDING
)
477 Irp
->IoStatus
.Status
= Status
;
478 IoCompleteRequest(Irp
, IO_NAMED_PIPE_INCREMENT
);