From: Nikolay Sivov Subject: [PATCH 2/2] ntdll: Implement RunlevelInformationInActivationContext in RtlQueryInformationActivationContext Message-Id: <20180217144116.28719-2-nsivov@codeweavers.com> Date: Sat, 17 Feb 2018 17:41:16 +0300 In-Reply-To: <20180217144116.28719-1-nsivov@codeweavers.com> References: <20180217144116.28719-1-nsivov@codeweavers.com> From: Michael Müller Signed-off-by: Nikolay Sivov --- Minor modifications from original to make tests pass on XP, where such context info is not supported. dlls/kernel32/tests/actctx.c | 243 ++++++++++++++++++++++++++++++++++++++++--- dlls/ntdll/actctx.c | 21 ++++ 2 files changed, 249 insertions(+), 15 deletions(-) diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index a182cfa4be..cef11a5e63 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -244,6 +244,61 @@ static const char manifest5[] = "" ""; +static const char manifest6[] = +"" +"" +"" +" " +" " +" " +" " +" " +"" +""; + +static const char manifest7[] = +"" +"" +"" +" " +" " +" " +" " +" " +"" +""; + +static const char manifest8[] = +"" +"" +"" +" " +" " +" " +" " +" " +" " +"" +""; + +static const char manifest9[] = +"" +"" +"" +" " +" " +" " +" " +" " +"" +"" +" " +" " +" " +" " +"" +""; + static const char testdep_manifest1[] = "" "" @@ -310,6 +365,38 @@ static const char wrong_manifest8[] = "" ""; +static const char wrong_manifest9[] = +"" +"" +"" +" " +" " +" " +" " +" " +" " +"" +""; + +static const char wrong_manifest10[] = +"" +"" +"" +" " +" " +" " +" " +" " +"" +"" +" " +" " +" " +" " +" " +"" +""; + static const char wrong_depmanifest1[] = "" "" @@ -783,6 +870,57 @@ static void test_file_info(HANDLE handle, ULONG assid, ULONG fileid, LPCWSTR fil HeapFree(GetProcessHeap(), 0, info); } +typedef struct { + ACTCTX_REQUESTED_RUN_LEVEL run_level; + DWORD ui_access; +} runlevel_info_t; + +static const runlevel_info_t runlevel_info0 = { + ACTCTX_RUN_LEVEL_UNSPECIFIED, FALSE, +}; + +static const runlevel_info_t runlevel_info6 = { + ACTCTX_RUN_LEVEL_AS_INVOKER, FALSE, +}; + +static const runlevel_info_t runlevel_info7 = { + ACTCTX_RUN_LEVEL_REQUIRE_ADMIN, TRUE, +}; + +static const runlevel_info_t runlevel_info8 = { + ACTCTX_RUN_LEVEL_REQUIRE_ADMIN, TRUE, +}; + +static const runlevel_info_t runlevel_info9 = { + ACTCTX_RUN_LEVEL_REQUIRE_ADMIN, FALSE, +}; + +static void test_runlevel_info(HANDLE handle, const runlevel_info_t *exinfo, int line) +{ + ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION runlevel_info; + SIZE_T size, retsize; + BOOL b; + + size = sizeof(runlevel_info); + b = pQueryActCtxW(0, handle, NULL, + RunlevelInformationInActivationContext, &runlevel_info, + sizeof(runlevel_info), &retsize); + if (!b && GetLastError() == ERROR_INVALID_PARAMETER) + { + win_skip("RunlevelInformationInActivationContext not supported.\n"); + return; + } + + ok_(__FILE__, line)(b, "QueryActCtx failed: %u\n", GetLastError()); + ok_(__FILE__, line)(retsize == size, "size=%ld, expected %ld\n", retsize, size); + + ok_(__FILE__, line)(runlevel_info.ulFlags == 0, "runlevel_info.ulFlags=%x\n", runlevel_info.ulFlags); + ok_(__FILE__, line)(runlevel_info.RunLevel == exinfo->run_level, + "runlevel_info.RunLevel=%u, expected %u\n", runlevel_info.RunLevel, exinfo->run_level); + ok_(__FILE__, line)(runlevel_info.UiAccess == exinfo->ui_access, + "runlevel_info.UiAccess=%u, expected %u\n", runlevel_info.UiAccess, exinfo->ui_access); +} + static HANDLE test_create(const char *file) { ACTCTXW actctx; @@ -814,7 +952,7 @@ static HANDLE test_create(const char *file) return handle; } -static void test_create_and_fail(const char *manifest, const char *depmanifest, int todo) +static void test_create_and_fail(const char *manifest, const char *depmanifest, int todo, BOOL is_broken) { ACTCTXW actctx; HANDLE handle; @@ -829,8 +967,14 @@ static void test_create_and_fail(const char *manifest, const char *depmanifest, handle = pCreateActCtxW(&actctx); todo_wine_if(todo) { - ok(handle == INVALID_HANDLE_VALUE, "handle != INVALID_HANDLE_VALUE\n"); - ok(GetLastError() == ERROR_SXS_CANT_GEN_ACTCTX, "GetLastError == %u\n", GetLastError()); + if (is_broken) + ok(broken(handle != INVALID_HANDLE_VALUE) || handle == INVALID_HANDLE_VALUE, + "Unexpected context handle %p.\n", handle); + else + ok(handle == INVALID_HANDLE_VALUE, "Unexpected context handle %p.\n", handle); + + if (handle == INVALID_HANDLE_VALUE) + ok(GetLastError() == ERROR_SXS_CANT_GEN_ACTCTX, "Unexpected error %d.\n", GetLastError()); } if (handle != INVALID_HANDLE_VALUE) pReleaseActCtx( handle ); DeleteFileA("bad.manifest"); @@ -873,27 +1017,31 @@ static void test_create_fail(void) ok(GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError == %u\n", GetLastError()); trace("wrong_manifest1\n"); - test_create_and_fail(wrong_manifest1, NULL, 0 ); + test_create_and_fail(wrong_manifest1, NULL, 0, FALSE); trace("wrong_manifest2\n"); - test_create_and_fail(wrong_manifest2, NULL, 0 ); + test_create_and_fail(wrong_manifest2, NULL, 0, FALSE); trace("wrong_manifest3\n"); - test_create_and_fail(wrong_manifest3, NULL, 1 ); + test_create_and_fail(wrong_manifest3, NULL, 1, FALSE); trace("wrong_manifest4\n"); - test_create_and_fail(wrong_manifest4, NULL, 1 ); + test_create_and_fail(wrong_manifest4, NULL, 1, FALSE); trace("wrong_manifest5\n"); - test_create_and_fail(wrong_manifest5, NULL, 0 ); + test_create_and_fail(wrong_manifest5, NULL, 0, FALSE); trace("wrong_manifest6\n"); - test_create_and_fail(wrong_manifest6, NULL, 0 ); + test_create_and_fail(wrong_manifest6, NULL, 0, FALSE); trace("wrong_manifest7\n"); - test_create_and_fail(wrong_manifest7, NULL, 1 ); + test_create_and_fail(wrong_manifest7, NULL, 1, FALSE); trace("wrong_manifest8\n"); - test_create_and_fail(wrong_manifest8, NULL, 0 ); + test_create_and_fail(wrong_manifest8, NULL, 0, FALSE); + trace("wrong_manifest9\n"); + test_create_and_fail(wrong_manifest9, NULL, 0, TRUE /* WinXP */); + trace("wrong_manifest10\n"); + test_create_and_fail(wrong_manifest10, NULL, 0, TRUE /* WinXP */); trace("UTF-16 manifest1 without BOM\n"); test_create_wide_and_fail(manifest1, FALSE ); trace("manifest2\n"); - test_create_and_fail(manifest2, NULL, 0 ); + test_create_and_fail(manifest2, NULL, 0, FALSE); trace("manifest2+depmanifest1\n"); - test_create_and_fail(manifest2, wrong_depmanifest1, 0 ); + test_create_and_fail(manifest2, wrong_depmanifest1, 0, FALSE); } struct strsection_header @@ -1825,8 +1973,6 @@ static void test_actctx(void) HANDLE handle; BOOL b; - test_create_fail(); - trace("default actctx\n"); b = pGetCurrentActCtx(&handle); @@ -1835,6 +1981,7 @@ static void test_actctx(void) if(b) { test_basic_info(handle, __LINE__); test_detailed_info(handle, &detailed_info0, __LINE__); + test_runlevel_info(handle, &runlevel_info0, __LINE__); pReleaseActCtx(handle); } @@ -2006,6 +2153,71 @@ static void test_actctx(void) pReleaseActCtx(handle); } + trace("manifest6\n"); + + if(create_manifest_file("test6.manifest", manifest6, -1, NULL, NULL)) { + handle = test_create("test6.manifest"); + ok(handle != INVALID_HANDLE_VALUE || broken(handle == INVALID_HANDLE_VALUE) /* WinXP */, + "Unexpected context handle %p.\n", handle); + DeleteFileA("test6.manifest"); + DeleteFileA("testdep.manifest"); + if(handle != INVALID_HANDLE_VALUE) + { + test_runlevel_info(handle, &runlevel_info6, __LINE__); + pReleaseActCtx(handle); + } + } + else + skip("Could not create manifest file 6\n"); + + trace("manifest7\n"); + + if(create_manifest_file("test7.manifest", manifest7, -1, NULL, NULL)) { + handle = test_create("test7.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("test7.manifest"); + DeleteFileA("testdep.manifest"); + if(handle != INVALID_HANDLE_VALUE) + { + test_runlevel_info(handle, &runlevel_info7, __LINE__); + pReleaseActCtx(handle); + } + } + else + skip("Could not create manifest file 7\n"); + + trace("manifest8\n"); + + if(create_manifest_file("test8.manifest", manifest8, -1, NULL, NULL)) { + handle = test_create("test8.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("test8.manifest"); + DeleteFileA("testdep.manifest"); + if(handle != INVALID_HANDLE_VALUE) + { + test_runlevel_info(handle, &runlevel_info8, __LINE__); + pReleaseActCtx(handle); + } + } + else + skip("Could not create manifest file 8\n"); + + trace("manifest9\n"); + + if(create_manifest_file("test9.manifest", manifest9, -1, NULL, NULL)) { + handle = test_create("test9.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("test9.manifest"); + DeleteFileA("testdep.manifest"); + if(handle != INVALID_HANDLE_VALUE) + { + test_runlevel_info(handle, &runlevel_info9, __LINE__); + pReleaseActCtx(handle); + } + } + else + skip("Could not create manifest file 9\n"); + trace("manifest4\n"); if(!create_manifest_file("test4.manifest", manifest4, -1, NULL, NULL)) { @@ -2731,6 +2943,7 @@ START_TEST(actctx) } test_actctx(); + test_create_fail(); test_CreateActCtx(); test_findsectionstring(); test_ZombifyActCtx(); diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index 3ba407d83a..4a3370048f 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -5271,6 +5271,27 @@ NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, HANDLE handle } break; + case RunlevelInformationInActivationContext: + { + ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION *acrli = buffer; + struct assembly *assembly; + SIZE_T len; + + if (!(actctx = check_actctx(handle))) return STATUS_INVALID_PARAMETER; + + len = sizeof(*acrli); + if (retlen) *retlen = len; + if (!buffer || bufsize < len) + return STATUS_BUFFER_TOO_SMALL; + + assembly = actctx->assemblies; + + acrli->ulFlags = 0; + acrli->RunLevel = assembly ? assembly->run_level : ACTCTX_RUN_LEVEL_UNSPECIFIED; + acrli->UiAccess = assembly ? assembly->ui_access : 0; + } + break; + default: FIXME( "class %u not implemented\n", class ); return STATUS_NOT_IMPLEMENTED; -- 2.16.1