-Fixed FileObject/Event dereferencing at IRP completion problem
[reactos.git] / reactos / ntoskrnl / io / dir.c
1 /* $Id: dir.c,v 1.16 2003/05/22 00:47:04 gdalsnes Exp $
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
23
24 NTSTATUS
25 STDCALL
26 NtNotifyChangeDirectoryFile (
27 IN HANDLE FileHandle,
28 IN HANDLE Event OPTIONAL,
29 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
30 IN PVOID ApcContext OPTIONAL,
31 OUT PIO_STATUS_BLOCK IoStatusBlock,
32 OUT PVOID Buffer,
33 IN ULONG BufferSize,
34 IN ULONG CompletionFilter,
35 IN BOOLEAN WatchTree
36 )
37 {
38 UNIMPLEMENTED;
39 }
40
41
42 NTSTATUS
43 STDCALL
44 NtQueryDirectoryFile(
45 IN HANDLE FileHandle,
46 IN HANDLE PEvent OPTIONAL,
47 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
48 IN PVOID ApcContext OPTIONAL,
49 OUT PIO_STATUS_BLOCK IoStatusBlock,
50 OUT PVOID FileInformation,
51 IN ULONG Length,
52 IN FILE_INFORMATION_CLASS FileInformationClass,
53 IN BOOLEAN ReturnSingleEntry,
54 IN PUNICODE_STRING FileName OPTIONAL,
55 IN BOOLEAN RestartScan
56 )
57 /*
58 * FUNCTION: Queries a directory file.
59 * ARGUMENTS:
60 * FileHandle = Handle to a directory file
61 * EventHandle = Handle to the event signaled on completion
62 * ApcRoutine = Asynchroneous procedure callback, called on completion
63 * ApcContext = Argument to the apc.
64 * IoStatusBlock = Caller supplies storage for extended status information.
65 * FileInformation = Caller supplies storage for the resulting information.
66 *
67 * FileNameInformation FILE_NAMES_INFORMATION
68 * FileDirectoryInformation FILE_DIRECTORY_INFORMATION
69 * FileFullDirectoryInformation FILE_FULL_DIRECTORY_INFORMATION
70 * FileBothDirectoryInformation FILE_BOTH_DIR_INFORMATION
71 *
72 * Length = Size of the storage supplied
73 * FileInformationClass = Indicates the type of information requested.
74 * ReturnSingleEntry = Specify true if caller only requests the first
75 * directory found.
76 * FileName = Initial directory name to query, that may contain wild
77 * cards.
78 * RestartScan = Number of times the action should be repeated
79 * RETURNS: Status [ STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_INSUFFICIENT_RESOURCES,
80 * STATUS_INVALID_PARAMETER, STATUS_INVALID_DEVICE_REQUEST, STATUS_BUFFER_OVERFLOW,
81 * STATUS_INVALID_INFO_CLASS, STATUS_NO_SUCH_FILE, STATUS_NO_MORE_FILES ]
82 */
83 {
84 PIRP Irp;
85 PDEVICE_OBJECT DeviceObject;
86 PFILE_OBJECT FileObject;
87 NTSTATUS Status;
88 PIO_STACK_LOCATION IoStack;
89 IO_STATUS_BLOCK IoSB;
90
91 DPRINT("NtQueryDirectoryFile()\n");
92
93 Status = ObReferenceObjectByHandle(FileHandle,
94 FILE_LIST_DIRECTORY,
95 IoFileObjectType,
96 UserMode,
97 (PVOID *)&FileObject,
98 NULL);
99
100 if (Status != STATUS_SUCCESS)
101 {
102 ObDereferenceObject(FileObject);
103 return(Status);
104 }
105 DeviceObject = FileObject->DeviceObject;
106
107 Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
108 if (Irp==NULL)
109 {
110 ObDereferenceObject(FileObject);
111 return STATUS_UNSUCCESSFUL;
112 }
113
114 //trigger FileObject/Event dereferencing
115 Irp->Tail.Overlay.OriginalFileObject = FileObject;
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 if (((PFILE_DIRECTORY_INFORMATION)FileInformation)->FileIndex != 0)
140 {
141 IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED;
142 }
143
144 IoStack->Parameters.QueryDirectory.FileInformationClass =
145 FileInformationClass;
146 IoStack->Parameters.QueryDirectory.FileName = FileName;
147 IoStack->Parameters.QueryDirectory.Length = Length;
148
149 Status = IoCallDriver(FileObject->DeviceObject,Irp);
150 if (Status==STATUS_PENDING && !(FileObject->Flags & FO_SYNCHRONOUS_IO))
151 {
152 if (FileObject->Flags & FO_ALERTABLE_IO)
153 {
154 KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,TRUE,NULL);
155 }
156 else
157 {
158 KeWaitForSingleObject(&FileObject->Event,Executive,KernelMode,FALSE,NULL);
159 }
160 Status = IoSB.Status;
161 }
162 if (IoStatusBlock)
163 {
164 *IoStatusBlock = IoSB;
165 }
166 return(Status);
167 }
168
169 NTSTATUS STDCALL NtQueryOleDirectoryFile(VOID)
170 {
171 UNIMPLEMENTED;
172 }
173
174
175 /* EOF */