diff --git a/modules/rostests/winetests/ntdll/CMakeLists.txt b/modules/rostests/winetests/ntdll/CMakeLists.txt index 2e9a5ef2d22..7baff0b38ea 100644 --- a/modules/rostests/winetests/ntdll/CMakeLists.txt +++ b/modules/rostests/winetests/ntdll/CMakeLists.txt @@ -1,6 +1,5 @@ include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -remove_definitions(-DWINVER=0x502 -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x502) add_definitions(-D__WINESRC__ -DWINETEST_USE_DBGSTR_LONGLONG) list(APPEND SOURCE @@ -24,7 +23,7 @@ list(APPEND SOURCE rtlstr.c string.c time.c - ntdll_test.h) + precomp.h) if(ARCH STREQUAL "i386") list(APPEND SOURCE generated.c) @@ -38,5 +37,5 @@ endif() set_module_type(ntdll_winetest win32cui) add_importlibs(ntdll_winetest user32 ole32 advapi32 msvcrt kernel32 ntdll) -add_pch(ntdll_winetest ntdll_test.h SOURCE) +add_pch(ntdll_winetest precomp.h SOURCE) add_rostests_file(TARGET ntdll_winetest) diff --git a/modules/rostests/winetests/ntdll/atom.c b/modules/rostests/winetests/ntdll/atom.c index e8ad049aa9b..a481758ee6e 100755 --- a/modules/rostests/winetests/ntdll/atom.c +++ b/modules/rostests/winetests/ntdll/atom.c @@ -21,7 +21,22 @@ * windows. */ -#include "ntdll_test.h" +#include +#include + +#include "ntstatus.h" +/* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro + * definition errors when we get to winnt.h + */ +#define WIN32_NO_STATUS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "winnls.h" +#include "winuser.h" +#include "wine/test.h" +#include "winternl.h" #ifndef __WINE_WINTERNL_H typedef unsigned short RTL_ATOM, *PRTL_ATOM; @@ -164,6 +179,7 @@ static void test_NtAtom(void) testThread = CreateThread(NULL, 0, RtlAtomTestThread, &AtomTable, 0, NULL); WaitForSingleObject(testThread, INFINITE); + CloseHandle(testThread); Len = 64; res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len); diff --git a/modules/rostests/winetests/ntdll/change.c b/modules/rostests/winetests/ntdll/change.c index 8dfc68d788d..0e76fb5635a 100644 --- a/modules/rostests/winetests/ntdll/change.c +++ b/modules/rostests/winetests/ntdll/change.c @@ -18,7 +18,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "ntdll_test.h" +#include +#define WIN32_NO_STATUS +#include +#include +#include +#include +#include +#include "wine/test.h" static NTSTATUS (WINAPI *pNtNotifyChangeDirectoryFile)( HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID, diff --git a/modules/rostests/winetests/ntdll/directory.c b/modules/rostests/winetests/ntdll/directory.c index 75f371cfa3b..5e458a4f129 100644 --- a/modules/rostests/winetests/ntdll/directory.c +++ b/modules/rostests/winetests/ntdll/directory.c @@ -24,7 +24,18 @@ * windows. */ -#include "ntdll_test.h" +#include +#include + +#include "ntstatus.h" +/* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro + * definition errors when we get to winnt.h + */ +#define WIN32_NO_STATUS + +#include "wine/test.h" +#include "winnls.h" +#include "winternl.h" static NTSTATUS (WINAPI *pNtClose)( PHANDLE ); static NTSTATUS (WINAPI *pNtOpenFile) ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG ); diff --git a/modules/rostests/winetests/ntdll/env.c b/modules/rostests/winetests/ntdll/env.c index 5d024ec319b..8989760f43c 100755 --- a/modules/rostests/winetests/ntdll/env.c +++ b/modules/rostests/winetests/ntdll/env.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #include "ntdll_test.h" static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen, diff --git a/modules/rostests/winetests/ntdll/error.c b/modules/rostests/winetests/ntdll/error.c index 5f725e647fb..fbbc07ee770 100755 --- a/modules/rostests/winetests/ntdll/error.c +++ b/modules/rostests/winetests/ntdll/error.c @@ -19,9 +19,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "ntdll_test.h" +#include +#include -#include +#include "ntstatus.h" +#define WIN32_NO_STATUS + +#include "wine/test.h" + +#include "windef.h" +#include "winbase.h" +#include "rpcnterr.h" +#include "winreg.h" +#include "winternl.h" /* FIXME!!! this test checks only mappings, defined by MSDN * It is necessary to add other mappings and to test them diff --git a/modules/rostests/winetests/ntdll/exception.c b/modules/rostests/winetests/ntdll/exception.c index 1fb7786f29a..acbde7b2cb4 100644 --- a/modules/rostests/winetests/ntdll/exception.c +++ b/modules/rostests/winetests/ntdll/exception.c @@ -18,9 +18,27 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "ntdll_test.h" +#include +#include +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x500 /* For NTSTATUS */ +#endif + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#define NONAMELESSUNION +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winreg.h" +#include "winternl.h" +#ifdef __REACTOS__ #include +#else +#include "excpt.h" +#endif +#include "wine/test.h" static void *code_mem; diff --git a/modules/rostests/winetests/ntdll/file.c b/modules/rostests/winetests/ntdll/file.c index 36ca9fc0cfd..8afc1757117 100644 --- a/modules/rostests/winetests/ntdll/file.c +++ b/modules/rostests/winetests/ntdll/file.c @@ -24,9 +24,23 @@ * windows. */ -#include "ntdll_test.h" +#include +#include -/* FIXME */ +#include "ntstatus.h" +/* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro + * definition errors when we get to winnt.h + */ +#define WIN32_NO_STATUS + +#include "wine/test.h" +#include "winternl.h" +#include "winuser.h" +#include "winioctl.h" +#ifndef __REACTOS__ +#include "ntifs.h" +#else +/* FIXME: Inspect */ typedef struct _REPARSE_DATA_BUFFER { ULONG ReparseTag; USHORT ReparseDataLength; @@ -52,6 +66,7 @@ typedef struct _REPARSE_DATA_BUFFER { } GenericReparseBuffer; } DUMMYUNIONNAME; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; +#endif #ifndef IO_COMPLETION_ALL_ACCESS #define IO_COMPLETION_ALL_ACCESS 0x001F0003 @@ -1970,7 +1985,6 @@ static void test_file_rename_information(void) static void test_file_link_information(void) { - static const WCHAR pipeW[] = {'\\','\\','.','\\','p','i','p','e','\\','w','i','n','e','_','t','e','s','t',0}; static const WCHAR foo_txtW[] = {'\\','f','o','o','.','t','x','t',0}; static const WCHAR fooW[] = {'f','o','o',0}; WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16], *filename, *p; @@ -2593,30 +2607,6 @@ static void test_file_link_information(void) CloseHandle( handle ); CloseHandle( handle2 ); - - handle = CreateEventA( NULL, FALSE, FALSE, "wine_test_event" ); - ok( !!handle, "Failed to create event: %u\n", GetLastError()); - - fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) ); - res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation ); - ok( res == STATUS_OBJECT_TYPE_MISMATCH, "res expected STATUS_OBJECT_TYPE_MISMATCH, got %x\n", res ); - HeapFree( GetProcessHeap(), 0, fni ); - - CloseHandle( handle ); - - handle = CreateNamedPipeW( pipeW, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE, 10, 512, 512, 0, NULL); - ok( handle != INVALID_HANDLE_VALUE, "Failed to create named pipe: %u\n", GetLastError()); - - fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) ); - res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation ); - ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res ); - fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0; - ok( !lstrcmpiW(fni->FileName, pipeW + 8), "FileName expected %s, got %s\n", - wine_dbgstr_w(pipeW + 8), wine_dbgstr_w(fni->FileName) ); - HeapFree( GetProcessHeap(), 0, fni ); - - CloseHandle( handle ); - HeapFree( GetProcessHeap(), 0, fli ); delete_object( oldpath ); delete_object( newpath ); @@ -4394,6 +4384,7 @@ static void test_read_write(void) static void test_ioctl(void) { HANDLE event = CreateEventA(NULL, TRUE, FALSE, NULL); + FILE_PIPE_PEEK_BUFFER peek_buf; IO_STATUS_BLOCK iosb; HANDLE file; NTSTATUS status; @@ -4410,6 +4401,13 @@ static void test_ioctl(void) status = pNtFsControlFile(file, (HANDLE)0xdeadbeef, NULL, NULL, &iosb, 0xdeadbeef, 0, 0, 0, 0); ok(status == STATUS_INVALID_HANDLE, "NtFsControlFile returned %x\n", status); + memset(&iosb, 0x55, sizeof(iosb)); + status = NtFsControlFile(file, NULL, NULL, NULL, &iosb, FSCTL_PIPE_PEEK, NULL, 0, + &peek_buf, sizeof(peek_buf)); + todo_wine + ok(status == STATUS_INVALID_DEVICE_REQUEST, "NtFsControlFile failed: %x\n", status); + ok(iosb.Status == 0x55555555, "iosb.Status = %x\n", iosb.Status); + CloseHandle(event); CloseHandle(file); } diff --git a/modules/rostests/winetests/ntdll/generated.c b/modules/rostests/winetests/ntdll/generated.c index 54b43a33747..d6a5c4286f8 100755 --- a/modules/rostests/winetests/ntdll/generated.c +++ b/modules/rostests/winetests/ntdll/generated.c @@ -5,8 +5,18 @@ * Unit tests for data structure packing */ +#ifndef __REACTOS__ +#define WINVER 0x0501 +#define _WIN32_IE 0x0501 +#define _WIN32_WINNT 0x0501 +#endif + +#define WINE_NOWINSOCK + #include "ntdll_test.h" +#include "wine/test.h" + /*********************************************************************** * Compatibility macros */ diff --git a/modules/rostests/winetests/ntdll/info.c b/modules/rostests/winetests/ntdll/info.c index f42619a820a..14ddf20d1eb 100755 --- a/modules/rostests/winetests/ntdll/info.c +++ b/modules/rostests/winetests/ntdll/info.c @@ -19,6 +19,8 @@ */ #include "ntdll_test.h" +#include +#include static NTSTATUS (WINAPI * pRtlDowncaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN); static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); @@ -1966,6 +1968,10 @@ static void test_queryvirtualmemory(void) } else skip( "bss is outside of module\n" ); /* this can happen on Mac OS */ + /* check error code when addr is higher than working set limit */ + status = pNtQueryVirtualMemory(NtCurrentProcess(), (void *)~0, MemoryBasicInformation, &mbi, sizeof(mbi), &readcount); + ok(status == STATUS_INVALID_PARAMETER, "Expected STATUS_INVALID_PARAMETER, got %08x\n", status); + trace("Check section name of NTDLL.DLL with invalid size\n"); module = GetModuleHandleA( "ntdll.dll" ); memset(msn, 0, sizeof(*msn)); @@ -2228,26 +2234,6 @@ static void test_query_data_alignment(void) ok(value == 64, "Expected 64, got %u\n", value); } -static void test_working_set_limit(void) -{ - DWORD_PTR lower = 0, upper = ~(DWORD_PTR)0; - MEMORY_BASIC_INFORMATION mbi; - SIZE_T readcount; - NTSTATUS status; - - while (lower != upper) - { - DWORD_PTR check = (lower >> 1) + (upper >> 1) + (lower & upper & 1); - status = pNtQueryVirtualMemory(NtCurrentProcess(), (void *)check, MemoryBasicInformation, - &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount); - if (status == STATUS_INVALID_PARAMETER) upper = check; - else lower = check + 1; - } - - trace("working set limit is %p\n", (void *)upper); - ok(upper != ~(DWORD_PTR)0, "expected != ~(DWORD_PTR)0\n"); -} - START_TEST(info) { char **argv; @@ -2391,7 +2377,4 @@ START_TEST(info) trace("Starting test_query_data_alignment()\n"); test_query_data_alignment(); - - trace("Starting test_working_set_limit()\n"); - test_working_set_limit(); } diff --git a/modules/rostests/winetests/ntdll/large_int.c b/modules/rostests/winetests/ntdll/large_int.c index 2313f9eab82..4562e6768e0 100755 --- a/modules/rostests/winetests/ntdll/large_int.c +++ b/modules/rostests/winetests/ntdll/large_int.c @@ -21,8 +21,11 @@ * windows. */ +#include + #include "ntdll_test.h" + /* Function ptrs for ntdll calls */ static HMODULE hntdll = 0; static LONGLONG (WINAPI *pRtlExtendedMagicDivide)(LONGLONG, LONGLONG, INT); diff --git a/modules/rostests/winetests/ntdll/ntdll_test.h b/modules/rostests/winetests/ntdll/ntdll_test.h index d192e332dd4..6883c9867bc 100755 --- a/modules/rostests/winetests/ntdll/ntdll_test.h +++ b/modules/rostests/winetests/ntdll/ntdll_test.h @@ -18,20 +18,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef _NTDLL_TEST_H_ -#define _NTDLL_TEST_H_ +#include -#include -#include +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x500 /* For NTSTATUS */ +#endif +#include "ntstatus.h" #define WIN32_NO_STATUS -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winreg.h" +#include "wine/winternl.h" -#include -#include -#include -#include -#include - -#endif /* !_NTDLL_TEST_H_ */ +#include "wine/test.h" diff --git a/modules/rostests/winetests/ntdll/om.c b/modules/rostests/winetests/ntdll/om.c index 49784e59644..84b783b80a0 100644 --- a/modules/rostests/winetests/ntdll/om.c +++ b/modules/rostests/winetests/ntdll/om.c @@ -20,6 +20,10 @@ */ #include "ntdll_test.h" +#include "winternl.h" +#include "stdio.h" +#include "winnt.h" +#include "stdlib.h" static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*, BOOL, LPCSTR); static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR); diff --git a/modules/rostests/winetests/ntdll/path.c b/modules/rostests/winetests/ntdll/path.c index 81cc17ef217..ff5f868f259 100755 --- a/modules/rostests/winetests/ntdll/path.c +++ b/modules/rostests/winetests/ntdll/path.c @@ -28,7 +28,7 @@ static ULONG (WINAPI *pRtlIsDosDeviceName_U)( PCWSTR dos_name ); static NTSTATUS (WINAPI *pRtlOemStringToUnicodeString)(UNICODE_STRING *, const STRING *, BOOLEAN ); static BOOLEAN (WINAPI *pRtlIsNameLegalDOS8Dot3)(const UNICODE_STRING*,POEM_STRING,PBOOLEAN); static DWORD (WINAPI *pRtlGetFullPathName_U)(const WCHAR*,ULONG,WCHAR*,WCHAR**); - +static NTSTATUS (WINAPI *pRtlDosPathNameToNtPathName_U_WithStatus)(const WCHAR*, UNICODE_STRING*, WCHAR**, CURDIR*); static void test_RtlDetermineDosPathNameType_U(void) { @@ -345,6 +345,35 @@ static void test_RtlGetFullPathName_U(void) } } +static void test_RtlDosPathNameToNtPathName_U_WithStatus(void) +{ + static const WCHAR emptyW[] = { 0 }; + WCHAR path[MAX_PATH]; + UNICODE_STRING nameW; + NTSTATUS status; + + if (!pRtlDosPathNameToNtPathName_U_WithStatus) + { + win_skip("RtlDosPathNameToNtPathName_U_WithStatus() is not supported.\n"); + return; + } + + GetCurrentDirectoryW( MAX_PATH, path ); + + status = pRtlDosPathNameToNtPathName_U_WithStatus( path, &nameW, NULL, NULL ); + ok(!status, "Failed convert to nt path, %#x.\n", status); + + status = pRtlDosPathNameToNtPathName_U_WithStatus( NULL, &nameW, NULL, NULL ); + ok(status == STATUS_OBJECT_NAME_INVALID || broken(status == STATUS_OBJECT_PATH_NOT_FOUND) /* W2k3 */, + "Unexpected status %#x.\n", status); + + status = pRtlDosPathNameToNtPathName_U_WithStatus( emptyW, &nameW, NULL, NULL ); + ok(status == STATUS_OBJECT_NAME_INVALID || broken(status == STATUS_OBJECT_PATH_NOT_FOUND) /* W2k3 */, + "Unexpected status %#x.\n", status); + + RtlFreeUnicodeString( &nameW ); +} + START_TEST(path) { HMODULE mod = GetModuleHandleA("ntdll.dll"); @@ -361,9 +390,11 @@ START_TEST(path) pRtlOemStringToUnicodeString = (void *)GetProcAddress(mod,"RtlOemStringToUnicodeString"); pRtlIsNameLegalDOS8Dot3 = (void *)GetProcAddress(mod,"RtlIsNameLegalDOS8Dot3"); pRtlGetFullPathName_U = (void *)GetProcAddress(mod,"RtlGetFullPathName_U"); + pRtlDosPathNameToNtPathName_U_WithStatus = (void *)GetProcAddress(mod, "RtlDosPathNameToNtPathName_U_WithStatus"); test_RtlDetermineDosPathNameType_U(); test_RtlIsDosDeviceName_U(); test_RtlIsNameLegalDOS8Dot3(); test_RtlGetFullPathName_U(); + test_RtlDosPathNameToNtPathName_U_WithStatus(); } diff --git a/modules/rostests/winetests/ntdll/pipe.c b/modules/rostests/winetests/ntdll/pipe.c index 48cfad03b5f..35d61b40adf 100644 --- a/modules/rostests/winetests/ntdll/pipe.c +++ b/modules/rostests/winetests/ntdll/pipe.c @@ -17,7 +17,19 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "ntdll_test.h" +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winreg.h" +#include "winnls.h" +#include "wine/test.h" +#include "winternl.h" +#include "winioctl.h" #ifndef __WINE_WINTERNL_H @@ -61,6 +73,7 @@ static NTSTATUS (WINAPI *pNtCreateNamedPipeFile) (PHANDLE handle, ULONG access, ULONG inbound_quota, ULONG outbound_quota, PLARGE_INTEGER timeout); static NTSTATUS (WINAPI *pNtQueryInformationFile) (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass); +static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)(HANDLE handle, PIO_STATUS_BLOCK io, void *buffer, ULONG length, FS_INFORMATION_CLASS info_class); static NTSTATUS (WINAPI *pNtSetInformationFile) (HANDLE handle, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS class); static NTSTATUS (WINAPI *pNtCancelIoFile) (HANDLE hFile, PIO_STATUS_BLOCK io_status); static NTSTATUS (WINAPI *pNtCancelIoFileEx) (HANDLE hFile, IO_STATUS_BLOCK *iosb, IO_STATUS_BLOCK *io_status); @@ -82,12 +95,13 @@ static BOOL init_func_ptrs(void) loadfunc(NtFsControlFile) loadfunc(NtCreateNamedPipeFile) loadfunc(NtQueryInformationFile) + loadfunc(NtQueryVolumeInformationFile) loadfunc(NtSetInformationFile) loadfunc(NtCancelIoFile) - loadfunc(NtCancelIoFileEx) loadfunc(RtlInitUnicodeString) /* not fatal */ + pNtCancelIoFileEx = (void *)GetProcAddress(module, "NtCancelIoFileEx"); module = GetModuleHandleA("kernel32.dll"); pOpenThread = (void *)GetProcAddress(module, "OpenThread"); pQueueUserAPC = (void *)GetProcAddress(module, "QueueUserAPC"); @@ -242,6 +256,9 @@ static void test_create(void) res, access[k], sharing[j]); ok(info.NamedPipeConfiguration == pipe_config[j], "wrong duplex status for pipe: %d, expected %d\n", info.NamedPipeConfiguration, pipe_config[j]); + + res = listen_pipe(hclient, hEvent, &iosb, FALSE); + ok(res == STATUS_ILLEGAL_FUNCTION, "expected STATUS_ILLEGAL_FUNCTION, got %x\n", res); CloseHandle(hclient); } @@ -569,21 +586,27 @@ static void test_cancelio(void) CloseHandle(hPipe); - res = create_pipe(&hPipe, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */); - ok(!res, "NtCreateNamedPipeFile returned %x\n", res); + if (pNtCancelIoFileEx) + { + res = create_pipe(&hPipe, FILE_SHARE_READ | FILE_SHARE_WRITE, 0 /* OVERLAPPED */); + ok(!res, "NtCreateNamedPipeFile returned %x\n", res); - memset(&iosb, 0x55, sizeof(iosb)); - res = listen_pipe(hPipe, hEvent, &iosb, FALSE); - ok(res == STATUS_PENDING, "NtFsControlFile returned %x\n", res); + memset(&iosb, 0x55, sizeof(iosb)); + res = listen_pipe(hPipe, hEvent, &iosb, FALSE); + ok(res == STATUS_PENDING, "NtFsControlFile returned %x\n", res); - res = pNtCancelIoFileEx(hPipe, &iosb, &cancel_sb); - ok(!res, "NtCancelIoFileEx returned %x\n", res); + res = pNtCancelIoFileEx(hPipe, &iosb, &cancel_sb); + ok(!res, "NtCancelIoFileEx returned %x\n", res); - ok(U(iosb).Status == STATUS_CANCELLED, "Wrong iostatus %x\n", U(iosb).Status); - ok(WaitForSingleObject(hEvent, 0) == 0, "hEvent not signaled\n"); + ok(U(iosb).Status == STATUS_CANCELLED, "Wrong iostatus %x\n", U(iosb).Status); + ok(WaitForSingleObject(hEvent, 0) == 0, "hEvent not signaled\n"); + + CloseHandle(hPipe); + } + else + win_skip("NtCancelIoFileEx not available\n"); CloseHandle(hEvent); - CloseHandle(hPipe); } static void _check_pipe_handle_state(int line, HANDLE handle, ULONG read, ULONG completion) @@ -779,7 +802,7 @@ static void WINAPI apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved ) ok( !reserved, "reserved is not 0: %x\n", reserved ); } -static void test_peek(HANDLE pipe, BOOL is_msgmode) +static void test_peek(HANDLE pipe) { FILE_PIPE_PEEK_BUFFER buf; IO_STATUS_BLOCK iosb; @@ -798,7 +821,6 @@ static void test_peek(HANDLE pipe, BOOL is_msgmode) ok(!status || status == STATUS_PENDING, "NtFsControlFile failed: %x\n", status); ok(buf.ReadDataAvailable == 1, "ReadDataAvailable = %u\n", buf.ReadDataAvailable); ok(!iosb.Status, "iosb.Status = %x\n", iosb.Status); - todo_wine_if(!is_msgmode) ok(is_signaled(event), "event is not signaled\n"); CloseHandle(event); @@ -865,7 +887,6 @@ static void read_pipe_test(ULONG pipe_flags, ULONG pipe_type) ret = WriteFile( write, buffer, 1, &written, NULL ); ok(ret && written == 1, "WriteFile error %d\n", GetLastError()); /* iosb updated here by async i/o */ - Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == 0, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 1, "wrong info %lu\n", iosb.Information ); ok( !is_signaled( read ), "read handle is signaled\n" ); @@ -891,7 +912,6 @@ static void read_pipe_test(ULONG pipe_flags, ULONG pipe_type) ret = WriteFile( write, buffer, 1, &written, NULL ); ok(ret && written == 1, "WriteFile error %d\n", GetLastError()); /* iosb updated here by async i/o */ - Sleep(1); /* FIXME: needed for wine to run the i/o apc */ ok( U(iosb).Status == 0, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 1, "wrong info %lu\n", iosb.Information ); ok( is_signaled( read ), "read handle is not signaled\n" ); @@ -910,7 +930,7 @@ static void read_pipe_test(ULONG pipe_flags, ULONG pipe_type) ret = WriteFile( write, buffer, 1, &written, NULL ); ok(ret && written == 1, "WriteFile error %d\n", GetLastError()); - test_peek(read, pipe_type & PIPE_TYPE_MESSAGE); + test_peek(read); status = NtReadFile( read, event, apc, &apc_count, &iosb, buffer, 1, NULL, NULL ); ok( status == STATUS_SUCCESS, "wrong status %x\n", status ); @@ -1037,7 +1057,6 @@ static void read_pipe_test(ULONG pipe_flags, ULONG pipe_type) ok( !apc_count, "apc was called\n" ); CloseHandle( write ); Sleep(1); /* FIXME: needed for wine to run the i/o apc */ - todo_wine_if(!(pipe_type & PIPE_TYPE_MESSAGE) && (pipe_flags & PIPE_ACCESS_OUTBOUND)) ok( U(iosb).Status == STATUS_PIPE_BROKEN, "wrong status %x\n", U(iosb).Status ); ok( iosb.Information == 0, "wrong info %lu\n", iosb.Information ); ok( is_signaled( event ), "event is not signaled\n" ); @@ -1151,10 +1170,325 @@ static void read_pipe_test(ULONG pipe_flags, ULONG pipe_type) CloseHandle( read ); CloseHandle( write ); } + else + win_skip("NtCancelIoFileEx not available\n"); CloseHandle(event); } +static void test_volume_info(void) +{ + FILE_FS_DEVICE_INFORMATION *device_info; + IO_STATUS_BLOCK iosb; + HANDLE read, write; + char buffer[128]; + NTSTATUS status; + + if (!create_pipe_pair( &read, &write, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_INBOUND, + PIPE_TYPE_MESSAGE, 4096 )) return; + + memset( buffer, 0xaa, sizeof(buffer) ); + status = pNtQueryVolumeInformationFile( read, &iosb, buffer, sizeof(buffer), FileFsDeviceInformation ); + ok( status == STATUS_SUCCESS, "NtQueryVolumeInformationFile failed: %x\n", status ); + ok( iosb.Information == sizeof(*device_info), "Information = %lu\n", iosb.Information ); + device_info = (FILE_FS_DEVICE_INFORMATION*)buffer; + ok( device_info->DeviceType == FILE_DEVICE_NAMED_PIPE, "DeviceType = %u\n", device_info->DeviceType ); + ok( !(device_info->Characteristics & ~FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL), + "Characteristics = %x\n", device_info->Characteristics ); + + memset( buffer, 0xaa, sizeof(buffer) ); + status = pNtQueryVolumeInformationFile( write, &iosb, buffer, sizeof(buffer), FileFsDeviceInformation ); + ok( status == STATUS_SUCCESS, "NtQueryVolumeInformationFile failed: %x\n", status ); + ok( iosb.Information == sizeof(*device_info), "Information = %lu\n", iosb.Information ); + device_info = (FILE_FS_DEVICE_INFORMATION*)buffer; + ok( device_info->DeviceType == FILE_DEVICE_NAMED_PIPE, "DeviceType = %u\n", device_info->DeviceType ); + ok( !(device_info->Characteristics & ~FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL), + "Characteristics = %x\n", device_info->Characteristics ); + + CloseHandle( read ); + CloseHandle( write ); +} + +#define test_file_name_fail(a,b) _test_file_name_fail(__LINE__,a,b) +static void _test_file_name_fail(unsigned line, HANDLE pipe, NTSTATUS expected_status) +{ + char buffer[512]; + IO_STATUS_BLOCK iosb; + NTSTATUS status; + + status = NtQueryInformationFile( pipe, &iosb, buffer, sizeof(buffer), FileNameInformation ); + ok_(__FILE__,line)( status == expected_status, "NtQueryInformationFile failed: %x, expected %x\n", + status, expected_status ); +} + +#define test_file_name(a) _test_file_name(__LINE__,a) +static void _test_file_name(unsigned line, HANDLE pipe) +{ + char buffer[512]; + FILE_NAME_INFORMATION *name_info = (FILE_NAME_INFORMATION*)buffer; + IO_STATUS_BLOCK iosb; + NTSTATUS status; + + static const WCHAR nameW[] = + {'\\','n','t','d','l','l','_','t','e','s','t','s','_','p','i','p','e','.','c'}; + + memset( buffer, 0xaa, sizeof(buffer) ); + memset( &iosb, 0xaa, sizeof(iosb) ); + status = NtQueryInformationFile( pipe, &iosb, buffer, sizeof(buffer), FileNameInformation ); + ok_(__FILE__,line)( status == STATUS_SUCCESS, "NtQueryInformationFile failed: %x\n", status ); + ok_(__FILE__,line)( iosb.Status == STATUS_SUCCESS, "Status = %x\n", iosb.Status ); + ok_(__FILE__,line)( iosb.Information == sizeof(name_info->FileNameLength) + sizeof(nameW), + "Information = %lu\n", iosb.Information ); + ok( name_info->FileNameLength == sizeof(nameW), "FileNameLength = %u\n", name_info->FileNameLength ); + ok( !memcmp(name_info->FileName, nameW, sizeof(nameW)), "FileName = %s\n", wine_dbgstr_w(name_info->FileName) ); + + /* too small buffer */ + memset( buffer, 0xaa, sizeof(buffer) ); + memset( &iosb, 0xaa, sizeof(iosb) ); + status = NtQueryInformationFile( pipe, &iosb, buffer, 20, FileNameInformation ); + ok( status == STATUS_BUFFER_OVERFLOW, "NtQueryInformationFile failed: %x\n", status ); + ok( iosb.Status == STATUS_BUFFER_OVERFLOW, "Status = %x\n", iosb.Status ); + ok( iosb.Information == 20, "Information = %lu\n", iosb.Information ); + ok( name_info->FileNameLength == sizeof(nameW), "FileNameLength = %u\n", name_info->FileNameLength ); + ok( !memcmp(name_info->FileName, nameW, 16), "FileName = %s\n", wine_dbgstr_w(name_info->FileName) ); + + /* too small buffer */ + memset( buffer, 0xaa, sizeof(buffer) ); + memset( &iosb, 0xaa, sizeof(iosb) ); + status = NtQueryInformationFile( pipe, &iosb, buffer, 4, FileNameInformation ); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryInformationFile failed: %x\n", status ); +} + +static void test_file_info(void) +{ + HANDLE server, client; + + if (!create_pipe_pair( &server, &client, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_INBOUND, + PIPE_TYPE_MESSAGE, 4096 )) return; + + test_file_name( client ); + test_file_name( server ); + + DisconnectNamedPipe( server ); + test_file_name_fail( client, STATUS_PIPE_DISCONNECTED ); + + CloseHandle( server ); + CloseHandle( client ); +} + +static PSECURITY_DESCRIPTOR get_security_descriptor(HANDLE handle, BOOL todo) +{ + SECURITY_DESCRIPTOR *sec_desc; + ULONG length = 0; + NTSTATUS status; + + status = NtQuerySecurityObject(handle, GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, + NULL, 0, &length); + todo_wine_if(todo && status == STATUS_PIPE_DISCONNECTED) + ok(status == STATUS_BUFFER_TOO_SMALL, + "Failed to query object security descriptor length: %08x\n", status); + if(status != STATUS_BUFFER_TOO_SMALL) return NULL; + ok(length != 0, "length = 0\n"); + + sec_desc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, length); + status = NtQuerySecurityObject(handle, GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, + sec_desc, length, &length); + ok(status == STATUS_SUCCESS, "Failed to query object security descriptor: %08x\n", status); + + return sec_desc; +} + +static TOKEN_OWNER *get_current_owner(void) +{ + TOKEN_OWNER *owner; + ULONG length = 0; + HANDLE token; + BOOL ret; + + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token); + ok(ret, "Failed to get process token: %u\n", GetLastError()); + + ret = GetTokenInformation(token, TokenOwner, NULL, 0, &length); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "GetTokenInformation failed: %u\n", GetLastError()); + ok(length != 0, "Failed to get token owner information length: %u\n", GetLastError()); + + owner = HeapAlloc(GetProcessHeap(), 0, length); + ret = GetTokenInformation(token, TokenOwner, owner, length, &length); + ok(ret, "Failed to get token owner information: %u)\n", GetLastError()); + + CloseHandle(token); + return owner; +} + +static TOKEN_PRIMARY_GROUP *get_current_group(void) +{ + TOKEN_PRIMARY_GROUP *group; + ULONG length = 0; + HANDLE token; + BOOL ret; + + ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token); + ok(ret, "Failed to get process token: %u\n", GetLastError()); + + ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &length); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "GetTokenInformation failed: %u\n", GetLastError()); + ok(length != 0, "Failed to get primary group token information length: %u\n", GetLastError()); + + group = HeapAlloc(GetProcessHeap(), 0, length); + ret = GetTokenInformation(token, TokenPrimaryGroup, group, length, &length); + ok(ret, "Failed to get primary group token information: %u\n", GetLastError()); + + CloseHandle(token); + return group; +} + +static SID *well_known_sid(WELL_KNOWN_SID_TYPE sid_type) +{ + DWORD size = SECURITY_MAX_SID_SIZE; + SID *sid; + BOOL ret; + + sid = HeapAlloc(GetProcessHeap(), 0, size); + ret = CreateWellKnownSid(sid_type, NULL, sid, &size); + ok(ret, "CreateWellKnownSid failed: %u\n", GetLastError()); + return sid; +} + +#define test_group(a,b,c) _test_group(__LINE__,a,b,c) +static void _test_group(unsigned line, HANDLE handle, SID *expected_sid, BOOL todo) +{ + SECURITY_DESCRIPTOR *sec_desc; + BOOLEAN defaulted; + PSID group_sid; + NTSTATUS status; + + sec_desc = get_security_descriptor(handle, todo); + if (!sec_desc) return; + + status = RtlGetGroupSecurityDescriptor(sec_desc, &group_sid, &defaulted); + ok_(__FILE__,line)(status == STATUS_SUCCESS, + "Failed to query group from security descriptor: %08x\n", status); + todo_wine_if(todo) + ok_(__FILE__,line)(EqualSid(group_sid, expected_sid), "SIDs are not equal\n"); + + HeapFree(GetProcessHeap(), 0, sec_desc); +} + +static void test_security_info(void) +{ + char sec_desc[SECURITY_DESCRIPTOR_MIN_LENGTH]; + TOKEN_PRIMARY_GROUP *process_group; + SECURITY_ATTRIBUTES sec_attr; + TOKEN_OWNER *process_owner; + HANDLE server, client, server2; + SID *world_sid, *local_sid; + ULONG length; + NTSTATUS status; + BOOL ret; + + trace("security tests...\n"); + + process_owner = get_current_owner(); + process_group = get_current_group(); + world_sid = well_known_sid(WinWorldSid); + local_sid = well_known_sid(WinLocalSid); + + ret = InitializeSecurityDescriptor(sec_desc, SECURITY_DESCRIPTOR_REVISION); + ok(ret, "InitializeSecurityDescriptor failed\n"); + + ret = SetSecurityDescriptorOwner(sec_desc, process_owner->Owner, FALSE); + ok(ret, "SetSecurityDescriptorOwner failed\n"); + + ret = SetSecurityDescriptorGroup(sec_desc, process_group->PrimaryGroup, FALSE); + ok(ret, "SetSecurityDescriptorGroup failed\n"); + + server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | WRITE_OWNER, PIPE_TYPE_BYTE, 10, + 0x20000, 0x20000, 0, NULL); + ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError()); + + client = CreateFileA(PIPENAME, GENERIC_ALL, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(client != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError()); + + test_group(server, process_group->PrimaryGroup, TRUE); + test_group(client, process_group->PrimaryGroup, TRUE); + + /* set server group, client changes as well */ + ret = SetSecurityDescriptorGroup(sec_desc, world_sid, FALSE); + ok(ret, "SetSecurityDescriptorGroup failed\n"); + status = NtSetSecurityObject(server, GROUP_SECURITY_INFORMATION, sec_desc); + ok(status == STATUS_SUCCESS, "NtSetSecurityObject failed: %08x\n", status); + + test_group(server, world_sid, FALSE); + test_group(client, world_sid, FALSE); + + /* new instance of pipe server has the same security descriptor */ + server2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE, 10, + 0x20000, 0x20000, 0, NULL); + ok(server2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError()); + test_group(server2, world_sid, FALSE); + + /* set client group, server changes as well */ + ret = SetSecurityDescriptorGroup(sec_desc, local_sid, FALSE); + ok(ret, "SetSecurityDescriptorGroup failed\n"); + status = NtSetSecurityObject(server, GROUP_SECURITY_INFORMATION, sec_desc); + ok(status == STATUS_SUCCESS, "NtSetSecurityObject failed: %08x\n", status); + + test_group(server, local_sid, FALSE); + test_group(client, local_sid, FALSE); + test_group(server2, local_sid, FALSE); + + CloseHandle(server); + /* SD is preserved after closing server object */ + test_group(client, local_sid, TRUE); + CloseHandle(client); + + server = server2; + client = CreateFileA(PIPENAME, GENERIC_ALL, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(client != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError()); + + test_group(client, local_sid, FALSE); + + ret = DisconnectNamedPipe(server); + ok(ret, "DisconnectNamedPipe failed: %u\n", GetLastError()); + + /* disconnected server may be queried for security info, but client does not */ + test_group(server, local_sid, FALSE); + status = NtQuerySecurityObject(client, GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, + NULL, 0, &length); + ok(status == STATUS_PIPE_DISCONNECTED, "NtQuerySecurityObject returned %08x\n", status); + status = NtSetSecurityObject(client, GROUP_SECURITY_INFORMATION, sec_desc); + ok(status == STATUS_PIPE_DISCONNECTED, "NtQuerySecurityObject returned %08x\n", status); + + /* attempting to create another pipe instance with specified sd fails */ + sec_attr.nLength = sizeof(sec_attr); + sec_attr.lpSecurityDescriptor = sec_desc; + sec_attr.bInheritHandle = FALSE; + ret = SetSecurityDescriptorGroup(sec_desc, local_sid, FALSE); + ok(ret, "SetSecurityDescriptorGroup failed\n"); + server2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | WRITE_OWNER, PIPE_TYPE_BYTE, 10, + 0x20000, 0x20000, 0, &sec_attr); + todo_wine + ok(server2 == INVALID_HANDLE_VALUE && GetLastError() == ERROR_ACCESS_DENIED, + "CreateNamedPipe failed: %u\n", GetLastError()); + if (server2 != INVALID_HANDLE_VALUE) CloseHandle(server2); + + CloseHandle(server); + CloseHandle(client); + + server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | WRITE_OWNER, PIPE_TYPE_BYTE, 10, + 0x20000, 0x20000, 0, &sec_attr); + ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError()); + test_group(server, local_sid, FALSE); + CloseHandle(server); + + HeapFree(GetProcessHeap(), 0, process_owner); + HeapFree(GetProcessHeap(), 0, process_group); + HeapFree(GetProcessHeap(), 0, world_sid); + HeapFree(GetProcessHeap(), 0, local_sid); +} + START_TEST(pipe) { if (!init_func_ptrs()) @@ -1199,4 +1533,8 @@ START_TEST(pipe) read_pipe_test(PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE); trace("starting message read in message mode server -> client\n"); read_pipe_test(PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE); + + test_volume_info(); + test_file_info(); + test_security_info(); } diff --git a/modules/rostests/winetests/ntdll/port.c b/modules/rostests/winetests/ntdll/port.c index 1b477180497..9525232ade5 100644 --- a/modules/rostests/winetests/ntdll/port.c +++ b/modules/rostests/winetests/ntdll/port.c @@ -17,7 +17,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "ntdll_test.h" +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winreg.h" +#include "winnls.h" +#include "wine/test.h" +#include "winternl.h" #ifndef __WINE_WINTERNL_H diff --git a/modules/rostests/winetests/ntdll/precomp.h b/modules/rostests/winetests/ntdll/precomp.h new file mode 100644 index 00000000000..1f8e9ce5524 --- /dev/null +++ b/modules/rostests/winetests/ntdll/precomp.h @@ -0,0 +1,20 @@ + +#ifndef _NTDLL_WINETEST_PRECOMP_H_ +#define _NTDLL_WINETEST_PRECOMP_H_ + +#include +#include + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include "ntdll_test.h" + +#include +#include +#include + +#endif /* !_NTDLL_WINETEST_PRECOMP_H_ */ diff --git a/modules/rostests/winetests/ntdll/process.c b/modules/rostests/winetests/ntdll/process.c index 8187f637e38..41303b7e9ae 100644 --- a/modules/rostests/winetests/ntdll/process.c +++ b/modules/rostests/winetests/ntdll/process.c @@ -18,8 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #include "ntdll_test.h" +#include "windef.h" +#include "winbase.h" + static NTSTATUS (WINAPI *pNtResumeProcess)(HANDLE); static NTSTATUS (WINAPI *pNtSuspendProcess)(HANDLE); static NTSTATUS (WINAPI *pNtSuspendThread)(HANDLE,PULONG); diff --git a/modules/rostests/winetests/ntdll/reg.c b/modules/rostests/winetests/ntdll/reg.c index 1f3bd0acb4b..b03cd077dfd 100755 --- a/modules/rostests/winetests/ntdll/reg.c +++ b/modules/rostests/winetests/ntdll/reg.c @@ -23,8 +23,11 @@ */ #include "ntdll_test.h" - -#include +#include "winternl.h" +#include "stdio.h" +#include "winnt.h" +#include "winnls.h" +#include "stdlib.h" /* A test string */ static const WCHAR stringW[] = {'s', 't', 'r', 'i', 'n', 'g', 'W', 0}; diff --git a/modules/rostests/winetests/ntdll/rtl.c b/modules/rostests/winetests/ntdll/rtl.c index 147fd2d116e..c4d49ea0512 100755 --- a/modules/rostests/winetests/ntdll/rtl.c +++ b/modules/rostests/winetests/ntdll/rtl.c @@ -21,14 +21,17 @@ * windows. */ -#include "ntdll_test.h" +#include -#include -#include -#include -#include +#include "ntdll_test.h" +#include "inaddr.h" +#include "in6addr.h" +#include "initguid.h" #define COBJMACROS -#include +#ifdef __REACTOS__ +#include +#endif +#include "shobjidl.h" #ifndef __WINE_WINTERNL_H @@ -112,6 +115,8 @@ static BOOL (WINAPI *pRtlIsCriticalSectionLockedByThread)(CRITICAL_SECTION static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, ULONG, ULONG); static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void *, void *, void *); static NTSTATUS (WINAPI *pRtlQueryPackageIdentity)(HANDLE, WCHAR*, SIZE_T*, WCHAR*, SIZE_T*, BOOLEAN*); +static NTSTATUS (WINAPI *pRtlMakeSelfRelativeSD)(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD); +static NTSTATUS (WINAPI *pRtlAbsoluteToSelfRelativeSD)(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PULONG); static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **); static NTSTATUS (WINAPI *pLdrUnregisterDllNotification)(void *); @@ -180,6 +185,8 @@ static void InitFunctionPtrs(void) pRtlInitializeCriticalSectionEx = (void *)GetProcAddress(hntdll, "RtlInitializeCriticalSectionEx"); pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules"); pRtlQueryPackageIdentity = (void *)GetProcAddress(hntdll, "RtlQueryPackageIdentity"); + pRtlMakeSelfRelativeSD = (void *)GetProcAddress(hntdll, "RtlMakeSelfRelativeSD"); + pRtlAbsoluteToSelfRelativeSD = (void *)GetProcAddress(hntdll, "RtlAbsoluteToSelfRelativeSD"); pLdrRegisterDllNotification = (void *)GetProcAddress(hntdll, "LdrRegisterDllNotification"); pLdrUnregisterDllNotification = (void *)GetProcAddress(hntdll, "LdrUnregisterDllNotification"); } @@ -3282,6 +3289,52 @@ static void test_LdrEnumerateLoadedModules(void) ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got 0x%08x\n", status); } +static void test_RtlMakeSelfRelativeSD(void) +{ + char buf[sizeof(SECURITY_DESCRIPTOR_RELATIVE) + 4]; + SECURITY_DESCRIPTOR_RELATIVE *sd_rel = (SECURITY_DESCRIPTOR_RELATIVE *)buf; + SECURITY_DESCRIPTOR sd; + NTSTATUS status; + DWORD len; + + if (!pRtlMakeSelfRelativeSD || !pRtlAbsoluteToSelfRelativeSD) + { + win_skip( "RtlMakeSelfRelativeSD/RtlAbsoluteToSelfRelativeSD not available\n" ); + return; + } + + memset( &sd, 0, sizeof(sd) ); + sd.Revision = SECURITY_DESCRIPTOR_REVISION; + + len = 0; + status = pRtlMakeSelfRelativeSD( &sd, NULL, &len ); + ok( status == STATUS_BUFFER_TOO_SMALL, "got %08x\n", status ); + ok( len == sizeof(*sd_rel), "got %u\n", len ); + + len += 4; + status = pRtlMakeSelfRelativeSD( &sd, sd_rel, &len ); + ok( status == STATUS_SUCCESS, "got %08x\n", status ); + ok( len == sizeof(*sd_rel) + 4, "got %u\n", len ); + + len = 0; + status = pRtlAbsoluteToSelfRelativeSD( &sd, NULL, &len ); + ok( status == STATUS_BUFFER_TOO_SMALL, "got %08x\n", status ); + ok( len == sizeof(*sd_rel), "got %u\n", len ); + + len += 4; + status = pRtlAbsoluteToSelfRelativeSD( &sd, sd_rel, &len ); + ok( status == STATUS_SUCCESS, "got %08x\n", status ); + ok( len == sizeof(*sd_rel) + 4, "got %u\n", len ); + + sd.Control = SE_SELF_RELATIVE; + status = pRtlMakeSelfRelativeSD( &sd, sd_rel, &len ); + ok( status == STATUS_SUCCESS, "got %08x\n", status ); + ok( len == sizeof(*sd_rel) + 4, "got %u\n", len ); + + status = pRtlAbsoluteToSelfRelativeSD( &sd, sd_rel, &len ); + ok( status == STATUS_BAD_DESCRIPTOR_FORMAT, "got %08x\n", status ); +} + static void test_RtlQueryPackageIdentity(void) { const WCHAR programW[] = {'M','i','c','r','o','s','o','f','t','.','W','i','n','d','o','w','s','.', @@ -3633,5 +3686,6 @@ START_TEST(rtl) test_RtlLeaveCriticalSection(); test_LdrEnumerateLoadedModules(); test_RtlQueryPackageIdentity(); + test_RtlMakeSelfRelativeSD(); test_LdrRegisterDllNotification(); } diff --git a/modules/rostests/winetests/ntdll/rtlstr.c b/modules/rostests/winetests/ntdll/rtlstr.c index c113f76a89d..7f889dfa0d0 100755 --- a/modules/rostests/winetests/ntdll/rtlstr.c +++ b/modules/rostests/winetests/ntdll/rtlstr.c @@ -22,9 +22,13 @@ * windows. */ -#include "ntdll_test.h" +#include -#include +#define INITGUID + +#include "ntdll_test.h" +#include "winnls.h" +#include "guiddef.h" #define HASH_STRING_ALGORITHM_X65599 1 #define HASH_STRING_ALGORITHM_INVALID 0xffffffff diff --git a/modules/rostests/winetests/ntdll/string.c b/modules/rostests/winetests/ntdll/string.c index 9de0039fe9f..8fca5d46d5e 100755 --- a/modules/rostests/winetests/ntdll/string.c +++ b/modules/rostests/winetests/ntdll/string.c @@ -21,8 +21,11 @@ * windows. */ +#include + #include "ntdll_test.h" + /* Function ptrs for ntdll calls */ static HMODULE hntdll = 0; static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN); @@ -56,7 +59,7 @@ static LPWSTR (WINAPIV *p_wcsrchr)(LPCWSTR, WCHAR); static void (__cdecl *p_qsort)(void *,size_t,size_t, int(__cdecl *compar)(const void *, const void *) ); static void* (__cdecl *p_bsearch)(void *,void*,size_t,size_t, int(__cdecl *compar)(const void *, const void *) ); -static int (__cdecl *p__snprintf)(char *, size_t, const char *, ...); +static int (WINAPIV *p__snprintf)(char *, size_t, const char *, ...); static void InitFunctionPtrs(void) diff --git a/modules/rostests/winetests/ntdll/time.c b/modules/rostests/winetests/ntdll/time.c index 7d9e65148e3..92b674f03e8 100755 --- a/modules/rostests/winetests/ntdll/time.c +++ b/modules/rostests/winetests/ntdll/time.c @@ -18,9 +18,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#ifndef __REACTOS__ +#define NONAMELESSUNION +#endif #include "ntdll_test.h" - -/* FIXME: Inspect */ +#ifndef __REACTOS__ +#include "ddk/wdm.h" +#else /* FIXME: Inspect */ typedef struct _KSYSTEM_TIME { ULONG LowPart; @@ -91,6 +95,8 @@ typedef struct _KUSER_SHARED_DATA { ULONG Wow64SharedInformation[MAX_WOW64_SHARED_ENTRIES]; } KSHARED_USER_DATA, *PKSHARED_USER_DATA; +#endif /* !__REACTOS__ */ + #define TICKSPERSEC 10000000 #define TICKSPERMSEC 10000 #define SECSPERDAY 86400 @@ -98,6 +104,8 @@ typedef struct _KUSER_SHARED_DATA { static VOID (WINAPI *pRtlTimeToTimeFields)( const LARGE_INTEGER *liTime, PTIME_FIELDS TimeFields) ; static VOID (WINAPI *pRtlTimeFieldsToTime)( PTIME_FIELDS TimeFields, PLARGE_INTEGER Time) ; static NTSTATUS (WINAPI *pNtQueryPerformanceCounter)( LARGE_INTEGER *counter, LARGE_INTEGER *frequency ); +static NTSTATUS (WINAPI *pRtlQueryTimeZoneInformation)( RTL_TIME_ZONE_INFORMATION *); +static NTSTATUS (WINAPI *pRtlQueryDynamicTimeZoneInformation)( RTL_DYNAMIC_TIME_ZONE_INFORMATION *); static ULONG (WINAPI *pNtGetTickCount)(void); static const int MonthLengths[2][12] = @@ -187,6 +195,42 @@ static void test_NtQueryPerformanceCounter(void) ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); } +static void test_RtlQueryTimeZoneInformation(void) +{ + RTL_DYNAMIC_TIME_ZONE_INFORMATION tzinfo; + NTSTATUS status; + + /* test RtlQueryTimeZoneInformation returns an indirect string, + e.g. @tzres.dll,-32 (Vista or later) */ + if (!pRtlQueryTimeZoneInformation || !pRtlQueryDynamicTimeZoneInformation) + { + win_skip("Time zone name tests requires Vista or later\n"); + return; + } + + memset(&tzinfo, 0, sizeof(tzinfo)); + status = pRtlQueryDynamicTimeZoneInformation(&tzinfo); + ok(status == STATUS_SUCCESS, + "RtlQueryDynamicTimeZoneInformation failed, got %08x\n", status); + todo_wine ok(tzinfo.StandardName[0] == '@', + "standard time zone name isn't an indirect string, got %s\n", + wine_dbgstr_w(tzinfo.StandardName)); + todo_wine ok(tzinfo.DaylightName[0] == '@', + "daylight time zone name isn't an indirect string, got %s\n", + wine_dbgstr_w(tzinfo.DaylightName)); + + memset(&tzinfo, 0, sizeof(tzinfo)); + status = pRtlQueryTimeZoneInformation((RTL_TIME_ZONE_INFORMATION *)&tzinfo); + ok(status == STATUS_SUCCESS, + "RtlQueryTimeZoneInformation failed, got %08x\n", status); + todo_wine ok(tzinfo.StandardName[0] == '@', + "standard time zone name isn't an indirect string, got %s\n", + wine_dbgstr_w(tzinfo.StandardName)); + todo_wine ok(tzinfo.DaylightName[0] == '@', + "daylight time zone name isn't an indirect string, got %s\n", + wine_dbgstr_w(tzinfo.DaylightName)); +} + static void test_NtGetTickCount(void) { #ifndef _WIN64 @@ -217,10 +261,16 @@ START_TEST(time) pRtlTimeFieldsToTime = (void *)GetProcAddress(mod,"RtlTimeFieldsToTime"); pNtQueryPerformanceCounter = (void *)GetProcAddress(mod, "NtQueryPerformanceCounter"); pNtGetTickCount = (void *)GetProcAddress(mod,"NtGetTickCount"); + pRtlQueryTimeZoneInformation = + (void *)GetProcAddress(mod, "RtlQueryTimeZoneInformation"); + pRtlQueryDynamicTimeZoneInformation = + (void *)GetProcAddress(mod, "RtlQueryDynamicTimeZoneInformation"); + if (pRtlTimeToTimeFields && pRtlTimeFieldsToTime) test_pRtlTimeToTimeFields(); else win_skip("Required time conversion functions are not available\n"); test_NtQueryPerformanceCounter(); test_NtGetTickCount(); + test_RtlQueryTimeZoneInformation(); }