systray: Add support for NIS_HIDDEN flag.
[wine.git] / dlls / kernel32 / change.c
blob0505ca91ace31637ef8b008a1b28158adcf289bb
1 /*
2 * Win32 file change notification functions
4 * Copyright 1998 Ulrich Weigand
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
27 #include "ntstatus.h"
28 #define WIN32_NO_STATUS
29 #define NONAMELESSUNION
30 #define NONAMELESSSTRUCT
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winerror.h"
34 #include "winternl.h"
35 #include "kernel_private.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(file);
40 /****************************************************************************
41 * FindFirstChangeNotificationA (KERNEL32.@)
43 HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName, BOOL bWatchSubtree,
44 DWORD dwNotifyFilter )
46 WCHAR *pathW;
48 if (!(pathW = FILE_name_AtoW( lpPathName, FALSE ))) return INVALID_HANDLE_VALUE;
49 return FindFirstChangeNotificationW( pathW, bWatchSubtree, dwNotifyFilter );
53 * NtNotifyChangeDirectoryFile may write back to the IO_STATUS_BLOCK
54 * asynchronously. We don't care about the contents, but it can't
55 * be placed on the stack since it will go out of scope when we return.
57 static IO_STATUS_BLOCK FindFirstChange_iosb;
59 /****************************************************************************
60 * FindFirstChangeNotificationW (KERNEL32.@)
62 HANDLE WINAPI FindFirstChangeNotificationW( LPCWSTR lpPathName, BOOL bWatchSubtree,
63 DWORD dwNotifyFilter)
65 UNICODE_STRING nt_name;
66 OBJECT_ATTRIBUTES attr;
67 NTSTATUS status;
68 HANDLE handle = INVALID_HANDLE_VALUE;
70 TRACE( "%s %d %x\n", debugstr_w(lpPathName), bWatchSubtree, dwNotifyFilter );
72 if (!RtlDosPathNameToNtPathName_U( lpPathName, &nt_name, NULL, NULL ))
74 SetLastError( ERROR_PATH_NOT_FOUND );
75 return handle;
78 attr.Length = sizeof(attr);
79 attr.RootDirectory = 0;
80 attr.Attributes = OBJ_CASE_INSENSITIVE;
81 attr.ObjectName = &nt_name;
82 attr.SecurityDescriptor = NULL;
83 attr.SecurityQualityOfService = NULL;
85 status = NtOpenFile( &handle, FILE_LIST_DIRECTORY | SYNCHRONIZE,
86 &attr, &FindFirstChange_iosb,
87 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
88 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT );
89 RtlFreeUnicodeString( &nt_name );
91 if (status != STATUS_SUCCESS)
93 SetLastError( RtlNtStatusToDosError(status) );
94 return INVALID_HANDLE_VALUE;
97 status = NtNotifyChangeDirectoryFile( handle, NULL, NULL, NULL,
98 &FindFirstChange_iosb,
99 NULL, 0, dwNotifyFilter, bWatchSubtree );
100 if (status != STATUS_PENDING)
102 NtClose( handle );
103 SetLastError( RtlNtStatusToDosError(status) );
104 return INVALID_HANDLE_VALUE;
106 return handle;
109 /****************************************************************************
110 * FindNextChangeNotification (KERNEL32.@)
112 BOOL WINAPI FindNextChangeNotification( HANDLE handle )
114 NTSTATUS status;
116 TRACE("%p\n",handle);
118 status = NtNotifyChangeDirectoryFile( handle, NULL, NULL, NULL,
119 &FindFirstChange_iosb,
120 NULL, 0, FILE_NOTIFY_CHANGE_SIZE, 0 );
121 if (status != STATUS_PENDING)
123 SetLastError( RtlNtStatusToDosError(status) );
124 return FALSE;
126 return TRUE;
129 /****************************************************************************
130 * FindCloseChangeNotification (KERNEL32.@)
132 BOOL WINAPI FindCloseChangeNotification( HANDLE handle )
134 return CloseHandle( handle );
137 /****************************************************************************
138 * ReadDirectoryChangesW (KERNEL32.@)
140 * NOTES
142 * The filter is remember from the first run and ignored on successive runs.
144 * If there's no output buffer on the first run, it's ignored successive runs
145 * and STATUS_NOTIFY_ENUM_DIRECTORY is returned with an empty buffer.
147 * If a NULL overlapped->hEvent is passed, the directory handle is used
148 * for signalling.
150 BOOL WINAPI ReadDirectoryChangesW( HANDLE handle, LPVOID buffer, DWORD len, BOOL subtree,
151 DWORD filter, LPDWORD returned, LPOVERLAPPED overlapped,
152 LPOVERLAPPED_COMPLETION_ROUTINE completion )
154 OVERLAPPED ov, *pov;
155 IO_STATUS_BLOCK *ios;
156 NTSTATUS status;
157 BOOL ret = TRUE;
158 LPVOID cvalue = NULL;
160 TRACE("%p %p %08x %d %08x %p %p %p\n", handle, buffer, len, subtree, filter,
161 returned, overlapped, completion );
163 if (!overlapped)
165 memset( &ov, 0, sizeof ov );
166 ov.hEvent = CreateEventW( NULL, 0, 0, NULL );
167 pov = &ov;
169 else
171 pov = overlapped;
172 if (!completion && ((ULONG_PTR)overlapped->hEvent & 1) == 0) cvalue = overlapped;
175 ios = (PIO_STATUS_BLOCK) pov;
176 ios->u.Status = STATUS_PENDING;
178 status = NtNotifyChangeDirectoryFile( handle, pov->hEvent, NULL, cvalue,
179 ios, buffer, len, filter, subtree );
180 if (status == STATUS_PENDING)
182 if (overlapped)
183 return TRUE;
185 WaitForSingleObjectEx( ov.hEvent, INFINITE, TRUE );
186 CloseHandle( ov.hEvent );
187 if (returned)
188 *returned = ios->Information;
189 status = ios->u.Status;
192 if (status != STATUS_SUCCESS)
194 SetLastError( RtlNtStatusToDosError(status) );
195 ret = FALSE;
198 return ret;