[NTDLL_WINETEST] Sync with Wine Staging 3.3. CORE-14434
authorAmine Khaldi <amine.khaldi@reactos.org>
Tue, 3 Apr 2018 12:43:22 +0000 (13:43 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Tue, 3 Apr 2018 12:43:22 +0000 (13:43 +0100)
23 files changed:
modules/rostests/winetests/ntdll/CMakeLists.txt
modules/rostests/winetests/ntdll/atom.c
modules/rostests/winetests/ntdll/change.c
modules/rostests/winetests/ntdll/directory.c
modules/rostests/winetests/ntdll/env.c
modules/rostests/winetests/ntdll/error.c
modules/rostests/winetests/ntdll/exception.c
modules/rostests/winetests/ntdll/file.c
modules/rostests/winetests/ntdll/generated.c
modules/rostests/winetests/ntdll/info.c
modules/rostests/winetests/ntdll/large_int.c
modules/rostests/winetests/ntdll/ntdll_test.h
modules/rostests/winetests/ntdll/om.c
modules/rostests/winetests/ntdll/path.c
modules/rostests/winetests/ntdll/pipe.c
modules/rostests/winetests/ntdll/port.c
modules/rostests/winetests/ntdll/precomp.h [new file with mode: 0644]
modules/rostests/winetests/ntdll/process.c
modules/rostests/winetests/ntdll/reg.c
modules/rostests/winetests/ntdll/rtl.c
modules/rostests/winetests/ntdll/rtlstr.c
modules/rostests/winetests/ntdll/string.c
modules/rostests/winetests/ntdll/time.c

index 2e9a5ef..7baff0b 100644 (file)
@@ -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)
index e8ad049..a481758 100755 (executable)
  * windows.
  */
 
-#include "ntdll_test.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+#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);
index 8dfc68d..0e76fb5 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "ntdll_test.h"
+#include <ntstatus.h>
+#define WIN32_NO_STATUS
+#include <windows.h>
+#include <winnt.h>
+#include <winternl.h>
+#include <winerror.h>
+#include <stdio.h>
+#include "wine/test.h"
 
 static NTSTATUS (WINAPI *pNtNotifyChangeDirectoryFile)(
                           HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,
index 75f371c..5e458a4 100644 (file)
  * windows.
  */
 
-#include "ntdll_test.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+#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 );
index 5d024ec..8989760 100755 (executable)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include <stdio.h>
+
 #include "ntdll_test.h"
 
 static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
index 5f725e6..fbbc07e 100755 (executable)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "ntdll_test.h"
+#include <stdarg.h>
+#include <stdio.h>
 
-#include <rpcnterr.h>
+#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
index 1fb7786..acbde7b 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "ntdll_test.h"
+#include <stdarg.h>
+#include <stdio.h>
 
+#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 <wine/exception.h>
+#else
+#include "excpt.h"
+#endif
+#include "wine/test.h"
 
 static void *code_mem;
 
index 36ca9fc..8afc175 100644 (file)
  * windows.
  */
 
-#include "ntdll_test.h"
+#include <stdio.h>
+#include <stdarg.h>
 
-/* 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);
 }
index 54b43a3..d6a5c42 100755 (executable)
@@ -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
  */
index f42619a..14ddf20 100755 (executable)
@@ -19,6 +19,8 @@
  */
 
 #include "ntdll_test.h"
+#include <winnls.h>
+#include <stdio.h>
 
 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();
 }
index 2313f9e..4562e67 100755 (executable)
  * windows.
  */
 
+#include <stdlib.h>
+
 #include "ntdll_test.h"
 
+
 /* Function ptrs for ntdll calls */
 static HMODULE hntdll = 0;
 static LONGLONG (WINAPI *pRtlExtendedMagicDivide)(LONGLONG, LONGLONG, INT);
index d192e33..6883c98 100755 (executable)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#ifndef _NTDLL_TEST_H_
-#define _NTDLL_TEST_H_
+#include <stdarg.h>
 
-#include <stdio.h>
-#include <ntstatus.h>
+#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 <wine/test.h>
-#include <winuser.h>
-#include <winnls.h>
-#include <winioctl.h>
-#include <wine/winternl.h>
-
-#endif /* !_NTDLL_TEST_H_ */
+#include "wine/test.h"
index 49784e5..84b783b 100644 (file)
  */
 
 #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);
index 81cc17e..ff5f868 100755 (executable)
@@ -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();
 }
index 48cfad0..35d61b4 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "ntdll_test.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+#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();
 }
index 1b47718..9525232 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "ntdll_test.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+#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 (file)
index 0000000..1f8e9ce
--- /dev/null
@@ -0,0 +1,20 @@
+
+#ifndef _NTDLL_WINETEST_PRECOMP_H_
+#define _NTDLL_WINETEST_PRECOMP_H_
+
+#include <stdio.h>
+#include <ntstatus.h>
+
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
+#define COBJMACROS
+
+#include "ntdll_test.h"
+
+#include <winuser.h>
+#include <winnls.h>
+#include <winioctl.h>
+
+#endif /* !_NTDLL_WINETEST_PRECOMP_H_ */
index 8187f63..41303b7 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include <stdio.h>
+
 #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);
index 1f3bd0a..b03cd07 100755 (executable)
  */
 
 #include "ntdll_test.h"
-
-#include <winreg.h>
+#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};
index 147fd2d..c4d49ea 100755 (executable)
  * windows.
  */
 
-#include "ntdll_test.h"
+#include <stdlib.h>
 
-#include <inaddr.h>
-#include <in6addr.h>
-#include <objbase.h>
-#include <initguid.h>
+#include "ntdll_test.h"
+#include "inaddr.h"
+#include "in6addr.h"
+#include "initguid.h"
 #define COBJMACROS
-#include <shobjidl.h>
+#ifdef __REACTOS__
+#include <objbase.h>
+#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();
 }
index c113f76..7f889df 100755 (executable)
  * windows.
  */
 
-#include "ntdll_test.h"
+#include <stdlib.h>
+
+#define INITGUID
 
-#include <initguid.h>
+#include "ntdll_test.h"
+#include "winnls.h"
+#include "guiddef.h"
 
 #define HASH_STRING_ALGORITHM_X65599   1
 #define HASH_STRING_ALGORITHM_INVALID  0xffffffff
index 9de0039..8fca5d4 100755 (executable)
  * windows.
  */
 
+#include <stdlib.h>
+
 #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)
index 7d9e651..92b674f 100755 (executable)
  * 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();
 }