From 93ee7df2aae3baadeae667908c8e544302cc05d5 Mon Sep 17 00:00:00 2001 From: Steven Edwards Date: Fri, 26 May 2006 17:54:55 +0000 Subject: [PATCH] sync ntdll tests to 0.9.14 svn path=/trunk/; revision=22056 --- reactos/regtests/winetests/ntdll/atom.c | 25 +- reactos/regtests/winetests/ntdll/change.c | 332 +++++ reactos/regtests/winetests/ntdll/env.c | 13 +- reactos/regtests/winetests/ntdll/error.c | 2 +- reactos/regtests/winetests/ntdll/exception.c | 249 ++++ reactos/regtests/winetests/ntdll/info.c | 12 +- reactos/regtests/winetests/ntdll/large_int.c | 2 +- reactos/regtests/winetests/ntdll/ntdll.rbuild | 3 + reactos/regtests/winetests/ntdll/om.c | 1124 ++++++++--------- reactos/regtests/winetests/ntdll/path.c | 2 +- reactos/regtests/winetests/ntdll/port.c | 305 +++++ reactos/regtests/winetests/ntdll/reg.c | 2 +- reactos/regtests/winetests/ntdll/rtl.c | 2 +- reactos/regtests/winetests/ntdll/rtlbitmap.c | 2 +- reactos/regtests/winetests/ntdll/rtlstr.c | 11 +- reactos/regtests/winetests/ntdll/string.c | 2 +- reactos/regtests/winetests/ntdll/testlist.c | 6 +- reactos/regtests/winetests/ntdll/time.c | 2 +- 18 files changed, 1500 insertions(+), 596 deletions(-) create mode 100644 reactos/regtests/winetests/ntdll/change.c create mode 100644 reactos/regtests/winetests/ntdll/exception.c create mode 100644 reactos/regtests/winetests/ntdll/port.c diff --git a/reactos/regtests/winetests/ntdll/atom.c b/reactos/regtests/winetests/ntdll/atom.c index c0a8e2d4d0d..a837e8b499f 100755 --- a/reactos/regtests/winetests/ntdll/atom.c +++ b/reactos/regtests/winetests/ntdll/atom.c @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * NOTES * We use function pointers here as there is no import library for NTDLL on @@ -35,7 +35,6 @@ #include "winreg.h" #include "winnls.h" #include "wine/test.h" -#include "wine/unicode.h" #include "winternl.h" #ifndef __WINE_WINTERNL_H @@ -112,14 +111,14 @@ static DWORD RtlAtomTestThread(LPVOID Table) ok(!res, "Failed with longenough buffer, retval: %lx\n", res); ok(RefCount == 1, "Refcount was not 1 but %lx\n", RefCount); ok(PinCount == 1, "Pincount was not 1 but %lx\n", PinCount); - ok(!strcmpW(Name, testAtom2), "We found wrong atom!!\n"); - ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); + ok(!lstrcmpW(Name, testAtom2), "We found wrong atom!!\n"); + ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); Len = 64; res = pRtlQueryAtomInAtomTable(AtomTable, Atom, NULL, NULL, Name, &Len); ok(!res, "RtlQueryAtomInAtomTable with optional args invalid failed, retval: %lx\n", res); - ok(!strcmpW(Name, testAtom2), "Found Wrong atom!\n"); - ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); + ok(!lstrcmpW(Name, testAtom2), "Found Wrong atom!\n"); + ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); res = pRtlPinAtomInAtomTable(AtomTable, Atom); ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res); @@ -184,8 +183,8 @@ static void test_NtAtom(void) ok(!res, "Unable to query atom in atom table, retval: %lx\n", res); ok(RefCount == 1, "RefCount is not 1 but %lx\n", RefCount); ok(PinCount == 1, "PinCount is not 1 but %lx\n", PinCount); - ok(!strcmpW(Name, testAtom2), "We found wrong atom\n"); - ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); + ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n"); + ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); res = pRtlEmptyAtomTable(AtomTable, FALSE); ok(!res, "Unable to empty atom table, retval %lx\n", res); @@ -195,8 +194,8 @@ static void test_NtAtom(void) ok(!res, "It seems RtlEmptyAtomTable deleted our pinned atom eaven though we asked it not to, retval: %lx\n", res); ok(RefCount == 1, "RefCount is not 1 but %lx\n", RefCount); ok(PinCount == 1, "PinCount is not 1 but %lx\n", PinCount); - ok(!strcmpW(Name, testAtom2), "We found wrong atom\n"); - ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); + ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n"); + ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); Len = 8; Name[0] = Name[1] = Name[2] = Name[3] = Name[4] = 0x55AA; @@ -267,7 +266,7 @@ static void test_NtAtom(void) Len = 0; res = pRtlQueryAtomInAtomTable(AtomTable, Atom1, NULL, NULL, Name, &Len); ok(res == STATUS_BUFFER_TOO_SMALL, "Got wrong retval, retval: %lx\n", res); - ok((strlenW(testAtom1) * sizeof(WCHAR)) == Len, "Got wrong length %lx\n", Len); + ok((lstrlenW(testAtom1) * sizeof(WCHAR)) == Len, "Got wrong length %lx\n", Len); res = pRtlPinAtomInAtomTable(AtomTable, Atom1); ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res); @@ -360,8 +359,8 @@ static void test_NtIntAtom(void) ok(!res, "Unable to query atom in atom table, retval: %lx\n", res); ok(PinCount == 1, "Expected pincount 1 but got %lx\n", PinCount); ok(RefCount == 1, "Expected refcount 1 but got %lx\n", RefCount); - ok(!strcmpW(testAtomOTT, Name), "Got wrong atom name\n"); - ok((strlenW(testAtomOTT) * sizeof(WCHAR)) == Len, "Got wrong len %ld\n", Len); + ok(!lstrcmpW(testAtomOTT, Name), "Got wrong atom name\n"); + ok((lstrlenW(testAtomOTT) * sizeof(WCHAR)) == Len, "Got wrong len %ld\n", Len); res = pRtlPinAtomInAtomTable(AtomTable, testAtom); ok(!res, "Unable to pin int atom, retval: %lx\n", res); diff --git a/reactos/regtests/winetests/ntdll/change.c b/reactos/regtests/winetests/ntdll/change.c new file mode 100644 index 00000000000..3a3ffa28f9f --- /dev/null +++ b/reactos/regtests/winetests/ntdll/change.c @@ -0,0 +1,332 @@ +/* + * File change notification tests + * + * Copyright 2006 Mike McCormack for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#define WIN32_NO_STATUS +#include +#include +#include +#include +#include +#include "wine/test.h" + +typedef NTSTATUS (WINAPI *fnNtNotifyChangeDirectoryFile)( + HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID, + PIO_STATUS_BLOCK,PVOID,ULONG,ULONG,BOOLEAN); +fnNtNotifyChangeDirectoryFile pNtNotifyChangeDirectoryFile; + +typedef NTSTATUS (WINAPI *fnNtCancelIoFile)(HANDLE,PIO_STATUS_BLOCK); +fnNtCancelIoFile pNtCancelIoFile; + + +static void test_ntncdf(void) +{ + NTSTATUS r; + HANDLE hdir, hEvent; + char buffer[0x1000]; + DWORD fflags, filter = 0; + IO_STATUS_BLOCK iosb; + 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; + + 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"); + + r = pNtNotifyChangeDirectoryFile(NULL,NULL,NULL,NULL,NULL,NULL,0,0,0); + ok(r==STATUS_ACCESS_VIOLATION, "should return access violation\n"); + + fflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED; + hdir = CreateFileW(path, GENERIC_READ|SYNCHRONIZE, FILE_SHARE_READ, NULL, + OPEN_EXISTING, fflags, NULL); + ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n"); + + hEvent = CreateEvent( NULL, 0, 0, NULL ); + + r = pNtNotifyChangeDirectoryFile(hdir,NULL,NULL,NULL,&iosb,NULL,0,0,0); + ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n"); + + r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,NULL,0,0,0); + ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n"); + + filter = FILE_NOTIFY_CHANGE_FILE_NAME; + filter |= FILE_NOTIFY_CHANGE_DIR_NAME; + filter |= FILE_NOTIFY_CHANGE_ATTRIBUTES; + filter |= FILE_NOTIFY_CHANGE_SIZE; + filter |= FILE_NOTIFY_CHANGE_LAST_WRITE; + filter |= FILE_NOTIFY_CHANGE_LAST_ACCESS; + filter |= FILE_NOTIFY_CHANGE_CREATION; + filter |= FILE_NOTIFY_CHANGE_SECURITY; + + U(iosb).Status = 1; + iosb.Information = 1; + r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,-1,0); + ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n"); + + ok( U(iosb).Status == 1, "information wrong\n"); + ok( iosb.Information == 1, "information wrong\n"); + + U(iosb).Status = 1; + iosb.Information = 0; + r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0); + ok(r==STATUS_PENDING, "should return status pending\n"); + + r = WaitForSingleObject( hEvent, 0 ); + ok( r == STATUS_TIMEOUT, "should timeout\n" ); + + r = WaitForSingleObject( hdir, 0 ); + 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( hEvent, 0 ); + ok( r == WAIT_OBJECT_0, "event should be ready\n" ); + + ok( U(iosb).Status == STATUS_SUCCESS, "information wrong\n"); + ok( iosb.Information == 0x12, "information 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" ); + + r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,0,0); + ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n"); + + r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,0,0); + ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n"); + + filter = FILE_NOTIFY_CHANGE_SIZE; + + U(iosb).Status = 1; + iosb.Information = 1; + r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,NULL,0,filter,0); + ok(r==STATUS_PENDING, "should status pending\n"); + + ok( U(iosb).Status == 1, "information wrong\n"); + ok( iosb.Information == 1, "information wrong\n"); + + r = WaitForSingleObject( hdir, 0 ); + ok( r == STATUS_TIMEOUT, "should timeout\n" ); + + r = RemoveDirectoryW( subdir ); + ok( r == TRUE, "failed to remove directory\n"); + + r = WaitForSingleObject( hdir, 100 ); + ok( r == WAIT_OBJECT_0, "should be ready\n" ); + + r = WaitForSingleObject( hdir, 100 ); + ok( r == WAIT_OBJECT_0, "should be ready\n" ); + + ok( U(iosb).Status == STATUS_NOTIFY_ENUM_DIR, "information wrong\n"); + ok( iosb.Information == 0, "information wrong\n"); + + CloseHandle(hdir); + CloseHandle(hEvent); + + r = RemoveDirectoryW( path ); + ok( r == TRUE, "failed to remove directory\n"); +} + + +static void test_ntncdf_async(void) +{ + NTSTATUS r; + HANDLE hdir, hEvent; + char buffer[0x1000]; + DWORD fflags, filter = 0; + IO_STATUS_BLOCK iosb, iosb2; + 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; + + 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"); + + r = pNtNotifyChangeDirectoryFile(NULL,NULL,NULL,NULL,NULL,NULL,0,0,0); + ok(r==STATUS_ACCESS_VIOLATION, "should return access violation\n"); + + fflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED; + hdir = CreateFileW(path, GENERIC_READ|SYNCHRONIZE, FILE_SHARE_READ, NULL, + OPEN_EXISTING, fflags, NULL); + ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n"); + + hEvent = CreateEvent( NULL, 0, 0, NULL ); + + filter = FILE_NOTIFY_CHANGE_FILE_NAME; + filter |= FILE_NOTIFY_CHANGE_DIR_NAME; + filter |= FILE_NOTIFY_CHANGE_ATTRIBUTES; + filter |= FILE_NOTIFY_CHANGE_SIZE; + filter |= FILE_NOTIFY_CHANGE_LAST_WRITE; + filter |= FILE_NOTIFY_CHANGE_LAST_ACCESS; + filter |= FILE_NOTIFY_CHANGE_CREATION; + filter |= FILE_NOTIFY_CHANGE_SECURITY; + + + U(iosb).Status = 0x01234567; + iosb.Information = 0x12345678; + r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0); + ok(r==STATUS_PENDING, "should status pending\n"); + ok(U(iosb).Status == 0x01234567, "status set too soon\n"); + ok(iosb.Information == 0x12345678, "info set too soon\n"); + + r = CreateDirectoryW( subdir, NULL ); + ok( r == TRUE, "failed to create directory\n"); + + r = WaitForSingleObject( hdir, 100 ); + ok( r == WAIT_OBJECT_0, "should be ready\n" ); + + ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n"); + ok(iosb.Information == 0x12, "info not set\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" ); + + r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0); + ok(r==STATUS_PENDING, "should status pending\n"); + + r = RemoveDirectoryW( subdir ); + ok( r == TRUE, "failed to remove directory\n"); + + r = WaitForSingleObject( hdir, 0 ); + ok( r == WAIT_OBJECT_0, "should be ready\n" ); + + ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n"); + ok(iosb.Information == 0x12, "info not set\n"); + + 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" ); + + /* check APCs */ + U(iosb).Status = 0; + iosb.Information = 0; + + r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,NULL,0,filter,0); + ok(r==STATUS_PENDING, "should status pending\n"); + + r = CreateDirectoryW( subdir, NULL ); + ok( r == TRUE, "failed to create directory\n"); + + r = WaitForSingleObject( hdir, 0 ); + ok( r == WAIT_OBJECT_0, "should be ready\n" ); + + ok(U(iosb).Status == STATUS_NOTIFY_ENUM_DIR, "status not successful\n"); + ok(iosb.Information == 0, "info not set\n"); + + U(iosb).Status = 0; + iosb.Information = 0; + + r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0); + ok(r==STATUS_PENDING, "should status pending\n"); + + r = RemoveDirectoryW( subdir ); + ok( r == TRUE, "failed to remove directory\n"); + + r = WaitForSingleObject( hEvent, 0 ); + ok( r == WAIT_OBJECT_0, "should be ready\n" ); + + ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n"); + ok(iosb.Information == 0x12, "info not set\n"); + + + U(iosb).Status = 0x01234567; + iosb.Information = 0x12345678; + r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0); + ok(r==STATUS_PENDING, "should status pending\n"); + + U(iosb2).Status = 0x01234567; + iosb2.Information = 0x12345678; + r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb2,buffer,sizeof buffer,filter,0); + ok(r==STATUS_PENDING, "should status pending\n"); + + ok(U(iosb).Status == 0x01234567, "status set too soon\n"); + ok(iosb.Information == 0x12345678, "info set too soon\n"); + + todo_wine { + r = pNtCancelIoFile(hdir, &iosb); + ok( r == STATUS_SUCCESS, "cancel failed\n"); + + CloseHandle(hdir); + + ok(U(iosb).Status == STATUS_SUCCESS, "status wrong\n"); + ok(U(iosb2).Status == STATUS_CANCELLED, "status wrong\n"); + } + ok(iosb.Information == 0, "info wrong\n"); + ok(iosb2.Information == 0, "info wrong\n"); + + r = RemoveDirectoryW( path ); + ok( r == TRUE, "failed to remove directory\n"); + + CloseHandle(hEvent); +} + +START_TEST(change) +{ + HMODULE hntdll = GetModuleHandle("ntdll"); + + pNtNotifyChangeDirectoryFile = (fnNtNotifyChangeDirectoryFile) + GetProcAddress(hntdll, "NtNotifyChangeDirectoryFile"); + pNtCancelIoFile = (fnNtCancelIoFile) + GetProcAddress(hntdll, "NtCancelIoFile"); + + if (!pNtNotifyChangeDirectoryFile) + return; + if (!pNtCancelIoFile) + return; + + test_ntncdf(); + test_ntncdf_async(); +} diff --git a/reactos/regtests/winetests/ntdll/env.c b/reactos/regtests/winetests/ntdll/env.c index ec88957b267..8f864a40130 100755 --- a/reactos/regtests/winetests/ntdll/env.c +++ b/reactos/regtests/winetests/ntdll/env.c @@ -15,13 +15,12 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include "ntdll_test.h" -#include "wine/unicode.h" static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen, LPCSTR src, DWORD srclen ); @@ -108,8 +107,8 @@ static void testQuery(void) pRtlMultiByteToUnicodeN( bn, sizeof(bn), NULL, test->val, strlen(test->val)+1 ); ok( value.Length == strlen(test->val) * sizeof(WCHAR), "Wrong length %d/%d for %s\n", value.Length, strlen(test->val) * sizeof(WCHAR), test->var ); - ok((value.Length == strlen(test->val) * sizeof(WCHAR) && strncmpW(bv, bn, test->len) == 0) || - strcmpW(bv, bn) == 0, + ok((value.Length == strlen(test->val) * sizeof(WCHAR) && memcmp(bv, bn, test->len*sizeof(WCHAR)) == 0) || + lstrcmpW(bv, bn) == 0, "Wrong result for %s/%d\n", test->var, test->len); ok(bv[test->len] == '@', "Writing too far away in the buffer for %s/%d\n", test->var, test->len); break; @@ -151,7 +150,7 @@ static void testSetHelper(LPWSTR* env, const char* var, const char* val, NTSTATU switch (nts) { case STATUS_SUCCESS: - ok(strcmpW(bval1, bval2) == 0, "Cannot get value written to environment\n"); + ok(lstrcmpW(bval1, bval2) == 0, "Cannot get value written to environment\n"); break; case STATUS_VARIABLE_NOT_FOUND: ok(val == NULL, "Couldn't find variable, but didn't delete it. val = %s\n", val); @@ -257,7 +256,7 @@ static void testExpand(void) ok(ul == strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR), "Wrong returned length for %s: %lu <> %u\n", test->src, ul, strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR)); - ok(strcmpW(dst, rst) == 0, "Wrong result for %s: expecting %s\n", + ok(lstrcmpW(dst, rst) == 0, "Wrong result for %s: expecting %s\n", test->src, test->dst); us_dst.Length = 0; @@ -269,7 +268,7 @@ static void testExpand(void) ok(ul == strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR), "Wrong returned length for %s (with buffer too small): %lu <> %u\n", test->src, ul, strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR)); - ok(strncmpW(dst, rst, 8) == 0, + ok(memcmp(dst, rst, 8*sizeof(WCHAR)) == 0, "Wrong result for %s (with buffer too small): expecting %s\n", test->src, test->dst); ok(dst[8] == '-', "Writing too far in buffer (got %c/%d)\n", dst[8], dst[8]); diff --git a/reactos/regtests/winetests/ntdll/error.c b/reactos/regtests/winetests/ntdll/error.c index b12897bebf7..9679c8f3423 100755 --- a/reactos/regtests/winetests/ntdll/error.c +++ b/reactos/regtests/winetests/ntdll/error.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include diff --git a/reactos/regtests/winetests/ntdll/exception.c b/reactos/regtests/winetests/ntdll/exception.c new file mode 100644 index 00000000000..e0aca2c97a4 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/exception.c @@ -0,0 +1,249 @@ +/* + * Unit test suite for ntdll exceptions + * + * Copyright 2005 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x500 /* For NTSTATUS */ +#endif + +#include +#define WIN32_NO_STATUS +#include +#define NTOS_MODE_USER +#include + +#include "wine/test.h" + +/* + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winreg.h" +#include "winternl.h" +#include "excpt.h" +#include "wine/test.h" + +*/ + +#ifdef __i386__ + +static struct _TEB * (WINAPI *pNtCurrentTeb)(void); + +/* Test various instruction combinations that cause a protection fault on the i386, + * and check what the resulting exception looks like. + */ + +static const struct exception +{ + BYTE code[18]; /* asm code */ + BYTE offset; /* offset of faulting instruction */ + BYTE length; /* length of faulting instruction */ + NTSTATUS status; /* expected status code */ + DWORD nb_params; /* expected number of parameters */ + DWORD params[4]; /* expected parameters */ +} exceptions[] = +{ + /* test some privileged instructions */ + { { 0xfb, 0xc3 }, /* sti; ret */ + 0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x6c, 0xc3 }, /* insb (%dx); ret */ + 0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x6d, 0xc3 }, /* insl (%dx); ret */ + 0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x6e, 0xc3 }, /* outsb (%dx); ret */ + 0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x6f, 0xc3 }, /* outsl (%dx); ret */ + 0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0xe4, 0x11, 0xc3 }, /* inb $0x11,%al; ret */ + 0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0xe5, 0x11, 0xc3 }, /* inl $0x11,%eax; ret */ + 0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0xe6, 0x11, 0xc3 }, /* outb %al,$0x11; ret */ + 0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0xe7, 0x11, 0xc3 }, /* outl %eax,$0x11; ret */ + 0, 2, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0xed, 0xc3 }, /* inl (%dx),%eax; ret */ + 0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0xee, 0xc3 }, /* outb %al,(%dx); ret */ + 0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0xef, 0xc3 }, /* outl %eax,(%dx); ret */ + 0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0xf4, 0xc3 }, /* hlt; ret */ + 0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0xfa, 0xc3 }, /* cli; ret */ + 0, 1, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + + /* test long jump to invalid selector */ + { { 0xea, 0, 0, 0, 0, 0, 0, 0xc3 }, /* ljmp $0,$0; ret */ + 0, 7, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, + + /* test iret to invalid selector */ + { { 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0xcf, 0x83, 0xc4, 0x0c, 0xc3 }, + /* pushl $0; pushl $0; pushl $0; iret; addl $12,%esp; ret */ + 6, 1, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, + + /* test loading an invalid selector */ + { { 0xb8, 0xef, 0xbe, 0x00, 0x00, 0x8e, 0xe8, 0xc3 }, /* mov $beef,%ax; mov %ax,%gs; ret */ + 5, 2, STATUS_ACCESS_VIOLATION, 2, { 0, 0xbee8 } }, + + /* test accessing a zero selector */ + { { 0x06, 0x31, 0xc0, 0x8e, 0xc0, 0x26, 0xa1, 0, 0, 0, 0, 0x07, 0xc3 }, + /* push %es; xor %eax,%eax; mov %ax,%es; mov %es:(0),%ax; pop %es */ + 5, 6, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, + + /* test moving %cs -> %ss */ + { { 0x0e, 0x17, 0x58, 0xc3 }, /* pushl %cs; popl %ss; popl %eax; ret */ + 1, 1, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, + + /* test overlong instruction (limit is 16 bytes) */ + { { 0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0xfa,0xc3 }, + 0, 16, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, + { { 0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0xfa,0xc3 }, + 0, 15, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + + /* test invalid interrupt */ + { { 0xcd, 0xff, 0xc3 }, /* int $0xff; ret */ + 0, 2, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, + + /* test moves to/from Crx */ + { { 0x0f, 0x20, 0xc0, 0xc3 }, /* movl %cr0,%eax; ret */ + 0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x0f, 0x20, 0xe0, 0xc3 }, /* movl %cr4,%eax; ret */ + 0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x0f, 0x22, 0xc0, 0xc3 }, /* movl %eax,%cr0; ret */ + 0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x0f, 0x22, 0xe0, 0xc3 }, /* movl %eax,%cr4; ret */ + 0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + + /* test moves to/from Drx */ + { { 0x0f, 0x21, 0xc0, 0xc3 }, /* movl %dr0,%eax; ret */ + 0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x0f, 0x21, 0xc8, 0xc3 }, /* movl %dr1,%eax; ret */ + 0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x0f, 0x21, 0xf8, 0xc3 }, /* movl %dr7,%eax; ret */ + 0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x0f, 0x23, 0xc0, 0xc3 }, /* movl %eax,%dr0; ret */ + 0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x0f, 0x23, 0xc8, 0xc3 }, /* movl %eax,%dr1; ret */ + 0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + { { 0x0f, 0x23, 0xf8, 0xc3 }, /* movl %eax,%dr7; ret */ + 0, 3, STATUS_PRIVILEGED_INSTRUCTION, 0 }, + + /* test memory reads */ + { { 0xa1, 0xfc, 0xff, 0xff, 0xff, 0xc3 }, /* movl 0xfffffffc,%eax; ret */ + 0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xfffffffc } }, + { { 0xa1, 0xfd, 0xff, 0xff, 0xff, 0xc3 }, /* movl 0xfffffffd,%eax; ret */ + 0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, + { { 0xa1, 0xfe, 0xff, 0xff, 0xff, 0xc3 }, /* movl 0xfffffffe,%eax; ret */ + 0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, + { { 0xa1, 0xff, 0xff, 0xff, 0xff, 0xc3 }, /* movl 0xffffffff,%eax; ret */ + 0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, + + /* test memory writes */ + { { 0xa3, 0xfc, 0xff, 0xff, 0xff, 0xc3 }, /* movl %eax,0xfffffffc; ret */ + 0, 5, STATUS_ACCESS_VIOLATION, 2, { 1, 0xfffffffc } }, + { { 0xa3, 0xfd, 0xff, 0xff, 0xff, 0xc3 }, /* movl %eax,0xfffffffd; ret */ + 0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, + { { 0xa3, 0xfe, 0xff, 0xff, 0xff, 0xc3 }, /* movl %eax,0xfffffffe; ret */ + 0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, + { { 0xa3, 0xff, 0xff, 0xff, 0xff, 0xc3 }, /* movl %eax,0xffffffff; ret */ + 0, 5, STATUS_ACCESS_VIOLATION, 2, { 0, 0xffffffff } }, +}; + +static int got_exception; + +static DWORD handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, + CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) +{ + const struct exception *except = *(const struct exception **)(frame + 1); + unsigned int i, entry = except - exceptions; + + got_exception++; + trace( "exception: %lx flags:%lx addr:%p\n", + rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress ); + + ok( rec->ExceptionCode == except->status, + "%u: Wrong exception code %lx/%lx\n", entry, rec->ExceptionCode, except->status ); + ok( rec->ExceptionAddress == except->code + except->offset, + "%u: Wrong exception address %p/%p\n", entry, + rec->ExceptionAddress, except->code + except->offset ); + + ok( rec->NumberParameters == except->nb_params, + "%u: Wrong number of parameters %lu/%lu\n", entry, rec->NumberParameters, except->nb_params ); + for (i = 0; i < rec->NumberParameters; i++) + ok( rec->ExceptionInformation[i] == except->params[i], + "%u: Wrong parameter %d: %lx/%lx\n", + entry, i, rec->ExceptionInformation[i], except->params[i] ); + + /* don't handle exception if it's not the address we expected */ + if (rec->ExceptionAddress != except->code + except->offset) return ExceptionContinueSearch; + + context->Eip += except->length; + return ExceptionContinueExecution; +} + +static void test_prot_fault(void) +{ + unsigned int i; + struct + { + EXCEPTION_REGISTRATION_RECORD frame; + const struct exception *except; + } exc_frame; + + pNtCurrentTeb = (void *)GetProcAddress( GetModuleHandleA("ntdll.dll"), "NtCurrentTeb" ); + if (!pNtCurrentTeb) + { + trace( "NtCurrentTeb not found, skipping tests\n" ); + return; + } + + exc_frame.frame.Handler = handler; + exc_frame.frame.Next = pNtCurrentTeb()->Tib.ExceptionList; + pNtCurrentTeb()->Tib.ExceptionList = &exc_frame.frame; + for (i = 0; i < sizeof(exceptions)/sizeof(exceptions[0]); i++) + { + void (*func)(void) = (void *)exceptions[i].code; + exc_frame.except = &exceptions[i]; + got_exception = 0; + func(); + if (!i && !got_exception) + { + trace( "No exception, assuming win9x, no point in testing further\n" ); + break; + } + ok( got_exception == (exceptions[i].status != 0), + "%u: bad exception count %d\n", i, got_exception ); + } + pNtCurrentTeb()->Tib.ExceptionList = exc_frame.frame.Next; +} + +#endif /* __i386__ */ + +START_TEST(exception) +{ +#ifdef __i386__ + test_prot_fault(); +#endif +} diff --git a/reactos/regtests/winetests/ntdll/info.c b/reactos/regtests/winetests/ntdll/info.c index e5bb9b48389..75eb0efb1a5 100755 --- a/reactos/regtests/winetests/ntdll/info.c +++ b/reactos/regtests/winetests/ntdll/info.c @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * */ @@ -729,7 +729,15 @@ static void test_query_process_handlecount(void) ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, one_before_last_pid); - trace("Handlecount for process with ID : %ld\n", one_before_last_pid); + if (!process) + { + trace("Could not open process with ID : %ld, error : %08lx. Going to use current one.\n", one_before_last_pid, GetLastError()); + process = GetCurrentProcess(); + trace("ProcessHandleCount for current process\n"); + } + else + trace("ProcessHandleCount for process with ID : %ld\n", one_before_last_pid); + status = pNtQueryInformationProcess( process, ProcessHandleCount, &handlecount, sizeof(handlecount), &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); ok( sizeof(handlecount) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(handlecount), ReturnLength); diff --git a/reactos/regtests/winetests/ntdll/large_int.c b/reactos/regtests/winetests/ntdll/large_int.c index 52c9d8f7232..a8fe2f563e6 100755 --- a/reactos/regtests/winetests/ntdll/large_int.c +++ b/reactos/regtests/winetests/ntdll/large_int.c @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * NOTES * We use function pointers here as there is no import library for NTDLL on diff --git a/reactos/regtests/winetests/ntdll/ntdll.rbuild b/reactos/regtests/winetests/ntdll/ntdll.rbuild index 214a94838c7..91833dd7730 100644 --- a/reactos/regtests/winetests/ntdll/ntdll.rbuild +++ b/reactos/regtests/winetests/ntdll/ntdll.rbuild @@ -3,12 +3,15 @@ ntdll atom.c + change.c env.c error.c + exception.c info.c large_int.c om.c path.c + port.c reg.c rtlbitmap.c rtl.c diff --git a/reactos/regtests/winetests/ntdll/om.c b/reactos/regtests/winetests/ntdll/om.c index 3ce779d0419..290398441c0 100644 --- a/reactos/regtests/winetests/ntdll/om.c +++ b/reactos/regtests/winetests/ntdll/om.c @@ -1,562 +1,562 @@ -/* - * Unit test suite for object manager functions - * - * Copyright 2005 Robert Shearman - * Copyright 2005 Vitaliy Margolen - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "ntdll_test.h" -#include "winternl.h" -#include "stdio.h" -#include "winnt.h" -#include "stdlib.h" - -static NTSTATUS (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR); -static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR ); -static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); -static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN, BOOLEAN); -static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN ); -static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES ); -static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG ); -static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE ); -static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER, - ULONG, ULONG, HANDLE ); -static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG ); -static NTSTATUS (WINAPI *pNtClose) ( HANDLE ); -static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, - ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, PLARGE_INTEGER ); -static NTSTATUS (WINAPI *pNtOpenDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); -static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); -static NTSTATUS (WINAPI *pNtOpenSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); -static NTSTATUS (WINAPI *pNtCreateSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PUNICODE_STRING); - - -void test_case_sensitive (void) -{ - static const WCHAR buffer1[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','t','e','s','t',0}; - static const WCHAR buffer2[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','T','e','s','t',0}; - static const WCHAR buffer3[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','T','E','s','t',0}; - static const WCHAR buffer4[] = {'\\','B','A','S','E','N','a','m','e','d','O','b','j','e','c','t','s','\\','t','e','s','t',0}; - NTSTATUS status; - OBJECT_ATTRIBUTES attr; - UNICODE_STRING str; - HANDLE Event, Mutant, h; - - pRtlInitUnicodeString(&str, buffer1); - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE); - ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08lx)\n", status); - - status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE); - ok(status == STATUS_OBJECT_NAME_COLLISION, - "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08lx)\n", status); - - pRtlInitUnicodeString(&str, buffer2); - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE); - ok(status == STATUS_SUCCESS, "Failed to create Event(%08lx)\n", status); - - pRtlInitUnicodeString(&str, buffer3); - InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); - status = pNtOpenMutant(&h, GENERIC_ALL, &attr); - ok(status == STATUS_OBJECT_TYPE_MISMATCH, - "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status); - - pNtClose(Mutant); - - pRtlInitUnicodeString(&str, buffer4); - InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); - status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE); - ok(status == STATUS_OBJECT_NAME_COLLISION, - "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION got(%08lx)\n", status); - - status = pNtCreateEvent(&h, GENERIC_ALL, &attr, FALSE, FALSE); - ok(status == STATUS_OBJECT_NAME_COLLISION, - "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08lx)\n", status); - - attr.Attributes = 0; - status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE); - ok(status == STATUS_OBJECT_PATH_NOT_FOUND, - "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status); - - pNtClose(Event); -} - -void test_namespace_pipe(void) -{ - static const WCHAR buffer1[] = {'\\','?','?','\\','P','I','P','E','\\','t','e','s','t','\\','p','i','p','e',0}; - static const WCHAR buffer2[] = {'\\','?','?','\\','P','I','P','E','\\','T','E','S','T','\\','P','I','P','E',0}; - static const WCHAR buffer3[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t','\\','p','i','p','e',0}; - static const WCHAR buffer4[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t',0}; - OBJECT_ATTRIBUTES attr; - UNICODE_STRING str; - IO_STATUS_BLOCK iosb; - NTSTATUS status; - LARGE_INTEGER timeout; - HANDLE pipe, h; - - timeout.QuadPart = -10000; - - pRtlInitUnicodeString(&str, buffer1); - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, - FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout); - ok(status == STATUS_SUCCESS, "Failed to create NamedPipe(%08lx)\n", status); - - status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, - FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout); - ok(status == STATUS_INSTANCE_NOT_AVAILABLE, - "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08lx)\n", status); - - pRtlInitUnicodeString(&str, buffer2); - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, - FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout); - ok(status == STATUS_INSTANCE_NOT_AVAILABLE, - "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08lx)\n", status); - - attr.Attributes = OBJ_CASE_INSENSITIVE; - status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN); - ok(status == STATUS_SUCCESS, "Failed to open NamedPipe(%08lx)\n", status); - pNtClose(h); - - pRtlInitUnicodeString(&str, buffer3); - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN); - ok(status == STATUS_OBJECT_PATH_NOT_FOUND || status == STATUS_PIPE_NOT_AVAILABLE, - "pNtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status); - - pRtlInitUnicodeString(&str, buffer4); - InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); - status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN); - ok(status == STATUS_OBJECT_NAME_NOT_FOUND, - "pNtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08lx)\n", status); - - pNtClose(pipe); -} - -#define DIRECTORY_QUERY (0x0001) -#define SYMBOLIC_LINK_QUERY 0x0001 - -#define DIR_TEST_CREATE_FAILURE(h,e) \ - status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr);\ - ok(status == e,"NtCreateDirectoryObject should have failed with %s got(%08lx)\n", #e, status); -#define DIR_TEST_OPEN_FAILURE(h,e) \ - status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr);\ - ok(status == e,"NtOpenDirectoryObject should have failed with %s got(%08lx)\n", #e, status); -#define DIR_TEST_CREATE_OPEN_FAILURE(h,n,e) \ - pRtlCreateUnicodeStringFromAsciiz(&str, n);\ - DIR_TEST_CREATE_FAILURE(h,e) DIR_TEST_OPEN_FAILURE(h,e)\ - pRtlFreeUnicodeString(&str); - -#define DIR_TEST_CREATE_SUCCESS(h) \ - status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr); \ - ok(status == STATUS_SUCCESS, "Failed to create Directory(%08lx)\n", status); -#define DIR_TEST_OPEN_SUCCESS(h) \ - status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr); \ - ok(status == STATUS_SUCCESS, "Failed to open Directory(%08lx)\n", status); -#define DIR_TEST_CREATE_OPEN_SUCCESS(h,n) \ - pRtlCreateUnicodeStringFromAsciiz(&str, n);\ - DIR_TEST_CREATE_SUCCESS(h) pNtClose(h); DIR_TEST_OPEN_SUCCESS(h) pNtClose(h); \ - pRtlFreeUnicodeString(&str); - -static void test_name_collisions(void) -{ - NTSTATUS status; - UNICODE_STRING str; - OBJECT_ATTRIBUTES attr; - HANDLE dir, h, h1, h2; - DWORD winerr; - LARGE_INTEGER size; - - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - pRtlCreateUnicodeStringFromAsciiz(&str, "\\"); - DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_COLLISION) - InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL); - - DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_EXISTS) - pNtClose(h); - status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); - ok(status == STATUS_OBJECT_TYPE_MISMATCH, - "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status); - pRtlFreeUnicodeString(&str); - - pRtlCreateUnicodeStringFromAsciiz(&str, "\\??\\PIPE\\om.c-mutant"); - status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); - ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_OBJECT_PATH_NOT_FOUND, - "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status); - pRtlFreeUnicodeString(&str); - - - pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects"); - DIR_TEST_OPEN_SUCCESS(&dir) - pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test"); - InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL); - - h = CreateMutexA(NULL, FALSE, "om.c-test"); - ok(h != 0, "CreateMutexA failed got ret=%p (%ld)\n", h, GetLastError()); - status = pNtCreateMutant(&h1, GENERIC_ALL, &attr, FALSE); - ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL, - "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status); - h2 = CreateMutexA(NULL, FALSE, "om.c-test"); - winerr = GetLastError(); - ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS, - "CreateMutexA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr); - pNtClose(h); - pNtClose(h1); - pNtClose(h2); - - h = CreateEventA(NULL, FALSE, FALSE, "om.c-test"); - ok(h != 0, "CreateEventA failed got ret=%p (%ld)\n", h, GetLastError()); - status = pNtCreateEvent(&h1, GENERIC_ALL, &attr, FALSE, FALSE); - ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL, - "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status); - h2 = CreateEventA(NULL, FALSE, FALSE, "om.c-test"); - winerr = GetLastError(); - ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS, - "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr); - pNtClose(h); - pNtClose(h1); - pNtClose(h2); - - h = CreateSemaphoreA(NULL, 1, 2, "om.c-test"); - ok(h != 0, "CreateSemaphoreA failed got ret=%p (%ld)\n", h, GetLastError()); - status = pNtCreateSemaphore(&h1, GENERIC_ALL, &attr, 1, 2); - ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL, - "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status); - h2 = CreateSemaphoreA(NULL, 1, 2, "om.c-test"); - winerr = GetLastError(); - ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS, - "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr); - pNtClose(h); - pNtClose(h1); - pNtClose(h2); - - h = CreateWaitableTimerA(NULL, TRUE, "om.c-test"); - ok(h != 0, "CreateWaitableTimerA failed got ret=%p (%ld)\n", h, GetLastError()); - status = pNtCreateTimer(&h1, GENERIC_ALL, &attr, NotificationTimer); - ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL, - "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status); - h2 = CreateWaitableTimerA(NULL, TRUE, "om.c-test"); - winerr = GetLastError(); - ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS, - "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr); - pNtClose(h); - pNtClose(h1); - pNtClose(h2); - - h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test"); - ok(h != 0, "CreateFileMappingA failed got ret=%p (%ld)\n", h, GetLastError()); - size.u.LowPart = 256; - size.u.HighPart = 0; - status = pNtCreateSection(&h1, SECTION_MAP_WRITE, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0); - ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL, - "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status); - h2 = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test"); - winerr = GetLastError(); - ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS, - "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr); - pNtClose(h); - pNtClose(h1); - pNtClose(h2); - - pRtlFreeUnicodeString(&str); - pNtClose(dir); -} - -void test_directory(void) -{ - NTSTATUS status; - UNICODE_STRING str; - OBJECT_ATTRIBUTES attr; - HANDLE dir, dir1, h; - - /* No name and/or no attributes */ - status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr); - ok(status == STATUS_ACCESS_VIOLATION, - "NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status); - status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr); - ok(status == STATUS_ACCESS_VIOLATION, - "NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status); - - status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL); - ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08lx)\n", status); - pNtClose(h); - status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL); - ok(status == STATUS_INVALID_PARAMETER, - "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status); - - InitializeObjectAttributes(&attr, NULL, 0, 0, NULL); - DIR_TEST_CREATE_SUCCESS(&dir) - DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) - - /* Bad name */ - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - - pRtlCreateUnicodeStringFromAsciiz(&str, ""); - DIR_TEST_CREATE_SUCCESS(&h) - pNtClose(h); - DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) - pRtlFreeUnicodeString(&str); - pNtClose(dir); - - DIR_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND) - - pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test"); - DIR_TEST_CREATE_SUCCESS(&h) - DIR_TEST_OPEN_SUCCESS(&dir1) - pRtlFreeUnicodeString(&str); - pNtClose(h); - pNtClose(dir1); - - - /* Use of root directory */ - - /* Can't use symlinks as a directory */ - pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local"); - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - status = pNtOpenSymbolicLinkObject(&dir, SYMBOLIC_LINK_QUERY, &attr);\ - ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08lx)\n", status); - pRtlFreeUnicodeString(&str); - InitializeObjectAttributes(&attr, &str, 0, dir, NULL); - pRtlCreateUnicodeStringFromAsciiz(&str, "one more level"); - DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH) - pRtlFreeUnicodeString(&str); - pNtClose(h); - pNtClose(dir); - - pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects"); - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - DIR_TEST_OPEN_SUCCESS(&dir) - pRtlFreeUnicodeString(&str); - - InitializeObjectAttributes(&attr, NULL, 0, dir, NULL); - DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_NAME_INVALID) - - InitializeObjectAttributes(&attr, &str, 0, dir, NULL); - DIR_TEST_CREATE_OPEN_SUCCESS(&h, "") - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD) - DIR_TEST_CREATE_OPEN_FAILURE(&h, "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND) - - pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test"); - DIR_TEST_CREATE_SUCCESS(&dir1) - DIR_TEST_OPEN_SUCCESS(&h) - pRtlFreeUnicodeString(&str); - - pNtClose(h); - pNtClose(dir1); - pNtClose(dir); - - /* Nested directories */ - pRtlCreateUnicodeStringFromAsciiz(&str, "\\"); - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - DIR_TEST_OPEN_SUCCESS(&dir) - InitializeObjectAttributes(&attr, &str, 0, dir, NULL); - DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) - pRtlFreeUnicodeString(&str); - pNtClose(dir); - - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test"); - DIR_TEST_CREATE_SUCCESS(&dir) - pRtlFreeUnicodeString(&str); - pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test\\one more level"); - DIR_TEST_CREATE_SUCCESS(&h) - pRtlFreeUnicodeString(&str); - pNtClose(h); - InitializeObjectAttributes(&attr, &str, 0, dir, NULL); - pRtlCreateUnicodeStringFromAsciiz(&str, "one more level"); - DIR_TEST_CREATE_SUCCESS(&h) - pRtlFreeUnicodeString(&str); - pNtClose(h); - - pNtClose(dir); - - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Global\\om.c-test"); - DIR_TEST_CREATE_SUCCESS(&dir) - pRtlFreeUnicodeString(&str); - pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local\\om.c-test\\one more level"); - DIR_TEST_CREATE_SUCCESS(&h) - pRtlFreeUnicodeString(&str); - pNtClose(h); - InitializeObjectAttributes(&attr, &str, 0, dir, NULL); - pRtlCreateUnicodeStringFromAsciiz(&str, "one more level"); - DIR_TEST_CREATE_SUCCESS(&dir) - pRtlFreeUnicodeString(&str); - pNtClose(h); - - pNtClose(dir); - - - /* Create other objects using RootDirectory */ - - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects"); - DIR_TEST_OPEN_SUCCESS(&dir) - pRtlFreeUnicodeString(&str); - InitializeObjectAttributes(&attr, &str, 0, dir, NULL); - - /* Test inavalid paths */ - pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant"); - status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); - ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, - "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status); - pRtlFreeUnicodeString(&str); - pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant\\"); - status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); - ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, - "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status); - pRtlFreeUnicodeString(&str); - - pRtlCreateUnicodeStringFromAsciiz(&str, "om.c\\-mutant"); - status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); - ok(status == STATUS_OBJECT_PATH_NOT_FOUND, - "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status); - pRtlFreeUnicodeString(&str); - - pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-mutant"); - status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); - ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08lx)\n", status); - pRtlFreeUnicodeString(&str); - pNtClose(h); - - pNtClose(dir); -} - -#define SYMLNK_TEST_CREATE_FAILURE(h,e) \ - status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\ - ok(status == e,"NtCreateSymbolicLinkObject should have failed with %s got(%08lx)\n", #e, status); -#define SYMLNK_TEST_OPEN_FAILURE(h,e) \ - status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\ - ok(status == e,"NtOpenSymbolicLinkObject should have failed with %s got(%08lx)\n", #e, status); -#define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) \ - pRtlCreateUnicodeStringFromAsciiz(&str, n);\ - pRtlCreateUnicodeStringFromAsciiz(&target, t);\ - SYMLNK_TEST_CREATE_FAILURE(h,e)\ - SYMLNK_TEST_OPEN_FAILURE(h,e)\ - pRtlFreeUnicodeString(&target);\ - pRtlFreeUnicodeString(&str); - -#define SYMLNK_TEST_CREATE_SUCCESS(h) \ - status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target); \ - ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08lx)\n", status); -#define SYMLNK_TEST_OPEN_SUCCESS(h) \ - status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr); \ - ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08lx)\n", status); - -void test_symboliclink(void) -{ - NTSTATUS status; - UNICODE_STRING str, target; - OBJECT_ATTRIBUTES attr; - HANDLE dir, link, h; - IO_STATUS_BLOCK iosb; - - /* No name and/or no attributes */ - SYMLNK_TEST_CREATE_OPEN_FAILURE(NULL, "", "", STATUS_ACCESS_VIOLATION) - - status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL); - ok(status == STATUS_ACCESS_VIOLATION, - "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status); - status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL); - ok(status == STATUS_INVALID_PARAMETER, - "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status); - - InitializeObjectAttributes(&attr, NULL, 0, 0, NULL); - SYMLNK_TEST_CREATE_FAILURE(&link, STATUS_INVALID_PARAMETER) - SYMLNK_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) - - /* Bad name */ - pRtlCreateUnicodeStringFromAsciiz(&target, "anywhere"); - InitializeObjectAttributes(&attr, &str, 0, 0, NULL); - - pRtlCreateUnicodeStringFromAsciiz(&str, ""); - SYMLNK_TEST_CREATE_SUCCESS(&link) - SYMLNK_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) - pNtClose(link); - pRtlFreeUnicodeString(&str); - - pRtlCreateUnicodeStringFromAsciiz(&str, "\\"); - todo_wine {SYMLNK_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH)} - pRtlFreeUnicodeString(&str); - pRtlFreeUnicodeString(&target); - - SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", "->Somewhere", STATUS_OBJECT_PATH_SYNTAX_BAD) - SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID) - SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", "->Somewhere", STATUS_OBJECT_NAME_INVALID) - SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", "->Somewhere", STATUS_OBJECT_NAME_INVALID) - SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID) - - - /* Compaund test */ - pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects"); - DIR_TEST_OPEN_SUCCESS(&dir) - pRtlFreeUnicodeString(&str); - - InitializeObjectAttributes(&attr, &str, 0, dir, NULL); - pRtlCreateUnicodeStringFromAsciiz(&str, "Local\\test-link"); - pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices"); - SYMLNK_TEST_CREATE_SUCCESS(&link) - pRtlFreeUnicodeString(&str); - pRtlFreeUnicodeString(&target); - - pRtlCreateUnicodeStringFromAsciiz(&str, "Local\\test-link\\PIPE"); - status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN); - todo_wine ok(status == STATUS_SUCCESS, "Failed to open NamedPipe(%08lx)\n", status); - pRtlFreeUnicodeString(&str); - - pNtClose(h); - pNtClose(link); - pNtClose(dir); -} - -START_TEST(om) -{ - HMODULE hntdll = GetModuleHandleA("ntdll.dll"); - if (hntdll) - { - pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz"); - pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); - pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent"); - pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant"); - pNtOpenMutant = (void *)GetProcAddress(hntdll, "NtOpenMutant"); - pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile"); - pNtClose = (void *)GetProcAddress(hntdll, "NtClose"); - pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString"); - pNtCreateNamedPipeFile = (void *)GetProcAddress(hntdll, "NtCreateNamedPipeFile"); - pNtOpenDirectoryObject = (void *)GetProcAddress(hntdll, "NtOpenDirectoryObject"); - pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject"); - pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject"); - pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject"); - pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore"); - pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer"); - pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection"); - - test_case_sensitive(); - test_namespace_pipe(); - test_name_collisions(); - test_directory(); - test_symboliclink(); - } -} +/* + * Unit test suite for object manager functions + * + * Copyright 2005 Robert Shearman + * Copyright 2005 Vitaliy Margolen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "ntdll_test.h" +#include "winternl.h" +#include "stdio.h" +#include "winnt.h" +#include "stdlib.h" + +static NTSTATUS (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR); +static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR ); +static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); +static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN, BOOLEAN); +static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN ); +static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES ); +static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG ); +static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE ); +static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER, + ULONG, ULONG, HANDLE ); +static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG ); +static NTSTATUS (WINAPI *pNtClose) ( HANDLE ); +static NTSTATUS (WINAPI *pNtCreateNamedPipeFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, + ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, PLARGE_INTEGER ); +static NTSTATUS (WINAPI *pNtOpenDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); +static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); +static NTSTATUS (WINAPI *pNtOpenSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); +static NTSTATUS (WINAPI *pNtCreateSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PUNICODE_STRING); + + +void test_case_sensitive (void) +{ + static const WCHAR buffer1[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','t','e','s','t',0}; + static const WCHAR buffer2[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','T','e','s','t',0}; + static const WCHAR buffer3[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s','\\','T','E','s','t',0}; + static const WCHAR buffer4[] = {'\\','B','A','S','E','N','a','m','e','d','O','b','j','e','c','t','s','\\','t','e','s','t',0}; + NTSTATUS status; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING str; + HANDLE Event, Mutant, h; + + pRtlInitUnicodeString(&str, buffer1); + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE); + ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08lx)\n", status); + + status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE); + ok(status == STATUS_OBJECT_NAME_COLLISION, + "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08lx)\n", status); + + pRtlInitUnicodeString(&str, buffer2); + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, FALSE, FALSE); + ok(status == STATUS_SUCCESS, "Failed to create Event(%08lx)\n", status); + + pRtlInitUnicodeString(&str, buffer3); + InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); + status = pNtOpenMutant(&h, GENERIC_ALL, &attr); + ok(status == STATUS_OBJECT_TYPE_MISMATCH, + "NtOpenMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status); + + pNtClose(Mutant); + + pRtlInitUnicodeString(&str, buffer4); + InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); + status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE); + ok(status == STATUS_OBJECT_NAME_COLLISION, + "NtCreateMutant should have failed with STATUS_OBJECT_NAME_COLLISION got(%08lx)\n", status); + + status = pNtCreateEvent(&h, GENERIC_ALL, &attr, FALSE, FALSE); + ok(status == STATUS_OBJECT_NAME_COLLISION, + "NtCreateEvent should have failed with STATUS_OBJECT_NAME_COLLISION got(%08lx)\n", status); + + attr.Attributes = 0; + status = pNtCreateMutant(&Mutant, GENERIC_ALL, &attr, FALSE); + ok(status == STATUS_OBJECT_PATH_NOT_FOUND, + "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status); + + pNtClose(Event); +} + +void test_namespace_pipe(void) +{ + static const WCHAR buffer1[] = {'\\','?','?','\\','P','I','P','E','\\','t','e','s','t','\\','p','i','p','e',0}; + static const WCHAR buffer2[] = {'\\','?','?','\\','P','I','P','E','\\','T','E','S','T','\\','P','I','P','E',0}; + static const WCHAR buffer3[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t','\\','p','i','p','e',0}; + static const WCHAR buffer4[] = {'\\','?','?','\\','p','i','p','e','\\','t','e','s','t',0}; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING str; + IO_STATUS_BLOCK iosb; + NTSTATUS status; + LARGE_INTEGER timeout; + HANDLE pipe, h; + + timeout.QuadPart = -10000; + + pRtlInitUnicodeString(&str, buffer1); + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout); + ok(status == STATUS_SUCCESS, "Failed to create NamedPipe(%08lx)\n", status); + + status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout); + ok(status == STATUS_INSTANCE_NOT_AVAILABLE, + "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08lx)\n", status); + + pRtlInitUnicodeString(&str, buffer2); + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + status = pNtCreateNamedPipeFile(&pipe, GENERIC_READ|GENERIC_WRITE, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_CREATE, FILE_PIPE_FULL_DUPLEX, FALSE, FALSE, FALSE, 1, 256, 256, &timeout); + ok(status == STATUS_INSTANCE_NOT_AVAILABLE, + "NtCreateNamedPipeFile should have failed with STATUS_INSTANCE_NOT_AVAILABLE got(%08lx)\n", status); + + attr.Attributes = OBJ_CASE_INSENSITIVE; + status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN); + ok(status == STATUS_SUCCESS, "Failed to open NamedPipe(%08lx)\n", status); + pNtClose(h); + + pRtlInitUnicodeString(&str, buffer3); + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN); + ok(status == STATUS_OBJECT_PATH_NOT_FOUND || status == STATUS_PIPE_NOT_AVAILABLE, + "pNtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status); + + pRtlInitUnicodeString(&str, buffer4); + InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, 0, NULL); + status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN); + ok(status == STATUS_OBJECT_NAME_NOT_FOUND, + "pNtOpenFile should have failed with STATUS_OBJECT_NAME_NOT_FOUND got(%08lx)\n", status); + + pNtClose(pipe); +} + +#define DIRECTORY_QUERY (0x0001) +#define SYMBOLIC_LINK_QUERY 0x0001 + +#define DIR_TEST_CREATE_FAILURE(h,e) \ + status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr);\ + ok(status == e,"NtCreateDirectoryObject should have failed with %s got(%08lx)\n", #e, status); +#define DIR_TEST_OPEN_FAILURE(h,e) \ + status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr);\ + ok(status == e,"NtOpenDirectoryObject should have failed with %s got(%08lx)\n", #e, status); +#define DIR_TEST_CREATE_OPEN_FAILURE(h,n,e) \ + pRtlCreateUnicodeStringFromAsciiz(&str, n);\ + DIR_TEST_CREATE_FAILURE(h,e) DIR_TEST_OPEN_FAILURE(h,e)\ + pRtlFreeUnicodeString(&str); + +#define DIR_TEST_CREATE_SUCCESS(h) \ + status = pNtCreateDirectoryObject(h, DIRECTORY_QUERY, &attr); \ + ok(status == STATUS_SUCCESS, "Failed to create Directory(%08lx)\n", status); +#define DIR_TEST_OPEN_SUCCESS(h) \ + status = pNtOpenDirectoryObject(h, DIRECTORY_QUERY, &attr); \ + ok(status == STATUS_SUCCESS, "Failed to open Directory(%08lx)\n", status); +#define DIR_TEST_CREATE_OPEN_SUCCESS(h,n) \ + pRtlCreateUnicodeStringFromAsciiz(&str, n);\ + DIR_TEST_CREATE_SUCCESS(h) pNtClose(h); DIR_TEST_OPEN_SUCCESS(h) pNtClose(h); \ + pRtlFreeUnicodeString(&str); + +static void test_name_collisions(void) +{ + NTSTATUS status; + UNICODE_STRING str; + OBJECT_ATTRIBUTES attr; + HANDLE dir, h, h1, h2; + DWORD winerr; + LARGE_INTEGER size; + + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + pRtlCreateUnicodeStringFromAsciiz(&str, "\\"); + DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_COLLISION) + InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL); + + DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_EXISTS) + pNtClose(h); + status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); + ok(status == STATUS_OBJECT_TYPE_MISMATCH, + "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status); + pRtlFreeUnicodeString(&str); + + pRtlCreateUnicodeStringFromAsciiz(&str, "\\??\\PIPE\\om.c-mutant"); + status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); + ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_OBJECT_PATH_NOT_FOUND, + "NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status); + pRtlFreeUnicodeString(&str); + + + pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects"); + DIR_TEST_OPEN_SUCCESS(&dir) + pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test"); + InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, dir, NULL); + + h = CreateMutexA(NULL, FALSE, "om.c-test"); + ok(h != 0, "CreateMutexA failed got ret=%p (%ld)\n", h, GetLastError()); + status = pNtCreateMutant(&h1, GENERIC_ALL, &attr, FALSE); + ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL, + "NtCreateMutant should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status); + h2 = CreateMutexA(NULL, FALSE, "om.c-test"); + winerr = GetLastError(); + ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS, + "CreateMutexA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr); + pNtClose(h); + pNtClose(h1); + pNtClose(h2); + + h = CreateEventA(NULL, FALSE, FALSE, "om.c-test"); + ok(h != 0, "CreateEventA failed got ret=%p (%ld)\n", h, GetLastError()); + status = pNtCreateEvent(&h1, GENERIC_ALL, &attr, FALSE, FALSE); + ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL, + "NtCreateEvent should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status); + h2 = CreateEventA(NULL, FALSE, FALSE, "om.c-test"); + winerr = GetLastError(); + ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS, + "CreateEventA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr); + pNtClose(h); + pNtClose(h1); + pNtClose(h2); + + h = CreateSemaphoreA(NULL, 1, 2, "om.c-test"); + ok(h != 0, "CreateSemaphoreA failed got ret=%p (%ld)\n", h, GetLastError()); + status = pNtCreateSemaphore(&h1, GENERIC_ALL, &attr, 1, 2); + ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL, + "NtCreateSemaphore should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status); + h2 = CreateSemaphoreA(NULL, 1, 2, "om.c-test"); + winerr = GetLastError(); + ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS, + "CreateSemaphoreA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr); + pNtClose(h); + pNtClose(h1); + pNtClose(h2); + + h = CreateWaitableTimerA(NULL, TRUE, "om.c-test"); + ok(h != 0, "CreateWaitableTimerA failed got ret=%p (%ld)\n", h, GetLastError()); + status = pNtCreateTimer(&h1, GENERIC_ALL, &attr, NotificationTimer); + ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL, + "NtCreateTimer should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status); + h2 = CreateWaitableTimerA(NULL, TRUE, "om.c-test"); + winerr = GetLastError(); + ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS, + "CreateWaitableTimerA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr); + pNtClose(h); + pNtClose(h1); + pNtClose(h2); + + h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test"); + ok(h != 0, "CreateFileMappingA failed got ret=%p (%ld)\n", h, GetLastError()); + size.u.LowPart = 256; + size.u.HighPart = 0; + status = pNtCreateSection(&h1, SECTION_MAP_WRITE, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0); + ok(status == STATUS_OBJECT_NAME_EXISTS && h1 != NULL, + "NtCreateSection should have succeeded with STATUS_OBJECT_NAME_EXISTS got(%08lx)\n", status); + h2 = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, "om.c-test"); + winerr = GetLastError(); + ok(h2 != 0 && winerr == ERROR_ALREADY_EXISTS, + "CreateFileMappingA should have succeeded with ERROR_ALREADY_EXISTS got ret=%p (%ld)\n", h2, winerr); + pNtClose(h); + pNtClose(h1); + pNtClose(h2); + + pRtlFreeUnicodeString(&str); + pNtClose(dir); +} + +void test_directory(void) +{ + NTSTATUS status; + UNICODE_STRING str; + OBJECT_ATTRIBUTES attr; + HANDLE dir, dir1, h; + + /* No name and/or no attributes */ + status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr); + ok(status == STATUS_ACCESS_VIOLATION, + "NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status); + status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr); + ok(status == STATUS_ACCESS_VIOLATION, + "NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status); + + status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL); + ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08lx)\n", status); + pNtClose(h); + status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL); + ok(status == STATUS_INVALID_PARAMETER, + "NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status); + + InitializeObjectAttributes(&attr, NULL, 0, 0, NULL); + DIR_TEST_CREATE_SUCCESS(&dir) + DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) + + /* Bad name */ + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + + pRtlCreateUnicodeStringFromAsciiz(&str, ""); + DIR_TEST_CREATE_SUCCESS(&h) + pNtClose(h); + DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) + pRtlFreeUnicodeString(&str); + pNtClose(dir); + + DIR_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD) + DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID) + DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID) + DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID) + DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND) + + pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test"); + DIR_TEST_CREATE_SUCCESS(&h) + DIR_TEST_OPEN_SUCCESS(&dir1) + pRtlFreeUnicodeString(&str); + pNtClose(h); + pNtClose(dir1); + + + /* Use of root directory */ + + /* Can't use symlinks as a directory */ + pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local"); + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + status = pNtOpenSymbolicLinkObject(&dir, SYMBOLIC_LINK_QUERY, &attr);\ + ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08lx)\n", status); + pRtlFreeUnicodeString(&str); + InitializeObjectAttributes(&attr, &str, 0, dir, NULL); + pRtlCreateUnicodeStringFromAsciiz(&str, "one more level"); + DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH) + pRtlFreeUnicodeString(&str); + pNtClose(h); + pNtClose(dir); + + pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects"); + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + DIR_TEST_OPEN_SUCCESS(&dir) + pRtlFreeUnicodeString(&str); + + InitializeObjectAttributes(&attr, NULL, 0, dir, NULL); + DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_NAME_INVALID) + + InitializeObjectAttributes(&attr, &str, 0, dir, NULL); + DIR_TEST_CREATE_OPEN_SUCCESS(&h, "") + DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD) + DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD) + DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD) + DIR_TEST_CREATE_OPEN_FAILURE(&h, "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND) + + pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test"); + DIR_TEST_CREATE_SUCCESS(&dir1) + DIR_TEST_OPEN_SUCCESS(&h) + pRtlFreeUnicodeString(&str); + + pNtClose(h); + pNtClose(dir1); + pNtClose(dir); + + /* Nested directories */ + pRtlCreateUnicodeStringFromAsciiz(&str, "\\"); + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + DIR_TEST_OPEN_SUCCESS(&dir) + InitializeObjectAttributes(&attr, &str, 0, dir, NULL); + DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) + pRtlFreeUnicodeString(&str); + pNtClose(dir); + + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test"); + DIR_TEST_CREATE_SUCCESS(&dir) + pRtlFreeUnicodeString(&str); + pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test\\one more level"); + DIR_TEST_CREATE_SUCCESS(&h) + pRtlFreeUnicodeString(&str); + pNtClose(h); + InitializeObjectAttributes(&attr, &str, 0, dir, NULL); + pRtlCreateUnicodeStringFromAsciiz(&str, "one more level"); + DIR_TEST_CREATE_SUCCESS(&h) + pRtlFreeUnicodeString(&str); + pNtClose(h); + + pNtClose(dir); + + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Global\\om.c-test"); + DIR_TEST_CREATE_SUCCESS(&dir) + pRtlFreeUnicodeString(&str); + pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local\\om.c-test\\one more level"); + DIR_TEST_CREATE_SUCCESS(&h) + pRtlFreeUnicodeString(&str); + pNtClose(h); + InitializeObjectAttributes(&attr, &str, 0, dir, NULL); + pRtlCreateUnicodeStringFromAsciiz(&str, "one more level"); + DIR_TEST_CREATE_SUCCESS(&dir) + pRtlFreeUnicodeString(&str); + pNtClose(h); + + pNtClose(dir); + + + /* Create other objects using RootDirectory */ + + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects"); + DIR_TEST_OPEN_SUCCESS(&dir) + pRtlFreeUnicodeString(&str); + InitializeObjectAttributes(&attr, &str, 0, dir, NULL); + + /* Test inavalid paths */ + pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant"); + status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); + ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, + "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status); + pRtlFreeUnicodeString(&str); + pRtlCreateUnicodeStringFromAsciiz(&str, "\\om.c-mutant\\"); + status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); + ok(status == STATUS_OBJECT_PATH_SYNTAX_BAD, + "NtCreateMutant should have failed with STATUS_OBJECT_PATH_SYNTAX_BAD got(%08lx)\n", status); + pRtlFreeUnicodeString(&str); + + pRtlCreateUnicodeStringFromAsciiz(&str, "om.c\\-mutant"); + status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); + ok(status == STATUS_OBJECT_PATH_NOT_FOUND, + "NtCreateMutant should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08lx)\n", status); + pRtlFreeUnicodeString(&str); + + pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-mutant"); + status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE); + ok(status == STATUS_SUCCESS, "Failed to create Mutant(%08lx)\n", status); + pRtlFreeUnicodeString(&str); + pNtClose(h); + + pNtClose(dir); +} + +#define SYMLNK_TEST_CREATE_FAILURE(h,e) \ + status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target);\ + ok(status == e,"NtCreateSymbolicLinkObject should have failed with %s got(%08lx)\n", #e, status); +#define SYMLNK_TEST_OPEN_FAILURE(h,e) \ + status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr);\ + ok(status == e,"NtOpenSymbolicLinkObject should have failed with %s got(%08lx)\n", #e, status); +#define SYMLNK_TEST_CREATE_OPEN_FAILURE(h,n,t,e) \ + pRtlCreateUnicodeStringFromAsciiz(&str, n);\ + pRtlCreateUnicodeStringFromAsciiz(&target, t);\ + SYMLNK_TEST_CREATE_FAILURE(h,e)\ + SYMLNK_TEST_OPEN_FAILURE(h,e)\ + pRtlFreeUnicodeString(&target);\ + pRtlFreeUnicodeString(&str); + +#define SYMLNK_TEST_CREATE_SUCCESS(h) \ + status = pNtCreateSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr, &target); \ + ok(status == STATUS_SUCCESS, "Failed to create SymbolicLink(%08lx)\n", status); +#define SYMLNK_TEST_OPEN_SUCCESS(h) \ + status = pNtOpenSymbolicLinkObject(h, SYMBOLIC_LINK_QUERY, &attr); \ + ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08lx)\n", status); + +void test_symboliclink(void) +{ + NTSTATUS status; + UNICODE_STRING str, target; + OBJECT_ATTRIBUTES attr; + HANDLE dir, link, h; + IO_STATUS_BLOCK iosb; + + /* No name and/or no attributes */ + SYMLNK_TEST_CREATE_OPEN_FAILURE(NULL, "", "", STATUS_ACCESS_VIOLATION) + + status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL, NULL); + ok(status == STATUS_ACCESS_VIOLATION, + "NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status); + status = pNtOpenSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, NULL); + ok(status == STATUS_INVALID_PARAMETER, + "NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status); + + InitializeObjectAttributes(&attr, NULL, 0, 0, NULL); + SYMLNK_TEST_CREATE_FAILURE(&link, STATUS_INVALID_PARAMETER) + SYMLNK_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) + + /* Bad name */ + pRtlCreateUnicodeStringFromAsciiz(&target, "anywhere"); + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); + + pRtlCreateUnicodeStringFromAsciiz(&str, ""); + SYMLNK_TEST_CREATE_SUCCESS(&link) + SYMLNK_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) + pNtClose(link); + pRtlFreeUnicodeString(&str); + + pRtlCreateUnicodeStringFromAsciiz(&str, "\\"); + todo_wine {SYMLNK_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH)} + pRtlFreeUnicodeString(&str); + pRtlFreeUnicodeString(&target); + + SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", "->Somewhere", STATUS_OBJECT_PATH_SYNTAX_BAD) + SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID) + SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", "->Somewhere", STATUS_OBJECT_NAME_INVALID) + SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", "->Somewhere", STATUS_OBJECT_NAME_INVALID) + SYMLNK_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", "->Somewhere", STATUS_OBJECT_NAME_INVALID) + + + /* Compaund test */ + pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects"); + DIR_TEST_OPEN_SUCCESS(&dir) + pRtlFreeUnicodeString(&str); + + InitializeObjectAttributes(&attr, &str, 0, dir, NULL); + pRtlCreateUnicodeStringFromAsciiz(&str, "Local\\test-link"); + pRtlCreateUnicodeStringFromAsciiz(&target, "\\DosDevices"); + SYMLNK_TEST_CREATE_SUCCESS(&link) + pRtlFreeUnicodeString(&str); + pRtlFreeUnicodeString(&target); + + pRtlCreateUnicodeStringFromAsciiz(&str, "Local\\test-link\\PIPE"); + status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN); + todo_wine ok(status == STATUS_SUCCESS, "Failed to open NamedPipe(%08lx)\n", status); + pRtlFreeUnicodeString(&str); + + pNtClose(h); + pNtClose(link); + pNtClose(dir); +} + +START_TEST(om) +{ + HMODULE hntdll = GetModuleHandleA("ntdll.dll"); + if (hntdll) + { + pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz"); + pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); + pNtCreateEvent = (void *)GetProcAddress(hntdll, "NtCreateEvent"); + pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant"); + pNtOpenMutant = (void *)GetProcAddress(hntdll, "NtOpenMutant"); + pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile"); + pNtClose = (void *)GetProcAddress(hntdll, "NtClose"); + pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString"); + pNtCreateNamedPipeFile = (void *)GetProcAddress(hntdll, "NtCreateNamedPipeFile"); + pNtOpenDirectoryObject = (void *)GetProcAddress(hntdll, "NtOpenDirectoryObject"); + pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject"); + pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject"); + pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject"); + pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore"); + pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer"); + pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection"); + + test_case_sensitive(); + test_namespace_pipe(); + test_name_collisions(); + test_directory(); + test_symboliclink(); + } +} diff --git a/reactos/regtests/winetests/ntdll/path.c b/reactos/regtests/winetests/ntdll/path.c index 7b2fb73011e..8423c09a1cd 100755 --- a/reactos/regtests/winetests/ntdll/path.c +++ b/reactos/regtests/winetests/ntdll/path.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "ntdll_test.h" diff --git a/reactos/regtests/winetests/ntdll/port.c b/reactos/regtests/winetests/ntdll/port.c new file mode 100644 index 00000000000..5b0300a0fc3 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/port.c @@ -0,0 +1,305 @@ +/* Unit test suite for Ntdll Port API functions + * + * Copyright 2006 James Hawkins + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "ntdll_test.h" +#include "windows.h" + +#ifndef __WINE_WINTERNL_H + +typedef struct _CLIENT_ID +{ + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID, *PCLIENT_ID; + +typedef struct _LPC_SECTION_WRITE +{ + ULONG Length; + HANDLE SectionHandle; + ULONG SectionOffset; + ULONG ViewSize; + PVOID ViewBase; + PVOID TargetViewBase; +} LPC_SECTION_WRITE, *PLPC_SECTION_WRITE; + +typedef struct _LPC_SECTION_READ +{ + ULONG Length; + ULONG ViewSize; + PVOID ViewBase; +} LPC_SECTION_READ, *PLPC_SECTION_READ; + +typedef struct _LPC_MESSAGE +{ + USHORT DataSize; + USHORT MessageSize; + USHORT MessageType; + USHORT VirtualRangesOffset; + CLIENT_ID ClientId; + ULONG MessageId; + ULONG SectionSize; + UCHAR Data[ANYSIZE_ARRAY]; +} LPC_MESSAGE, *PLPC_MESSAGE; + +#endif + +/* Types of LPC messages */ +#define UNUSED_MSG_TYPE 0 +#define LPC_REQUEST 1 +#define LPC_REPLY 2 +#define LPC_DATAGRAM 3 +#define LPC_LOST_REPLY 4 +#define LPC_PORT_CLOSED 5 +#define LPC_CLIENT_DIED 6 +#define LPC_EXCEPTION 7 +#define LPC_DEBUG_EVENT 8 +#define LPC_ERROR_EVENT 9 +#define LPC_CONNECTION_REQUEST 10 + +static const WCHAR PORTNAME[] = {'\\','M','y','P','o','r','t',0}; + +#define REQUEST1 "Request1" +#define REQUEST2 "Request2" +#define REPLY "Reply" + +#define MAX_MESSAGE_LEN 30 + +UNICODE_STRING port; +static char selfname[MAX_PATH]; +static int myARGC; +static char** myARGV; + +/* Function pointers for ntdll calls */ +static HMODULE hntdll = 0; +static NTSTATUS (WINAPI *pNtCompleteConnectPort)(HANDLE); +static NTSTATUS (WINAPI *pNtAcceptConnectPort)(PHANDLE,ULONG,PLPC_MESSAGE,ULONG, + ULONG,PLPC_SECTION_READ); +static NTSTATUS (WINAPI *pNtReplyPort)(HANDLE,PLPC_MESSAGE); +static NTSTATUS (WINAPI *pNtReplyWaitReceivePort)(PHANDLE,PULONG,PLPC_MESSAGE, + PLPC_MESSAGE); +static NTSTATUS (WINAPI *pNtCreatePort)(PHANDLE,POBJECT_ATTRIBUTES,ULONG,ULONG,ULONG); +static NTSTATUS (WINAPI *pNtRequestWaitReplyPort)(HANDLE,PLPC_MESSAGE,PLPC_MESSAGE); +static NTSTATUS (WINAPI *pNtRequestPort)(HANDLE,PLPC_MESSAGE); +static NTSTATUS (WINAPI *pNtRegisterThreadTerminatePort)(HANDLE); +static NTSTATUS (WINAPI *pNtConnectPort)(PHANDLE,PUNICODE_STRING, + PSECURITY_QUALITY_OF_SERVICE, + PLPC_SECTION_WRITE,PLPC_SECTION_READ, + PVOID,PVOID,PULONG); +static NTSTATUS (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING,LPCWSTR); +static NTSTATUS (WINAPI *pNtWaitForSingleObject)(HANDLE,BOOLEAN,PLARGE_INTEGER); + +static BOOL init_function_ptrs(void) +{ + hntdll = LoadLibraryA("ntdll.dll"); + + if (hntdll) + { + pNtCompleteConnectPort = (void *)GetProcAddress(hntdll, "NtCompleteConnectPort"); + pNtAcceptConnectPort = (void *)GetProcAddress(hntdll, "NtAcceptConnectPort"); + pNtReplyPort = (void *)GetProcAddress(hntdll, "NtReplyPort"); + pNtReplyWaitReceivePort = (void *)GetProcAddress(hntdll, "NtReplyWaitReceivePort"); + pNtCreatePort = (void *)GetProcAddress(hntdll, "NtCreatePort"); + pNtRequestWaitReplyPort = (void *)GetProcAddress(hntdll, "NtRequestWaitReplyPort"); + pNtRequestPort = (void *)GetProcAddress(hntdll, "NtRequestPort"); + pNtRegisterThreadTerminatePort = (void *)GetProcAddress(hntdll, "NtRegisterThreadTerminatePort"); + pNtConnectPort = (void *)GetProcAddress(hntdll, "NtConnectPort"); + pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString"); + pNtWaitForSingleObject = (void *)GetProcAddress(hntdll, "NtWaitForSingleObject"); + } + + if (!pNtCompleteConnectPort || !pNtAcceptConnectPort || + !pNtReplyWaitReceivePort || !pNtCreatePort || !pNtRequestWaitReplyPort || + !pNtRequestPort || !pNtRegisterThreadTerminatePort || + !pNtConnectPort || !pRtlInitUnicodeString) + { + return FALSE; + } + + return TRUE; +} + +static void ProcessConnectionRequest(PLPC_MESSAGE LpcMessage, PHANDLE pAcceptPortHandle) +{ + NTSTATUS status; + + ok(LpcMessage->MessageType == LPC_CONNECTION_REQUEST, + "Expected LPC_CONNECTION_REQUEST, got %d\n", LpcMessage->MessageType); + ok(!*LpcMessage->Data, "Expected empty string!\n"); + + status = pNtAcceptConnectPort(pAcceptPortHandle, 0, LpcMessage, 1, 0, NULL); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status); + + status = pNtCompleteConnectPort(*pAcceptPortHandle); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status); +} + +static void ProcessLpcRequest(HANDLE PortHandle, PLPC_MESSAGE LpcMessage) +{ + NTSTATUS status; + + ok(LpcMessage->MessageType == LPC_REQUEST, + "Expected LPC_REQUEST, got %d\n", LpcMessage->MessageType); + ok(!lstrcmp((LPSTR)LpcMessage->Data, REQUEST2), + "Expected %s, got %s\n", REQUEST2, LpcMessage->Data); + + lstrcpy((LPSTR)LpcMessage->Data, REPLY); + + status = pNtReplyPort(PortHandle, LpcMessage); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status); + ok(LpcMessage->MessageType == LPC_REQUEST, + "Expected LPC_REQUEST, got %d\n", LpcMessage->MessageType); + ok(!lstrcmp((LPSTR)LpcMessage->Data, REPLY), + "Expected %s, got %s\n", REPLY, LpcMessage->Data); +} + +static DWORD WINAPI test_ports_client(LPVOID arg) +{ + SECURITY_QUALITY_OF_SERVICE sqos; + LPC_MESSAGE *LpcMessage, *out; + HANDLE PortHandle; + ULONG len, size; + NTSTATUS status; + + sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); + sqos.ImpersonationLevel = SecurityImpersonation; + sqos.ContextTrackingMode = SECURITY_STATIC_TRACKING; + sqos.EffectiveOnly = TRUE; + + status = pNtConnectPort(&PortHandle, &port, &sqos, 0, 0, &len, NULL, NULL); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status); + + status = pNtRegisterThreadTerminatePort(PortHandle); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status); + + size = FIELD_OFFSET(LPC_MESSAGE, Data) + MAX_MESSAGE_LEN; + LpcMessage = HeapAlloc(GetProcessHeap(), 0, size); + out = HeapAlloc(GetProcessHeap(), 0, size); + + memset(LpcMessage, 0, size); + LpcMessage->DataSize = lstrlen(REQUEST1) + 1; + LpcMessage->MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data) + LpcMessage->DataSize; + lstrcpy((LPSTR)LpcMessage->Data, REQUEST1); + + status = pNtRequestPort(PortHandle, LpcMessage); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status); + ok(LpcMessage->MessageType == 0, "Expected 0, got %d\n", LpcMessage->MessageType); + ok(!lstrcmp((LPSTR)LpcMessage->Data, REQUEST1), + "Expected %s, got %s\n", REQUEST1, LpcMessage->Data); + + /* Fill in the message */ + memset(LpcMessage, 0, size); + LpcMessage->DataSize = lstrlen(REQUEST2) + 1; + LpcMessage->MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data) + LpcMessage->DataSize; + lstrcpy((LPSTR)LpcMessage->Data, REQUEST2); + + /* Send the message and wait for the reply */ + status = pNtRequestWaitReplyPort(PortHandle, LpcMessage, out); + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status); + ok(!lstrcmp((LPSTR)out->Data, REPLY), "Expected %s, got %s\n", REPLY, out->Data); + ok(out->MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->MessageType); + + return 0; +} + +static void test_ports_server(void) +{ + OBJECT_ATTRIBUTES obj; + HANDLE PortHandle; + HANDLE AcceptPortHandle; + PLPC_MESSAGE LpcMessage; + ULONG size; + NTSTATUS status; + BOOL done = FALSE; + + pRtlInitUnicodeString(&port, PORTNAME); + + memset(&obj, 0, sizeof(OBJECT_ATTRIBUTES)); + obj.Length = sizeof(OBJECT_ATTRIBUTES); + obj.ObjectName = &port; + + status = pNtCreatePort(&PortHandle, &obj, 100, 100, 0); + todo_wine + { + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status); + } + + size = FIELD_OFFSET(LPC_MESSAGE, Data) + MAX_MESSAGE_LEN; + LpcMessage = HeapAlloc(GetProcessHeap(), 0, size); + memset(LpcMessage, 0, size); + + while (TRUE) + { + status = pNtReplyWaitReceivePort(PortHandle, NULL, NULL, LpcMessage); + todo_wine + { + ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld(%lx)\n", status, status); + } + /* STATUS_INVALID_HANDLE: win2k without admin rights will perform an + * endless loop here + */ + if ((status == STATUS_NOT_IMPLEMENTED) || + (status == STATUS_INVALID_HANDLE)) return; + + switch (LpcMessage->MessageType) + { + case LPC_CONNECTION_REQUEST: + ProcessConnectionRequest(LpcMessage, &AcceptPortHandle); + break; + + case LPC_REQUEST: + ProcessLpcRequest(PortHandle, LpcMessage); + done = TRUE; + break; + + case LPC_DATAGRAM: + ok(!lstrcmp((LPSTR)LpcMessage->Data, REQUEST1), + "Expected %s, got %s\n", REQUEST1, LpcMessage->Data); + break; + + case LPC_CLIENT_DIED: + ok(done, "Expected LPC request to be completed!\n"); + return; + + default: + ok(FALSE, "Unexpected message: %d\n", LpcMessage->MessageType); + break; + } + } +} + +START_TEST(port) +{ + HANDLE thread; + DWORD id; + + if (!init_function_ptrs()) + return; + + myARGC = winetest_get_mainargs(&myARGV); + strcpy(selfname, myARGV[0]); + + thread = CreateThread(NULL, 0, test_ports_client, NULL, 0, &id); + ok(thread != NULL, "Expected non-NULL thread handle!\n"); + + test_ports_server(); + CloseHandle(thread); +} diff --git a/reactos/regtests/winetests/ntdll/reg.c b/reactos/regtests/winetests/ntdll/reg.c index b6a0d9230df..0b1cc437bf2 100755 --- a/reactos/regtests/winetests/ntdll/reg.c +++ b/reactos/regtests/winetests/ntdll/reg.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * NOTE: I don't test every RelativeTo value because it would be redundant, all calls go through * helper function RTL_GetKeyHandle().--Brad DeMorrow diff --git a/reactos/regtests/winetests/ntdll/rtl.c b/reactos/regtests/winetests/ntdll/rtl.c index fe79e36885e..d0adaa8a0d9 100755 --- a/reactos/regtests/winetests/ntdll/rtl.c +++ b/reactos/regtests/winetests/ntdll/rtl.c @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * NOTES * We use function pointers here as there is no import library for NTDLL on diff --git a/reactos/regtests/winetests/ntdll/rtlbitmap.c b/reactos/regtests/winetests/ntdll/rtlbitmap.c index 3ab115782d3..d45eedcaf20 100755 --- a/reactos/regtests/winetests/ntdll/rtlbitmap.c +++ b/reactos/regtests/winetests/ntdll/rtlbitmap.c @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * NOTES * We use function pointers here as some of the bitmap functions exist only diff --git a/reactos/regtests/winetests/ntdll/rtlstr.c b/reactos/regtests/winetests/ntdll/rtlstr.c index 84bf83d4f3a..f4939e9f1c3 100755 --- a/reactos/regtests/winetests/ntdll/rtlstr.c +++ b/reactos/regtests/winetests/ntdll/rtlstr.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * NOTES * We use function pointers here as there is no import library for NTDLL on @@ -1672,6 +1672,9 @@ static void test_RtlIntegerToChar(void) static const WCHAR szGuid[] = { '{','0','1','0','2','0','3','0','4','-', '0','5','0','6','-' ,'0','7','0','8','-','0','9','0','A','-', '0','B','0','C','0','D','0','E','0','F','0','A','}','\0' }; +static const WCHAR szGuid2[] = { '{','0','1','0','2','0','3','0','4','-', + '0','5','0','6','-' ,'0','7','0','8','-','0','9','0','A','-', + '0','B','0','C','0','D','0','E','0','F','0','A',']','\0' }; DEFINE_GUID(IID_Endianess, 0x01020304, 0x0506, 0x0708, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x0A); @@ -1687,6 +1690,12 @@ static void test_RtlGUIDFromString(void) ret = pRtlGUIDFromString(&str, &guid); ok(ret == 0, "expected ret=0, got 0x%0lx\n", ret); ok(memcmp(&guid, &IID_Endianess, sizeof(guid)) == 0, "Endianess broken\n"); + + str.Length = str.MaximumLength = (sizeof(szGuid2) - 1) / sizeof(WCHAR); + str.Buffer = (LPWSTR)szGuid2; + + ret = pRtlGUIDFromString(&str, &guid); + ok(ret, "expected ret!=0\n"); } static void test_RtlStringFromGUID(void) diff --git a/reactos/regtests/winetests/ntdll/string.c b/reactos/regtests/winetests/ntdll/string.c index f7cc7994a63..28583749426 100755 --- a/reactos/regtests/winetests/ntdll/string.c +++ b/reactos/regtests/winetests/ntdll/string.c @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * NOTES * We use function pointers here as there is no import library for NTDLL on diff --git a/reactos/regtests/winetests/ntdll/testlist.c b/reactos/regtests/winetests/ntdll/testlist.c index cdc093a8299..1797ab97be7 100644 --- a/reactos/regtests/winetests/ntdll/testlist.c +++ b/reactos/regtests/winetests/ntdll/testlist.c @@ -27,16 +27,16 @@ extern void func_time(void); const struct test winetest_testlist[] = { { "atom", func_atom }, -// { "change", func_change }, + { "change", func_change }, { "env", func_env }, { "error", func_error }, -// { "exception", func_exception }, + { "exception", func_exception }, // { "generated", func_generated }, { "info", func_info }, { "large_int", func_large_int }, { "om", func_om }, { "path", func_path }, -// { "port", func_port }, + { "port", func_port }, { "reg", func_reg }, { "rtl", func_rtl }, { "rtlbitmap", func_rtlbitmap }, diff --git a/reactos/regtests/winetests/ntdll/time.c b/reactos/regtests/winetests/ntdll/time.c index f5c586d5e15..2e9adbc11a5 100755 --- a/reactos/regtests/winetests/ntdll/time.c +++ b/reactos/regtests/winetests/ntdll/time.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "ntdll_test.h"