kernel32: ReadDirectoryChangesW fixes.

ReadDirectoryChangesW remembers whether it's recording changes or not.
Don't initialize overlapped->InternalHigh.
The hEvent is cleared when ReadDirectoryChanges is called.
This commit is contained in:
Mike McCormack 2006-02-07 16:50:36 +01:00 committed by Alexandre Julliard
parent be22a96847
commit 0790f95589
6 changed files with 40 additions and 14 deletions

View File

@ -132,6 +132,19 @@ BOOL WINAPI FindCloseChangeNotification( HANDLE handle )
return CloseHandle( handle ); return CloseHandle( handle );
} }
/****************************************************************************
* ReadDirectoryChangesW (KERNEL32.@)
*
* NOTES
*
* The filter is remember from the first run and ignored on successive runs.
*
* If there's no output buffer on the first run, it's ignored successive runs
* and STATUS_NOTIFY_ENUM_DIRECTORY is returned with an empty buffer.
*
* If a NULL overlapped->hEvent is passed, the directory handle is used
* for signalling.
*/
BOOL WINAPI ReadDirectoryChangesW( HANDLE handle, LPVOID buffer, DWORD len, BOOL subtree, BOOL WINAPI ReadDirectoryChangesW( HANDLE handle, LPVOID buffer, DWORD len, BOOL subtree,
DWORD filter, LPDWORD returned, LPOVERLAPPED overlapped, DWORD filter, LPDWORD returned, LPOVERLAPPED overlapped,
LPOVERLAPPED_COMPLETION_ROUTINE completion ) LPOVERLAPPED_COMPLETION_ROUTINE completion )
@ -155,7 +168,6 @@ BOOL WINAPI ReadDirectoryChangesW( HANDLE handle, LPVOID buffer, DWORD len, BOOL
ios = (PIO_STATUS_BLOCK) pov; ios = (PIO_STATUS_BLOCK) pov;
ios->Status = STATUS_PENDING; ios->Status = STATUS_PENDING;
ios->Information = 0;
status = NtNotifyChangeDirectoryFile( handle, pov->hEvent, NULL, NULL, status = NtNotifyChangeDirectoryFile( handle, pov->hEvent, NULL, NULL,
ios, buffer, len, filter, subtree ); ios, buffer, len, filter, subtree );

View File

@ -1899,6 +1899,7 @@ NtNotifyChangeDirectoryFile( HANDLE FileHandle, HANDLE Event,
req->handle = FileHandle; req->handle = FileHandle;
req->event = Event; req->event = Event;
req->filter = CompletionFilter; req->filter = CompletionFilter;
req->want_data = (Buffer != NULL);
req->io_apc = read_changes_apc; req->io_apc = read_changes_apc;
req->io_sb = IoStatusBlock; req->io_sb = IoStatusBlock;
req->io_user = info; req->io_user = info;

View File

@ -1401,6 +1401,7 @@ struct read_directory_changes_request
obj_handle_t handle; obj_handle_t handle;
obj_handle_t event; obj_handle_t event;
unsigned int filter; unsigned int filter;
int want_data;
void* io_apc; void* io_apc;
void* io_sb; void* io_sb;
void* io_user; void* io_user;
@ -4363,6 +4364,6 @@ union generic_reply
struct query_symlink_reply query_symlink_reply; struct query_symlink_reply query_symlink_reply;
}; };
#define SERVER_PROTOCOL_VERSION 224 #define SERVER_PROTOCOL_VERSION 225
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -141,6 +141,7 @@ struct dir
struct event *event; struct event *event;
unsigned int filter; /* notification filter */ unsigned int filter; /* notification filter */
int notified; /* SIGIO counter */ int notified; /* SIGIO counter */
int want_data; /* return change data */
long signaled; /* the file changed */ long signaled; /* the file changed */
struct fd *inotify_fd; /* inotify file descriptor */ struct fd *inotify_fd; /* inotify file descriptor */
int wd; /* inotify watch descriptor */ int wd; /* inotify watch descriptor */
@ -254,6 +255,7 @@ struct object *create_dir_obj( struct fd *fd )
dir->filter = 0; dir->filter = 0;
dir->notified = 0; dir->notified = 0;
dir->signaled = 0; dir->signaled = 0;
dir->want_data = 0;
dir->inotify_fd = NULL; dir->inotify_fd = NULL;
dir->wd = -1; dir->wd = -1;
grab_object( fd ); grab_object( fd );
@ -412,20 +414,23 @@ static void inotify_do_change_notify( struct dir *dir, struct inotify_event *ie
{ {
struct change_record *record; struct change_record *record;
record = malloc( sizeof (*record) + ie->len - 1 ) ; if (dir->want_data)
if (!record) {
return; record = malloc( sizeof (*record) + ie->len - 1 ) ;
if (!record)
return;
if( ie->mask & IN_CREATE ) if( ie->mask & IN_CREATE )
record->action = FILE_ACTION_ADDED; record->action = FILE_ACTION_ADDED;
else if( ie->mask & IN_DELETE ) else if( ie->mask & IN_DELETE )
record->action = FILE_ACTION_REMOVED; record->action = FILE_ACTION_REMOVED;
else else
record->action = FILE_ACTION_MODIFIED; record->action = FILE_ACTION_MODIFIED;
memcpy( record->name, ie->name, ie->len ); memcpy( record->name, ie->name, ie->len );
record->len = strlen( ie->name ); record->len = strlen( ie->name );
list_add_tail( &dir->change_records, &record->entry ); list_add_tail( &dir->change_records, &record->entry );
}
if (!list_empty( &dir->change_q )) if (!list_empty( &dir->change_q ))
async_terminate_head( &dir->change_q, STATUS_ALERTED ); async_terminate_head( &dir->change_q, STATUS_ALERTED );
@ -551,12 +556,17 @@ DECL_HANDLER(read_directory_changes)
{ {
insert_change( dir ); insert_change( dir );
dir->filter = req->filter; dir->filter = req->filter;
dir->want_data = req->want_data;
} }
/* remove any notifications */ /* remove any notifications */
if (dir->signaled>0) if (dir->signaled>0)
dir->signaled--; dir->signaled--;
/* clear the event */
if (event)
reset_event( event );
/* setup the real notification */ /* setup the real notification */
#ifdef USE_INOTIFY #ifdef USE_INOTIFY
if (!inotify_adjust_changes( dir )) if (!inotify_adjust_changes( dir ))

View File

@ -1045,6 +1045,7 @@ enum char_info_mode
obj_handle_t handle; /* handle to the directory */ obj_handle_t handle; /* handle to the directory */
obj_handle_t event; /* handle to the event */ obj_handle_t event; /* handle to the event */
unsigned int filter; /* notification filter */ unsigned int filter; /* notification filter */
int want_data; /* flag indicating whether change data should be collected */
void* io_apc; /* APC routine to queue upon end of async */ void* io_apc; /* APC routine to queue upon end of async */
void* io_sb; /* I/O status block (unique across all async on this handle) */ void* io_sb; /* I/O status block (unique across all async on this handle) */
void* io_user; /* data to pass back to caller */ void* io_user; /* data to pass back to caller */

View File

@ -1449,6 +1449,7 @@ static void dump_read_directory_changes_request( const struct read_directory_cha
fprintf( stderr, " handle=%p,", req->handle ); fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " event=%p,", req->event ); fprintf( stderr, " event=%p,", req->event );
fprintf( stderr, " filter=%08x,", req->filter ); fprintf( stderr, " filter=%08x,", req->filter );
fprintf( stderr, " want_data=%d,", req->want_data );
fprintf( stderr, " io_apc=%p,", req->io_apc ); fprintf( stderr, " io_apc=%p,", req->io_apc );
fprintf( stderr, " io_sb=%p,", req->io_sb ); fprintf( stderr, " io_sb=%p,", req->io_sb );
fprintf( stderr, " io_user=%p", req->io_user ); fprintf( stderr, " io_user=%p", req->io_user );