Module: wine Branch: refs/heads/master Commit: 7a61f086f17057a19ad3a65e2f177bbe3de136ac URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=7a61f086f17057a19ad3a65e...
Author: Mike McCormack mike@codeweavers.com Date: Tue Feb 7 16:50:44 2006 +0100
kernel32: More test cases for ReadDirectoryChangesW.
---
dlls/kernel/tests/change.c | 174 ++++++++++++++++++++++++++++++++++++++------ 1 files changed, 150 insertions(+), 24 deletions(-)
diff --git a/dlls/kernel/tests/change.c b/dlls/kernel/tests/change.c index 1b384ae..e21a875 100644 --- a/dlls/kernel/tests/change.c +++ b/dlls/kernel/tests/change.c @@ -29,9 +29,12 @@ #include <stdarg.h> #include <stdio.h>
+#include "ntstatus.h" +#define WIN32_NO_STATUS #include "wine/test.h" #include <windef.h> #include <winbase.h> +#include <winternl.h>
static DWORD CALLBACK NotificationThread(LPVOID arg) { @@ -316,22 +319,19 @@ static void test_ffcn(void)
typedef BOOL (WINAPI *fnReadDirectoryChangesW)(HANDLE,LPVOID,DWORD,BOOL,DWORD, LPDWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE); +fnReadDirectoryChangesW pReadDirectoryChangesW;
static void test_readdirectorychanges(void) { HANDLE hdir; char buffer[0x1000]; - DWORD fflags, filter = 0, r; + DWORD fflags, filter = 0, r, dwCount; OVERLAPPED ov; WCHAR path[MAX_PATH], subdir[MAX_PATH]; static const WCHAR szBoo[] = { '\','b','o','o',0 }; static const WCHAR szHoo[] = { '\','h','o','o',0 }; - fnReadDirectoryChangesW pReadDirectoryChangesW; - HMODULE hkernel32; + PFILE_NOTIFY_INFORMATION pfni;
- hkernel32 = GetModuleHandle("kernel32"); - pReadDirectoryChangesW = (fnReadDirectoryChangesW) - GetProcAddress(hkernel32, "ReadDirectoryChangesW"); if (!pReadDirectoryChangesW) return;
@@ -356,11 +356,12 @@ static void test_readdirectorychanges(vo ok(r==FALSE, "should return false\n");
fflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED; - hdir = CreateFileW(path, GENERIC_READ|SYNCHRONIZE, FILE_SHARE_READ, NULL, + hdir = CreateFileW(path, GENERIC_READ|SYNCHRONIZE|FILE_LIST_DIRECTORY, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, fflags, NULL); ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
- ov.hEvent = CreateEvent( NULL, 0, 0, NULL ); + ov.hEvent = CreateEvent( NULL, 1, 0, NULL );
SetLastError(0xd0b00b00); r = pReadDirectoryChangesW(hdir,NULL,0,FALSE,0,NULL,NULL,NULL); @@ -382,28 +383,40 @@ static void test_readdirectorychanges(vo filter |= FILE_NOTIFY_CHANGE_SECURITY;
SetLastError(0xd0b00b00); + ov.Internal = 0; + ov.InternalHigh = 0; + memset( buffer, 0, sizeof buffer ); + r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,-1,NULL,&ov,NULL); ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n"); ok(r==FALSE, "should return false\n");
- r = pReadDirectoryChangesW(hdir,NULL,0,FALSE,filter,NULL,&ov,NULL); - ok(r==TRUE, "should return true\n"); + r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,&ov,NULL); + ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n"); + ok(r==FALSE, "should return false\n");
- r = WaitForSingleObject( ov.hEvent, 0 ); - ok( r == STATUS_TIMEOUT, "should timeout\n" ); + r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL); + ok(r==TRUE, "should return true\n");
- r = WaitForSingleObject( hdir, 0 ); + r = WaitForSingleObject( ov.hEvent, 10 ); ok( r == STATUS_TIMEOUT, "should timeout\n" );
r = CreateDirectoryW( subdir, NULL ); ok( r == TRUE, "failed to create directory\n");
- r = WaitForSingleObject( hdir, 0 ); - ok( r == STATUS_TIMEOUT, "should timeout\n" ); - - r = WaitForSingleObject( ov.hEvent, 0 ); + r = WaitForSingleObject( ov.hEvent, INFINITE ); ok( r == WAIT_OBJECT_0, "event should be ready\n" );
+ ok( ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n"); + ok( ov.InternalHigh == 0x12, "ov.InternalHigh wrong\n"); + + pfni = (PFILE_NOTIFY_INFORMATION) buffer; + ok( pfni->NextEntryOffset == 0, "offset wrong\n" ); + ok( pfni->Action == FILE_ACTION_ADDED, "action wrong\n" ); + ok( pfni->FileNameLength == 6, "len wrong\n" ); + ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" ); + + ResetEvent(ov.hEvent); SetLastError(0xd0b00b00); r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,NULL,NULL); ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n"); @@ -415,22 +428,39 @@ static void test_readdirectorychanges(vo
filter = FILE_NOTIFY_CHANGE_SIZE;
- CloseHandle( ov.hEvent ); - ov.hEvent = NULL; - r = pReadDirectoryChangesW(hdir,NULL,0,FALSE,filter,NULL,&ov,NULL); + SetEvent(ov.hEvent); + ov.Internal = 1; + ov.InternalHigh = 1; + ov.Offset = 0; + ov.OffsetHigh = 0; + memset( buffer, 0, sizeof buffer ); + r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL); ok(r==TRUE, "should return true\n");
- r = WaitForSingleObject( hdir, 0 ); + ok( ov.Internal == STATUS_PENDING, "ov.Internal wrong\n"); + ok( ov.InternalHigh == 1, "ov.InternalHigh wrong\n"); + + r = WaitForSingleObject( ov.hEvent, 0 ); ok( r == STATUS_TIMEOUT, "should timeout\n" );
r = RemoveDirectoryW( subdir ); ok( r == TRUE, "failed to remove directory\n");
- r = WaitForSingleObject( hdir, 0 ); + r = WaitForSingleObject( ov.hEvent, INFINITE ); ok( r == WAIT_OBJECT_0, "should be ready\n" );
- r = WaitForSingleObject( hdir, 0 ); - ok( r == WAIT_OBJECT_0, "should be ready\n" ); + ok( ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n"); + ok( ov.InternalHigh == 0x12, "ov.InternalHigh wrong\n"); + + r = GetOverlappedResult( hdir, &ov, &dwCount, TRUE ); + ok( r == TRUE, "getoverlappedresult failed\n"); + ok( dwCount == 0x12, "count wrong\n"); + + pfni = (PFILE_NOTIFY_INFORMATION) buffer; + ok( pfni->NextEntryOffset == 0, "offset wrong\n" ); + ok( pfni->Action == FILE_ACTION_REMOVED, "action wrong\n" ); + ok( pfni->FileNameLength == 6, "len wrong\n" ); + ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
CloseHandle(hdir);
@@ -438,10 +468,106 @@ static void test_readdirectorychanges(vo ok( r == TRUE, "failed to remove directory\n"); }
+/* show the behaviour when a null buffer is passed */ +static void test_readdirectorychanges_null(void) +{ + NTSTATUS r; + HANDLE hdir; + char buffer[0x1000]; + DWORD fflags, filter = 0; + OVERLAPPED ov; + WCHAR path[MAX_PATH], subdir[MAX_PATH]; + static const WCHAR szBoo[] = { '\','b','o','o',0 }; + static const WCHAR szHoo[] = { '\','h','o','o',0 }; + PFILE_NOTIFY_INFORMATION pfni; + + if (!pReadDirectoryChangesW) + return; + + r = GetTempPathW( MAX_PATH, path ); + ok( r != 0, "temp path failed\n"); + if (!r) + return; + + lstrcatW( path, szBoo ); + lstrcpyW( subdir, path ); + lstrcatW( subdir, szHoo ); + + RemoveDirectoryW( subdir ); + RemoveDirectoryW( path ); + + r = CreateDirectoryW(path, NULL); + ok( r == TRUE, "failed to create directory\n"); + + fflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED; + hdir = CreateFileW(path, GENERIC_READ|SYNCHRONIZE|FILE_LIST_DIRECTORY, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, fflags, NULL); + ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n"); + + ov.hEvent = CreateEvent( NULL, 1, 0, NULL ); + + filter = FILE_NOTIFY_CHANGE_FILE_NAME; + filter |= FILE_NOTIFY_CHANGE_DIR_NAME; + + SetLastError(0xd0b00b00); + ov.Internal = 0; + ov.InternalHigh = 0; + memset( buffer, 0, sizeof buffer ); + + r = pReadDirectoryChangesW(hdir,NULL,0,FALSE,filter,NULL,&ov,NULL); + ok(r==TRUE, "should return true\n"); + + r = WaitForSingleObject( ov.hEvent, 0 ); + ok( r == STATUS_TIMEOUT, "should timeout\n" ); + + r = CreateDirectoryW( subdir, NULL ); + ok( r == TRUE, "failed to create directory\n"); + + r = WaitForSingleObject( ov.hEvent, 0 ); + ok( r == WAIT_OBJECT_0, "event should be ready\n" ); + + ok( ov.Internal == STATUS_NOTIFY_ENUM_DIR, "ov.Internal wrong\n"); + ok( ov.InternalHigh == 0, "ov.InternalHigh wrong\n"); + + ov.Internal = 0; + ov.InternalHigh = 0; + ov.Offset = 0; + ov.OffsetHigh = 0; + memset( buffer, 0, sizeof buffer ); + + r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL); + ok(r==TRUE, "should return true\n"); + + r = WaitForSingleObject( ov.hEvent, 0 ); + ok( r == STATUS_TIMEOUT, "should timeout\n" ); + + r = RemoveDirectoryW( subdir ); + ok( r == TRUE, "failed to remove directory\n"); + + r = WaitForSingleObject( ov.hEvent, INFINITE ); + ok( r == WAIT_OBJECT_0, "should be ready\n" ); + + ok( ov.Internal == STATUS_NOTIFY_ENUM_DIR, "ov.Internal wrong\n"); + ok( ov.InternalHigh == 0, "ov.InternalHigh wrong\n"); + + pfni = (PFILE_NOTIFY_INFORMATION) buffer; + ok( pfni->NextEntryOffset == 0, "offset wrong\n" ); + + CloseHandle(hdir); + + r = RemoveDirectoryW( path ); + ok( r == TRUE, "failed to remove directory\n"); +}
START_TEST(change) { + HMODULE hkernel32 = GetModuleHandle("kernel32"); + pReadDirectoryChangesW = (fnReadDirectoryChangesW) + GetProcAddress(hkernel32, "ReadDirectoryChangesW"); + test_FindFirstChangeNotification(); test_ffcn(); test_readdirectorychanges(); + test_readdirectorychanges_null(); }