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
;
39 Stack
= IoGetCurrentIrpStackLocation(Irp
);
41 /* Obtain the callers parameters */
42 BufferLength
= Stack
->Parameters
.QueryDirectory
.Length
;
43 SearchPattern
= Stack
->Parameters
.QueryDirectory
.FileName
;
44 FileInformationClass
= Stack
->Parameters
.QueryDirectory
.FileInformationClass
;
45 FileIndex
= Stack
->Parameters
.QueryDirectory
.FileIndex
;
47 DPRINT("SearchPattern: %p '%wZ'\n", SearchPattern
, SearchPattern
);
49 /* Determine Buffer for result */
52 Buffer
= MmGetSystemAddressForMdl(Irp
->MdlAddress
);
56 Buffer
= Irp
->UserBuffer
;
59 /* Build the search pattern string */
60 DPRINT("Ccb->u.Directory.SearchPattern.Buffer: %p\n", Ccb
->u
.Directory
.SearchPattern
.Buffer
);
61 if (Ccb
->u
.Directory
.SearchPattern
.Buffer
== NULL
)
65 if (SearchPattern
!= NULL
)
67 Ccb
->u
.Directory
.SearchPattern
.Buffer
=
68 ExAllocatePool(NonPagedPool
, SearchPattern
->Length
+ sizeof(WCHAR
));
69 if (Ccb
->u
.Directory
.SearchPattern
.Buffer
== NULL
)
71 return STATUS_INSUFFICIENT_RESOURCES
;
74 Ccb
->u
.Directory
.SearchPattern
.Length
= SearchPattern
->Length
;
75 Ccb
->u
.Directory
.SearchPattern
.MaximumLength
= SearchPattern
->Length
+ sizeof(WCHAR
);
76 RtlCopyMemory(Ccb
->u
.Directory
.SearchPattern
.Buffer
,
77 SearchPattern
->Buffer
,
78 SearchPattern
->Length
);
79 Ccb
->u
.Directory
.SearchPattern
.Buffer
[SearchPattern
->Length
/ sizeof(WCHAR
)] = 0;
83 Ccb
->u
.Directory
.SearchPattern
.Buffer
=
84 ExAllocatePool(NonPagedPool
, 2 * sizeof(WCHAR
));
85 if (Ccb
->u
.Directory
.SearchPattern
.Buffer
== NULL
)
87 return STATUS_INSUFFICIENT_RESOURCES
;
90 Ccb
->u
.Directory
.SearchPattern
.Length
= sizeof(WCHAR
);
91 Ccb
->u
.Directory
.SearchPattern
.MaximumLength
= 2 * sizeof(WCHAR
);
92 Ccb
->u
.Directory
.SearchPattern
.Buffer
[0] = L
'*';
93 Ccb
->u
.Directory
.SearchPattern
.Buffer
[1] = 0;
96 DPRINT("Search pattern: '%wZ'\n", &Ccb
->u
.Directory
.SearchPattern
);
98 /* Determine the file index */
99 if (First
|| (Stack
->Flags
& SL_RESTART_SCAN
))
102 } else if ((Stack
->Flags
& SL_INDEX_SPECIFIED
) == 0)
104 FileIndex
= Ccb
->u
.Directory
.FileIndex
+ 1;
106 DPRINT("FileIndex: %lu\n", FileIndex
);
108 DPRINT("Buffer = %p tofind = %wZ\n", Buffer
, &Ccb
->u
.Directory
.SearchPattern
);
113 CurrentEntry
= Vcb
->PipeListHead
.Flink
;
114 while (CurrentEntry
!= &Vcb
->PipeListHead
&& Found
== FALSE
)
116 /* Get the FCB of the next pipe */
117 PipeFcb
= CONTAINING_RECORD(CurrentEntry
,
121 /* Make sure it is a pipe FCB */
122 ASSERT(PipeFcb
->Type
== FCB_PIPE
);
124 DPRINT("PipeName: %wZ\n", &PipeFcb
->PipeName
);
126 if (FsRtlIsNameInExpression(&Ccb
->u
.Directory
.SearchPattern
,
131 DPRINT("Found pipe: %wZ\n", &PipeFcb
->PipeName
);
133 if (PipeIndex
>= FileIndex
)
135 switch (FileInformationClass
)
137 case FileDirectoryInformation
:
138 DirectoryBuffer
= (PFILE_DIRECTORY_INFORMATION
)Buffer
;
139 DirectoryBuffer
->NextEntryOffset
= 0;
140 DirectoryBuffer
->FileIndex
= PipeIndex
;
141 DirectoryBuffer
->FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
142 DirectoryBuffer
->EndOfFile
.QuadPart
= PipeFcb
->CurrentInstances
;
143 DirectoryBuffer
->AllocationSize
.LowPart
= PipeFcb
->MaximumInstances
;
144 DirectoryBuffer
->FileNameLength
= PipeFcb
->PipeName
.Length
;
145 RtlCopyMemory(DirectoryBuffer
->FileName
,
146 PipeFcb
->PipeName
.Buffer
,
147 PipeFcb
->PipeName
.Length
);
148 *Size
= sizeof(FILE_DIRECTORY_INFORMATION
) + PipeFcb
->PipeName
.Length
- 1;
149 Status
= STATUS_SUCCESS
;
152 case FileNamesInformation
:
153 NamesBuffer
= (PFILE_NAMES_INFORMATION
)Buffer
;
154 NamesBuffer
->NextEntryOffset
= 0;
155 NamesBuffer
->FileIndex
= PipeIndex
;
156 NamesBuffer
->FileNameLength
= PipeFcb
->PipeName
.Length
;
157 RtlCopyMemory(NamesBuffer
->FileName
,
158 PipeFcb
->PipeName
.Buffer
,
159 PipeFcb
->PipeName
.Length
);
160 *Size
= sizeof(FILE_NAMES_INFORMATION
) + PipeFcb
->PipeName
.Length
- 1;
161 Status
= STATUS_SUCCESS
;
165 DPRINT1("Invalid information class: %lu\n", FileInformationClass
);
166 Status
= STATUS_INVALID_INFO_CLASS
;
170 Ccb
->u
.Directory
.FileIndex
= PipeIndex
;
173 // if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
174 // return STATUS_SUCCESS;
182 CurrentEntry
= CurrentEntry
->Flink
;
186 Status
= STATUS_NO_MORE_FILES
;
193 NpfsDirectoryControl(PDEVICE_OBJECT DeviceObject
,
196 PIO_STACK_LOCATION IoStack
;
197 PFILE_OBJECT FileObject
;
203 DPRINT("NpfsDirectoryControl() called\n");
205 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
207 FileObject
= IoStack
->FileObject
;
209 if (NpfsGetCcb(FileObject
, &Ccb
) != CCB_DIRECTORY
)
211 Status
= STATUS_INVALID_PARAMETER
;
213 Irp
->IoStatus
.Status
= Status
;
214 Irp
->IoStatus
.Information
= 0;
216 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
223 switch (IoStack
->MinorFunction
)
225 case IRP_MN_QUERY_DIRECTORY
:
226 Status
= NpfsQueryDirectory(Ccb
,
231 case IRP_MN_NOTIFY_CHANGE_DIRECTORY
:
232 DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
233 Status
= STATUS_NOT_IMPLEMENTED
;
237 DPRINT1("NPFS: MinorFunction %d\n", IoStack
->MinorFunction
);
238 Status
= STATUS_INVALID_DEVICE_REQUEST
;
242 Irp
->IoStatus
.Status
= Status
;
243 Irp
->IoStatus
.Information
= Size
;
245 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);