APIs introduced in Windows 10 (NT10.0).
Device form and family are hardcoded to Unknown and Windows.Desktop respectively.
Unit tests included in dlls/ntdll/tests/env.c
Signed-off-by: Kacper RÄ…czy <gfw.kra(a)gmail.com>
---
dlls/ntdll/ntdll.spec | 2 ++
dlls/ntdll/tests/env.c | 61 ++++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/version.c | 49 +++++++++++++++++++++++++++++++++
include/winnt.h | 9 +++++++
4 files changed, 121 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 1862358e593..00dae98b9ad 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -530,6 +530,7 @@
# @ stub RtlComputeImportTableHash
# @ stub RtlComputePrivatizedDllName_U
@ stub RtlConsoleMultiByteToUnicodeN
+@ stdcall RtlConvertDeviceFamilyInfoToString(ptr ptr ptr ptr)
@ stub RtlConvertExclusiveToShared
@ stdcall -arch=win32 -ret64 RtlConvertLongToLargeInteger(long)
# @ stub RtlConvertPropertyToVariant
@@ -712,6 +713,7 @@
@ stdcall RtlGetCurrentProcessorNumberEx(ptr)
@ stdcall RtlGetCurrentTransaction()
@ stdcall RtlGetDaclSecurityDescriptor(ptr ptr ptr ptr)
+@ stdcall RtlGetDeviceFamilyInfoEnum(ptr ptr ptr)
@ stdcall RtlGetElementGenericTable(ptr long)
# @ stub RtlGetElementGenericTableAvl
@ stdcall RtlGetEnabledExtendedFeatures(int64)
diff --git a/dlls/ntdll/tests/env.c b/dlls/ntdll/tests/env.c
index e998880f03b..050320d0182 100644
--- a/dlls/ntdll/tests/env.c
+++ b/dlls/ntdll/tests/env.c
@@ -654,6 +654,65 @@ static void test_RtlSetEnvironmentVariable(void)
ok(!status, "got %#lx\n", status);
}
+static void test_RtlGetDeviceFamilyInfoEnum(void)
+{
+ DWORD family, form;
+ ULONGLONG uap;
+ RTL_OSVERSIONINFOEXW version;
+
+ RtlGetVersion(&version);
+ RtlGetDeviceFamilyInfoEnum(&uap, &family, &form);
+ ok( ((uap >> 48) & 0xffff) == version.dwMajorVersion,
+ "First 16-bit chunk of UAP does not match major system version %llx\n", uap );
+ ok( ((uap >> 32) & 0xffff) == version.dwMinorVersion,
+ "Second 16-bit chunk of UAP does not match minor system version %llx\n", uap );
+ ok( ((uap >> 16) & 0xffff) == version.dwBuildNumber,
+ "Third 16-bit chunk of UAP does not match build number %llx\n", uap );
+ ok( family <= DEVICEFAMILYINFOENUM_MAX,
+ "Device family is not valid: %lx\n", family );
+ ok( form <= DEVICEFAMILYDEVICEFORM_MAX,
+ "Device form is not valid: %lx\n", form );
+}
+
+static void test_RtlConvertDeviceFamilyInfoToString(void)
+{
+ static const WCHAR *DeviceForms[] = {
+ L"Unknown", L"Phone", L"Tablet", L"Desktop", L"Notebook",
+ L"Convertible", L"Detachable", L"All-in-One", L"Stick PC", L"Puck",
+ L"Surface Hub", L"Head-mounted display", L"Industry handheld", L"Industry tablet", L"Banking",
+ L"Building automation", L"Digital signage", L"Gaming", L"Home automation", L"Industrial automation",
+ L"Kiosk", L"Maker board", L"Medical", L"Networking", L"Point of Service",
+ L"Printing", L"Thin client", L"Toy", L"Vending", L"Industry other"
+ };
+
+ DWORD family_bufsize = 0, form_bufsize = 0;
+ WCHAR *family, *form;
+ BOOL form_valid = FALSE;
+
+ RtlConvertDeviceFamilyInfoToString(&family_bufsize, &form_bufsize, NULL, NULL);
+ ok( family_bufsize == sizeof( L"Windows.Desktop" ),
+ "Device family bufsize does not match: %lu\n", family_bufsize );
+ ok( form_bufsize > 0, "Device form bufsize is invalid: %lu\n", form_bufsize );
+
+ family = malloc(family_bufsize);
+ form = malloc(form_bufsize);
+ RtlConvertDeviceFamilyInfoToString(&family_bufsize, &form_bufsize, family, form);
+ ok( wcscmp(family, L"Windows.Desktop") == 0,
+ "Device family string is not equal to Windows.Desktop: %ls\n", family );
+ /* Device form depends on OEM setting in registry,
+ * lets check all possible values to make it work on Windows */
+ for (int i = 0; i < sizeof(DeviceForms) / sizeof(WCHAR*); i++) {
+ if (wcscmp(form, DeviceForms[i]) == 0) {
+ form_valid = TRUE;
+ break;
+ }
+ }
+ ok( form_valid, "Device form string is not valid or known: %ls\n", form);
+
+ free(family);
+ free(form);
+}
+
START_TEST(env)
{
HMODULE mod = GetModuleHandleA("ntdll.dll");
@@ -672,4 +731,6 @@ START_TEST(env)
test_process_params();
test_RtlSetCurrentEnvironment();
test_RtlSetEnvironmentVariable();
+ test_RtlGetDeviceFamilyInfoEnum();
+ test_RtlConvertDeviceFamilyInfoToString();
}
diff --git a/dlls/ntdll/version.c b/dlls/ntdll/version.c
index b9eabb31154..885258f00f2 100644
--- a/dlls/ntdll/version.c
+++ b/dlls/ntdll/version.c
@@ -761,6 +761,55 @@ NTSTATUS WINAPI RtlVerifyVersionInfo( const RTL_OSVERSIONINFOEXW *info,
}
+/*********************************************************************
+ * RtlGetDeviceFamilyInfoEnum (NTDLL.@)
+ */
+void WINAPI RtlGetDeviceFamilyInfoEnum( ULONGLONG *uap_info, DWORD *device_family, DWORD *device_form )
+{
+ TRACE("(%p,%p,%p)\n", uap_info, device_family, device_form);
+
+ if (device_form)
+ *device_form = DEVICEFAMILYDEVICEFORM_UNKNOWN;
+ if (device_family)
+ *device_family = DEVICEFAMILYINFOENUM_DESKTOP;
+ if (!uap_info)
+ return;
+
+ /**
+ * UAP info is 64 bit unsigned integer which contains four 16-bit chunks:
+ * 1. os version major
+ * 2. os version minor
+ * 3. current build number
+ * 4. update build revision
+ */
+ *uap_info = 0;
+ *uap_info |= (((ULONGLONG)current_version->dwMajorVersion & 0xffff) << 48);
+ *uap_info |= (((ULONGLONG)current_version->dwMinorVersion & 0xffff) << 32);
+ *uap_info |= (((ULONGLONG)current_version->dwBuildNumber & 0xffff) << 16);
+ /* UBR not available */
+}
+
+
+/*********************************************************************
+ * RtlConvertDeviceFamilyInfoToString (NTDLL.@)
+ */
+void WINAPI RtlConvertDeviceFamilyInfoToString( DWORD *device_family_bufsize, DWORD *device_form_bufsize,
+ WCHAR *device_family, WCHAR *device_form )
+{
+ static const DWORD device_family_len = sizeof( L"Windows.Desktop" );
+ static const DWORD device_form_len = sizeof( L"Unknown" );
+
+ TRACE("(%p,%p,%p,%p)\n", device_family_bufsize, device_form_bufsize, device_family, device_form);
+
+ if (*device_family_bufsize >= device_family_len)
+ wcscpy( device_family, L"Windows.Desktop" );
+ if (*device_form_bufsize >= device_form_len)
+ wcscpy( device_form, L"Unknown" );
+ *device_family_bufsize = device_family_len;
+ *device_form_bufsize = device_form_len;
+}
+
+
/******************************************************************************
* VerSetConditionMask (NTDLL.@)
*/
diff --git a/include/winnt.h b/include/winnt.h
index 50f6452b145..c2945f31925 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -6224,6 +6224,15 @@ typedef struct _SYSTEM_CPU_SET_INFORMATION
} DUMMYUNIONNAME;
} SYSTEM_CPU_SET_INFORMATION, *PSYSTEM_CPU_SET_INFORMATION;
+#define DEVICEFAMILYINFOENUM_DESKTOP 0x00000003
+#define DEVICEFAMILYINFOENUM_MAX 0x00000011
+
+#define DEVICEFAMILYDEVICEFORM_UNKNOWN 0x00000000
+#define DEVICEFAMILYDEVICEFORM_MAX 0x00000021
+
+NTSYSAPI VOID WINAPI RtlGetDeviceFamilyInfoEnum(ULONGLONG*, DWORD*, DWORD*);
+NTSYSAPI VOID WINAPI RtlConvertDeviceFamilyInfoToString(DWORD*, DWORD*, WCHAR*, WCHAR*);
+
/* Threadpool things */
typedef DWORD TP_VERSION,*PTP_VERSION;
--
2.37.0