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:
parent
be22a96847
commit
0790f95589
|
@ -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 );
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 ))
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
Loading…
Reference in New Issue