From 733ae7526f2498282b42254b867e5c2d278b379a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sun, 17 Jan 2016 00:50:50 +0100
Subject: ntdll/tests: Add basic tests for RtlQueryPackageIdentity.

---
 dlls/ntdll/tests/Makefile.in |  2 +-
 dlls/ntdll/tests/rtl.c       | 76 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/tests/Makefile.in b/dlls/ntdll/tests/Makefile.in
index fc352dd..0de4fe8 100644
--- a/dlls/ntdll/tests/Makefile.in
+++ b/dlls/ntdll/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL   = ntdll.dll
-IMPORTS   = user32
+IMPORTS   = user32 ole32 advapi32
 
 C_SRCS = \
 	atom.c \
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index 1b17a7e..95b58c3 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -25,6 +25,9 @@
 
 #include "ntdll_test.h"
 #include "inaddr.h"
+#include "initguid.h"
+#define COBJMACROS
+#include "shobjidl.h"
 
 #ifndef __WINE_WINTERNL_H
 
@@ -99,6 +102,7 @@ static NTSTATUS  (WINAPI *pRtlCompressBuffer)(USHORT, const UCHAR*, ULONG, PUCHA
 static BOOL      (WINAPI *pRtlIsCriticalSectionLocked)(CRITICAL_SECTION *);
 static BOOL      (WINAPI *pRtlIsCriticalSectionLockedByThread)(CRITICAL_SECTION *);
 static NTSTATUS  (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, ULONG, ULONG);
+static NTSTATUS  (WINAPI *pRtlQueryPackageIdentity)(HANDLE, WCHAR*, SIZE_T*, WCHAR*, SIZE_T*, BOOLEAN*);
 
 static HMODULE hkernel32 = 0;
 static BOOL      (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
@@ -153,6 +157,7 @@ static void InitFunctionPtrs(void)
         pRtlIsCriticalSectionLocked = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLocked");
         pRtlIsCriticalSectionLockedByThread = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLockedByThread");
         pRtlInitializeCriticalSectionEx = (void *)GetProcAddress(hntdll, "RtlInitializeCriticalSectionEx");
+        pRtlQueryPackageIdentity = (void *)GetProcAddress(hntdll, "RtlQueryPackageIdentity");
     }
     hkernel32 = LoadLibraryA("kernel32.dll");
     ok(hkernel32 != 0, "LoadLibrary failed\n");
@@ -2091,6 +2096,76 @@ static void test_RtlInitializeCriticalSectionEx(void)
     RtlDeleteCriticalSection(&cs);
 }
 
+static void test_RtlQueryPackageIdentity(void)
+{
+    const WCHAR programW[] = {'M','i','c','r','o','s','o','f','t','.','W','i','n','d','o','w','s','.',
+                              'P','h','o','t','o','s','_','8','w','e','k','y','b','3','d','8','b','b','w','e','!','A','p','p',0};
+    const WCHAR fullnameW[] = {'M','i','c','r','o','s','o','f','t','.','W','i','n','d','o','w','s','.',
+                               'P','h','o','t','o','s', 0};
+    const WCHAR appidW[] = {'A','p','p',0};
+    IApplicationActivationManager *manager;
+    WCHAR buf1[MAX_PATH], buf2[MAX_PATH];
+    HANDLE process, token;
+    SIZE_T size1, size2;
+    NTSTATUS status;
+    DWORD processid;
+    HRESULT hr;
+    BOOL ret;
+
+    if (!pRtlQueryPackageIdentity)
+    {
+        win_skip("RtlQueryPackageIdentity not available\n");
+        return;
+    }
+
+    size1 = size2 = MAX_PATH * sizeof(WCHAR);
+    status = pRtlQueryPackageIdentity((HANDLE)~(ULONG_PTR)3, buf1, &size1, buf2, &size2, NULL);
+    ok(status == STATUS_NOT_FOUND, "expected STATUS_NOT_FOUND, got %08x\n", status);
+
+    CoInitializeEx(0, COINIT_APARTMENTTHREADED);
+    hr = CoCreateInstance(&CLSID_ApplicationActivationManager, NULL, CLSCTX_LOCAL_SERVER,
+                          &IID_IApplicationActivationManager, (void **)&manager);
+    if (FAILED(hr))
+    {
+        todo_wine win_skip("Failed to create ApplicationActivationManager (%x)\n", hr);
+        goto done;
+    }
+
+    hr = IApplicationActivationManager_ActivateApplication(manager, programW, NULL,
+                                                           AO_NOERRORUI, &processid);
+    if (FAILED(hr))
+    {
+        todo_wine win_skip("Failed to start program (%x)\n", hr);
+        IApplicationActivationManager_Release(manager);
+        goto done;
+    }
+
+    process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE, FALSE, processid);
+    ok(process != NULL, "OpenProcess failed with %u\n", GetLastError());
+    ret = OpenProcessToken(process, TOKEN_QUERY, &token);
+    ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
+
+    size1 = size2 = MAX_PATH * sizeof(WCHAR);
+    status = pRtlQueryPackageIdentity(token, buf1, &size1, buf2, &size2, NULL);
+    ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+    ok(!memcmp(buf1, fullnameW, sizeof(fullnameW) - sizeof(WCHAR)),
+       "Expected buf1 to begin with %s, got %s\n", wine_dbgstr_w(fullnameW), wine_dbgstr_w(buf1));
+    ok(size1 >= sizeof(WCHAR) && !(size1 % sizeof(WCHAR)), "Unexpected size1 = %lu\n", size1);
+    ok(buf1[size1 / sizeof(WCHAR) - 1] == 0, "Expected buf1[%lu] == 0\n", size1 / sizeof(WCHAR) - 1);
+
+    ok(!lstrcmpW(buf2, appidW), "Expected buf2 to be %s, got %s\n", wine_dbgstr_w(appidW), wine_dbgstr_w(buf2));
+    ok(size2 >= sizeof(WCHAR) && !(size2 % sizeof(WCHAR)), "Unexpected size2 = %lu\n", size2);
+    ok(buf2[size2 / sizeof(WCHAR) - 1] == 0, "Expected buf2[%lu] == 0\n", size2 / sizeof(WCHAR) - 1);
+
+    CloseHandle(token);
+    TerminateProcess(process, 0);
+    CloseHandle(process);
+
+done:
+    CoUninitialize();
+}
+
 START_TEST(rtl)
 {
     InitFunctionPtrs();
@@ -2122,4 +2197,5 @@ START_TEST(rtl)
     test_RtlDecompressBuffer();
     test_RtlIsCriticalSectionLocked();
     test_RtlInitializeCriticalSectionEx();
+    test_RtlQueryPackageIdentity();
 }
-- 
2.7.1

