[PATCH 5/5] kernel32: Implement GetPackagePath().
Paul Gofman
pgofman at codeweavers.com
Fri Mar 26 04:37:47 CDT 2021
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
.../api-ms-win-appmodel-runtime-l1-1-1.spec | 2 +-
.../ext-ms-win-kernel32-package-l1-1-1.spec | 2 +-
dlls/kernel32/kernel32.spec | 1 +
dlls/kernel32/tests/version.c | 64 +++++++++++++--
dlls/kernelbase/kernelbase.spec | 2 +-
dlls/kernelbase/version.c | 82 +++++++++++++++++++
include/appmodel.h | 1 +
7 files changed, 146 insertions(+), 8 deletions(-)
diff --git a/dlls/api-ms-win-appmodel-runtime-l1-1-1/api-ms-win-appmodel-runtime-l1-1-1.spec b/dlls/api-ms-win-appmodel-runtime-l1-1-1/api-ms-win-appmodel-runtime-l1-1-1.spec
index 72a0a33baf5..e77ac397b03 100644
--- a/dlls/api-ms-win-appmodel-runtime-l1-1-1/api-ms-win-appmodel-runtime-l1-1-1.spec
+++ b/dlls/api-ms-win-appmodel-runtime-l1-1-1/api-ms-win-appmodel-runtime-l1-1-1.spec
@@ -13,7 +13,7 @@
@ stdcall GetPackageFullName(long ptr ptr) kernel32.GetPackageFullName
@ stub GetPackageId
@ stub GetPackageInfo
-@ stub GetPackagePath
+@ stdcall GetPackagePath(ptr long ptr ptr) kernel32.GetPackagePath
@ stub GetPackagePathByFullName
@ stdcall GetPackagesByPackageFamily(wstr ptr ptr ptr ptr) kernel32.GetPackagesByPackageFamily
@ stub GetStagedPackageOrigin
diff --git a/dlls/ext-ms-win-kernel32-package-l1-1-1/ext-ms-win-kernel32-package-l1-1-1.spec b/dlls/ext-ms-win-kernel32-package-l1-1-1/ext-ms-win-kernel32-package-l1-1-1.spec
index 42566176b56..58bf807b4be 100644
--- a/dlls/ext-ms-win-kernel32-package-l1-1-1/ext-ms-win-kernel32-package-l1-1-1.spec
+++ b/dlls/ext-ms-win-kernel32-package-l1-1-1/ext-ms-win-kernel32-package-l1-1-1.spec
@@ -11,7 +11,7 @@
@ stdcall GetPackageFullName(long ptr ptr) kernel32.GetPackageFullName
@ stub GetPackageId
@ stub GetPackageInfo
-@ stub GetPackagePath
+@ stdcall GetPackagePath(ptr long ptr ptr) kernel32.GetPackagePath
@ stdcall GetPackagesByPackageFamily(wstr ptr ptr ptr ptr) kernel32.GetPackagesByPackageFamily
@ stub GetStagedPackageOrigin
@ stub OpenPackageInfoByFullName
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 4cfcf6df188..7d5160a51da 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -768,6 +768,7 @@
@ stdcall -import GetPackagesByPackageFamily(wstr ptr ptr ptr ptr)
@ stdcall GetPackageFamilyName(long ptr ptr) kernelbase.GetPackageFamilyName
@ stdcall GetPackageFullName(long ptr ptr) kernelbase.GetPackageFullName
+@ stdcall -import GetPackagePath(ptr long ptr ptr)
@ stdcall -import GetPhysicallyInstalledSystemMemory(ptr)
@ stdcall -import GetPriorityClass(long)
@ stdcall GetPrivateProfileIntA(str str long str)
diff --git a/dlls/kernel32/tests/version.c b/dlls/kernel32/tests/version.c
index ed1ef3e3bf7..1d5dc550d46 100644
--- a/dlls/kernel32/tests/version.c
+++ b/dlls/kernel32/tests/version.c
@@ -23,6 +23,7 @@
#include "winternl.h"
#include "appmodel.h"
+static LONG (WINAPI * pGetPackagePath)(const PACKAGE_ID *, const UINT32, UINT32 *, WCHAR *);
static LONG (WINAPI * pGetPackagesByPackageFamily)(const WCHAR *, UINT32 *, WCHAR **, UINT32 *, WCHAR *);
static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *);
static UINT (WINAPI * pGetSystemFirmwareTable)(DWORD, DWORD, void *, DWORD);
@@ -45,6 +46,7 @@ static void init_function_pointers(void)
hmod = GetModuleHandleA("kernel32.dll");
+ GET_PROC(GetPackagePath);
GET_PROC(GetPackagesByPackageFamily);
GET_PROC(GetProductInfo);
GET_PROC(GetSystemFirmwareTable);
@@ -943,15 +945,15 @@ static void test_PackageIdFromFullName(void)
static void test_package_info(void)
{
static const WCHAR package_family_msvc140[] = L"Microsoft.VCLibs.140.00_8wekyb3d8bbwe";
- UINT32 count, length, curr_length, size;
+ UINT32 count, length, curr_length, size, path_length, total_length;
+ WCHAR buffer[2048], path[MAX_PATH];
+ PACKAGE_ID *id, saved_id;
WCHAR *full_names[32];
BYTE id_buffer[512];
- WCHAR buffer[2048];
+ DWORD arch, attrib;
BOOL arch_found;
SYSTEM_INFO si;
unsigned int i;
- PACKAGE_ID *id;
- DWORD arch;
LONG ret;
if (!pGetPackagesByPackageFamily)
@@ -1032,6 +1034,10 @@ static void test_package_info(void)
ok(count == ARRAY_SIZE(full_names), "Got unexpected count %u.\n", count);
ok(length == ARRAY_SIZE(buffer), "Got unexpected length %u.\n", length);
+ length = 0;
+ ret = pGetPackagePath(NULL, 0, &length, NULL);
+ ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %u.\n", ret);
+
count = 0;
length = 0;
ret = pGetPackagesByPackageFamily(package_family_msvc140, &count, NULL, &length, NULL);
@@ -1050,6 +1056,7 @@ static void test_package_info(void)
ok(count >= 1, "Got unexpected count %u.\n", count);
ok(length > 1, "Got unexpected length %u.\n", length);
+ total_length = length;
id = (PACKAGE_ID *)id_buffer;
curr_length = 0;
arch_found = FALSE;
@@ -1063,9 +1070,56 @@ static void test_package_info(void)
if (id->processorArchitecture == arch)
arch_found = TRUE;
+
+ path_length = 0;
+ ret = pGetPackagePath(id, 0, &path_length, NULL);
+ ok(ret == ERROR_INSUFFICIENT_BUFFER, "Got unexpected ret %u.\n", ret);
+ ok(path_length > 1, "Got unexpected path_length %u.\n", path_length);
+
+ length = path_length;
+ ret = pGetPackagePath(id, 0, &length, path);
+ ok(ret == ERROR_SUCCESS, "Got unexpected ret %u.\n", ret);
+ ok(length == path_length, "Got unexpected length %u.\n", length);
+ attrib = GetFileAttributesW(path);
+ ok(attrib != INVALID_FILE_ATTRIBUTES && attrib & FILE_ATTRIBUTE_DIRECTORY,
+ "Got unexpected attrib %#x, GetLastError() %u.\n", attrib, GetLastError());
}
- ok(curr_length == length, "Got unexpected length %u.\n", length);
+ ok(curr_length == total_length, "Got unexpected length %u.\n", length);
ok(arch_found, "Did not find package for current arch.\n");
+
+ size = sizeof(id_buffer);
+ ret = pPackageIdFromFullName(full_names[0], 0, &size, id_buffer);
+ ok(ret == ERROR_SUCCESS, "Got unexpected ret %u.\n", ret);
+ saved_id = *id;
+
+ id->publisherId = NULL;
+ length = ARRAY_SIZE(path);
+ ret = pGetPackagePath(id, 0, &length, path);
+ ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %u.\n", ret);
+
+ *id = saved_id;
+ id->name = NULL;
+ length = ARRAY_SIZE(path);
+ ret = pGetPackagePath(id, 0, &length, path);
+ ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %u.\n", ret);
+
+ *id = saved_id;
+ id->publisher = NULL;
+ length = ARRAY_SIZE(path);
+ ret = pGetPackagePath(id, 0, &length, path);
+ ok(ret == ERROR_SUCCESS, "Got unexpected ret %u.\n", ret);
+
+ *id = saved_id;
+ id->processorArchitecture = ~0u;
+ length = ARRAY_SIZE(path);
+ ret = pGetPackagePath(id, 0, &length, path);
+ ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %u.\n", ret);
+
+ *id = saved_id;
+ id->name[0] = L'X';
+ length = ARRAY_SIZE(path);
+ ret = pGetPackagePath(id, 0, &length, path);
+ ok(ret == ERROR_NOT_FOUND, "Got unexpected ret %u.\n", ret);
}
START_TEST(version)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index fc7671781f1..d318313e0f0 100644
--- a/dlls/kernelbase/kernelbase.spec
+++ b/dlls/kernelbase/kernelbase.spec
@@ -601,7 +601,7 @@
# @ stub GetPackageInfo
# @ stub GetPackageInstallTime
# @ stub GetPackageOSMaxVersionTested
-# @ stub GetPackagePath
+@ stdcall GetPackagePath(ptr long ptr ptr)
# @ stub GetPackagePathByFullName
# @ stub GetPackagePathOnVolume
# @ stub GetPackageProperty
diff --git a/dlls/kernelbase/version.c b/dlls/kernelbase/version.c
index b2a6ceb182e..e762d446953 100644
--- a/dlls/kernelbase/version.c
+++ b/dlls/kernelbase/version.c
@@ -1839,3 +1839,85 @@ LONG WINAPI GetPackagesByPackageFamily(const WCHAR *family_name, UINT32 *count,
return short_buffer ? ERROR_INSUFFICIENT_BUFFER : ERROR_SUCCESS;
}
+
+
+/***********************************************************************
+ * GetPackagePath (kernelbase.@)
+ */
+LONG WINAPI GetPackagePath(const PACKAGE_ID *package_id, const UINT32 reserved, UINT32 *length, WCHAR *path)
+{
+ WCHAR *key_name = NULL, *expanded_path = NULL;
+ UINT32 required_length, have_length;
+ unsigned int offset;
+ HKEY key = NULL;
+ DWORD size;
+ LONG ret;
+
+ TRACE("package_id %p, reserved %u, length %p, path %p.\n", package_id, reserved, length, path);
+
+ if (!length)
+ return ERROR_INVALID_PARAMETER;
+ if (!path && *length)
+ return ERROR_INVALID_PARAMETER;
+
+ required_length = 0;
+ if ((ret = PackageFullNameFromId(package_id, &required_length, NULL)) != ERROR_INSUFFICIENT_BUFFER)
+ return ret;
+
+ offset = lstrlenW(packages_key_name) + 1;
+ if (!(key_name = heap_alloc((offset + required_length) * sizeof(WCHAR))))
+ {
+ ERR("No memory.");
+ return ERROR_OUTOFMEMORY;
+ }
+
+ if ((ret = PackageFullNameFromId(package_id, &required_length, key_name + offset)))
+ goto done;
+
+ memcpy(key_name, packages_key_name, (offset - 1) * sizeof(WCHAR));
+ key_name[offset - 1] = L'\\';
+
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, key_name, 0, KEY_READ, &key))
+ {
+ WARN("Key %s not found.\n", debugstr_w(key_name));
+ ret = ERROR_NOT_FOUND;
+ goto done;
+ }
+ if (RegGetValueW(key, NULL, L"Path", RRF_RT_REG_SZ, NULL, NULL, &size))
+ {
+ WARN("Path value not found in %s.\n", debugstr_w(key_name));
+ ret = ERROR_NOT_FOUND;
+ goto done;
+ }
+ if (!(expanded_path = heap_alloc(size)))
+ {
+ ERR("No memory.");
+ ret = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+ if (RegGetValueW(key, NULL, L"Path", RRF_RT_REG_SZ, NULL, expanded_path, &size))
+ {
+ WARN("Could not get Path value from %s.\n", debugstr_w(key_name));
+ ret = ERROR_NOT_FOUND;
+ goto done;
+ }
+
+ have_length = *length;
+ *length = lstrlenW(expanded_path) + 1;
+ if (have_length >= *length)
+ {
+ memcpy(path, expanded_path, *length * sizeof(*path));
+ ret = ERROR_SUCCESS;
+ }
+ else
+ {
+ ret = ERROR_INSUFFICIENT_BUFFER;
+ }
+
+done:
+ if (key)
+ RegCloseKey(key);
+ heap_free(expanded_path);
+ heap_free(key_name);
+ return ret;
+}
diff --git a/include/appmodel.h b/include/appmodel.h
index be59bc70f5f..c73cb8d26ef 100644
--- a/include/appmodel.h
+++ b/include/appmodel.h
@@ -82,6 +82,7 @@ LONG WINAPI AppPolicyGetProcessTerminationMethod(HANDLE token, AppPolicyProcessT
LONG WINAPI AppPolicyGetShowDeveloperDiagnostic(HANDLE token, AppPolicyShowDeveloperDiagnostic *policy);
LONG WINAPI AppPolicyGetThreadInitializationType(HANDLE token, AppPolicyThreadInitializationType *policy);
LONG WINAPI AppPolicyGetWindowingModel(HANDLE processToken, AppPolicyWindowingModel *policy);
+LONG WINAPI GetPackagePath(const PACKAGE_ID *package_id, const UINT32 reserved, UINT32 *length, WCHAR *path);
LONG WINAPI GetPackagesByPackageFamily(const WCHAR *family_name, UINT32 *count, WCHAR **full_names,
UINT32 *buffer_length, WCHAR *buffer);
LONG WINAPI PackageFullNameFromId(const PACKAGE_ID *package_id, UINT32 *length, WCHAR *full_name);
--
2.30.2
More information about the wine-devel
mailing list