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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #define WIN32_NO_STATUS
33 #include "kernel_private.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(file
);
38 /****************************************************************************
39 * FindFirstChangeNotificationA (KERNEL32.@)
41 HANDLE WINAPI
FindFirstChangeNotificationA( LPCSTR lpPathName
, BOOL bWatchSubtree
,
42 DWORD dwNotifyFilter
)
46 if (!(pathW
= FILE_name_AtoW( lpPathName
, FALSE
))) return INVALID_HANDLE_VALUE
;
47 return FindFirstChangeNotificationW( pathW
, bWatchSubtree
, dwNotifyFilter
);
51 * NtNotifyChangeDirectoryFile may write back to the IO_STATUS_BLOCK
52 * asynchronously. We don't care about the contents, but it can't
53 * be placed on the stack since it will go out of scope when we return.
55 static IO_STATUS_BLOCK FindFirstChange_iosb
;
57 /****************************************************************************
58 * FindFirstChangeNotificationW (KERNEL32.@)
60 HANDLE WINAPI
FindFirstChangeNotificationW( LPCWSTR lpPathName
, BOOL bWatchSubtree
,
63 UNICODE_STRING nt_name
;
64 OBJECT_ATTRIBUTES attr
;
66 HANDLE handle
= INVALID_HANDLE_VALUE
;
68 TRACE( "%s %d %lx\n", debugstr_w(lpPathName
), bWatchSubtree
, dwNotifyFilter
);
70 if (!RtlDosPathNameToNtPathName_U( lpPathName
, &nt_name
, NULL
, NULL
))
72 SetLastError( ERROR_PATH_NOT_FOUND
);
76 attr
.Length
= sizeof(attr
);
77 attr
.RootDirectory
= 0;
78 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
79 attr
.ObjectName
= &nt_name
;
80 attr
.SecurityDescriptor
= NULL
;
81 attr
.SecurityQualityOfService
= NULL
;
83 status
= NtOpenFile( &handle
, FILE_LIST_DIRECTORY
| SYNCHRONIZE
,
84 &attr
, &FindFirstChange_iosb
,
85 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
86 FILE_DIRECTORY_FILE
| FILE_SYNCHRONOUS_IO_NONALERT
);
87 RtlFreeUnicodeString( &nt_name
);
89 if (status
!= STATUS_SUCCESS
)
91 SetLastError( RtlNtStatusToDosError(status
) );
92 return INVALID_HANDLE_VALUE
;
95 status
= NtNotifyChangeDirectoryFile( handle
, NULL
, NULL
, NULL
,
96 &FindFirstChange_iosb
,
97 NULL
, 0, dwNotifyFilter
, bWatchSubtree
);
98 if (status
!= STATUS_PENDING
)
101 SetLastError( RtlNtStatusToDosError(status
) );
102 return INVALID_HANDLE_VALUE
;
107 /****************************************************************************
108 * FindNextChangeNotification (KERNEL32.@)
110 BOOL WINAPI
FindNextChangeNotification( HANDLE handle
)
114 TRACE("%p\n",handle
);
116 status
= NtNotifyChangeDirectoryFile( handle
, NULL
, NULL
, NULL
,
117 &FindFirstChange_iosb
,
118 NULL
, 0, FILE_NOTIFY_CHANGE_SIZE
, 0 );
119 if (status
!= STATUS_PENDING
)
121 SetLastError( RtlNtStatusToDosError(status
) );
127 /****************************************************************************
128 * FindCloseChangeNotification (KERNEL32.@)
130 BOOL WINAPI
FindCloseChangeNotification( HANDLE handle
)
132 return CloseHandle( handle
);
135 BOOL WINAPI
ReadDirectoryChangesW( HANDLE handle
, LPVOID buffer
, DWORD len
, BOOL subtree
,
136 DWORD filter
, LPDWORD returned
, LPOVERLAPPED overlapped
,
137 LPOVERLAPPED_COMPLETION_ROUTINE completion
)
140 IO_STATUS_BLOCK
*ios
;
144 TRACE("%p %p %08lx %d %08lx %p %p %p\n", handle
, buffer
, len
, subtree
, filter
,
145 returned
, overlapped
, completion
);
149 memset( &ov
, 0, sizeof ov
);
150 ov
.hEvent
= CreateEventW( NULL
, 0, 0, NULL
);
156 ios
= (PIO_STATUS_BLOCK
) pov
;
157 ios
->Status
= STATUS_PENDING
;
158 ios
->Information
= 0;
160 status
= NtNotifyChangeDirectoryFile( handle
, pov
->hEvent
, NULL
, NULL
,
161 ios
, buffer
, len
, filter
, subtree
);
162 if (status
== STATUS_PENDING
)
167 WaitForSingleObjectEx( ov
.hEvent
, INFINITE
, TRUE
);
168 CloseHandle( ov
.hEvent
);
170 *returned
= ios
->Information
;
171 status
= ios
->Status
;
174 if (status
!= STATUS_SUCCESS
)
176 SetLastError( RtlNtStatusToDosError(status
) );