- Update to r53061
[reactos.git] / dll / win32 / kernel32 / client / file / cnotify.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/file/find.c
6 * PURPOSE: Find functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
8 * UPDATE HISTORY:
9 * Created 01/11/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <k32.h>
15 #define NDEBUG
16 #include <debug.h>
17
18 /* FUNCTIONS ****************************************************************/
19
20 /*
21 * @implemented
22 */
23 BOOL WINAPI
24 FindCloseChangeNotification (HANDLE hChangeHandle)
25 {
26 NTSTATUS Status = NtClose(hChangeHandle);
27 if(!NT_SUCCESS(Status))
28 {
29 BaseSetLastNTError(Status);
30 return FALSE;
31 }
32
33 return TRUE;
34 }
35
36
37 /*
38 * @implemented
39 */
40 HANDLE
41 WINAPI
42 FindFirstChangeNotificationA(IN LPCSTR lpPathName,
43 IN BOOL bWatchSubtree,
44 IN DWORD dwNotifyFilter)
45 {
46 /* Call the W(ide) function */
47 ConvertWin32AnsiChangeApiToUnicodeApi(FindFirstChangeNotification,
48 lpPathName,
49 bWatchSubtree,
50 dwNotifyFilter);
51 }
52
53
54 /*
55 * @implemented
56 */
57 HANDLE
58 WINAPI
59 FindFirstChangeNotificationW (
60 LPCWSTR lpPathName,
61 BOOL bWatchSubtree,
62 DWORD dwNotifyFilter
63 )
64 {
65 NTSTATUS Status;
66 UNICODE_STRING NtPathU;
67 IO_STATUS_BLOCK IoStatus;
68 OBJECT_ATTRIBUTES ObjectAttributes;
69 HANDLE hDir;
70
71 if (!RtlDosPathNameToNtPathName_U (lpPathName,
72 &NtPathU,
73 NULL,
74 NULL))
75 {
76 BaseSetLastNTError(STATUS_OBJECT_PATH_SYNTAX_BAD);
77 return INVALID_HANDLE_VALUE;
78 }
79
80
81
82 InitializeObjectAttributes (&ObjectAttributes,
83 &NtPathU,
84 OBJ_CASE_INSENSITIVE,
85 NULL,
86 NULL);
87
88 Status = NtOpenFile (&hDir,
89 SYNCHRONIZE|FILE_LIST_DIRECTORY,
90 &ObjectAttributes,
91 &IoStatus,
92 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
93 FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT);
94
95 RtlFreeHeap(RtlGetProcessHeap(),
96 0,
97 NtPathU.Buffer);
98
99
100
101 if (!NT_SUCCESS(Status))
102 {
103 BaseSetLastNTError(Status);
104 return INVALID_HANDLE_VALUE;
105 }
106
107 Status = NtNotifyChangeDirectoryFile(hDir,
108 NULL,
109 NULL,
110 NULL,
111 &IoStatus,
112 NULL,//Buffer,
113 0,//BufferLength,
114 dwNotifyFilter,
115 (BOOLEAN)bWatchSubtree);
116 if (!NT_SUCCESS(Status))
117 {
118 NtClose(hDir);
119 BaseSetLastNTError(Status);
120 return INVALID_HANDLE_VALUE;
121 }
122
123 return hDir;
124 }
125
126
127 /*
128 * @implemented
129 */
130 BOOL
131 WINAPI
132 FindNextChangeNotification (
133 HANDLE hChangeHandle
134 )
135 {
136 IO_STATUS_BLOCK IoStatus;
137 NTSTATUS Status;
138
139 Status = NtNotifyChangeDirectoryFile(hChangeHandle,
140 NULL,
141 NULL,
142 NULL,
143 &IoStatus,
144 NULL,//Buffer,
145 0,//BufferLength,
146 FILE_NOTIFY_CHANGE_SECURITY,//meaningless/ignored for subsequent calls, but must contain a valid flag
147 0 //meaningless/ignored for subsequent calls
148 );
149
150 if (!NT_SUCCESS(Status))
151 {
152 BaseSetLastNTError(Status);
153 return FALSE;
154 }
155
156 return TRUE;
157 }
158
159
160 extern VOID
161 (WINAPI ApcRoutine)(PVOID ApcContext,
162 struct _IO_STATUS_BLOCK* IoStatusBlock,
163 ULONG Reserved);
164
165
166 /*
167 * @implemented
168 */
169 BOOL
170 WINAPI
171 ReadDirectoryChangesW(
172 HANDLE hDirectory,
173 LPVOID lpBuffer OPTIONAL,
174 DWORD nBufferLength,
175 BOOL bWatchSubtree,
176 DWORD dwNotifyFilter,
177 LPDWORD lpBytesReturned, /* undefined for asych. operations */
178 LPOVERLAPPED lpOverlapped OPTIONAL,
179 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine /* OPTIONAL???????? */
180 )
181 {
182 PVOID CompletionRoutine;
183 NTSTATUS Status;
184 IO_STATUS_BLOCK IoStatus;
185 HANDLE EventHandle;
186 PIO_APC_ROUTINE IoApcRoutine;
187
188 if (lpOverlapped )
189 {
190 if (lpCompletionRoutine)
191 {
192 CompletionRoutine = (PVOID) lpCompletionRoutine;
193 EventHandle = NULL;
194 IoApcRoutine = ApcRoutine;
195 }
196 else
197 {
198 if (((ULONG_PTR) lpOverlapped->hEvent & 1) == 0)
199 CompletionRoutine = (PVOID) lpOverlapped;
200 else
201 CompletionRoutine = NULL;
202
203 EventHandle = lpOverlapped->hEvent;
204 IoApcRoutine = NULL;
205 }
206
207 lpOverlapped->Internal = STATUS_PENDING;
208 }
209 else
210 {
211 EventHandle = NULL;
212 IoApcRoutine = NULL;
213 CompletionRoutine = NULL;
214 }
215
216 Status = NtNotifyChangeDirectoryFile(
217 hDirectory,
218 EventHandle,
219 IoApcRoutine,
220 CompletionRoutine, /* ApcContext */
221 lpOverlapped ? (PIO_STATUS_BLOCK) lpOverlapped : &IoStatus,
222 lpBuffer,
223 nBufferLength,
224 dwNotifyFilter,
225 (BOOLEAN)bWatchSubtree
226 );
227
228 if ((Status == STATUS_PENDING) && (!lpOverlapped))
229 {
230 Status = NtWaitForSingleObject(hDirectory, FALSE, NULL);
231
232 if (NT_SUCCESS(Status))
233 {
234 Status = IoStatus.Status;
235 }
236 }
237
238 if (!NT_SUCCESS(Status))
239 {
240 BaseSetLastNTError(Status);
241 return FALSE;
242 }
243
244
245 /* NOTE: lpBytesReturned is undefined for asynch. operations */
246 *lpBytesReturned = IoStatus.Information;
247
248 return TRUE;
249 }
250
251
252
253
254
255 /* EOF */