[KERNEL32]
[reactos.git] / reactos / dll / win32 / kernel32 / 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 SetLastErrorByStatus(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 NTSTATUS Status;
47 ANSI_STRING PathNameString;
48
49 RtlInitAnsiString(&PathNameString, lpPathName);
50 Status = RtlAnsiStringToUnicodeString(&(NtCurrentTeb()->StaticUnicodeString), &PathNameString, FALSE);
51 if (!NT_SUCCESS(Status))
52 {
53 if (Status != STATUS_BUFFER_OVERFLOW)
54 {
55 SetLastError(ERROR_FILENAME_EXCED_RANGE);
56 }
57 else
58 {
59 BaseSetLastNTError(Status);
60 }
61 return INVALID_HANDLE_VALUE;
62 }
63
64 return FindFirstChangeNotificationW(NtCurrentTeb()->StaticUnicodeString.Buffer,
65 bWatchSubtree, dwNotifyFilter);
66 }
67
68
69 /*
70 * @implemented
71 */
72 HANDLE
73 WINAPI
74 FindFirstChangeNotificationW (
75 LPCWSTR lpPathName,
76 BOOL bWatchSubtree,
77 DWORD dwNotifyFilter
78 )
79 {
80 NTSTATUS Status;
81 UNICODE_STRING NtPathU;
82 IO_STATUS_BLOCK IoStatus;
83 OBJECT_ATTRIBUTES ObjectAttributes;
84 HANDLE hDir;
85
86 if (!RtlDosPathNameToNtPathName_U (lpPathName,
87 &NtPathU,
88 NULL,
89 NULL))
90 {
91 SetLastErrorByStatus(STATUS_OBJECT_PATH_SYNTAX_BAD);
92 return INVALID_HANDLE_VALUE;
93 }
94
95
96
97 InitializeObjectAttributes (&ObjectAttributes,
98 &NtPathU,
99 OBJ_CASE_INSENSITIVE,
100 NULL,
101 NULL);
102
103 Status = NtOpenFile (&hDir,
104 SYNCHRONIZE|FILE_LIST_DIRECTORY,
105 &ObjectAttributes,
106 &IoStatus,
107 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
108 FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT);
109
110 RtlFreeHeap(RtlGetProcessHeap(),
111 0,
112 NtPathU.Buffer);
113
114
115
116 if (!NT_SUCCESS(Status))
117 {
118 SetLastErrorByStatus(Status);
119 return INVALID_HANDLE_VALUE;
120 }
121
122 Status = NtNotifyChangeDirectoryFile(hDir,
123 NULL,
124 NULL,
125 NULL,
126 &IoStatus,
127 NULL,//Buffer,
128 0,//BufferLength,
129 dwNotifyFilter,
130 (BOOLEAN)bWatchSubtree);
131 if (!NT_SUCCESS(Status))
132 {
133 NtClose(hDir);
134 SetLastErrorByStatus(Status);
135 return INVALID_HANDLE_VALUE;
136 }
137
138 return hDir;
139 }
140
141
142 /*
143 * @implemented
144 */
145 BOOL
146 WINAPI
147 FindNextChangeNotification (
148 HANDLE hChangeHandle
149 )
150 {
151 IO_STATUS_BLOCK IoStatus;
152 NTSTATUS Status;
153
154 Status = NtNotifyChangeDirectoryFile(hChangeHandle,
155 NULL,
156 NULL,
157 NULL,
158 &IoStatus,
159 NULL,//Buffer,
160 0,//BufferLength,
161 FILE_NOTIFY_CHANGE_SECURITY,//meaningless/ignored for subsequent calls, but must contain a valid flag
162 0 //meaningless/ignored for subsequent calls
163 );
164
165 if (!NT_SUCCESS(Status))
166 {
167 SetLastErrorByStatus(Status);
168 return FALSE;
169 }
170
171 return TRUE;
172 }
173
174
175 extern VOID
176 (WINAPI ApcRoutine)(PVOID ApcContext,
177 struct _IO_STATUS_BLOCK* IoStatusBlock,
178 ULONG Reserved);
179
180
181 /*
182 * @implemented
183 */
184 BOOL
185 WINAPI
186 ReadDirectoryChangesW(
187 HANDLE hDirectory,
188 LPVOID lpBuffer OPTIONAL,
189 DWORD nBufferLength,
190 BOOL bWatchSubtree,
191 DWORD dwNotifyFilter,
192 LPDWORD lpBytesReturned, /* undefined for asych. operations */
193 LPOVERLAPPED lpOverlapped OPTIONAL,
194 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine /* OPTIONAL???????? */
195 )
196 {
197 PVOID CompletionRoutine;
198 NTSTATUS Status;
199 IO_STATUS_BLOCK IoStatus;
200 HANDLE EventHandle;
201 PIO_APC_ROUTINE IoApcRoutine;
202
203 if (lpOverlapped )
204 {
205 if (lpCompletionRoutine)
206 {
207 CompletionRoutine = (PVOID) lpCompletionRoutine;
208 EventHandle = NULL;
209 IoApcRoutine = ApcRoutine;
210 }
211 else
212 {
213 if (((ULONG_PTR) lpOverlapped->hEvent & 1) == 0)
214 CompletionRoutine = (PVOID) lpOverlapped;
215 else
216 CompletionRoutine = NULL;
217
218 EventHandle = lpOverlapped->hEvent;
219 IoApcRoutine = NULL;
220 }
221
222 lpOverlapped->Internal = STATUS_PENDING;
223 }
224 else
225 {
226 EventHandle = NULL;
227 IoApcRoutine = NULL;
228 CompletionRoutine = NULL;
229 }
230
231 Status = NtNotifyChangeDirectoryFile(
232 hDirectory,
233 EventHandle,
234 IoApcRoutine,
235 CompletionRoutine, /* ApcContext */
236 lpOverlapped ? (PIO_STATUS_BLOCK) lpOverlapped : &IoStatus,
237 lpBuffer,
238 nBufferLength,
239 dwNotifyFilter,
240 (BOOLEAN)bWatchSubtree
241 );
242
243 if ((Status == STATUS_PENDING) && (!lpOverlapped))
244 {
245 Status = NtWaitForSingleObject(hDirectory, FALSE, NULL);
246
247 if (NT_SUCCESS(Status))
248 {
249 Status = IoStatus.Status;
250 }
251 }
252
253 if (!NT_SUCCESS(Status))
254 {
255 SetLastErrorByStatus(Status);
256 return FALSE;
257 }
258
259
260 /* NOTE: lpBytesReturned is undefined for asynch. operations */
261 *lpBytesReturned = IoStatus.Information;
262
263 return TRUE;
264 }
265
266
267
268
269
270 /* EOF */