ReactOS 0.4.15-dev-8100-g1887773
cnotify.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/file/cnotify.c
5 * PURPOSE: Find functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 * UPDATE HISTORY:
8 * Created 01/11/98
9 */
10
11/* INCLUDES *******************************************************************/
12
13#include <k32.h>
14#define NDEBUG
15#include <debug.h>
16
17/* GLOBALS ********************************************************************/
18
21
22/* PRIVATE FUNCTIONS **********************************************************/
23
24VOID
29{
30 PBASEP_ACTCTX_BLOCK ActivationBlock = ApcContext;
32 DWORD BytesTransfered, Result;
33 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx;
34 PVOID ActivationContext = NULL;
35
36 /* Setup the activation frame */
37 RtlZeroMemory(&ActCtx, sizeof(ActCtx));
38 ActCtx.Size = sizeof(ActCtx);
40
41 /* Check if the routine returned an error */
43 {
44 /* Convert the error code and don't copy anything */
46 BytesTransfered = 0;
47 }
48 else
49 {
50 /* Set success code and copy the bytes transferred */
52 BytesTransfered = IoStatusBlock->Information;
53 }
54
55 /* Read context and routine out from the activation block */
56 ActivationContext = ActivationBlock->ActivationContext;
57 CompletionRoutine = ActivationBlock->CompletionRoutine;
58
59 /* Check if the block should be freed */
60 if (!(ActivationBlock->Flags & 1))
61 {
62 /* Free it */
64 }
65
66 /* Activate the context, call the routine, and then deactivate the context */
67 RtlActivateActivationContextUnsafeFast(&ActCtx, ActivationContext);
69 RtlDeactivateActivationContextUnsafeFast(&ActCtx);
70}
71
72VOID
77{
79 DWORD Result, BytesTransfered;
80
81 /* Check if the routine returned an error */
83 {
84 /* Convert the error code and don't copy anything */
86 BytesTransfered = 0;
87 }
88 else
89 {
90 /* Set success code and copy the bytes transferred */
92 BytesTransfered = IoStatusBlock->Information;
93 }
94
95 /* Call the callback routine */
97}
98
99/* PUBLIC FUNCTIONS ***********************************************************/
100
101/*
102 * @implemented
103 */
104BOOL
105WINAPI
107{
108 /* Just close the handle */
109 return CloseHandle(hChangeHandle);
110}
111
112/*
113 * @implemented
114 */
115HANDLE
116WINAPI
118 IN BOOL bWatchSubtree,
119 IN DWORD dwNotifyFilter)
120{
121 /* Call the W(ide) function */
123 lpPathName,
124 bWatchSubtree,
125 dwNotifyFilter);
126}
127
128/*
129 * @implemented
130 */
131HANDLE
132WINAPI
134 IN BOOL bWatchSubtree,
135 IN DWORD dwNotifyFilter)
136{
138 UNICODE_STRING NtPathU;
140 HANDLE hDir;
141 RTL_RELATIVE_NAME_U RelativeName;
142 PWCHAR PathBuffer;
144
145 /* Convert to NT path and get the relative name too */
146 if (!RtlDosPathNameToNtPathName_U(lpPathName,
147 &NtPathU,
148 NULL,
149 &RelativeName))
150 {
151 /* Bail out if the path name makes no sense */
154 }
155
156 /* Save the path buffer in case we free it later */
157 PathBuffer = NtPathU.Buffer;
158
159 /* If we have a relative name... */
160 if (RelativeName.RelativeName.Length)
161 {
162 /* Do a relative open with only the relative path set */
163 NtPathU = RelativeName.RelativeName;
164 }
165 else
166 {
167 /* Do a full path open with no containing directory */
168 RelativeName.ContainingDirectory = NULL;
169 }
170
171 /* Now open the directory name that was passed in */
173 &NtPathU,
175 RelativeName.ContainingDirectory,
176 NULL);
177 Status = NtOpenFile(&hDir,
183
184 /* Release our buffer and relative name structure */
185 RtlReleaseRelativeName(&RelativeName);
186 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
187
188 /* Check if the open failed */
189 if (!NT_SUCCESS(Status))
190 {
191 /* Bail out in that case */
194 }
195
196 /* Now setup the notification on the directory as requested */
198 NULL,
199 NULL,
200 NULL,
203 sizeof(staticchangebuff),
204 dwNotifyFilter,
205 (BOOLEAN)bWatchSubtree);
206 if (!NT_SUCCESS(Status))
207 {
208 /* We failed, close the handle and convert the error */
209 NtClose(hDir);
212 }
213
214 /* Return the directory handle on success, or invalid handle otherwise */
215 return hDir;
216}
217
218/*
219 * @implemented
220 */
221BOOL
222WINAPI
224{
226
227 /* Just call the native API directly, dealing with the non-optional parameters */
228 Status = NtNotifyChangeDirectoryFile(hChangeHandle,
229 NULL,
230 NULL,
231 NULL,
234 sizeof(staticchangebuff),
236 TRUE);
237 if (!NT_SUCCESS(Status))
238 {
239 /* Convert the error code and fail */
241 return FALSE;
242 }
243
244 /* All went well */
245 return TRUE;
246}
247
248/*
249 * @implemented
250 */
251BOOL
252WINAPI
256 IN BOOL bWatchSubtree,
257 IN DWORD dwNotifyFilter,
260 IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
261{
262
267 PBASEP_ACTCTX_BLOCK ActivationContext = NULL;
268 BOOL Result = TRUE;
270
271 /* Is the caller doing this synchronously? */
272 if (!lpOverlapped)
273 {
274 /* Great, just pass in the parameters */
276 NULL,
277 NULL,
278 NULL,
280 lpBuffer,
282 dwNotifyFilter,
283 bWatchSubtree);
284 if (Status == STATUS_PENDING)
285 {
286 /* Wait for completion since we are synchronous */
287 Status = NtWaitForSingleObject(hDirectory, FALSE, NULL);
288 if (!NT_SUCCESS(Status))
289 {
290 /* The wait failed, bail out */
292 return FALSE;
293 }
294
295 /* Retrieve the final status code */
297 }
298
299 /* Did the operation succeed? */
300 if (NT_SUCCESS(Status))
301 {
302 /* Return the bytes transferd and success */
304 return Result;
305 }
306
307 /* Convert error code and return failure */
309 return FALSE;
310 }
311
312 /* Does the caller want an APC callback? */
313 if (lpCompletionRoutine)
314 {
315 /* Don't use an event in this case */
317
318 /* Allocate a Fusion/SxS activation context for the callback routine */
320 lpCompletionRoutine,
322 &ActivationContext);
323 if (!NT_SUCCESS(Status))
324 {
325 /* This failed, so abandon the call */
327 return FALSE;
328 }
329
330 /* Use the SxS context as the APC context */
331 ApcContext = ActivationContext;
332 if (ActivationContext)
333 {
334 /* And use a special stub routine that deals with activation */
336 }
337 else
338 {
339 /* If there was no context, however, use the simple stub routine */
340 ApcContext = lpCompletionRoutine;
342 }
343 }
344 else
345 {
346 /* Use the even with no APC routine */
347 EventHandle = lpOverlapped->hEvent;
348 ApcRoutine = 0;
349
350 /* LPOVERLAPPED should be ignored if event is ORed with 1 */
352 }
353
354 /* Set the initial status to pending and call the native API */
355 lpOverlapped->Internal = STATUS_PENDING;
361 lpBuffer,
363 dwNotifyFilter,
364 (BOOLEAN)bWatchSubtree);
365 if (NT_ERROR(Status))
366 {
367 /* Normally we cleanup the context in the completion routine, but we failed */
368 if (ActivationContext) BasepFreeActivationContextActivationBlock(ActivationContext);
369
370 /* Convert the error and fail */
372 return FALSE;
373 }
374
375 /* Return success */
376 return Result;
377}
378
379/* EOF */
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define ConvertWin32AnsiChangeApiToUnicodeApi(obj, name,...)
Definition: base_x.h:76
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
BOOL WINAPI FindCloseChangeNotification(IN HANDLE hChangeHandle)
Definition: cnotify.c:106
VOID WINAPI BasepIoCompletion(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN DWORD Reserved)
Definition: cnotify.c:26
BOOL WINAPI FindNextChangeNotification(IN HANDLE hChangeHandle)
Definition: cnotify.c:223
IO_STATUS_BLOCK staticIoStatusBlock
Definition: cnotify.c:20
VOID WINAPI BasepIoCompletionSimple(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN DWORD Reserved)
Definition: cnotify.c:74
BOOL WINAPI ReadDirectoryChangesW(IN HANDLE hDirectory, IN LPVOID lpBuffer OPTIONAL, IN DWORD nBufferLength, IN BOOL bWatchSubtree, IN DWORD dwNotifyFilter, OUT LPDWORD lpBytesReturned, IN LPOVERLAPPED lpOverlapped OPTIONAL, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: cnotify.c:253
HANDLE WINAPI FindFirstChangeNotificationW(IN LPCWSTR lpPathName, IN BOOL bWatchSubtree, IN DWORD dwNotifyFilter)
Definition: cnotify.c:133
CHAR staticchangebuff[sizeof(FILE_NOTIFY_INFORMATION)+16]
Definition: cnotify.c:19
HANDLE WINAPI FindFirstChangeNotificationA(IN LPCSTR lpPathName, IN BOOL bWatchSubtree, IN DWORD dwNotifyFilter)
Definition: cnotify.c:117
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CloseHandle
Definition: compat.h:739
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FILE_SHARE_READ
Definition: compat.h:136
NTSTATUS NTAPI BasepAllocateActivationContextActivationBlock(IN DWORD Flags, IN PVOID CompletionRoutine, IN PVOID CompletionContext, OUT PBASEP_ACTCTX_BLOCK *ActivationBlock)
Definition: actctx.c:45
VOID NTAPI BasepFreeActivationContextActivationBlock(IN PBASEP_ACTCTX_BLOCK ActivationBlock)
Definition: actctx.c:26
#define ULONG_PTR
Definition: config.h:101
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
NTSTATUS NTAPI NtNotifyChangeDirectoryFile(IN HANDLE FileHandle, IN HANDLE EventHandle OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG BufferSize, IN ULONG CompletionFilter, IN BOOLEAN WatchTree)
Definition: iofunc.c:1622
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:247
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:93
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:727
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE ApcRoutine
Definition: iofuncs.h:726
VOID NTAPI RtlReleaseRelativeName(_In_ PRTL_RELATIVE_NAME_U RelativeName)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
#define RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER
Definition: rtltypes.h:101
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
VOID(* PIO_APC_ROUTINE)(IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved)
Definition: nt_native.h:877
#define STATUS_PENDING
Definition: ntstatus.h:82
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PVOID ActivationContext
Definition: kernel32.h:102
LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
Definition: kernel32.h:104
UNICODE_STRING RelativeName
Definition: rtltypes.h:1380
HANDLE ContainingDirectory
Definition: rtltypes.h:1381
uint32_t * LPDWORD
Definition: typedefs.h:59
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
#define OUT
Definition: typedefs.h:40
#define NT_ERROR(Status)
Definition: umtypes.h:106
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895
void(CALLBACK * LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD, DWORD, LPOVERLAPPED)
Definition: winbase.h:1451
#define FindFirstChangeNotification
Definition: winbase.h:3781
_In_ LPCSTR _In_opt_ LPCSTR _In_ DWORD nBufferLength
Definition: winbase.h:3073
_In_ DWORD _In_ DWORD _In_ DWORD _Out_ LPDWORD lpBytesReturned
Definition: winddi.h:1705
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define WINAPI
Definition: msvc.h:6
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
struct _FILE_NOTIFY_INFORMATION FILE_NOTIFY_INFORMATION
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:857
#define FILE_NOTIFY_CHANGE_SECURITY
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175