2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/filesastems/npfs/dirctl.c
5 * PURPOSE: Named pipe filesystem
6 * PROGRAMMER: Eric Kohl
9 /* INCLUDES ******************************************************************/
16 /* FUNCTIONS *****************************************************************/
19 NpfsQueryDirectory(PNPFS_CCB Ccb
,
23 PIO_STACK_LOCATION Stack
;
24 LONG BufferLength
= 0;
25 PUNICODE_STRING SearchPattern
= NULL
;
26 FILE_INFORMATION_CLASS FileInformationClass
;
29 BOOLEAN First
= FALSE
;
30 PLIST_ENTRY CurrentEntry
;
34 BOOLEAN Found
= FALSE
;
35 NTSTATUS Status
= STATUS_SUCCESS
;
36 PFILE_NAMES_INFORMATION NamesBuffer
;
37 PFILE_DIRECTORY_INFORMATION DirectoryBuffer
;
38 PFILE_FULL_DIR_INFORMATION FullDirBuffer
;
39 PFILE_BOTH_DIR_INFORMATION BothDirBuffer
;
41 Stack
= IoGetCurrentIrpStackLocation(Irp
);
43 /* Obtain the callers parameters */
44 BufferLength
= Stack
->Parameters
.QueryDirectory
.Length
;
45 SearchPattern
= Stack
->Parameters
.QueryDirectory
.FileName
;
46 FileInformationClass
= Stack
->Parameters
.QueryDirectory
.FileInformationClass
;
47 FileIndex
= Stack
->Parameters
.QueryDirectory
.FileIndex
;
49 DPRINT("SearchPattern: %p '%wZ'\n", SearchPattern
, SearchPattern
);
51 /* Determine Buffer for result */
54 Buffer
= MmGetSystemAddressForMdl(Irp
->MdlAddress
);
58 Buffer
= Irp
->UserBuffer
;
61 /* Build the search pattern string */
62 DPRINT("Ccb->u.Directory.SearchPattern.Buffer: %p\n", Ccb
->u
.Directory
.SearchPattern
.Buffer
);
63 if (Ccb
->u
.Directory
.SearchPattern
.Buffer
== NULL
)
67 if (SearchPattern
!= NULL
)
69 Ccb
->u
.Directory
.SearchPattern
.Buffer
=
70 ExAllocatePool(NonPagedPool
, SearchPattern
->Length
+ sizeof(WCHAR
));
71 if (Ccb
->u
.Directory
.SearchPattern
.Buffer
== NULL
)
73 return STATUS_INSUFFICIENT_RESOURCES
;
76 Ccb
->u
.Directory
.SearchPattern
.Length
= SearchPattern
->Length
;
77 Ccb
->u
.Directory
.SearchPattern
.MaximumLength
= SearchPattern
->Length
+ sizeof(WCHAR
);
78 RtlCopyMemory(Ccb
->u
.Directory
.SearchPattern
.Buffer
,
79 SearchPattern
->Buffer
,
80 SearchPattern
->Length
);
81 Ccb
->u
.Directory
.SearchPattern
.Buffer
[SearchPattern
->Length
/ sizeof(WCHAR
)] = 0;
85 Ccb
->u
.Directory
.SearchPattern
.Buffer
=
86 ExAllocatePool(NonPagedPool
, 2 * sizeof(WCHAR
));
87 if (Ccb
->u
.Directory
.SearchPattern
.Buffer
== NULL
)
89 return STATUS_INSUFFICIENT_RESOURCES
;
92 Ccb
->u
.Directory
.SearchPattern
.Length
= sizeof(WCHAR
);
93 Ccb
->u
.Directory
.SearchPattern
.MaximumLength
= 2 * sizeof(WCHAR
);
94 Ccb
->u
.Directory
.SearchPattern
.Buffer
[0] = L
'*';
95 Ccb
->u
.Directory
.SearchPattern
.Buffer
[1] = 0;
98 DPRINT("Search pattern: '%wZ'\n", &Ccb
->u
.Directory
.SearchPattern
);
100 /* Determine the file index */
101 if (First
|| (Stack
->Flags
& SL_RESTART_SCAN
))
104 } else if ((Stack
->Flags
& SL_INDEX_SPECIFIED
) == 0)
106 FileIndex
= Ccb
->u
.Directory
.FileIndex
+ 1;
108 DPRINT("FileIndex: %lu\n", FileIndex
);
110 DPRINT("Buffer = %p tofind = %wZ\n", Buffer
, &Ccb
->u
.Directory
.SearchPattern
);
115 CurrentEntry
= Vcb
->PipeListHead
.Flink
;
116 while (CurrentEntry
!= &Vcb
->PipeListHead
&& Found
== FALSE
)
118 /* Get the FCB of the next pipe */
119 PipeFcb
= CONTAINING_RECORD(CurrentEntry
,
123 /* Make sure it is a pipe FCB */
124 ASSERT(PipeFcb
->Type
== FCB_PIPE
);
126 DPRINT("PipeName: %wZ\n", &PipeFcb
->PipeName
);
128 if (FsRtlIsNameInExpression(&Ccb
->u
.Directory
.SearchPattern
,
133 DPRINT("Found pipe: %wZ\n", &PipeFcb
->PipeName
);
135 if (PipeIndex
>= FileIndex
)
137 RtlZeroMemory(Buffer
, BufferLength
);
139 switch (FileInformationClass
)
141 case FileDirectoryInformation
:
142 DirectoryBuffer
= (PFILE_DIRECTORY_INFORMATION
)Buffer
;
143 DirectoryBuffer
->NextEntryOffset
= 0;
144 DirectoryBuffer
->FileIndex
= PipeIndex
;
145 DirectoryBuffer
->FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
146 DirectoryBuffer
->EndOfFile
.QuadPart
= PipeFcb
->CurrentInstances
;
147 DirectoryBuffer
->AllocationSize
.LowPart
= PipeFcb
->MaximumInstances
;
148 DirectoryBuffer
->FileNameLength
= PipeFcb
->PipeName
.Length
;
149 RtlCopyMemory(DirectoryBuffer
->FileName
,
150 PipeFcb
->PipeName
.Buffer
,
151 PipeFcb
->PipeName
.Length
);
152 *Size
= sizeof(FILE_DIRECTORY_INFORMATION
) + PipeFcb
->PipeName
.Length
- sizeof(WCHAR
);
153 Status
= STATUS_SUCCESS
;
156 case FileFullDirectoryInformation
:
157 FullDirBuffer
= (PFILE_FULL_DIR_INFORMATION
)Buffer
;
158 FullDirBuffer
->NextEntryOffset
= 0;
159 FullDirBuffer
->FileIndex
= PipeIndex
;
160 FullDirBuffer
->FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
161 FullDirBuffer
->EndOfFile
.QuadPart
= PipeFcb
->CurrentInstances
;
162 FullDirBuffer
->AllocationSize
.LowPart
= PipeFcb
->MaximumInstances
;
163 FullDirBuffer
->FileNameLength
= PipeFcb
->PipeName
.Length
;
164 RtlCopyMemory(FullDirBuffer
->FileName
,
165 PipeFcb
->PipeName
.Buffer
,
166 PipeFcb
->PipeName
.Length
);
167 *Size
= sizeof(FILE_FULL_DIR_INFORMATION
) + PipeFcb
->PipeName
.Length
- sizeof(WCHAR
);
168 Status
= STATUS_SUCCESS
;
171 case FileBothDirectoryInformation
:
172 BothDirBuffer
= (PFILE_BOTH_DIR_INFORMATION
)Buffer
;
173 BothDirBuffer
->NextEntryOffset
= 0;
174 BothDirBuffer
->FileIndex
= PipeIndex
;
175 BothDirBuffer
->FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
176 BothDirBuffer
->EndOfFile
.QuadPart
= PipeFcb
->CurrentInstances
;
177 BothDirBuffer
->AllocationSize
.LowPart
= PipeFcb
->MaximumInstances
;
178 BothDirBuffer
->FileNameLength
= PipeFcb
->PipeName
.Length
;
179 RtlCopyMemory(BothDirBuffer
->FileName
,
180 PipeFcb
->PipeName
.Buffer
,
181 PipeFcb
->PipeName
.Length
);
182 *Size
= sizeof(FILE_BOTH_DIR_INFORMATION
) + PipeFcb
->PipeName
.Length
- sizeof(WCHAR
);
183 Status
= STATUS_SUCCESS
;
186 case FileNamesInformation
:
187 NamesBuffer
= (PFILE_NAMES_INFORMATION
)Buffer
;
188 NamesBuffer
->NextEntryOffset
= 0;
189 NamesBuffer
->FileIndex
= PipeIndex
;
190 NamesBuffer
->FileNameLength
= PipeFcb
->PipeName
.Length
;
191 RtlCopyMemory(NamesBuffer
->FileName
,
192 PipeFcb
->PipeName
.Buffer
,
193 PipeFcb
->PipeName
.Length
);
194 *Size
= sizeof(FILE_NAMES_INFORMATION
) + PipeFcb
->PipeName
.Length
- sizeof(WCHAR
);
195 Status
= STATUS_SUCCESS
;
199 DPRINT1("Invalid information class: %lu\n", FileInformationClass
);
200 Status
= STATUS_INVALID_INFO_CLASS
;
204 Ccb
->u
.Directory
.FileIndex
= PipeIndex
;
207 // if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
208 // return STATUS_SUCCESS;
216 CurrentEntry
= CurrentEntry
->Flink
;
220 Status
= STATUS_NO_MORE_FILES
;
227 NpfsDirectoryControl(PDEVICE_OBJECT DeviceObject
,
230 PIO_STACK_LOCATION IoStack
;
231 PFILE_OBJECT FileObject
;
237 DPRINT("NpfsDirectoryControl() called\n");
239 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
241 FileObject
= IoStack
->FileObject
;
243 if (NpfsGetCcb(FileObject
, &Ccb
) != CCB_DIRECTORY
)
245 Status
= STATUS_INVALID_PARAMETER
;
247 Irp
->IoStatus
.Status
= Status
;
248 Irp
->IoStatus
.Information
= 0;
250 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
257 switch (IoStack
->MinorFunction
)
259 case IRP_MN_QUERY_DIRECTORY
:
260 Status
= NpfsQueryDirectory(Ccb
,
265 case IRP_MN_NOTIFY_CHANGE_DIRECTORY
:
266 DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
267 Status
= STATUS_NOT_IMPLEMENTED
;
271 DPRINT1("NPFS: MinorFunction %d\n", IoStack
->MinorFunction
);
272 Status
= STATUS_INVALID_DEVICE_REQUEST
;
276 Irp
->IoStatus
.Status
= Status
;
277 Irp
->IoStatus
.Information
= Size
;
279 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);