f3a2b3f1ab9205daa60c48b4fbe1d13689c360af
[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 not be valid if !RestartScan.
141     */
142    if (!RestartScan)
143      {
144         IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED;
145         switch (FileInformationClass) {
146            case FileIdBothDirectoryInformation:
147               IoStack->Parameters.QueryDirectory.FileIndex = ((FILE_ID_BOTH_DIR_INFORMATION *)FileInformation)->FileIndex;
148               break;
149            default: KeBugCheck(0); /* FIXME: such 'FileInformationClass' NOT IMPLEMENTED YET */
150            }
151      }
152    
153    IoStack->Parameters.QueryDirectory.FileInformationClass = 
154      FileInformationClass;
155    IoStack->Parameters.QueryDirectory.FileName = FileName;
156    IoStack->Parameters.QueryDirectory.Length = Length;
157    
158    Status = IoCallDriver(FileObject->DeviceObject,Irp);
159    if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
160      {
161         if (FileObject->Flags & FO_ALERTABLE_IO)
162           {
163              KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,TRUE,NULL);
164           }
165         else
166           {
167              KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,FALSE,NULL);
168           }
169         Status = IoSB.Status;
170      }
171    if (IoStatusBlock)
172      {
173        *IoStatusBlock = IoSB;
174      }
175    return(Status);
176 }
177
178 #ifndef LIBCAPTIVE
179
180 NTSTATUS STDCALL NtQueryOleDirectoryFile(VOID)
181 {
182    UNIMPLEMENTED;
183 }
184
185 #endif /* LIBCAPTIVE */
186
187 /* EOF */