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@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;