+ntoskrnl/io/dir.c
[reactos.git] / ntoskrnl / io / dir.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            ntoskrnl/io/dir.c
6  * PURPOSE:         Directory functions
7  * PROGRAMMER:      David Welch (welch@mcmail.com)
8  * UPDATE HISTORY:
9  *                  Created 22/05/98
10  */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/io.h>
16
17 #define NDEBUG
18 #include <internal/debug.h>
19
20 /* FUNCTIONS *****************************************************************/
21
22 #ifndef LIBCAPTIVE
23
24
25 NTSTATUS
26 STDCALL
27 NtNotifyChangeDirectoryFile (
28         IN      HANDLE                  FileHandle,
29         IN      HANDLE                  Event           OPTIONAL, 
30         IN      PIO_APC_ROUTINE         ApcRoutine      OPTIONAL, 
31         IN      PVOID                   ApcContext      OPTIONAL, 
32         OUT     PIO_STATUS_BLOCK        IoStatusBlock,
33         OUT     PVOID                   Buffer,
34         IN      ULONG                   BufferSize,
35         IN      ULONG                   CompletionFilter,
36         IN      BOOLEAN                 WatchTree
37         )
38 {
39         UNIMPLEMENTED;
40 }
41
42 #endif /* LIBCAPTIVE */
43
44 NTSTATUS
45 STDCALL 
46 NtQueryDirectoryFile(
47         IN      HANDLE                  FileHandle,
48         IN      HANDLE                  PEvent          OPTIONAL,
49         IN      PIO_APC_ROUTINE         ApcRoutine      OPTIONAL,
50         IN      PVOID                   ApcContext      OPTIONAL,
51         OUT     PIO_STATUS_BLOCK        IoStatusBlock,
52         OUT     PVOID                   FileInformation,
53         IN      ULONG                   Length,
54         IN      FILE_INFORMATION_CLASS  FileInformationClass,
55         IN      BOOLEAN                 ReturnSingleEntry,
56         IN      PUNICODE_STRING         FileName        OPTIONAL,
57         IN      BOOLEAN                 RestartScan
58         )
59 /*
60  * FUNCTION: Queries a directory file.
61  * ARGUMENTS:
62  *        FileHandle = Handle to a directory file
63  *        EventHandle  = Handle to the event signaled on completion
64  *        ApcRoutine = Asynchroneous procedure callback, called on completion
65  *        ApcContext = Argument to the apc.
66  *        IoStatusBlock = Caller supplies storage for extended status information.
67  *        FileInformation = Caller supplies storage for the resulting information.
68  *
69  *              FileNameInformation             FILE_NAMES_INFORMATION
70  *              FileDirectoryInformation        FILE_DIRECTORY_INFORMATION
71  *              FileFullDirectoryInformation    FILE_FULL_DIRECTORY_INFORMATION
72  *              FileBothDirectoryInformation    FILE_BOTH_DIR_INFORMATION
73  *
74  *        Length = Size of the storage supplied
75  *        FileInformationClass = Indicates the type of information requested.  
76  *        ReturnSingleEntry = Specify true if caller only requests the first 
77  *                            directory found.
78  *        FileName = Initial directory name to query, that may contain wild 
79  *                   cards.
80  *        RestartScan = Number of times the action should be repeated
81  * RETURNS: Status [ STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_INSUFFICIENT_RESOURCES,
82  *                   STATUS_INVALID_PARAMETER, STATUS_INVALID_DEVICE_REQUEST, STATUS_BUFFER_OVERFLOW,
83  *                   STATUS_INVALID_INFO_CLASS, STATUS_NO_SUCH_FILE, STATUS_NO_MORE_FILES ]
84  */
85 {
86    PIRP Irp;
87    PDEVICE_OBJECT DeviceObject;
88    PFILE_OBJECT FileObject;
89    NTSTATUS Status;
90    PIO_STACK_LOCATION IoStack;
91    IO_STATUS_BLOCK IoSB;
92    
93    DPRINT("NtQueryDirectoryFile()\n");
94    
95    Status = ObReferenceObjectByHandle(FileHandle,
96                                       FILE_LIST_DIRECTORY,
97                                       IoFileObjectType,
98                                       UserMode,
99                                       (PVOID *)&FileObject,
100                                       NULL);
101    
102    if (Status != STATUS_SUCCESS)
103      {
104         ObDereferenceObject(FileObject);
105         return(Status);
106      }
107    DeviceObject = FileObject->DeviceObject;
108    
109    Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
110    if (Irp==NULL)
111      {
112         ObDereferenceObject(FileObject);
113         return STATUS_UNSUCCESSFUL;
114      }
115    
116    
117    Irp->UserIosb = &IoSB;
118    Irp->UserEvent = &FileObject->Event;
119    KeResetEvent( &FileObject->Event );
120    Irp->UserBuffer=FileInformation;
121    
122    IoStack = IoGetNextIrpStackLocation(Irp);
123    
124    IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
125    IoStack->MinorFunction = IRP_MN_QUERY_DIRECTORY;
126    IoStack->Flags = 0;
127    IoStack->Control = 0;
128    IoStack->DeviceObject = DeviceObject;
129    IoStack->FileObject = FileObject;
130    
131    if (RestartScan)
132      {
133         IoStack->Flags = IoStack->Flags | SL_RESTART_SCAN;
134      }
135    if (ReturnSingleEntry)
136      {
137         IoStack->Flags = IoStack->Flags | SL_RETURN_SINGLE_ENTRY;
138      }
139    /* SL_INDEX_SPECIFIED may take precedense over SL_RESTART_SCAN
140     * and 'FileInformation' may note be valid if !RestartScan.
141     * FIXME: 'PFILE_DIRECTORY_INFORMATION' type is dependent on 'FileInformationClass'!
142     */
143    if (!RestartScan && ((PFILE_DIRECTORY_INFORMATION)FileInformation)->FileIndex != 0)
144      {
145         IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED;
146      }
147    
148    IoStack->Parameters.QueryDirectory.FileInformationClass = 
149      FileInformationClass;
150    IoStack->Parameters.QueryDirectory.FileName = FileName;
151    IoStack->Parameters.QueryDirectory.Length = Length;
152    
153    Status = IoCallDriver(FileObject->DeviceObject,Irp);
154    if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
155      {
156         if (FileObject->Flags & FO_ALERTABLE_IO)
157           {
158              KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,TRUE,NULL);
159           }
160         else
161           {
162              KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,FALSE,NULL);
163           }
164         Status = IoSB.Status;
165      }
166    if (IoStatusBlock)
167      {
168        *IoStatusBlock = IoSB;
169      }
170    return(Status);
171 }
172
173 #ifndef LIBCAPTIVE
174
175 NTSTATUS STDCALL NtQueryOleDirectoryFile(VOID)
176 {
177    UNIMPLEMENTED;
178 }
179
180 #endif /* LIBCAPTIVE */
181
182 /* EOF */