Module: wine Branch: stable Commit: fffa143180de3889cc670be59201be741f7c0775 URL: http://source.winehq.org/git/wine.git/?a=commit;h=fffa143180de3889cc670be592...
Author: Michael Müller michael@fds-team.de Date: Wed Sep 21 15:00:41 2016 +0200
ntdll: Open current working directory with FILE_TRAVERSE access.
Signed-off-by: Michael Müller michael@fds-team.de Signed-off-by: Sebastian Lackner sebastian@fds-team.de Signed-off-by: Alexandre Julliard julliard@winehq.org (cherry picked from commit 6f2f307b1dcc8e4749eee05325961d77e3473fe1) Signed-off-by: Michael Stefaniuc mstefani@winehq.org
---
dlls/kernel32/tests/directory.c | 50 +++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/path.c | 3 ++- 2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/tests/directory.c b/dlls/kernel32/tests/directory.c index 9baae47..316c2e2 100644 --- a/dlls/kernel32/tests/directory.c +++ b/dlls/kernel32/tests/directory.c @@ -24,6 +24,28 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" +#include "winternl.h" + +static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG); + +static void init(void) +{ + HMODULE hntdll = GetModuleHandleA("ntdll.dll"); + pNtQueryObject = (void *)GetProcAddress(hntdll, "NtQueryObject"); +} + +#define TEST_GRANTED_ACCESS(a,b) test_granted_access(a,b,__LINE__) +static void test_granted_access(HANDLE handle, ACCESS_MASK access, int line) +{ + OBJECT_BASIC_INFORMATION obj_info; + NTSTATUS status; + + status = pNtQueryObject(handle, ObjectBasicInformation, &obj_info, + sizeof(obj_info), NULL); + ok_(__FILE__, line)(!status, "NtQueryObject with err: %08x\n", status); + ok_(__FILE__, line)(obj_info.GrantedAccess == access, "Granted access should " + "be 0x%08x, instead of 0x%08x\n", access, obj_info.GrantedAccess); +}
/* If you change something in these tests, please do the same * for GetSystemDirectory tests. @@ -417,6 +439,7 @@ static void test_CreateDirectoryW(void)
static void test_RemoveDirectoryA(void) { + char curdir[MAX_PATH]; char tmpdir[MAX_PATH]; BOOL ret;
@@ -425,6 +448,18 @@ static void test_RemoveDirectoryA(void) ret = CreateDirectoryA(tmpdir, NULL); ok(ret == TRUE, "CreateDirectoryA should always succeed\n");
+ GetCurrentDirectoryA(MAX_PATH, curdir); + ok(SetCurrentDirectoryA(tmpdir), "SetCurrentDirectoryA failed\n"); + + SetLastError(0xdeadbeef); + ok(!RemoveDirectoryA(tmpdir), "RemoveDirectoryA succeeded\n"); + ok(GetLastError() == ERROR_SHARING_VIOLATION, + "Expected ERROR_SHARING_VIOLATION, got %u\n", GetLastError()); + + TEST_GRANTED_ACCESS(NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.Handle, + FILE_TRAVERSE | SYNCHRONIZE); + + SetCurrentDirectoryA(curdir); ret = RemoveDirectoryA(tmpdir); ok(ret == TRUE, "RemoveDirectoryA should always succeed\n");
@@ -445,6 +480,7 @@ static void test_RemoveDirectoryA(void)
static void test_RemoveDirectoryW(void) { + WCHAR curdir[MAX_PATH]; WCHAR tmpdir[MAX_PATH]; BOOL ret; static const WCHAR tmp_dir_name[] = {'P','l','e','a','s','e',' ','R','e','m','o','v','e',' ','M','e',0}; @@ -461,6 +497,18 @@ static void test_RemoveDirectoryW(void)
ok(ret == TRUE, "CreateDirectoryW should always succeed\n");
+ GetCurrentDirectoryW(MAX_PATH, curdir); + ok(SetCurrentDirectoryW(tmpdir), "SetCurrentDirectoryW failed\n"); + + SetLastError(0xdeadbeef); + ok(!RemoveDirectoryW(tmpdir), "RemoveDirectoryW succeeded\n"); + ok(GetLastError() == ERROR_SHARING_VIOLATION, + "Expected ERROR_SHARING_VIOLATION, got %u\n", GetLastError()); + + TEST_GRANTED_ACCESS(NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.Handle, + FILE_TRAVERSE | SYNCHRONIZE); + + SetCurrentDirectoryW(curdir); ret = RemoveDirectoryW(tmpdir); ok(ret == TRUE, "RemoveDirectoryW should always succeed\n");
@@ -488,6 +536,8 @@ static void test_SetCurrentDirectoryA(void)
START_TEST(directory) { + init(); + test_GetWindowsDirectoryA(); test_GetWindowsDirectoryW();
diff --git a/dlls/ntdll/path.c b/dlls/ntdll/path.c index ae0646a..de7366c 100644 --- a/dlls/ntdll/path.c +++ b/dlls/ntdll/path.c @@ -984,7 +984,8 @@ NTSTATUS WINAPI RtlSetCurrentDirectory_U(const UNICODE_STRING* dir) attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL;
- nts = NtOpenFile( &handle, SYNCHRONIZE, &attr, &io, 0, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ); + nts = NtOpenFile( &handle, FILE_TRAVERSE | SYNCHRONIZE, &attr, &io, FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ); if (nts != STATUS_SUCCESS) goto out;
/* don't keep the directory handle open on removable media */