Wine-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
January 2019
- 68 participants
- 552 discussions
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/setupapi/devinst.c | 101 +++++++++++++++++++++
dlls/setupapi/setupapi.spec | 2 +-
dlls/setupapi/tests/devinst.c | 163 +++++++++++++++++++++++++++++++++-
include/setupapi.h | 2 +
4 files changed, 266 insertions(+), 2 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index 36c1854654..13f7853290 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -327,6 +327,28 @@ static WCHAR *get_refstr_key_path(struct device_iface *iface)
return path;
}
+static BOOL is_valid_property_type(DEVPROPTYPE prop_type)
+{
+ DWORD type = prop_type & DEVPROP_MASK_TYPE;
+ DWORD typemod = prop_type & DEVPROP_MASK_TYPEMOD;
+
+ if (type > MAX_DEVPROP_TYPE)
+ return FALSE;
+ if (typemod > MAX_DEVPROP_TYPEMOD)
+ return FALSE;
+
+ if (typemod == DEVPROP_TYPEMOD_ARRAY
+ && (type == DEVPROP_TYPE_EMPTY || type == DEVPROP_TYPE_NULL || type == DEVPROP_TYPE_STRING
+ || type == DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING))
+ return FALSE;
+
+ if (typemod == DEVPROP_TYPEMOD_LIST
+ && !(type == DEVPROP_TYPE_STRING || type == DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING))
+ return FALSE;
+
+ return TRUE;
+}
+
static LPWSTR SETUPDI_CreateSymbolicLinkPath(LPCWSTR instanceId,
const GUID *InterfaceClassGuid, LPCWSTR ReferenceString)
{
@@ -3410,6 +3432,85 @@ BOOL WINAPI SetupDiSetDeviceInstallParamsW(
return TRUE;
}
+BOOL WINAPI SetupDiSetDevicePropertyW(HDEVINFO devinfo, PSP_DEVINFO_DATA device_data, const DEVPROPKEY *key,
+ DEVPROPTYPE type, const BYTE *buffer, DWORD size, DWORD flags)
+{
+ static const WCHAR propertiesW[] = {'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's', 0};
+ static const WCHAR formatW[] = {'\\', '%', '0', '4', 'X', 0};
+ struct device *device;
+ HKEY properties_hkey, property_hkey;
+ WCHAR property_hkey_path[44];
+ LSTATUS ls;
+
+ TRACE("%p %p %p %#x %p %d %#x\n", devinfo, device_data, key, type, buffer, size, flags);
+
+ if (!(device = get_device(devinfo, device_data)))
+ return FALSE;
+
+ if (!key || !is_valid_property_type(type)
+ || (buffer && !size && !(type == DEVPROP_TYPE_EMPTY || type == DEVPROP_TYPE_NULL))
+ || (buffer && size && (type == DEVPROP_TYPE_EMPTY || type == DEVPROP_TYPE_NULL)))
+ {
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+
+ if (size && !buffer)
+ {
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ return FALSE;
+ }
+
+ if (flags)
+ {
+ SetLastError(ERROR_INVALID_FLAGS);
+ return FALSE;
+ }
+
+ ls = RegCreateKeyExW(device->key, propertiesW, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &properties_hkey, NULL);
+ if (ls)
+ {
+ SetLastError(ls);
+ return FALSE;
+ }
+
+ SETUPDI_GuidToString(&key->fmtid, property_hkey_path);
+ sprintfW(property_hkey_path + 38, formatW, key->pid);
+
+ if (type == DEVPROP_TYPE_EMPTY)
+ {
+ ls = RegDeleteKeyW(properties_hkey, property_hkey_path);
+ RegCloseKey(properties_hkey);
+ SetLastError(ls == ERROR_FILE_NOT_FOUND ? ERROR_NOT_FOUND : ls);
+ return !ls;
+ }
+ else if (type == DEVPROP_TYPE_NULL)
+ {
+ if (!(ls = RegOpenKeyW(properties_hkey, property_hkey_path, &property_hkey)))
+ {
+ ls = RegDeleteValueW(property_hkey, NULL);
+ RegCloseKey(property_hkey);
+ }
+
+ RegCloseKey(properties_hkey);
+ SetLastError(ls == ERROR_FILE_NOT_FOUND ? ERROR_NOT_FOUND : ls);
+ return !ls;
+ }
+ else
+ {
+ if (!(ls = RegCreateKeyExW(properties_hkey, property_hkey_path, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL,
+ &property_hkey, NULL)))
+ {
+ ls = RegSetValueExW(property_hkey, NULL, 0, 0xffff0000 | (0xffff & type), buffer, size);
+ RegCloseKey(property_hkey);
+ }
+
+ RegCloseKey(properties_hkey);
+ SetLastError(ls);
+ return !ls;
+ }
+}
+
static HKEY SETUPDI_OpenDevKey(struct device *device, REGSAM samDesired)
{
HKEY enumKey, key = INVALID_HANDLE_VALUE;
diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec
index eb2dab204d..fb44298292 100644
--- a/dlls/setupapi/setupapi.spec
+++ b/dlls/setupapi/setupapi.spec
@@ -475,7 +475,7 @@
@ stdcall SetupDiSetDeviceInstallParamsW(ptr ptr ptr)
@ stub SetupDiSetDeviceInterfaceDefault
@ stub SetupDiSetDeviceInterfacePropertyW
-@ stub SetupDiSetDevicePropertyW
+@ stdcall SetupDiSetDevicePropertyW(ptr ptr ptr long ptr long long)
@ stdcall SetupDiSetDeviceRegistryPropertyA(ptr ptr long ptr long)
@ stdcall SetupDiSetDeviceRegistryPropertyW(ptr ptr long ptr long)
@ stub SetupDiSetDriverInstallParamsA
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index 74fa545029..0a77fca9c2 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -26,7 +26,8 @@
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
-#include "guiddef.h"
+#include "initguid.h"
+#include "devpkey.h"
#include "setupapi.h"
#include "cfgmgr32.h"
@@ -37,6 +38,8 @@
static GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}};
static GUID guid2 = {0x6a55b5a5, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}};
+BOOL (WINAPI *pSetupDiSetDevicePropertyW)(HDEVINFO, PSP_DEVINFO_DATA, const DEVPROPKEY *, DEVPROPTYPE, const BYTE *, DWORD, DWORD);
+
static void test_create_device_list_ex(void)
{
static const WCHAR machine[] = { 'd','u','m','m','y',0 };
@@ -342,6 +345,163 @@ static void test_device_info(void)
SetupDiDestroyDeviceInfoList(set);
}
+static void test_device_property(void)
+{
+ static const WCHAR valueW[] = {'d', 'e', 'a', 'd', 'b', 'e', 'e', 'f', 0};
+ SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+ HMODULE hmod;
+ HDEVINFO set;
+ DWORD err;
+ BOOL ret;
+
+ hmod = LoadLibraryA("setupapi.dll");
+ pSetupDiSetDevicePropertyW = (void *)GetProcAddress(hmod, "SetupDiSetDevicePropertyW");
+
+ if (!pSetupDiSetDevicePropertyW)
+ {
+ win_skip("SetupDiSetDevicePropertyW() are only available on vista+, skipping tests.\n");
+ FreeLibrary(hmod);
+ return;
+ }
+
+ set = SetupDiCreateDeviceInfoList(&guid, NULL);
+ ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError());
+
+ ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device_data);
+ ok(ret, "Failed to create device, error %#x.\n", GetLastError());
+
+ /* SetupDiSetDevicePropertyW */
+ /* #1 Null device info list */
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(NULL, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_HANDLE, "Expect last error %#x, got %#x\n", ERROR_INVALID_HANDLE, err);
+
+ /* #2 Null device */
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, NULL, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_PARAMETER, "Expect last error %#x, got %#x\n", ERROR_INVALID_PARAMETER, err);
+
+ /* #3 Null property key pointer */
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, NULL, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_DATA, "Expect last error %#x, got %#x\n", ERROR_INVALID_DATA, err);
+
+ /* #4 Invalid property key type */
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, 0xffff, (const BYTE *)valueW, sizeof(valueW), 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_DATA, "Expect last error %#x, got %#x\n", ERROR_INVALID_DATA, err);
+
+ /* #5 Null buffer pointer */
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, NULL, sizeof(valueW), 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_USER_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INVALID_USER_BUFFER, err);
+
+ /* #6 Zero buffer size */
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, 0, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_DATA, "Expect last error %#x, got %#x\n", ERROR_INVALID_DATA, err);
+
+ /* #7 Flags not zero */
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 1);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_FLAGS, "Expect last error %#x, got %#x\n", ERROR_INVALID_FLAGS, err);
+
+ /* #8 Normal */
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ err = GetLastError();
+ ok(ret, "Expect success\n");
+ ok(err == NO_ERROR, "Expect last error %#x, got %#x\n", NO_ERROR, err);
+
+ /* #9 Delete property with buffer not null */
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ ok(ret, "Expect success\n");
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_EMPTY, (const BYTE *)valueW, 0, 0);
+ err = GetLastError();
+ ok(ret, "Expect success\n");
+ ok(err == NO_ERROR, "Expect last error %#x, got %#x\n", NO_ERROR, err);
+
+ /* #10 Delete property with size not zero */
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ ok(ret, "Expect success\n");
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_EMPTY, NULL, sizeof(valueW), 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_USER_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INVALID_USER_BUFFER, err);
+
+ /* #11 Delete property */
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ ok(ret, "Expect success\n");
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_EMPTY, NULL, 0, 0);
+ err = GetLastError();
+ ok(ret, "Expect success\n");
+ ok(err == NO_ERROR, "Expect last error %#x, got %#x\n", NO_ERROR, err);
+
+ /* #12 Delete non-existent property */
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_EMPTY, NULL, 0, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_NOT_FOUND, "Expect last error %#x, got %#x\n", ERROR_NOT_FOUND, err);
+
+ /* #13 Delete property value with buffer not null */
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ ok(ret, "Expect success\n");
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_NULL, (const BYTE *)valueW, 0, 0);
+ err = GetLastError();
+ ok(ret, "Expect success\n");
+ ok(err == NO_ERROR, "Expect last error %#x, got %#x\n", NO_ERROR, err);
+
+ /* #14 Delete property value with size not zero */
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ ok(ret, "Expect success\n");
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_NULL, NULL, sizeof(valueW), 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_USER_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INVALID_USER_BUFFER, err);
+
+ /* #15 Delete property value */
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ ok(ret, "Expect success\n");
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_NULL, NULL, 0, 0);
+ err = GetLastError();
+ ok(ret, "Expect success\n");
+ ok(err == NO_ERROR, "Expect last error %#x, got %#x\n", NO_ERROR, err);
+
+ /* #16 Delete non-existent property value */
+ SetLastError(0xdeadbeef);
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_NULL, NULL, 0, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_NOT_FOUND, "Expect last error %#x, got %#x\n", ERROR_NOT_FOUND, err);
+
+ ret = SetupDiRemoveDevice(set, &device_data);
+ ok(ret, "Got unexpected error %#x.\n", GetLastError());
+
+ SetupDiDestroyDeviceInfoList(set);
+ FreeLibrary(hmod);
+}
+
static void test_get_device_instance_id(void)
{
BOOL ret;
@@ -1339,6 +1499,7 @@ START_TEST(devinst)
test_open_class_key();
test_install_class();
test_device_info();
+ test_device_property();
test_get_device_instance_id();
test_register_device_info();
test_device_iface();
diff --git a/include/setupapi.h b/include/setupapi.h
index 76e255cc44..4491617d8a 100644
--- a/include/setupapi.h
+++ b/include/setupapi.h
@@ -1634,6 +1634,8 @@ BOOL WINAPI SetupDiSetDeviceInterfaceDefault(HDEVINFO, PSP_DEVICE_INTERFACE_
BOOL WINAPI SetupDiSetDeviceInstallParamsA(HDEVINFO, PSP_DEVINFO_DATA, PSP_DEVINSTALL_PARAMS_A);
BOOL WINAPI SetupDiSetDeviceInstallParamsW(HDEVINFO, PSP_DEVINFO_DATA, PSP_DEVINSTALL_PARAMS_W);
#define SetupDiSetDeviceInstallParams WINELIB_NAME_AW(SetupDiSetDeviceInstallParams)
+BOOL WINAPI SetupDiSetDevicePropertyW(HDEVINFO, PSP_DEVINFO_DATA, const DEVPROPKEY *, DEVPROPTYPE, const BYTE *, DWORD, DWORD);
+#define SetupDiSetDeviceProperty WINELIB_NAME_AW(SetupDiSetDeviceProperty) /* note: A function doesn't exist */
BOOL WINAPI SetupDiSetDeviceRegistryPropertyA(HDEVINFO, PSP_DEVINFO_DATA, DWORD, const BYTE *, DWORD);
BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(HDEVINFO, PSP_DEVINFO_DATA, DWORD, const BYTE *, DWORD);
#define SetupDiSetDeviceRegistryProperty WINELIB_NAME_AW(SetupDiSetDeviceRegistryProperty)
--
2.20.1
1
0
Signed-off-by: Sven Baars <sven.wine(a)gmail.com>
---
This patch supersedes 156918. Note that the changed implementation in 156918 makes most
of these tests succeed, and doesn't cause any crashes, so this still does not contain
a test of whatever is the actual problem that does not allow for just copying
the pointer.
dlls/gdiplus/tests/font.c | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/dlls/gdiplus/tests/font.c b/dlls/gdiplus/tests/font.c
index 03e7a04e08..33b75c5bc5 100644
--- a/dlls/gdiplus/tests/font.c
+++ b/dlls/gdiplus/tests/font.c
@@ -141,6 +141,8 @@ static void test_createfont(void)
expect(Ok, stat);
stat = GdipGetFamilyName(fontfamily2, familyname, 0);
expect(Ok, stat);
+todo_wine
+ ok (fontfamily == fontfamily2, "Unexpected family instance.\n");
ok (lstrcmpiW(Tahoma, familyname) == 0, "Expected Tahoma, got %s\n",
wine_dbgstr_w(familyname));
stat = GdipDeleteFontFamily(fontfamily2);
@@ -343,6 +345,8 @@ static void test_fontfamily (void)
ZeroMemory (itsName, sizeof(itsName));
stat = GdipCloneFontFamily(family, &clonedFontFamily);
expect (Ok, stat);
+todo_wine
+ ok (family == clonedFontFamily, "Unexpected family instance.\n");
GdipDeleteFontFamily(family);
stat = GdipGetFamilyName(clonedFontFamily, itsName, LANG_NEUTRAL);
expect(Ok, stat);
@@ -1187,8 +1191,9 @@ todo_wine
static void test_GdipGetFontCollectionFamilyList(void)
{
- GpFontFamily *family, *family2;
+ GpFontFamily *family, *family2, **families;
GpFontCollection *collection;
+ UINT i;
INT found, count;
GpStatus status;
@@ -1228,15 +1233,32 @@ static void test_GdipGetFontCollectionFamilyList(void)
ok(found == 1, "Unexpected list count %d.\n", found);
ok(family != NULL, "Expected family instance.\n");
- family = NULL;
+ family2 = NULL;
found = 0;
status = GdipGetFontCollectionFamilyList(collection, 1, &family2, &found);
ok(status == Ok, "Failed to get family list, status %d.\n", status);
ok(found == 1, "Unexpected list count %d.\n", found);
- ok(family2 != family, "Unexpected family instance.\n");
+todo_wine
+ ok(family2 == family, "Unexpected family instance.\n");
- GdipDeleteFontFamily(family);
- GdipDeleteFontFamily(family2);
+ status = GdipDeleteFontFamily(family);
+ expect(Ok, status);
+
+ status = GdipDeleteFontFamily(family2);
+ expect(Ok, status);
+
+ families = GdipAlloc((count + 1) * sizeof(*families));
+ found = 0;
+ status = GdipGetFontCollectionFamilyList(collection, count + 1, families, &found);
+ ok(status == Ok, "Failed to get family list, status %d.\n", status);
+ ok(found == count, "Unexpected list count %d, extected %d.\n", found, count);
+
+ for (i = 0; i < found; i++)
+ {
+ status = GdipDeleteFontFamily(families[i]);
+ expect(Ok, status);
+ }
+ GdipFree(families);
}
static void test_GdipGetFontCollectionFamilyCount(void)
--
2.17.1
2
1
[PATCH 2/2] crypt32: Add support for importing RSA private keys from PFX blobs.
by Hans Leidekker 28 Jan '19
by Hans Leidekker 28 Jan '19
28 Jan '19
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/crypt32/pfx.c | 133 +++++++++++++++++++++++++++++++++++++
dlls/crypt32/tests/store.c | 27 +++++++-
2 files changed, 159 insertions(+), 1 deletion(-)
diff --git a/dlls/crypt32/pfx.c b/dlls/crypt32/pfx.c
index ce842cd087..59c6c93f53 100644
--- a/dlls/crypt32/pfx.c
+++ b/dlls/crypt32/pfx.c
@@ -50,6 +50,8 @@ MAKE_FUNCPTR(gnutls_pkcs12_import);
MAKE_FUNCPTR(gnutls_pkcs12_init);
MAKE_FUNCPTR(gnutls_pkcs12_simple_parse);
MAKE_FUNCPTR(gnutls_x509_crt_export);
+MAKE_FUNCPTR(gnutls_x509_privkey_export_rsa_raw2);
+MAKE_FUNCPTR(gnutls_x509_privkey_get_pk_algorithm2);
#undef MAKE_FUNCPTR
static void gnutls_log( int level, const char *msg )
@@ -84,6 +86,8 @@ BOOL gnutls_initialize(void)
LOAD_FUNCPTR(gnutls_pkcs12_init)
LOAD_FUNCPTR(gnutls_pkcs12_simple_parse)
LOAD_FUNCPTR(gnutls_x509_crt_export)
+ LOAD_FUNCPTR(gnutls_x509_privkey_export_rsa_raw2)
+ LOAD_FUNCPTR(gnutls_x509_privkey_get_pk_algorithm2)
#undef LOAD_FUNCPTR
if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS)
@@ -112,6 +116,121 @@ void gnutls_uninitialize(void)
wine_dlclose( libgnutls_handle, NULL, 0 );
libgnutls_handle = NULL;
}
+
+#define RSA_MAGIC_KEY ('R' | ('S' << 8) | ('A' << 16) | ('2' << 24))
+#define RSA_PUBEXP 65537
+
+static HCRYPTPROV import_key( gnutls_x509_privkey_t key, DWORD flags )
+{
+ int i, ret;
+ unsigned int bitlen;
+ gnutls_datum_t m, e, d, p, q, u, e1, e2;
+ BLOBHEADER *hdr;
+ RSAPUBKEY *rsakey;
+ HCRYPTPROV prov = 0;
+ HCRYPTKEY cryptkey;
+ BYTE *buf, *src, *dst;
+ DWORD size;
+
+ if ((ret = pgnutls_x509_privkey_get_pk_algorithm2( key, &bitlen )) < 0)
+ {
+ pgnutls_perror( ret );
+ return 0;
+ }
+
+ if (ret != GNUTLS_PK_RSA)
+ {
+ FIXME( "key algorithm %u not supported\n", ret );
+ return 0;
+ }
+
+ if ((ret = pgnutls_x509_privkey_export_rsa_raw2( key, &m, &e, &d, &p, &q, &u, &e1, &e2 )) < 0)
+ {
+ pgnutls_perror( ret );
+ return 0;
+ }
+
+ size = sizeof(hdr) + sizeof(RSAPUBKEY) + (bitlen * 9 / 16);
+ if (!(buf = heap_alloc( size ))) goto done;
+
+ hdr = (BLOBHEADER *)buf;
+ hdr->bType = PRIVATEKEYBLOB;
+ hdr->bVersion = CUR_BLOB_VERSION;
+ hdr->reserved = 0;
+ hdr->aiKeyAlg = CALG_RSA_KEYX;
+
+ rsakey = (RSAPUBKEY *)(hdr + 1);
+ rsakey->magic = RSA_MAGIC_KEY;
+ rsakey->bitlen = bitlen;
+ rsakey->pubexp = RSA_PUBEXP;
+
+ dst = (BYTE *)(rsakey + 1);
+ if (m.size == bitlen / 8 + 1 && !m.data[0]) src = m.data + 1;
+ else if (m.size != bitlen / 8) goto done;
+ else src = m.data;
+ for (i = bitlen / 8 - 1; i >= 0; i--) *dst++ = src[i];
+
+ if (p.size == bitlen / 16 + 1 && !p.data[0]) src = p.data + 1;
+ else if (p.size != bitlen / 16) goto done;
+ else src = p.data;
+ for (i = bitlen / 16 - 1; i >= 0; i--) *dst++ = src[i];
+
+ if (q.size == bitlen / 16 + 1 && !q.data[0]) src = q.data + 1;
+ else if (q.size != bitlen / 16) goto done;
+ else src = q.data;
+ for (i = bitlen / 16 - 1; i >= 0; i--) *dst++ = src[i];
+
+ if (e1.size == bitlen / 16 + 1 && !e1.data[0]) src = e1.data + 1;
+ else if (e1.size != bitlen / 16) goto done;
+ else src = e1.data;
+ for (i = bitlen / 16 - 1; i >= 0; i--) *dst++ = src[i];
+
+ if (e2.size == bitlen / 16 + 1 && !e2.data[0]) src = e2.data + 1;
+ else if (e2.size != bitlen / 16) goto done;
+ else src = e2.data;
+ for (i = bitlen / 16 - 1; i >= 0; i--) *dst++ = src[i];
+
+ if (u.size == bitlen / 16 + 1 && !u.data[0]) src = u.data + 1;
+ else if (u.size != bitlen / 16) goto done;
+ else src = u.data;
+ for (i = bitlen / 16 - 1; i >= 0; i--) *dst++ = src[i];
+
+ if (d.size == bitlen / 8 + 1 && !d.data[0]) src = d.data + 1;
+ else if (d.size != bitlen / 8) goto done;
+ else src = d.data;
+ for (i = bitlen / 8 - 1; i >= 0; i--) *dst++ = src[i];
+
+ if (!CryptAcquireContextW( &prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET ))
+ {
+ if (GetLastError() != NTE_EXISTS) goto done;
+ if (!CryptAcquireContextW( &prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, 0 ))
+ {
+ WARN( "CryptAcquireContextW failed %08x\n", GetLastError() );
+ goto done;
+ }
+ }
+
+ if (!CryptImportKey( prov, buf, size, 0, flags, &cryptkey ))
+ {
+ WARN( "CryptImportKey failed %08x\n", GetLastError() );
+ CryptReleaseContext( prov, 0 );
+ prov = 0;
+ }
+ else CryptDestroyKey( cryptkey );
+
+done:
+ free( m.data );
+ free( e.data );
+ free( d.data );
+ free( p.data );
+ free( q.data );
+ free( u.data );
+ free( e1.data );
+ free( e2.data );
+ heap_free( buf );
+ return prov;
+}
+
#endif
HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *password, DWORD flags )
@@ -123,6 +242,8 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
gnutls_x509_crt_t *chain;
unsigned int chain_len, i;
HCERTSTORE store = NULL;
+ CERT_KEY_CONTEXT key_ctx;
+ HCRYPTPROV prov = 0;
int ret;
TRACE_(crypt)( "(%p, %p, %08x)\n", pfx, password, flags );
@@ -162,6 +283,7 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
goto error;
}
+ if (!(prov = import_key( key, flags & CRYPT_EXPORTABLE ))) goto error;
if (!(store = CertOpenStore( CERT_STORE_PROV_MEMORY, 0, 0, 0, NULL )))
{
WARN( "CertOpenStore failed %08x\n", GetLastError() );
@@ -197,6 +319,16 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
}
heap_free( crt_data );
+ key_ctx.cbSize = sizeof(key_ctx);
+ key_ctx.hCryptProv = prov;
+ key_ctx.dwKeySpec = AT_KEYEXCHANGE;
+ if (!CertSetCertificateContextProperty( ctx, CERT_KEY_CONTEXT_PROP_ID, 0, &key_ctx ))
+ {
+ WARN( "CertSetCertificateContextProperty failed %08x\n", GetLastError() );
+ CertFreeCertificateContext( ctx );
+ goto error;
+ }
+
if (!CertAddCertificateContextToStore( store, ctx, CERT_STORE_ADD_ALWAYS, NULL ))
{
WARN( "CertAddCertificateContextToStore failed %08x\n", GetLastError() );
@@ -210,6 +342,7 @@ HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *passwor
return store;
error:
+ CryptReleaseContext( prov, 0 );
CertCloseStore( store, 0 );
pgnutls_pkcs12_deinit( p12 );
return NULL;
diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c
index 94aba7b1d1..b13fee6cd1 100644
--- a/dlls/crypt32/tests/store.c
+++ b/dlls/crypt32/tests/store.c
@@ -3284,7 +3284,11 @@ static void test_PFXImportCertStore(void)
{
HCERTSTORE store;
CRYPT_DATA_BLOB pfx;
- DWORD count;
+ const CERT_CONTEXT *cert;
+ CERT_KEY_CONTEXT key;
+ CERT_INFO *info;
+ DWORD count, size;
+ BOOL ret;
SetLastError( 0xdeadbeef );
store = PFXImportCertStore( NULL, NULL, 0 );
@@ -3298,6 +3302,27 @@ static void test_PFXImportCertStore(void)
if (!store) return;
count = countCertsInStore( store );
ok( count == 1, "got %u\n", count );
+
+ cert = CertFindCertificateInStore( store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL );
+ ok( cert != NULL, "got %u\n", GetLastError() );
+ ok( cert->dwCertEncodingType == X509_ASN_ENCODING, "got %u\n", cert->dwCertEncodingType );
+ ok( cert->pbCertEncoded != NULL, "pbCertEncoded not set\n" );
+ ok( cert->cbCertEncoded == 1123, "got %u\n", cert->cbCertEncoded );
+ ok( cert->pCertInfo != NULL, "pCertInfo not set\n" );
+ ok( cert->hCertStore == store, "got %p\n", cert->hCertStore );
+
+ info = cert->pCertInfo;
+ ok( info->dwVersion == CERT_V1, "got %u\n", info->dwVersion );
+ ok( !strcmp(info->SignatureAlgorithm.pszObjId, szOID_RSA_SHA256RSA),
+ "got \"%s\"\n", info->SignatureAlgorithm.pszObjId );
+
+ size = sizeof(key);
+ ret = CertGetCertificateContextProperty( cert, CERT_KEY_CONTEXT_PROP_ID, &key, &size );
+ ok( ret, "got %08x\n", GetLastError() );
+ ok( key.cbSize == sizeof(key), "got %u\n", key.cbSize );
+ ok( key.hCryptProv, "hCryptProv not set\n" );
+ ok( key.dwKeySpec == AT_KEYEXCHANGE, "got %u\n", key.dwKeySpec );
+
CertCloseStore( store, 0 );
}
--
2.20.1
2
1
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/setupapi/devinst.c | 66 ++++++++++++-
dlls/setupapi/tests/devinst.c | 175 +++++++++++++++++++++++++++++++++-
2 files changed, 234 insertions(+), 7 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index 13f7853290..ffb781bfd6 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -3815,13 +3815,69 @@ BOOL WINAPI SetupDiGetINFClassW(PCWSTR inf, LPGUID class_guid, PWSTR class_name,
/***********************************************************************
* SetupDiGetDevicePropertyW (SETUPAPI.@)
*/
-BOOL WINAPI SetupDiGetDevicePropertyW(HDEVINFO info_set, PSP_DEVINFO_DATA info_data,
+BOOL WINAPI SetupDiGetDevicePropertyW(HDEVINFO devinfo, PSP_DEVINFO_DATA device_data,
const DEVPROPKEY *prop_key, DEVPROPTYPE *prop_type, BYTE *prop_buff,
DWORD prop_buff_size, DWORD *required_size, DWORD flags)
{
- FIXME("%p, %p, %p, %p, %p, %d, %p, 0x%08x stub\n", info_set, info_data, prop_key,
- prop_type, prop_buff, prop_buff_size, required_size, flags);
+ static const WCHAR formatW[] = {'\\', '%', '0', '4', 'X', 0};
+ WCHAR key_path[55] = {'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's', '\\'};
+ HKEY hkey;
+ DWORD value_type;
+ DWORD value_size = 0;
+ LSTATUS ls;
+ struct device *device;
- SetLastError(ERROR_NOT_FOUND);
- return FALSE;
+ TRACE("%p, %p, %p, %p, %p, %d, %p, %#x\n", devinfo, device_data, prop_key, prop_type, prop_buff, prop_buff_size,
+ required_size, flags);
+
+ if (!(device = get_device(devinfo, device_data)))
+ return FALSE;
+
+ if (!prop_key)
+ {
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+
+ if (!prop_type || (!prop_buff && prop_buff_size))
+ {
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ return FALSE;
+ }
+
+ if (flags)
+ {
+ SetLastError(ERROR_INVALID_FLAGS);
+ return FALSE;
+ }
+
+ SETUPDI_GuidToString(&prop_key->fmtid, key_path + 11);
+ sprintfW(key_path + 49, formatW, prop_key->pid);
+
+ ls = RegOpenKeyExW(device->key, key_path, 0, KEY_QUERY_VALUE, &hkey);
+ if (!ls)
+ {
+ value_size = prop_buff_size;
+ ls = RegQueryValueExW(hkey, NULL, NULL, &value_type, prop_buff, &value_size);
+ }
+
+ switch (ls)
+ {
+ case NO_ERROR:
+ case ERROR_MORE_DATA:
+ *prop_type = 0xffff & value_type;
+ ls = (ls == ERROR_MORE_DATA || !prop_buff) ? ERROR_INSUFFICIENT_BUFFER : NO_ERROR;
+ break;
+ case ERROR_FILE_NOT_FOUND:
+ *prop_type = DEVPROP_TYPE_EMPTY;
+ value_size = 0;
+ ls = ERROR_NOT_FOUND;
+ break;
+ }
+
+ if (required_size)
+ *required_size = value_size;
+
+ SetLastError(ls);
+ return !ls;
}
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index 0a77fca9c2..5eb0c6befd 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -39,6 +39,7 @@ static GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0
static GUID guid2 = {0x6a55b5a5, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}};
BOOL (WINAPI *pSetupDiSetDevicePropertyW)(HDEVINFO, PSP_DEVINFO_DATA, const DEVPROPKEY *, DEVPROPTYPE, const BYTE *, DWORD, DWORD);
+BOOL (WINAPI *pSetupDiGetDevicePropertyW)(HDEVINFO, PSP_DEVINFO_DATA, const DEVPROPKEY *, DEVPROPTYPE *, BYTE *, DWORD, DWORD *, DWORD);
static void test_create_device_list_ex(void)
{
@@ -351,15 +352,19 @@ static void test_device_property(void)
SP_DEVINFO_DATA device_data = {sizeof(device_data)};
HMODULE hmod;
HDEVINFO set;
+ DEVPROPTYPE type;
+ DWORD size;
+ BYTE buffer[256];
DWORD err;
BOOL ret;
hmod = LoadLibraryA("setupapi.dll");
pSetupDiSetDevicePropertyW = (void *)GetProcAddress(hmod, "SetupDiSetDevicePropertyW");
+ pSetupDiGetDevicePropertyW = (void *)GetProcAddress(hmod, "SetupDiGetDevicePropertyW");
- if (!pSetupDiSetDevicePropertyW)
+ if (!pSetupDiSetDevicePropertyW || !pSetupDiGetDevicePropertyW)
{
- win_skip("SetupDiSetDevicePropertyW() are only available on vista+, skipping tests.\n");
+ win_skip("SetupDi{Set,Get}DevicePropertyW() are only available on vista+, skipping tests.\n");
FreeLibrary(hmod);
return;
}
@@ -495,6 +500,172 @@ static void test_device_property(void)
ok(!ret, "Expect failure\n");
ok(err == ERROR_NOT_FOUND, "Expect last error %#x, got %#x\n", ERROR_NOT_FOUND, err);
+
+ /* SetupDiGetDevicePropertyW */
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ ok(ret, "Expect success\n");
+
+ /* #1 Null device info list */
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ size = 0;
+ ret = pSetupDiGetDevicePropertyW(NULL, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_HANDLE, "Expect last error %#x, got %#x\n", ERROR_INVALID_HANDLE, err);
+ ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
+ ok(size == 0, "Expect size %d, got %d\n", 0, size);
+
+ /* #2 Null device */
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ size = 0;
+ ret = pSetupDiGetDevicePropertyW(set, NULL, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_PARAMETER, "Expect last error %#x, got %#x\n", ERROR_INVALID_PARAMETER, err);
+ ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
+ ok(size == 0, "Expect size %d, got %d\n", 0, size);
+
+ /* #3 Null property key */
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ size = 0;
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, NULL, &type, buffer, sizeof(buffer), &size, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_DATA, "Expect last error %#x, got %#x\n", ERROR_INVALID_DATA, err);
+ ok(size == 0, "Expect size %d, got %d\n", 0, size);
+
+ /* #4 Null property type */
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ size = 0;
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, NULL, buffer, sizeof(buffer), &size, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_USER_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INVALID_USER_BUFFER, err);
+ ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
+ ok(size == 0, "Expect size %d, got %d\n", 0, size);
+
+ /* #5 Null buffer */
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ size = 0;
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, NULL, sizeof(buffer), &size, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_USER_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INVALID_USER_BUFFER, err);
+ ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
+ ok(size == 0, "Expect size %d, got %d\n", 0, size);
+
+ /* #6 Null buffer with zero size and wrong type */
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_UINT64;
+ size = 0;
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, NULL, 0, &size, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INSUFFICIENT_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INSUFFICIENT_BUFFER, err);
+ ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
+ ok(size == sizeof(valueW), "Expect size %d, got %d\n", sizeof(valueW), size);
+
+ /* #7 Zero buffer size */
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ size = 0;
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, 0, &size, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INSUFFICIENT_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INSUFFICIENT_BUFFER, err);
+ ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
+ ok(size == sizeof(valueW), "Expect size %d, got %d\n", sizeof(valueW), size);
+
+ /* #8 Null required size */
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), NULL, 0);
+ err = GetLastError();
+ ok(ret, "Expect success\n");
+ ok(err == NO_ERROR, "Expect last error %#x, got %#x\n", NO_ERROR, err);
+ ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
+
+ /* #9 Flags not zero */
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ size = 0;
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 1);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INVALID_FLAGS, "Expect last error %#x, got %#x\n", ERROR_INVALID_FLAGS, err);
+ ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
+ ok(size == 0, "Expect size %d, got %d\n", 0, size);
+
+ /* #10 Non-existent property key */
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ size = 0;
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_HardwareIds, &type, buffer, sizeof(buffer), &size, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_NOT_FOUND, "Expect last error %#x, got %#x\n", ERROR_NOT_FOUND, err);
+ ok(size == 0, "Expect size %d, got %d\n", 0, size);
+
+ /* #11 Wrong property key type */
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_UINT64;
+ size = 0;
+ memset(buffer, 0, sizeof(buffer));
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 0);
+ err = GetLastError();
+ ok(ret, "Expect success\n");
+ ok(err == NO_ERROR, "Expect last error %#x, got %#x\n", NO_ERROR, err);
+ ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
+ ok(size == sizeof(valueW), "Expect size %d, got %d\n", sizeof(valueW), size);
+ ok(!lstrcmpW((WCHAR *)buffer, valueW), "Expect buffer %s, got %s\n", wine_dbgstr_w(valueW), wine_dbgstr_w((WCHAR *)buffer));
+
+ /* #12 Get null property value */
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ ok(ret, "Expect success\n");
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_NULL, NULL, 0, 0);
+ ok(ret, "Expect success\n");
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ size = 0;
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_NOT_FOUND, "Expect last error %#x, got %#x\n", ERROR_NOT_FOUND, err);
+ ok(size == 0, "Expect size %d, got %d\n", 0, size);
+
+ /* #13 Insufficient buffer size */
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ ok(ret, "Expect success\n");
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ size = 0;
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(valueW) - 1, &size, 0);
+ err = GetLastError();
+ ok(!ret, "Expect failure\n");
+ ok(err == ERROR_INSUFFICIENT_BUFFER, "Expect last error %#x, got %#x\n", ERROR_INSUFFICIENT_BUFFER, err);
+ ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
+ ok(size == sizeof(valueW), "Expect size %d, got %d\n", sizeof(valueW), size);
+
+ /* #14 Normal */
+ ret = pSetupDiSetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, DEVPROP_TYPE_STRING, (const BYTE *)valueW, sizeof(valueW), 0);
+ ok(ret, "Expect success\n");
+ SetLastError(0xdeadbeef);
+ type = DEVPROP_TYPE_STRING;
+ size = 0;
+ memset(buffer, 0, sizeof(buffer));
+ ret = pSetupDiGetDevicePropertyW(set, &device_data, &DEVPKEY_Device_FriendlyName, &type, buffer, sizeof(buffer), &size, 0);
+ err = GetLastError();
+ ok(ret, "Expect success\n");
+ ok(err == NO_ERROR, "Expect last error %#x, got %#x\n", NO_ERROR, err);
+ ok(type == DEVPROP_TYPE_STRING, "Expect type %#x, got %#x\n", DEVPROP_TYPE_STRING, type);
+ ok(size == sizeof(valueW), "Expect size %d, got %d\n", sizeof(valueW), size);
+ ok(!lstrcmpW((WCHAR *)buffer, valueW), "Expect buffer %s, got %s\n", wine_dbgstr_w(valueW), wine_dbgstr_w((WCHAR *)buffer));
+
ret = SetupDiRemoveDevice(set, &device_data);
ok(ret, "Got unexpected error %#x.\n", GetLastError());
--
2.20.1
2
1
[PATCH 3/3] services: Associate notify handle with service handle instead of service entry.
by Jacek Caban 28 Jan '19
by Jacek Caban 28 Jan '19
28 Jan '19
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/advapi32/tests/service.c | 2 --
programs/services/rpc.c | 68 +++++++++++++++++------------------
programs/services/services.h | 4 ---
3 files changed, 34 insertions(+), 40 deletions(-)
1
0
28 Jan '19
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
programs/services/rpc.c | 6 ++++++
programs/services/services.c | 3 +++
programs/services/services.h | 1 +
3 files changed, 10 insertions(+)
1
0
[PATCH 1/3] advapi32/tests: Add test using NotifyServiceStatusChange on different handles of the same service.
by Jacek Caban 28 Jan '19
by Jacek Caban 28 Jan '19
28 Jan '19
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/advapi32/tests/service.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
1
0
[PATCH] winhttp: Implement WinHttpSetOption(WINHTTP_OPTION_CLIENT_CERT_CONTEXT).
by Hans Leidekker 28 Jan '19
by Hans Leidekker 28 Jan '19
28 Jan '19
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/winhttp/session.c | 30 ++++++++++++++++++++++++++++--
dlls/winhttp/winhttp_private.h | 1 +
2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index 82615ad12f..890894d1c0 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -611,6 +611,7 @@ static void request_destroy( struct object_header *hdr )
release_object( &request->connect->hdr );
CertFreeCertificateContext( request->server_cert );
+ CertFreeCertificateContext( request->client_cert );
destroy_authinfo( request->authinfo );
destroy_authinfo( request->proxy_authinfo );
@@ -1000,14 +1001,39 @@ static BOOL request_set_option( struct object_header *hdr, DWORD option, void *b
return TRUE;
}
case WINHTTP_OPTION_CLIENT_CERT_CONTEXT:
+ {
+ const CERT_CONTEXT *cert;
+
if (!(hdr->flags & WINHTTP_FLAG_SECURE))
{
SetLastError( ERROR_WINHTTP_INCORRECT_HANDLE_STATE );
return FALSE;
}
- FIXME("WINHTTP_OPTION_CLIENT_CERT_CONTEXT\n");
- return TRUE;
+ if (!buffer)
+ {
+ CertFreeCertificateContext( request->client_cert );
+ request->client_cert = NULL;
+ }
+ else if (buflen >= sizeof(cert))
+ {
+ if (!(cert = CertDuplicateCertificateContext( buffer ))) return FALSE;
+ CertFreeCertificateContext( request->client_cert );
+ request->client_cert = cert;
+ }
+ else
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+ if (request->cred_handle_initialized)
+ {
+ FreeCredentialsHandle( &request->cred_handle );
+ request->cred_handle_initialized = FALSE;
+ }
+
+ return TRUE;
+ }
case WINHTTP_OPTION_ENABLE_FEATURE:
if(buflen == sizeof( DWORD ) && *(DWORD *)buffer == WINHTTP_ENABLE_SSL_REVOCATION)
{
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h
index b46f7087d8..33b96b97f0 100644
--- a/dlls/winhttp/winhttp_private.h
+++ b/dlls/winhttp/winhttp_private.h
@@ -182,6 +182,7 @@ struct request
DWORD security_flags;
BOOL check_revocation;
const CERT_CONTEXT *server_cert;
+ const CERT_CONTEXT *client_cert;
int resolve_timeout;
int connect_timeout;
int send_timeout;
--
2.20.1
2
1
28 Jan '19
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/crypt32/Makefile.in | 2 +
dlls/crypt32/crypt32_private.h | 3 +
dlls/crypt32/decode.c | 14 --
dlls/crypt32/encode.c | 14 --
dlls/crypt32/main.c | 6 +
dlls/crypt32/pfx.c | 238 +++++++++++++++++++++++++++++
dlls/crypt32/tests/store.c | 264 +++++++++++++++++++++++++++++++++
include/wincrypt.h | 12 +-
8 files changed, 523 insertions(+), 30 deletions(-)
create mode 100644 dlls/crypt32/pfx.c
diff --git a/dlls/crypt32/Makefile.in b/dlls/crypt32/Makefile.in
index 0934222119..f56617c079 100644
--- a/dlls/crypt32/Makefile.in
+++ b/dlls/crypt32/Makefile.in
@@ -4,6 +4,7 @@ IMPORTLIB = crypt32
IMPORTS = user32 advapi32 bcrypt
DELAYIMPORTS = cryptnet
EXTRALIBS = $(SECURITY_LIBS)
+EXTRAINCL = $(GNUTLS_CFLAGS)
C_SRCS = \
base64.c \
@@ -21,6 +22,7 @@ C_SRCS = \
msg.c \
object.c \
oid.c \
+ pfx.c \
proplist.c \
protectdata.c \
provstore.c \
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index ac70fe04f8..3d0129e7d4 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -451,4 +451,7 @@ void init_empty_store(void) DECLSPEC_HIDDEN;
*/
#define IS_INTOID(x) (((ULONG_PTR)(x) >> 16) == 0)
+BOOL gnutls_initialize(void) DECLSPEC_HIDDEN;
+void gnutls_uninitialize(void) DECLSPEC_HIDDEN;
+
#endif
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index e70940aa7d..d886abb503 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -6393,17 +6393,3 @@ BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
ret = FALSE;
return ret;
}
-
-HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
- DWORD dwFlags)
-{
- FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);
- return NULL;
-}
-
-BOOL WINAPI PFXVerifyPassword(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
- DWORD dwFlags)
-{
- FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);
- return FALSE;
-}
diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c
index 9d052b61c1..d59deb4b9e 100644
--- a/dlls/crypt32/encode.c
+++ b/dlls/crypt32/encode.c
@@ -4758,20 +4758,6 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
return ret;
}
-BOOL WINAPI PFXExportCertStore(HCERTSTORE hStore, CRYPT_DATA_BLOB *pPFX,
- LPCWSTR szPassword, DWORD dwFlags)
-{
- return PFXExportCertStoreEx(hStore, pPFX, szPassword, NULL, dwFlags);
-}
-
-BOOL WINAPI PFXExportCertStoreEx(HCERTSTORE hStore, CRYPT_DATA_BLOB *pPFX,
- LPCWSTR szPassword, void *pvReserved, DWORD dwFlags)
-{
- FIXME_(crypt)("(%p, %p, %p, %p, %08x): stub\n", hStore, pPFX, szPassword,
- pvReserved, dwFlags);
- return FALSE;
-}
-
BOOL WINAPI CryptExportPublicKeyInfo(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD dwKeySpec,
DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, DWORD *pcbInfo)
{
diff --git a/dlls/crypt32/main.c b/dlls/crypt32/main.c
index d0643f4107..d64fbbd2e6 100644
--- a/dlls/crypt32/main.c
+++ b/dlls/crypt32/main.c
@@ -54,6 +54,9 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved)
DisableThreadLibraryCalls(hInst);
init_empty_store();
crypt_oid_init();
+#ifdef SONAME_LIBGNUTLS
+ gnutls_initialize();
+#endif
break;
case DLL_PROCESS_DETACH:
if (pvReserved) break;
@@ -61,6 +64,9 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved)
crypt_sip_free();
default_chain_engine_free();
if (hDefProv) CryptReleaseContext(hDefProv, 0);
+#ifdef SONAME_LIBGNUTLS
+ gnutls_uninitialize();
+#endif
break;
}
return TRUE;
diff --git a/dlls/crypt32/pfx.c b/dlls/crypt32/pfx.c
new file mode 100644
index 0000000000..ce842cd087
--- /dev/null
+++ b/dlls/crypt32/pfx.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2019 Hans Leidekker for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+#ifdef SONAME_LIBGNUTLS
+#include <gnutls/pkcs12.h>
+#endif
+
+#include "windef.h"
+#include "winbase.h"
+#include "wincrypt.h"
+#include "snmp.h"
+
+#include "wine/debug.h"
+#include "wine/heap.h"
+#include "wine/library.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(crypt);
+
+#ifdef SONAME_LIBGNUTLS
+WINE_DECLARE_DEBUG_CHANNEL(winediag);
+
+static void *libgnutls_handle;
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f
+MAKE_FUNCPTR(gnutls_global_deinit);
+MAKE_FUNCPTR(gnutls_global_init);
+MAKE_FUNCPTR(gnutls_global_set_log_function);
+MAKE_FUNCPTR(gnutls_global_set_log_level);
+MAKE_FUNCPTR(gnutls_perror);
+MAKE_FUNCPTR(gnutls_pkcs12_deinit);
+MAKE_FUNCPTR(gnutls_pkcs12_import);
+MAKE_FUNCPTR(gnutls_pkcs12_init);
+MAKE_FUNCPTR(gnutls_pkcs12_simple_parse);
+MAKE_FUNCPTR(gnutls_x509_crt_export);
+#undef MAKE_FUNCPTR
+
+static void gnutls_log( int level, const char *msg )
+{
+ TRACE( "<%d> %s", level, msg );
+}
+
+BOOL gnutls_initialize(void)
+{
+ int ret;
+
+ if (!(libgnutls_handle = wine_dlopen( SONAME_LIBGNUTLS, RTLD_NOW, NULL, 0 )))
+ {
+ ERR_(winediag)( "failed to load libgnutls, no support for pfx import/export\n" );
+ return FALSE;
+ }
+
+#define LOAD_FUNCPTR(f) \
+ if (!(p##f = wine_dlsym( libgnutls_handle, #f, NULL, 0 ))) \
+ { \
+ ERR( "failed to load %s\n", #f ); \
+ goto fail; \
+ }
+
+ LOAD_FUNCPTR(gnutls_global_deinit)
+ LOAD_FUNCPTR(gnutls_global_init)
+ LOAD_FUNCPTR(gnutls_global_set_log_function)
+ LOAD_FUNCPTR(gnutls_global_set_log_level)
+ LOAD_FUNCPTR(gnutls_perror)
+ LOAD_FUNCPTR(gnutls_pkcs12_deinit)
+ LOAD_FUNCPTR(gnutls_pkcs12_import)
+ LOAD_FUNCPTR(gnutls_pkcs12_init)
+ LOAD_FUNCPTR(gnutls_pkcs12_simple_parse)
+ LOAD_FUNCPTR(gnutls_x509_crt_export)
+#undef LOAD_FUNCPTR
+
+ if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS)
+ {
+ pgnutls_perror( ret );
+ goto fail;
+ }
+
+ if (TRACE_ON( crypt ))
+ {
+ pgnutls_global_set_log_level( 4 );
+ pgnutls_global_set_log_function( gnutls_log );
+ }
+
+ return TRUE;
+
+fail:
+ wine_dlclose( libgnutls_handle, NULL, 0 );
+ libgnutls_handle = NULL;
+ return FALSE;
+}
+
+void gnutls_uninitialize(void)
+{
+ pgnutls_global_deinit();
+ wine_dlclose( libgnutls_handle, NULL, 0 );
+ libgnutls_handle = NULL;
+}
+#endif
+
+HCERTSTORE WINAPI PFXImportCertStore( CRYPT_DATA_BLOB *pfx, const WCHAR *password, DWORD flags )
+{
+#ifdef SONAME_LIBGNUTLS
+ gnutls_pkcs12_t p12;
+ gnutls_datum_t pfx_data;
+ gnutls_x509_privkey_t key;
+ gnutls_x509_crt_t *chain;
+ unsigned int chain_len, i;
+ HCERTSTORE store = NULL;
+ int ret;
+
+ TRACE_(crypt)( "(%p, %p, %08x)\n", pfx, password, flags );
+ if (!pfx)
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return NULL;
+ }
+ if (password)
+ {
+ FIXME( "password not supported\n" );
+ return NULL;
+ }
+ if (flags & ~(CRYPT_EXPORTABLE|CRYPT_USER_KEYSET|PKCS12_NO_PERSIST_KEY))
+ {
+ FIXME( "flags %08x not supported\n", flags );
+ return NULL;
+ }
+
+ if ((ret = pgnutls_pkcs12_init( &p12 )) < 0)
+ {
+ pgnutls_perror( ret );
+ return NULL;
+ }
+
+ pfx_data.data = pfx->pbData;
+ pfx_data.size = pfx->cbData;
+ if ((ret = pgnutls_pkcs12_import( p12, &pfx_data, GNUTLS_X509_FMT_DER, 0 )) < 0)
+ {
+ pgnutls_perror( ret );
+ return NULL;
+ }
+
+ if ((ret = pgnutls_pkcs12_simple_parse( p12, "", &key, &chain, &chain_len, NULL, NULL, NULL, 0 )) < 0)
+ {
+ pgnutls_perror( ret );
+ goto error;
+ }
+
+ if (!(store = CertOpenStore( CERT_STORE_PROV_MEMORY, 0, 0, 0, NULL )))
+ {
+ WARN( "CertOpenStore failed %08x\n", GetLastError() );
+ goto error;
+ }
+
+ if (chain_len > 1) FIXME_(crypt)( "handle certificate chain\n" );
+ for (i = 0; i < chain_len; i++)
+ {
+ const void *ctx;
+ BYTE *crt_data;
+ size_t size = 0;
+
+ if ((ret = pgnutls_x509_crt_export( chain[i], GNUTLS_X509_FMT_DER, NULL, &size )) != GNUTLS_E_SHORT_MEMORY_BUFFER)
+ {
+ pgnutls_perror( ret );
+ goto error;
+ }
+
+ if (!(crt_data = heap_alloc( size ))) goto error;
+ if ((ret = pgnutls_x509_crt_export( chain[i], GNUTLS_X509_FMT_DER, crt_data, &size )) < 0)
+ {
+ pgnutls_perror( ret );
+ heap_free( crt_data );
+ goto error;
+ }
+
+ if (!(ctx = CertCreateContext( CERT_STORE_CERTIFICATE_CONTEXT, X509_ASN_ENCODING, crt_data, size, 0, NULL )))
+ {
+ WARN( "CertCreateContext failed %08x\n", GetLastError() );
+ heap_free( crt_data );
+ goto error;
+ }
+ heap_free( crt_data );
+
+ if (!CertAddCertificateContextToStore( store, ctx, CERT_STORE_ADD_ALWAYS, NULL ))
+ {
+ WARN( "CertAddCertificateContextToStore failed %08x\n", GetLastError() );
+ CertFreeCertificateContext( ctx );
+ goto error;
+ }
+ CertFreeCertificateContext( ctx );
+ }
+
+ pgnutls_pkcs12_deinit( p12 );
+ return store;
+
+error:
+ CertCloseStore( store, 0 );
+ pgnutls_pkcs12_deinit( p12 );
+ return NULL;
+
+#endif
+ FIXME_(crypt)( "(%p, %p, %08x)\n", pfx, password, flags );
+ return NULL;
+}
+
+BOOL WINAPI PFXVerifyPassword( CRYPT_DATA_BLOB *pfx, const WCHAR *password, DWORD flags )
+{
+ FIXME_(crypt)( "(%p, %p, %08x): stub\n", pfx, password, flags );
+ return FALSE;
+}
+
+BOOL WINAPI PFXExportCertStore( HCERTSTORE store, CRYPT_DATA_BLOB *pfx, const WCHAR *password, DWORD flags )
+{
+ return PFXExportCertStoreEx( store, pfx, password, NULL, flags );
+}
+
+BOOL WINAPI PFXExportCertStoreEx( HCERTSTORE store, CRYPT_DATA_BLOB *pfx, const WCHAR *password, void *reserved,
+ DWORD flags )
+{
+ FIXME_(crypt)( "(%p, %p, %p, %p, %08x): stub\n", store, pfx, password, reserved, flags );
+ return FALSE;
+}
diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c
index d862902c88..94aba7b1d1 100644
--- a/dlls/crypt32/tests/store.c
+++ b/dlls/crypt32/tests/store.c
@@ -3038,6 +3038,269 @@ static void test_I_UpdateStore(void)
CertCloseStore(store2, 0);
}
+const BYTE pfxdata[] =
+{
+ 0x30, 0x82, 0x0b, 0x1d, 0x02, 0x01, 0x03, 0x30, 0x82, 0x0a, 0xe3, 0x06,
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
+ 0x0a, 0xd4, 0x04, 0x82, 0x0a, 0xd0, 0x30, 0x82, 0x0a, 0xcc, 0x30, 0x82,
+ 0x05, 0x07, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
+ 0x06, 0xa0, 0x82, 0x04, 0xf8, 0x30, 0x82, 0x04, 0xf4, 0x02, 0x01, 0x00,
+ 0x30, 0x82, 0x04, 0xed, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xac, 0x3e, 0x35,
+ 0xa8, 0xed, 0x0d, 0x50, 0x07, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x04,
+ 0xc0, 0x5a, 0x62, 0x55, 0x25, 0xf6, 0x2c, 0xf1, 0x78, 0x6c, 0x63, 0x96,
+ 0x8a, 0xea, 0x04, 0x64, 0xb3, 0x99, 0x3b, 0x80, 0x50, 0x05, 0x37, 0x55,
+ 0xa3, 0x5e, 0x9f, 0x35, 0xc3, 0x3c, 0xdc, 0xf6, 0xc4, 0xc1, 0x39, 0xa2,
+ 0xd7, 0x50, 0xad, 0xf9, 0x29, 0x3c, 0x51, 0xea, 0x15, 0x20, 0x25, 0xd3,
+ 0x4d, 0x69, 0xdf, 0x10, 0xd8, 0x9d, 0x60, 0x78, 0x8a, 0x70, 0x44, 0x7f,
+ 0x01, 0x4f, 0x4a, 0xfa, 0xab, 0xfd, 0x46, 0x48, 0x96, 0x2b, 0x69, 0xfc,
+ 0x11, 0xf8, 0x3f, 0xd3, 0x79, 0x09, 0x75, 0x81, 0x47, 0xdf, 0xce, 0xfe,
+ 0x07, 0x2f, 0x0a, 0xd8, 0xac, 0x87, 0x14, 0x1f, 0x7b, 0x95, 0x70, 0xee,
+ 0x7e, 0x52, 0x90, 0x11, 0xd6, 0x69, 0xf4, 0xd5, 0x38, 0x85, 0xc9, 0xc1,
+ 0x07, 0x01, 0xe8, 0xbb, 0xfb, 0xe2, 0x08, 0xa8, 0xfa, 0xbf, 0xf0, 0x92,
+ 0x63, 0x1d, 0xbb, 0x2b, 0x45, 0x6f, 0xce, 0x97, 0x01, 0xd7, 0x95, 0xf0,
+ 0x9c, 0x9a, 0x6b, 0x73, 0x01, 0xbf, 0xf9, 0x3d, 0xc8, 0x2b, 0x86, 0x7a,
+ 0xd5, 0x65, 0x84, 0xd7, 0xff, 0xb2, 0xf9, 0x20, 0x52, 0x35, 0xc5, 0x60,
+ 0x33, 0x70, 0x1d, 0x2f, 0x26, 0x09, 0x1c, 0x22, 0x17, 0xd8, 0x08, 0x4e,
+ 0x69, 0x20, 0xe2, 0x71, 0xe4, 0x07, 0xb1, 0x48, 0x5f, 0x20, 0x08, 0x7a,
+ 0xbf, 0x65, 0x53, 0x23, 0x07, 0xf9, 0x6c, 0xde, 0x3e, 0x29, 0xbf, 0x6b,
+ 0xef, 0xbb, 0x6a, 0x5f, 0x79, 0xa1, 0x72, 0xa1, 0x10, 0x24, 0x80, 0xb4,
+ 0x44, 0xb8, 0xc9, 0xfc, 0xa3, 0x36, 0x7e, 0x23, 0x37, 0x58, 0xc6, 0x1e,
+ 0xe8, 0x42, 0x4d, 0xb5, 0xf5, 0x58, 0x93, 0x21, 0x38, 0xa2, 0xc4, 0xa9,
+ 0x01, 0x96, 0xf9, 0x61, 0xac, 0x55, 0xb3, 0x3d, 0xe4, 0x54, 0x8b, 0x6c,
+ 0xc3, 0x83, 0xff, 0x50, 0x87, 0x94, 0xe8, 0x35, 0x3c, 0x26, 0x0d, 0x20,
+ 0x8a, 0x25, 0x0e, 0xb6, 0x67, 0x78, 0x29, 0xc7, 0xbf, 0x76, 0x8e, 0x62,
+ 0x62, 0xc4, 0x50, 0xd6, 0xc5, 0x3c, 0xb4, 0x7a, 0x35, 0xbe, 0x53, 0x52,
+ 0xc4, 0xe4, 0x10, 0xb3, 0xe0, 0x73, 0xb0, 0xd1, 0xc1, 0x5a, 0x4f, 0x4e,
+ 0x64, 0x0d, 0x92, 0x51, 0x2d, 0x4d, 0xec, 0xb0, 0xc6, 0x40, 0x1b, 0x03,
+ 0x89, 0x7f, 0xc2, 0x2c, 0xe3, 0x2c, 0xbd, 0x8c, 0x9c, 0xd9, 0xe0, 0x08,
+ 0x59, 0xd3, 0xaf, 0x48, 0x56, 0x89, 0x60, 0x85, 0x76, 0xe0, 0xd8, 0x7c,
+ 0xcf, 0x02, 0x8f, 0xfd, 0xb2, 0x8f, 0x2b, 0x61, 0xcf, 0x28, 0x56, 0x8b,
+ 0x6b, 0x03, 0x2b, 0x2f, 0x83, 0x31, 0xa0, 0x1c, 0xd1, 0x6c, 0x87, 0x49,
+ 0xc4, 0x77, 0x55, 0x1f, 0x61, 0x45, 0x58, 0x88, 0x9f, 0x01, 0xc3, 0x63,
+ 0x62, 0x30, 0x35, 0xdf, 0x61, 0x74, 0x55, 0x63, 0x3f, 0xae, 0x41, 0xc1,
+ 0xb8, 0xf0, 0x9f, 0xab, 0x25, 0xad, 0x41, 0x5c, 0x1f, 0x00, 0x0d, 0xef,
+ 0xf0, 0xcf, 0xaf, 0x41, 0x23, 0xca, 0x8c, 0x38, 0xea, 0x5a, 0xe4, 0x8b,
+ 0xb4, 0x89, 0xd0, 0x76, 0x7f, 0x2b, 0x77, 0x8f, 0xe4, 0x44, 0xd5, 0x37,
+ 0xac, 0xc2, 0x09, 0x7e, 0x7e, 0x7e, 0x02, 0x5c, 0x27, 0x01, 0xcb, 0x4d,
+ 0xea, 0xb3, 0x97, 0x36, 0x35, 0xd2, 0x05, 0x3c, 0x4e, 0xb8, 0x04, 0x5c,
+ 0xb8, 0x95, 0x3f, 0xc6, 0xbf, 0xd4, 0x20, 0x01, 0xfb, 0xed, 0x37, 0x5a,
+ 0xad, 0x4c, 0x61, 0x93, 0xfe, 0x95, 0x7c, 0x34, 0x11, 0x15, 0x9d, 0x00,
+ 0x0b, 0x99, 0x69, 0xcb, 0x7e, 0xb9, 0x53, 0x46, 0x57, 0x39, 0x3f, 0x59,
+ 0x4b, 0x30, 0x8d, 0xfb, 0x84, 0x66, 0x2d, 0x06, 0xc9, 0x88, 0xa6, 0x18,
+ 0xd7, 0x36, 0xc6, 0xf6, 0xf7, 0x47, 0x85, 0x38, 0xc8, 0x3d, 0x37, 0xea,
+ 0x57, 0x4c, 0xb0, 0x7c, 0x95, 0x29, 0x84, 0xab, 0xbb, 0x19, 0x86, 0xc2,
+ 0xc5, 0x99, 0x01, 0x38, 0x6b, 0xf1, 0xd3, 0x1d, 0xa8, 0x02, 0xf9, 0x6f,
+ 0xaa, 0xf1, 0x57, 0xd0, 0x88, 0x68, 0x62, 0x5f, 0x9f, 0x7a, 0x63, 0xba,
+ 0x3a, 0xc9, 0x95, 0x11, 0x3c, 0xf9, 0xa1, 0xc1, 0x35, 0xfe, 0xd5, 0x12,
+ 0x49, 0x88, 0x0d, 0x5c, 0xe2, 0xd1, 0x15, 0x18, 0xfb, 0xd5, 0x7f, 0x19,
+ 0x3f, 0xaf, 0xa0, 0xcb, 0x31, 0x20, 0x9e, 0x03, 0x93, 0xa4, 0x66, 0xbd,
+ 0x83, 0xe8, 0x60, 0x34, 0x55, 0x0d, 0x97, 0x10, 0x23, 0x24, 0x7a, 0x45,
+ 0x36, 0xb4, 0xc4, 0xee, 0x60, 0x6f, 0xd8, 0x46, 0xc5, 0xac, 0x2b, 0xa9,
+ 0x18, 0x74, 0x83, 0x1e, 0xdf, 0x7c, 0x1a, 0x5a, 0xe8, 0x5f, 0x8b, 0x4f,
+ 0x9f, 0x40, 0x3e, 0x5e, 0xfb, 0xd3, 0x68, 0xac, 0x34, 0x62, 0x30, 0x23,
+ 0xb6, 0xbc, 0xdf, 0xbc, 0xc7, 0x25, 0xd2, 0x1b, 0x57, 0x33, 0xfb, 0x78,
+ 0x22, 0x21, 0x1e, 0x3a, 0xf6, 0x44, 0x18, 0x7e, 0x12, 0x36, 0x47, 0x58,
+ 0xd0, 0x59, 0x26, 0x98, 0x98, 0x95, 0xf4, 0xd1, 0xaa, 0x45, 0xaa, 0xe7,
+ 0xd1, 0xe6, 0x2d, 0x78, 0xf0, 0x8b, 0x1c, 0xfd, 0xf8, 0x50, 0x60, 0xa2,
+ 0x1e, 0x7f, 0xe3, 0x31, 0x77, 0x31, 0x58, 0x99, 0x0f, 0xda, 0x0e, 0xa3,
+ 0xc6, 0x7a, 0x30, 0x45, 0x55, 0x11, 0x91, 0x77, 0x41, 0x79, 0xd3, 0x56,
+ 0xb2, 0x07, 0x00, 0x61, 0xab, 0xec, 0x27, 0xc7, 0x9f, 0xfa, 0x89, 0x08,
+ 0xc2, 0x87, 0xcf, 0xe9, 0xdc, 0x9e, 0x29, 0x22, 0xfb, 0x23, 0x7f, 0x9d,
+ 0x89, 0xd5, 0x6e, 0x75, 0x20, 0xd8, 0x00, 0x5b, 0xc4, 0x94, 0xbb, 0xc5,
+ 0xb2, 0xba, 0x77, 0x2b, 0xf6, 0x3c, 0x88, 0xb0, 0x4c, 0x38, 0x46, 0x55,
+ 0xee, 0x8b, 0x03, 0x15, 0xbc, 0x0a, 0x1d, 0x47, 0x87, 0x44, 0xaf, 0xb1,
+ 0x2a, 0xa7, 0x4d, 0x08, 0xdf, 0x3b, 0x2d, 0x70, 0xa1, 0x67, 0x31, 0x76,
+ 0x6e, 0x6f, 0x40, 0x3b, 0x3b, 0xe8, 0xf9, 0xdf, 0x90, 0xa4, 0xce, 0x7f,
+ 0xb8, 0x2d, 0x69, 0xcb, 0x1c, 0x1e, 0x94, 0xcd, 0xb1, 0xd8, 0x43, 0x22,
+ 0xb8, 0x4f, 0x98, 0x92, 0x74, 0xb3, 0xde, 0xeb, 0x7a, 0xcb, 0xfa, 0xd0,
+ 0x36, 0xe4, 0x5d, 0xfa, 0xd3, 0xce, 0xf9, 0xba, 0x3e, 0x0f, 0x6c, 0xc3,
+ 0x5b, 0xb3, 0x81, 0x84, 0x6e, 0x5d, 0xc1, 0x21, 0x89, 0xec, 0x67, 0x9a,
+ 0xfd, 0x55, 0x20, 0xb0, 0x71, 0x53, 0xae, 0xf8, 0xa4, 0x8d, 0xd5, 0xe5,
+ 0x2d, 0x3a, 0xce, 0x89, 0x55, 0x8c, 0x4f, 0x3b, 0x37, 0x95, 0x4e, 0x15,
+ 0xbe, 0xe7, 0xd1, 0x7a, 0x36, 0x82, 0x45, 0x69, 0x7c, 0x27, 0x4f, 0xb9,
+ 0x4b, 0x7d, 0xcd, 0x59, 0xc8, 0xf4, 0x8b, 0x0f, 0x4f, 0x75, 0x23, 0xd3,
+ 0xd0, 0xc7, 0x10, 0x79, 0xc0, 0xf1, 0xac, 0x14, 0xf7, 0x0d, 0xc8, 0x5e,
+ 0xfc, 0xff, 0x1a, 0x2b, 0x10, 0x88, 0x7e, 0x7e, 0x2f, 0xfa, 0x7b, 0x9f,
+ 0x47, 0x23, 0x34, 0xfc, 0xf5, 0xde, 0xd9, 0xa3, 0x05, 0x99, 0x2a, 0x96,
+ 0x83, 0x3d, 0xa4, 0x7f, 0x6a, 0x66, 0x9b, 0xe7, 0xf1, 0x00, 0x4e, 0x9a,
+ 0xfc, 0x68, 0xd2, 0x74, 0x17, 0xba, 0xc9, 0xc8, 0x20, 0x39, 0xa1, 0xa8,
+ 0x85, 0xc6, 0x10, 0x2b, 0xab, 0x97, 0x34, 0x2d, 0x49, 0x68, 0x57, 0xb0,
+ 0x43, 0xee, 0x25, 0xbb, 0x35, 0x1b, 0x03, 0x99, 0xa3, 0x21, 0x68, 0x66,
+ 0x86, 0x3f, 0xc6, 0xfc, 0x49, 0xf0, 0xba, 0x5f, 0x00, 0xc6, 0xe3, 0x1c,
+ 0xb2, 0x9f, 0x16, 0x7f, 0xc7, 0x40, 0x4a, 0x9a, 0x39, 0xc1, 0x95, 0x69,
+ 0xa2, 0x87, 0xba, 0x58, 0xc6, 0xf2, 0xd6, 0x66, 0xa6, 0x4c, 0x6d, 0x29,
+ 0x9c, 0xa8, 0x6e, 0xa9, 0xd2, 0xe4, 0x54, 0x17, 0x89, 0xe2, 0x43, 0xf0,
+ 0xe1, 0x8b, 0x57, 0x84, 0x6c, 0x87, 0x63, 0x17, 0xbb, 0xf6, 0x33, 0x1b,
+ 0xe4, 0x34, 0x6a, 0x80, 0x70, 0x7b, 0x1b, 0xfd, 0xf8, 0x79, 0x28, 0xc8,
+ 0x3c, 0x8e, 0xa4, 0xd5, 0xb8, 0x96, 0x54, 0xd4, 0xec, 0x72, 0xe5, 0x40,
+ 0x8f, 0x56, 0xde, 0x82, 0x15, 0x72, 0x4d, 0xd8, 0x0c, 0x07, 0xea, 0xe6,
+ 0x44, 0xcd, 0x94, 0x73, 0x5c, 0x04, 0xe8, 0x8e, 0xb7, 0xc7, 0xc9, 0x29,
+ 0xdc, 0x04, 0xef, 0x7c, 0x31, 0x9b, 0x50, 0xbc, 0xea, 0x71, 0x1f, 0x28,
+ 0x22, 0xb6, 0x04, 0x53, 0x2e, 0x71, 0xc4, 0xf6, 0xbb, 0x88, 0x51, 0xee,
+ 0x3e, 0x76, 0x65, 0xb4, 0x4b, 0x1b, 0xa3, 0xec, 0x7b, 0xa7, 0x9d, 0x31,
+ 0x5d, 0xb8, 0x9f, 0xab, 0x6b, 0x54, 0x7d, 0xbd, 0xc1, 0x2c, 0x55, 0xb0,
+ 0x23, 0x8c, 0x06, 0x60, 0x01, 0x4f, 0x60, 0x85, 0x56, 0x7f, 0xfb, 0x99,
+ 0x0c, 0xdc, 0x8c, 0x09, 0x37, 0x46, 0x5b, 0x97, 0x5d, 0xe8, 0x31, 0x00,
+ 0x1b, 0x30, 0x9b, 0x02, 0x92, 0x29, 0xb5, 0x20, 0xce, 0x4b, 0x90, 0xfb,
+ 0x91, 0x07, 0x5a, 0xd3, 0xf5, 0xa0, 0xe6, 0x8f, 0xf8, 0x73, 0xc5, 0x4b,
+ 0xbb, 0xad, 0x2a, 0xeb, 0xa8, 0xb7, 0x68, 0x34, 0x36, 0x47, 0xd5, 0x4b,
+ 0x61, 0x89, 0x53, 0xe6, 0xb6, 0xb1, 0x07, 0xe4, 0x08, 0x2e, 0xed, 0x50,
+ 0xd4, 0x1e, 0xed, 0x7f, 0xbf, 0x35, 0x68, 0x04, 0x45, 0x72, 0x86, 0x71,
+ 0x15, 0x55, 0xdf, 0xe6, 0x30, 0xc0, 0x8b, 0x8a, 0xb0, 0x6c, 0xd0, 0x35,
+ 0x57, 0x8f, 0x04, 0x37, 0xbc, 0xe1, 0xb8, 0xbf, 0x27, 0x37, 0x3d, 0xd0,
+ 0xc8, 0x46, 0x67, 0x42, 0x51, 0x30, 0x82, 0x05, 0xbd, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0xae,
+ 0x04, 0x82, 0x05, 0xaa, 0x30, 0x82, 0x05, 0xa6, 0x30, 0x82, 0x05, 0xa2,
+ 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01,
+ 0x02, 0xa0, 0x82, 0x04, 0xee, 0x30, 0x82, 0x04, 0xea, 0x30, 0x1c, 0x06,
+ 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30,
+ 0x0e, 0x04, 0x08, 0x9f, 0xa4, 0x72, 0x2b, 0x6b, 0x0e, 0xcb, 0x9f, 0x02,
+ 0x02, 0x08, 0x00, 0x04, 0x82, 0x04, 0xc8, 0xe5, 0x35, 0xb9, 0x72, 0x28,
+ 0x20, 0x28, 0xad, 0xe3, 0x01, 0xd7, 0x0b, 0xe0, 0x4e, 0x36, 0xc3, 0x73,
+ 0x06, 0xd5, 0xf6, 0x75, 0x1a, 0x78, 0xb2, 0xd8, 0xf6, 0x5a, 0x85, 0x8e,
+ 0x50, 0xa3, 0x05, 0x49, 0x02, 0x2d, 0xf8, 0xa3, 0x2f, 0xe6, 0x02, 0x7a,
+ 0xd5, 0x0b, 0x1d, 0xf1, 0xd1, 0xe4, 0x16, 0xaa, 0x70, 0x2e, 0x34, 0xdb,
+ 0x56, 0xd9, 0x33, 0x94, 0x11, 0xaa, 0x60, 0xd4, 0xfa, 0x5b, 0xd1, 0xb3,
+ 0x2e, 0x86, 0x6a, 0x5a, 0x69, 0xdf, 0x11, 0x91, 0xb0, 0xca, 0x82, 0xff,
+ 0x63, 0xad, 0x6a, 0x0b, 0x90, 0xa6, 0xc7, 0x9b, 0xef, 0x9a, 0xf8, 0x96,
+ 0xec, 0xe4, 0xc4, 0xdf, 0x55, 0x4c, 0x12, 0x07, 0xab, 0x7c, 0x5c, 0x68,
+ 0x47, 0xf2, 0x92, 0xfb, 0x94, 0xab, 0xc3, 0x64, 0xd3, 0xfe, 0xb2, 0x16,
+ 0xb4, 0x78, 0x80, 0x52, 0xe9, 0x32, 0x39, 0x3b, 0x8d, 0x12, 0x91, 0x36,
+ 0xfd, 0xa1, 0x97, 0xc2, 0x0a, 0x4a, 0xf1, 0xb3, 0x8a, 0xe4, 0x01, 0xed,
+ 0x0a, 0xda, 0x2e, 0xa0, 0x38, 0xa9, 0x47, 0x3d, 0x3a, 0x64, 0x87, 0x06,
+ 0xc3, 0x83, 0x60, 0xaf, 0x84, 0xdb, 0x87, 0xff, 0x70, 0x61, 0x43, 0x7d,
+ 0x2d, 0x61, 0x9a, 0xf7, 0x0d, 0xca, 0x0c, 0x0f, 0xbe, 0x43, 0x5b, 0x99,
+ 0xe1, 0x90, 0x64, 0x1f, 0xa7, 0x1b, 0xa6, 0xa6, 0x5c, 0x13, 0x70, 0xa3,
+ 0xdb, 0xd7, 0xf0, 0xe8, 0x7a, 0xb0, 0xd1, 0x9b, 0x52, 0xa6, 0x4f, 0xd6,
+ 0xff, 0x54, 0x4d, 0xa6, 0x15, 0x05, 0x5c, 0xe9, 0x04, 0x6a, 0xc3, 0x49,
+ 0x12, 0x2f, 0x24, 0x03, 0xc3, 0x80, 0x06, 0xa6, 0x07, 0x8b, 0x96, 0xe7,
+ 0x39, 0x31, 0x6d, 0xd3, 0x1b, 0xa5, 0x45, 0x58, 0x04, 0xe7, 0x87, 0xdf,
+ 0x26, 0xfb, 0x1b, 0x9f, 0x92, 0x93, 0x32, 0x12, 0x9a, 0xc9, 0xe6, 0xcb,
+ 0x88, 0x14, 0x9f, 0x23, 0x0b, 0x52, 0xa2, 0xb8, 0x32, 0x6c, 0xa9, 0x33,
+ 0xa1, 0x17, 0xe8, 0x4a, 0xd4, 0x5c, 0x7d, 0xb3, 0xa3, 0x64, 0x86, 0x03,
+ 0x7c, 0x7c, 0x3f, 0x99, 0xdc, 0x21, 0x9f, 0x93, 0xc6, 0xb9, 0x1d, 0xe0,
+ 0x21, 0x79, 0x78, 0x35, 0xdc, 0x1e, 0x27, 0x3c, 0x73, 0x7f, 0x0f, 0xd6,
+ 0x4f, 0xde, 0xe9, 0xb4, 0xb7, 0xe3, 0xf5, 0x72, 0xce, 0x42, 0xf3, 0x91,
+ 0x5b, 0x84, 0xba, 0xbb, 0xae, 0xf0, 0x87, 0x0f, 0x50, 0xa4, 0x5e, 0x80,
+ 0x23, 0x57, 0x2b, 0xa0, 0xa3, 0xc3, 0x8a, 0x2f, 0xa8, 0x7a, 0x1a, 0x65,
+ 0x8f, 0x62, 0xf8, 0x3e, 0xe2, 0xcd, 0xbc, 0x63, 0x56, 0x8e, 0x77, 0xf3,
+ 0xf9, 0x69, 0x10, 0x57, 0xa8, 0xaf, 0x67, 0x2a, 0x9f, 0x7f, 0x7e, 0xeb,
+ 0x1d, 0x99, 0xa6, 0x67, 0xcd, 0x9e, 0x42, 0x2e, 0x5e, 0x4e, 0x61, 0x24,
+ 0xfa, 0xca, 0x2a, 0xeb, 0x62, 0x1f, 0xa3, 0x14, 0x0a, 0x06, 0x4b, 0x77,
+ 0x78, 0x77, 0x9b, 0xf1, 0x03, 0xcc, 0xb5, 0xfe, 0xfb, 0x7a, 0x77, 0xa6,
+ 0x82, 0x9f, 0xe5, 0xde, 0x9d, 0x0d, 0x4d, 0x37, 0xc6, 0x12, 0x73, 0x6d,
+ 0xea, 0xbb, 0x48, 0xf0, 0xd2, 0x81, 0xcc, 0x1a, 0x47, 0xfa, 0xa4, 0xd2,
+ 0xb2, 0x27, 0xa0, 0xfc, 0x30, 0x04, 0xdb, 0x05, 0xd3, 0x0b, 0xbc, 0x4d,
+ 0x7a, 0x99, 0xef, 0x7f, 0x26, 0x01, 0xd4, 0x07, 0x0b, 0x1e, 0x99, 0x06,
+ 0x3c, 0xde, 0x3d, 0x1c, 0x21, 0x82, 0x68, 0x46, 0x35, 0x38, 0x61, 0xea,
+ 0xd4, 0xc2, 0x65, 0x09, 0x39, 0x87, 0xb4, 0xd3, 0x5d, 0x3c, 0xa3, 0x79,
+ 0xe4, 0x01, 0x4e, 0xbf, 0x18, 0xba, 0x57, 0x3f, 0xdd, 0xea, 0x0a, 0x6b,
+ 0x99, 0xfb, 0x93, 0xfa, 0xab, 0xee, 0x08, 0xdf, 0x38, 0x23, 0xae, 0x8d,
+ 0xa8, 0x03, 0x13, 0xfe, 0x83, 0x88, 0xb0, 0xc2, 0xf9, 0x90, 0xa5, 0x1c,
+ 0x01, 0x6f, 0x71, 0x91, 0x42, 0x35, 0x81, 0x74, 0x71, 0x6c, 0xba, 0x86,
+ 0x48, 0xfe, 0x96, 0xd2, 0x88, 0x12, 0x36, 0x4e, 0xa6, 0x2f, 0xd1, 0xdb,
+ 0xfa, 0xbf, 0xdb, 0x84, 0x01, 0xfc, 0x7d, 0x7a, 0xac, 0x20, 0xae, 0xf5,
+ 0x95, 0xc9, 0xdc, 0x10, 0x5f, 0x4c, 0xae, 0x85, 0x01, 0x8b, 0xfe, 0x77,
+ 0x13, 0x01, 0xae, 0x39, 0x59, 0x7e, 0xbc, 0xfd, 0xc9, 0x42, 0xe4, 0x13,
+ 0x07, 0x3f, 0xa9, 0x74, 0xd9, 0xd5, 0xfc, 0xb9, 0x78, 0xbe, 0x97, 0xf5,
+ 0xe7, 0x36, 0x7f, 0xfa, 0x23, 0x30, 0xeb, 0xab, 0x92, 0xd3, 0xdc, 0x3f,
+ 0x7f, 0xc0, 0x77, 0x93, 0xf9, 0x88, 0xe3, 0x4e, 0x13, 0x53, 0x6d, 0x71,
+ 0x87, 0xe9, 0x24, 0x2b, 0xae, 0x26, 0xbf, 0x62, 0x51, 0x04, 0x42, 0xe1,
+ 0x13, 0x9d, 0xd8, 0x9f, 0x59, 0x87, 0x3f, 0xfc, 0x94, 0xff, 0xcf, 0x88,
+ 0x88, 0xe6, 0xeb, 0x6e, 0xc1, 0x96, 0x04, 0x27, 0xc8, 0xda, 0xfa, 0xe8,
+ 0x2e, 0xbb, 0x2c, 0x6e, 0xf4, 0xb4, 0x00, 0x7d, 0x8d, 0x3b, 0xef, 0x8b,
+ 0x18, 0xa9, 0x5f, 0x32, 0xa9, 0xf2, 0x3a, 0x7e, 0x65, 0x2d, 0x6e, 0x8d,
+ 0x75, 0x77, 0xf6, 0xa6, 0xd8, 0xf9, 0x6b, 0x51, 0xe6, 0x66, 0x52, 0x59,
+ 0x39, 0x97, 0x22, 0xda, 0xb2, 0xd6, 0x82, 0x5a, 0x6e, 0x61, 0x60, 0x16,
+ 0x48, 0x7b, 0xf1, 0xc3, 0x4d, 0x7f, 0x50, 0xfa, 0x4d, 0x58, 0x27, 0x30,
+ 0xc8, 0x96, 0xe0, 0x41, 0x4f, 0x6b, 0xeb, 0x88, 0xa2, 0x7a, 0xef, 0x8a,
+ 0x88, 0xc8, 0x50, 0x4b, 0x55, 0x66, 0xee, 0xbf, 0xc4, 0x01, 0x82, 0x4c,
+ 0xec, 0xde, 0x37, 0x64, 0xd6, 0x1e, 0xcf, 0x3e, 0x2e, 0xfe, 0x84, 0x68,
+ 0xbf, 0xa3, 0x68, 0x77, 0xa9, 0x03, 0xe4, 0xf8, 0xd7, 0xb2, 0x6e, 0xa3,
+ 0xc4, 0xc3, 0x36, 0x53, 0xf3, 0xdd, 0x7e, 0x4c, 0xf0, 0xe9, 0xb2, 0x44,
+ 0xe6, 0x60, 0x3d, 0x00, 0x9a, 0x08, 0xc3, 0x21, 0x17, 0x49, 0xda, 0x49,
+ 0xfb, 0x4c, 0x8b, 0xe9, 0x10, 0x66, 0xfe, 0xb7, 0xe0, 0xf9, 0xdd, 0xbf,
+ 0x41, 0xfe, 0x04, 0x9b, 0x7f, 0xe8, 0xd6, 0x2e, 0x4d, 0x0f, 0x7b, 0x10,
+ 0x73, 0x4c, 0xa1, 0x3e, 0x43, 0xb7, 0xcf, 0x94, 0x97, 0x7e, 0x24, 0xbb,
+ 0x87, 0xbf, 0x22, 0xb8, 0x3e, 0xeb, 0x9a, 0x3f, 0xe3, 0x86, 0xee, 0x21,
+ 0xbc, 0xf5, 0x44, 0xeb, 0x60, 0x2e, 0xe7, 0x8f, 0x89, 0xa4, 0x91, 0x61,
+ 0x28, 0x90, 0x85, 0x68, 0xe0, 0xa9, 0x62, 0x93, 0x86, 0x5a, 0x15, 0xbe,
+ 0xb2, 0x76, 0x83, 0xf2, 0x0f, 0x00, 0xc7, 0xb6, 0x57, 0xe9, 0x1f, 0x92,
+ 0x49, 0xfe, 0x50, 0x85, 0xbf, 0x39, 0x3d, 0xe4, 0x8b, 0x72, 0x2d, 0x49,
+ 0xbe, 0x05, 0x0a, 0x34, 0x56, 0x80, 0xc6, 0x1f, 0x46, 0x59, 0xc9, 0xfe,
+ 0x40, 0xfb, 0x78, 0x6d, 0x7a, 0xe5, 0x30, 0xe9, 0x81, 0x55, 0x75, 0x05,
+ 0x63, 0xd2, 0x22, 0xee, 0x2e, 0x6e, 0xb9, 0x18, 0xe5, 0x8a, 0x5a, 0x66,
+ 0xbd, 0x74, 0x30, 0xe3, 0x8b, 0x76, 0x22, 0x18, 0x1e, 0xef, 0x69, 0xe8,
+ 0x9d, 0x07, 0xa7, 0x9a, 0x87, 0x6c, 0x04, 0x4b, 0x74, 0x2b, 0xbe, 0x37,
+ 0x2f, 0x29, 0x9b, 0x60, 0x9d, 0x8b, 0x57, 0x55, 0x34, 0xca, 0x41, 0x25,
+ 0xae, 0x56, 0x92, 0x34, 0x1b, 0x9e, 0xbd, 0xfe, 0x74, 0xbd, 0x4e, 0x29,
+ 0xf0, 0x5e, 0x27, 0x94, 0xb0, 0x9e, 0x23, 0x9f, 0x4a, 0x0f, 0xa1, 0xdf,
+ 0xe7, 0xc4, 0xdb, 0xbe, 0x0f, 0x1a, 0x0b, 0x6c, 0xb0, 0xe1, 0x06, 0x7c,
+ 0x5a, 0x5b, 0x81, 0x1c, 0xb6, 0x12, 0xec, 0x6f, 0x3b, 0xbb, 0x84, 0x36,
+ 0xd5, 0x28, 0x16, 0xea, 0x51, 0xa8, 0x99, 0x24, 0x8f, 0xe7, 0xf8, 0xe9,
+ 0xce, 0xa1, 0x65, 0x96, 0x6f, 0x4e, 0x2f, 0xb7, 0x6f, 0x65, 0x39, 0xad,
+ 0xfd, 0x2e, 0xa0, 0x37, 0x32, 0x2f, 0xf3, 0x95, 0xa1, 0x3a, 0xa1, 0x9d,
+ 0x2c, 0x9e, 0xa1, 0x4b, 0x7e, 0xc9, 0x7e, 0x86, 0xaa, 0x16, 0x00, 0x82,
+ 0x1d, 0x36, 0xbf, 0x98, 0x0a, 0x82, 0x5b, 0xcc, 0xc4, 0x6a, 0xad, 0xa0,
+ 0x1f, 0x47, 0x98, 0xde, 0x8d, 0x68, 0x38, 0x3f, 0x33, 0xe2, 0x08, 0x3b,
+ 0x2a, 0x65, 0xd9, 0x2f, 0x53, 0x68, 0xb8, 0x78, 0xd0, 0x1d, 0xbb, 0x2a,
+ 0x73, 0x19, 0xba, 0x58, 0xea, 0xf1, 0x0a, 0xaa, 0xa6, 0xbe, 0x27, 0xd6,
+ 0x00, 0x6b, 0x4e, 0x43, 0x8e, 0x5b, 0x19, 0xc1, 0x37, 0x0f, 0xfb, 0x81,
+ 0x72, 0x10, 0xb6, 0x20, 0x32, 0xcd, 0xa2, 0x7c, 0x90, 0xd4, 0xf5, 0xcf,
+ 0x1c, 0xcb, 0x14, 0x24, 0x7a, 0x4d, 0xf5, 0xd5, 0xd9, 0xce, 0x6a, 0x64,
+ 0xc9, 0xd3, 0xa7, 0x36, 0x6f, 0x1d, 0xf1, 0xe9, 0x71, 0x6c, 0x3d, 0x02,
+ 0xa4, 0x62, 0xb1, 0x82, 0x5c, 0x13, 0x4b, 0x6b, 0x68, 0xe2, 0x31, 0xef,
+ 0xe4, 0x46, 0xfd, 0xe5, 0xa8, 0x29, 0xe9, 0x1e, 0xad, 0xff, 0x33, 0xdb,
+ 0x0b, 0xc0, 0x92, 0xb1, 0xef, 0xeb, 0xb3, 0x6f, 0x96, 0x7b, 0xdf, 0xcd,
+ 0x07, 0x19, 0x86, 0x60, 0x98, 0xcf, 0x95, 0xfe, 0x98, 0xdd, 0x29, 0xa6,
+ 0x35, 0x7b, 0x46, 0x13, 0x03, 0xa8, 0xd9, 0x7c, 0xb3, 0xdf, 0x9f, 0x14,
+ 0xb7, 0x34, 0x5a, 0xc4, 0x12, 0x81, 0xc5, 0x98, 0x25, 0x8d, 0x3e, 0xe3,
+ 0xd8, 0x2d, 0xe4, 0x54, 0xab, 0xb0, 0x13, 0xfd, 0xd1, 0x3f, 0x3b, 0xbf,
+ 0xa9, 0x45, 0x28, 0x8a, 0x2f, 0x9c, 0x1e, 0x2d, 0xe5, 0xab, 0x13, 0x95,
+ 0x97, 0xc3, 0x34, 0x37, 0x8d, 0x93, 0x66, 0x31, 0x81, 0xa0, 0x30, 0x23,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31,
+ 0x16, 0x04, 0x14, 0xa5, 0x23, 0x9b, 0x7e, 0xe6, 0x45, 0x71, 0xbf, 0x48,
+ 0xc6, 0x27, 0x3c, 0x96, 0x87, 0x63, 0xbd, 0x1f, 0xde, 0x72, 0x12, 0x30,
+ 0x79, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x11, 0x01,
+ 0x31, 0x6c, 0x1e, 0x6a, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72,
+ 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20,
+ 0x00, 0x45, 0x00, 0x6e, 0x00, 0x68, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63,
+ 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x52, 0x00, 0x53, 0x00, 0x41,
+ 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x41,
+ 0x00, 0x45, 0x00, 0x53, 0x00, 0x20, 0x00, 0x43, 0x00, 0x72, 0x00, 0x79,
+ 0x00, 0x70, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x67, 0x00, 0x72, 0x00, 0x61,
+ 0x00, 0x70, 0x00, 0x68, 0x00, 0x69, 0x00, 0x63, 0x00, 0x20, 0x00, 0x50,
+ 0x00, 0x72, 0x00, 0x6f, 0x00, 0x76, 0x00, 0x69, 0x00, 0x64, 0x00, 0x65,
+ 0x00, 0x72, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
+ 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x93, 0xa8, 0xb2, 0x7e, 0xb7,
+ 0xab, 0xf1, 0x1c, 0x3c, 0x36, 0x58, 0xdc, 0x67, 0x6d, 0x42, 0xa6, 0xfc,
+ 0x53, 0x01, 0xe6, 0x04, 0x08, 0x77, 0x57, 0x22, 0xa1, 0x7d, 0xb9, 0xa2,
+ 0x69, 0x02, 0x02, 0x08, 0x00
+};
+
+static void test_PFXImportCertStore(void)
+{
+ HCERTSTORE store;
+ CRYPT_DATA_BLOB pfx;
+ DWORD count;
+
+ SetLastError( 0xdeadbeef );
+ store = PFXImportCertStore( NULL, NULL, 0 );
+ ok( store == NULL, "got %p\n", store );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError() );
+
+ pfx.pbData = (BYTE *)pfxdata;
+ pfx.cbData = sizeof(pfxdata);
+ store = PFXImportCertStore( &pfx, NULL, CRYPT_EXPORTABLE|CRYPT_USER_KEYSET|PKCS12_NO_PERSIST_KEY );
+ ok( store != NULL || broken(store == NULL) /* winxp */, "got %p\n", store );
+ if (!store) return;
+ count = countCertsInStore( store );
+ ok( count == 1, "got %u\n", count );
+ CertCloseStore( store, 0 );
+}
+
START_TEST(store)
{
/* various combinations of CertOpenStore */
@@ -3068,4 +3331,5 @@ START_TEST(store)
testEmptyStore();
test_I_UpdateStore();
+ test_PFXImportCertStore();
}
diff --git a/include/wincrypt.h b/include/wincrypt.h
index a1b1305902..85c832850e 100644
--- a/include/wincrypt.h
+++ b/include/wincrypt.h
@@ -3969,8 +3969,16 @@ typedef BOOL (WINAPI *PFN_CMSG_IMPORT_KEY_TRANS)(
#define CMSG_ENCODE_HASHED_SUBJECT_IDENTIFIER_FLAG 0x2
/* PFXImportCertStore flags */
-#define CRYPT_USER_KEYSET 0x00001000
-#define PKCS12_IMPORT_RESERVED_MASK 0xffff0000
+#define CRYPT_USER_KEYSET 0x00001000
+#define PKCS12_IMPORT_SILENT 0x00000040
+#define PKCS12_PREFER_CNG_KSP 0x00000100
+#define PKCS12_ALWAYS_CNG_KSP 0x00000200
+#define PKCS12_ONLY_CERTIFICATES 0x00000400
+#define PKCS12_ONLY_NOT_ENCRYPTED_CERTIFICATES 0x00000800
+#define PKCS12_ALLOW_OVERWRITE_KEY 0x00004000
+#define PKCS12_NO_PERSIST_KEY 0x00008000
+#define PKCS12_VIRTUAL_ISOLATION_KEY 0x00010000
+#define PKCS12_IMPORT_RESERVED_MASK 0xffff0000
/* PFXExportCertStore flags */
#define REPORT_NO_PRIVATE_KEY 0x00000001
#define REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY 0x00000002
--
2.20.1
1
0
28 Jan '19
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
programs/wineboot/wineboot.c | 190 ++++++++++++++++++++++++++++-------
1 file changed, 151 insertions(+), 39 deletions(-)
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index 075b4c8b08..32e4225491 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -163,11 +163,112 @@ static DWORD set_reg_value( HKEY hkey, const WCHAR *name, const WCHAR *value )
return RegSetValueExW( hkey, name, 0, REG_SZ, (const BYTE *)value, (strlenW(value) + 1) * sizeof(WCHAR) );
}
+extern void do_cpuid( unsigned int ax, unsigned int *p );
+#if defined(_MSC_VER)
+void do_cpuid( unsigned int ax, unsigned int *p )
+{
+ __cpuid( p, ax );
+}
+#elif defined(__i386__)
+__ASM_GLOBAL_FUNC( do_cpuid,
+ "pushl %esi\n\t"
+ "pushl %ebx\n\t"
+ "movl 12(%esp),%eax\n\t"
+ "movl 16(%esp),%esi\n\t"
+ "cpuid\n\t"
+ "movl %eax,(%esi)\n\t"
+ "movl %ebx,4(%esi)\n\t"
+ "movl %ecx,8(%esi)\n\t"
+ "movl %edx,12(%esi)\n\t"
+ "popl %ebx\n\t"
+ "popl %esi\n\t"
+ "ret" )
+#elif defined(__x86_64__)
+__ASM_GLOBAL_FUNC( do_cpuid,
+ "pushq %rbx\n\t"
+ "movl %edi,%eax\n\t"
+ "cpuid\n\t"
+ "movl %eax,(%rsi)\n\t"
+ "movl %ebx,4(%rsi)\n\t"
+ "movl %ecx,8(%rsi)\n\t"
+ "movl %edx,12(%rsi)\n\t"
+ "popq %rbx\n\t"
+ "ret" )
+#else
+void do_cpuid( unsigned int ax, unsigned int *p )
+{
+ FIXME("\n");
+}
+#endif
+
+static void regs_to_str( unsigned int *regs, unsigned int len, WCHAR *buffer )
+{
+ unsigned int i;
+ unsigned char *p = (unsigned char *)regs;
+
+ for (i = 0; i < len; i++) { buffer[i] = *p++; }
+ buffer[i] = 0;
+}
+
+static unsigned int get_model( unsigned int reg0, unsigned int *stepping, unsigned int *family )
+{
+ unsigned int model, family_id = (reg0 & (0x0f << 8)) >> 8;
+
+ model = (reg0 & (0x0f << 4)) >> 4;
+ if (family_id == 6 || family_id == 15) model |= (reg0 & (0x0f << 16)) >> 12;
+
+ *family = family_id;
+ if (family_id == 15) *family += (reg0 & (0xff << 20)) >> 20;
+
+ *stepping = reg0 & 0x0f;
+ return model;
+}
+
+static void get_identifier( WCHAR *buf, const WCHAR *arch )
+{
+ static const WCHAR fmtW[] = {'%','s',' ','F','a','m','i','l','y',' ','%','u',' ','M','o','d','e','l',
+ ' ','%','u',' ','S','t','e','p','p','i','n','g',' ','%','u',0};
+ unsigned int regs[4] = {0, 0, 0, 0}, family, model, stepping;
+
+ do_cpuid( 1, regs );
+ model = get_model( regs[0], &stepping, &family );
+ sprintfW( buf, fmtW, arch, family, model, stepping );
+}
+
+static void get_vendorid( WCHAR *buf )
+{
+ unsigned int tmp, regs[4] = {0, 0, 0, 0};
+
+ do_cpuid( 0, regs );
+ tmp = regs[2]; /* swap edx and ecx */
+ regs[2] = regs[3];
+ regs[3] = tmp;
+
+ regs_to_str( regs + 1, 12, buf );
+}
+
+static void get_namestring( WCHAR *buf )
+{
+ unsigned int regs[4] = {0, 0, 0, 0};
+ int i;
+
+ do_cpuid( 0x80000000, regs );
+ if (regs[0] >= 0x80000004)
+ {
+ do_cpuid( 0x80000002, regs );
+ regs_to_str( regs, 16, buf );
+ do_cpuid( 0x80000003, regs );
+ regs_to_str( regs, 16, buf + 16 );
+ do_cpuid( 0x80000004, regs );
+ regs_to_str( regs, 16, buf + 32 );
+ }
+ for (i = strlenW(buf) - 1; i >= 0 && buf[i] == ' '; i--) buf[i] = 0;
+}
+
/* create the volatile hardware registry keys */
static void create_hardware_registry_keys(void)
{
- static const WCHAR SystemW[] = {'H','a','r','d','w','a','r','e','\\',
- 'D','e','s','c','r','i','p','t','i','o','n','\\',
+ static const WCHAR SystemW[] = {'H','a','r','d','w','a','r','e','\\','D','e','s','c','r','i','p','t','i','o','n','\\',
'S','y','s','t','e','m',0};
static const WCHAR fpuW[] = {'F','l','o','a','t','i','n','g','P','o','i','n','t','P','r','o','c','e','s','s','o','r',0};
static const WCHAR cpuW[] = {'C','e','n','t','r','a','l','P','r','o','c','e','s','s','o','r',0};
@@ -178,22 +279,22 @@ static void create_hardware_registry_keys(void)
static const WCHAR ARMSysidW[] = {'A','R','M',' ','p','r','o','c','e','s','s','o','r',' ','f','a','m','i','l','y',0};
static const WCHAR mhzKeyW[] = {'~','M','H','z',0};
static const WCHAR VendorIdentifierW[] = {'V','e','n','d','o','r','I','d','e','n','t','i','f','i','e','r',0};
- static const WCHAR VenidIntelW[] = {'G','e','n','u','i','n','e','I','n','t','e','l',0};
- /* static const WCHAR VenidAMDW[] = {'A','u','t','h','e','n','t','i','c','A','M','D',0}; */
static const WCHAR PercentDW[] = {'%','d',0};
- static const WCHAR IntelCpuDescrW[] = {'x','8','6',' ','F','a','m','i','l','y',' ','%','d',' ','M','o','d','e','l',' ','%','d',
- ' ','S','t','e','p','p','i','n','g',' ','%','d',0};
static const WCHAR ARMCpuDescrW[] = {'A','R','M',' ','F','a','m','i','l','y',' ','%','d',' ','M','o','d','e','l',' ','%','d',
- ' ','R','e','v','i','s','i','o','n',' ','%','d',0};
- static const WCHAR IntelCpuStringW[] = {'I','n','t','e','l','(','R',')',' ','P','e','n','t','i','u','m','(','R',')',' ','4',' ',
- 'C','P','U',' ','2','.','4','0','G','H','z',0};
+ ' ','R','e','v','i','s','i','o','n',' ','%','d',0};
+ static const WCHAR x86W[] = {'x','8','6',0};
+ static const WCHAR intel64W[] = {'I','n','t','e','l','6','4',0};
+ static const WCHAR amd64W[] = {'A','M','D','6','4',0};
+ static const WCHAR authenticamdW[] = {'A','u','t','h','e','n','t','i','c','A','M','D',0};
unsigned int i;
HKEY hkey, system_key, cpu_key, fpu_key;
SYSTEM_CPU_INFORMATION sci;
PROCESSOR_POWER_INFORMATION* power_info;
ULONG sizeof_power_info = sizeof(PROCESSOR_POWER_INFORMATION) * NtCurrentTeb()->Peb->NumberOfProcessors;
- WCHAR idW[60];
+ WCHAR id[60], namestr[49], vendorid[13];
+ get_namestring( namestr );
+ get_vendorid( vendorid );
NtQuerySystemInformation( SystemCpuInformation, &sci, sizeof(sci), NULL );
power_info = HeapAlloc( GetProcessHeap(), 0, sizeof_power_info );
@@ -202,16 +303,20 @@ static void create_hardware_registry_keys(void)
if (NtPowerInformation( ProcessorInformation, NULL, 0, power_info, sizeof_power_info ))
memset( power_info, 0, sizeof_power_info );
- /*TODO: report 64bit processors properly*/
- switch(sci.Architecture)
+ switch (sci.Architecture)
{
case PROCESSOR_ARCHITECTURE_ARM:
case PROCESSOR_ARCHITECTURE_ARM64:
- sprintfW( idW, ARMCpuDescrW, sci.Level, HIBYTE(sci.Revision), LOBYTE(sci.Revision) );
+ sprintfW( id, ARMCpuDescrW, sci.Level, HIBYTE(sci.Revision), LOBYTE(sci.Revision) );
break;
- default:
+
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ get_identifier( id, !strcmpW(vendorid, authenticamdW) ? amd64W : intel64W );
+ break;
+
case PROCESSOR_ARCHITECTURE_INTEL:
- sprintfW( idW, IntelCpuDescrW, sci.Level, HIBYTE(sci.Revision), LOBYTE(sci.Revision) );
+ default:
+ get_identifier( id, x86W );
break;
}
@@ -222,14 +327,16 @@ static void create_hardware_registry_keys(void)
return;
}
- switch(sci.Architecture)
+ switch (sci.Architecture)
{
case PROCESSOR_ARCHITECTURE_ARM:
case PROCESSOR_ARCHITECTURE_ARM64:
set_reg_value( system_key, IdentifierW, ARMSysidW );
break;
- default:
+
case PROCESSOR_ARCHITECTURE_INTEL:
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ default:
set_reg_value( system_key, IdentifierW, SysidW );
break;
}
@@ -252,10 +359,10 @@ static void create_hardware_registry_keys(void)
KEY_ALL_ACCESS, NULL, &hkey, NULL ))
{
RegSetValueExW( hkey, FeatureSetW, 0, REG_DWORD, (BYTE *)&sci.FeatureSet, sizeof(DWORD) );
- set_reg_value( hkey, IdentifierW, idW );
- /*TODO; report ARM and AMD properly*/
- set_reg_value( hkey, ProcessorNameStringW, IntelCpuStringW );
- set_reg_value( hkey, VendorIdentifierW, VenidIntelW );
+ set_reg_value( hkey, IdentifierW, id );
+ /* TODO: report ARM properly */
+ set_reg_value( hkey, ProcessorNameStringW, namestr );
+ set_reg_value( hkey, VendorIdentifierW, vendorid );
RegSetValueExW( hkey, mhzKeyW, 0, REG_DWORD, (BYTE *)&power_info[i].MaxMhz, sizeof(DWORD) );
RegCloseKey( hkey );
}
@@ -264,7 +371,7 @@ static void create_hardware_registry_keys(void)
!RegCreateKeyExW( fpu_key, numW, 0, NULL, REG_OPTION_VOLATILE,
KEY_ALL_ACCESS, NULL, &hkey, NULL ))
{
- set_reg_value( hkey, IdentifierW, idW );
+ set_reg_value( hkey, IdentifierW, id );
RegCloseKey( hkey );
}
}
@@ -301,50 +408,56 @@ static void create_environment_registry_keys( void )
static const WCHAR NumProcW[] = {'N','U','M','B','E','R','_','O','F','_','P','R','O','C','E','S','S','O','R','S',0};
static const WCHAR ProcArchW[] = {'P','R','O','C','E','S','S','O','R','_','A','R','C','H','I','T','E','C','T','U','R','E',0};
static const WCHAR x86W[] = {'x','8','6',0};
- static const WCHAR armW[] = {'A','R','M',0};
- static const WCHAR arm64W[] = {'A','R','M','6','4',0};
- static const WCHAR AMD64W[] = {'A','M','D','6','4',0};
+ static const WCHAR intel64W[] = {'I','n','t','e','l','6','4',0};
+ static const WCHAR amd64W[] = {'A','M','D','6','4',0};
+ static const WCHAR authenticamdW[] = {'A','u','t','h','e','n','t','i','c','A','M','D',0};
+ static const WCHAR commaW[] = {',',' ',0};
static const WCHAR ProcIdW[] = {'P','R','O','C','E','S','S','O','R','_','I','D','E','N','T','I','F','I','E','R',0};
static const WCHAR ProcLvlW[] = {'P','R','O','C','E','S','S','O','R','_','L','E','V','E','L',0};
static const WCHAR ProcRevW[] = {'P','R','O','C','E','S','S','O','R','_','R','E','V','I','S','I','O','N',0};
static const WCHAR PercentDW[] = {'%','d',0};
static const WCHAR Percent04XW[] = {'%','0','4','x',0};
- static const WCHAR IntelCpuDescrW[] = {'%','s',' ','F','a','m','i','l','y',' ','%','d',' ','M','o','d','e','l',' ','%','d',
- ' ','S','t','e','p','p','i','n','g',' ','%','d',',',' ','G','e','n','u','i','n','e','I','n','t','e','l',0};
static const WCHAR ARMCpuDescrW[] = {'A','R','M',' ','F','a','m','i','l','y',' ','%','d',' ','M','o','d','e','l',' ','%','d',
- ' ','R','e','v','i','s','i','o','n',' ','%','d',0};
-
+ ' ','R','e','v','i','s','i','o','n',' ','%','d',0};
HKEY env_key;
SYSTEM_CPU_INFORMATION sci;
- WCHAR buffer[60];
+ WCHAR buffer[60], vendorid[13];
const WCHAR *arch;
if (RegCreateKeyW( HKEY_LOCAL_MACHINE, EnvironW, &env_key )) return;
+ get_vendorid( vendorid );
NtQuerySystemInformation( SystemCpuInformation, &sci, sizeof(sci), NULL );
sprintfW( buffer, PercentDW, NtCurrentTeb()->Peb->NumberOfProcessors );
set_reg_value( env_key, NumProcW, buffer );
- switch(sci.Architecture)
+ switch (sci.Architecture)
{
- case PROCESSOR_ARCHITECTURE_AMD64: arch = AMD64W; break;
- case PROCESSOR_ARCHITECTURE_ARM: arch = armW; break;
- case PROCESSOR_ARCHITECTURE_ARM64: arch = arm64W; break;
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ arch = !strcmpW(vendorid, authenticamdW) ? amd64W : intel64W;
+ break;
+
+ case PROCESSOR_ARCHITECTURE_INTEL:
default:
- case PROCESSOR_ARCHITECTURE_INTEL: arch = x86W; break;
+ arch = x86W;
+ break;
}
set_reg_value( env_key, ProcArchW, arch );
- switch(sci.Architecture)
+ switch (sci.Architecture)
{
case PROCESSOR_ARCHITECTURE_ARM:
case PROCESSOR_ARCHITECTURE_ARM64:
sprintfW( buffer, ARMCpuDescrW, sci.Level, HIBYTE(sci.Revision), LOBYTE(sci.Revision) );
break;
- default:
+
+ case PROCESSOR_ARCHITECTURE_AMD64:
case PROCESSOR_ARCHITECTURE_INTEL:
- sprintfW( buffer, IntelCpuDescrW, arch, sci.Level, HIBYTE(sci.Revision), LOBYTE(sci.Revision) );
+ default:
+ get_identifier( buffer, arch );
+ strcatW( buffer, commaW );
+ strcatW( buffer, vendorid );
break;
}
set_reg_value( env_key, ProcIdW, buffer );
@@ -352,7 +465,6 @@ static void create_environment_registry_keys( void )
sprintfW( buffer, PercentDW, sci.Level );
set_reg_value( env_key, ProcLvlW, buffer );
- /* Properly report model/stepping */
sprintfW( buffer, Percent04XW, sci.Revision );
set_reg_value( env_key, ProcRevW, buffer );
--
2.20.1
1
0