APIs introduced in Windows 10 (NT10.0). DeviceForm and Family is fixed to Desktop configuration.
Signed-off-by: Kacper Raczy gfw.kra@gmail.com --- dlls/ntdll/ntdll.spec | 2 ++ dlls/ntdll/rtl.c | 2 +- dlls/ntdll/version.c | 54 ++++++++++++++++++++++++++++++++++++++++++- include/winnt.h | 10 ++++++++ 4 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index b1650ab4306..4539a9bd0ed 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -712,6 +712,8 @@ @ stdcall RtlGetCurrentProcessorNumberEx(ptr) @ stdcall RtlGetCurrentTransaction() @ stdcall RtlGetDaclSecurityDescriptor(ptr ptr ptr ptr) +@ stdcall RtlGetDeviceFamilyInfoEnum(ptr ptr ptr) +@ stdcall RtlConvertDeviceFamilyInfoToString(ptr ptr ptr ptr) @ stdcall RtlGetElementGenericTable(ptr long) # @ stub RtlGetElementGenericTableAvl @ stdcall RtlGetEnabledExtendedFeatures(int64) diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index 11067f44941..421cf377d32 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -2211,4 +2211,4 @@ char WINAPI RtlQueryProcessPlaceholderCompatibilityMode(void) { FIXME("stub\n"); return PHCM_APPLICATION_DEFAULT; -} +} \ No newline at end of file diff --git a/dlls/ntdll/version.c b/dlls/ntdll/version.c index 492c24cc636..b9af53452a2 100644 --- a/dlls/ntdll/version.c +++ b/dlls/ntdll/version.c @@ -609,7 +609,6 @@ void WINAPI RtlGetNtVersionNumbers( LPDWORD major, LPDWORD minor, LPDWORD build if (build) *build = (0xF0000000 | current_version->dwBuildNumber); }
- /****************************************************************************** * RtlGetNtProductType (NTDLL.@) */ @@ -760,6 +759,59 @@ NTSTATUS WINAPI RtlVerifyVersionInfo( const RTL_OSVERSIONINFOEXW *info, return STATUS_SUCCESS; }
+/********************************************************************* + * RtlGetDeviceFamilyInfoEnum (NTDLL.@) + * + * NOTES + * Introduced in Windows 10 (NT10.0) + */ +VOID WINAPI RtlGetDeviceFamilyInfoEnum(ULONGLONG *uap_info, DWORD *device_family, DWORD *device_form) +{ + ULONGLONG uap_info_temp; + + if (device_form != NULL) + *device_form = DEVICEFAMILYDEVICEFORM_DESKTOP; + if (device_family != NULL) + *device_family = DEVICEFAMILYINFOENUM_DESKTOP; + if (uap_info == NULL) + 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. UBR + */ + uap_info_temp = 0; + uap_info_temp |= (((ULONGLONG) current_version->dwMajorVersion & 0xffff) << 48); /* os version major */ + uap_info_temp |= (((ULONGLONG) current_version->dwMinorVersion & 0xffff) << 32); /* os version minor */ + uap_info_temp |= (((ULONGLONG) current_version->dwBuildNumber & 0xffff) << 16); /* current build number */ + /* UBR not available */ + *uap_info = uap_info_temp; +} + +/********************************************************************* + * RtlConvertDeviceFamilyInfoToString (NTDLL.@) + * + * NOTES + * Introduced in Windows 10 (NT10.0) + */ +VOID WINAPI RtlConvertDeviceFamilyInfoToString( + DWORD *device_family_bufsize, + DWORD *device_form_bufsize, + const LPWSTR device_family, + const LPWSTR device_form +) { + if (device_family_bufsize != NULL) + *device_family_bufsize = (DWORD)wcslen(DEVICEFAMILYDEVICEFORM_DESKTOP_STR) + 1; + if (device_family != NULL) + wcscpy(device_family, DEVICEFAMILYDEVICEFORM_DESKTOP_STR); + if (device_form_bufsize != NULL) + *device_form_bufsize = (DWORD)wcslen(DEVICEFAMILYINFOENUM_DESKTOP_STR) + 1; + if (device_form != NULL) + wcscpy(device_form, DEVICEFAMILYINFOENUM_DESKTOP_STR); +}
/****************************************************************************** * VerSetConditionMask (NTDLL.@) diff --git a/include/winnt.h b/include/winnt.h index 87c4b4da92d..b07df911c69 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -6224,6 +6224,16 @@ typedef struct _SYSTEM_CPU_SET_INFORMATION } DUMMYUNIONNAME; } SYSTEM_CPU_SET_INFORMATION, *PSYSTEM_CPU_SET_INFORMATION;
+/* Windows 10 Rtl apis */ + +#define DEVICEFAMILYDEVICEFORM_DESKTOP 0x00000003 +#define DEVICEFAMILYINFOENUM_DESKTOP 0x00000003 +#define DEVICEFAMILYDEVICEFORM_DESKTOP_STR L"Desktop" +#define DEVICEFAMILYINFOENUM_DESKTOP_STR L"Windows.Desktop" + +NTSYSAPI VOID WINAPI RtlGetDeviceFamilyInfoEnum(ULONGLONG*, DWORD*, DWORD*); +NTSYSAPI VOID WINAPI RtlConvertDeviceFamilyInfoToString(DWORD*, DWORD*, const LPWSTR, const LPWSTR); + /* Threadpool things */ typedef DWORD TP_VERSION,*PTP_VERSION;
Hi, thanks for the patch!
This could use a test which includes checks for return data. Without that it is hard to say if the patch is correct. Version data is not constant of course but it could be checked if it matches RtlGetVersion(). A few thoughts regarding on some possible improvements to the patch regardless (once there is a test which verifies it general correctness):
On 6/22/22 08:49, Kacper Raczy wrote:
+/*********************************************************************
- RtlGetDeviceFamilyInfoEnum (NTDLL.@)
- NOTES
- Introduced in Windows 10 (NT10.0)
- */
+VOID WINAPI RtlGetDeviceFamilyInfoEnum(ULONGLONG *uap_info, DWORD *device_family, DWORD *device_form)
I think we currently prefer 'void' over 'VOID' and such.
Formatting: spaces around function arguments (see, e. g., RtlVerifyVersionInfo above).
+{
- ULONGLONG uap_info_temp;
Do you really need this temporary variable, any reason not to use *uap_info directly?
- if (device_form != NULL)
We usually check such just as 'if (device_form) ...'
- uap_info_temp |= (((ULONGLONG) current_version->dwMajorVersion & 0xffff) << 48); /* os version major */
Space after (ULONGLONG)
- uap_info_temp |= (((ULONGLONG) current_version->dwMinorVersion & 0xffff) << 32); /* os version minor */
- uap_info_temp |= (((ULONGLONG) current_version->dwBuildNumber & 0xffff) << 16); /* current build number */
- /* UBR not available */
- *uap_info = uap_info_temp;
+}
+/*********************************************************************
- RtlConvertDeviceFamilyInfoToString (NTDLL.@)
- NOTES
- Introduced in Windows 10 (NT10.0)
- */
+VOID WINAPI RtlConvertDeviceFamilyInfoToString(
- DWORD *device_family_bufsize,
- DWORD *device_form_bufsize,
- const LPWSTR device_family,
- const LPWSTR device_form
Parameters formatting. Also I think we currently prefer const WCHAR * over LPWSTR.
+) {
- if (device_family_bufsize != NULL)
*device_family_bufsize = (DWORD)wcslen(DEVICEFAMILYDEVICEFORM_DESKTOP_STR) + 1;
- if (device_family != NULL)
wcscpy(device_family, DEVICEFAMILYDEVICEFORM_DESKTOP_STR);
This looks suspicious. Does Windows really only sets buffer size but does not check it before copying the output? Also, not apparent without the test if bufsize is wide character count or buffer size in bytes.
Formatting; " wcscpy(device_family, DEVICEFAMILYDEVICEFORM_DESKTOP_STR);" -> " wcscpy( device_family, DEVICEFAMILYDEVICEFORM_DESKTOP_STR );"
- if (device_form_bufsize != NULL)
*device_form_bufsize = (DWORD)wcslen(DEVICEFAMILYINFOENUM_DESKTOP_STR) + 1;
(DWORD) cast is not needed
Thanks for the feedback. Will add some unit tests later today.
As for RtlConvertDeviceFamilyInfoToString you’re right, size should be in bytes and on Windows it copies the output only if provided buffer sizes are sufficient. Otherwise only buffer sizes are assigned.
Wiadomość napisana przez Paul Gofman pgofman@codeweavers.com w dniu 22.06.2022, o godz. 16:16:
Hi, thanks for the patch!
This could use a test which includes checks for return data. Without that it is hard to say if the patch is correct. Version data is not constant of course but it could be checked if it matches RtlGetVersion(). A few thoughts regarding on some possible improvements to the patch regardless (once there is a test which verifies it general correctness):
On 6/22/22 08:49, Kacper Raczy wrote:
+/*********************************************************************
- RtlGetDeviceFamilyInfoEnum (NTDLL.@)
- NOTES
- Introduced in Windows 10 (NT10.0)
- */
+VOID WINAPI RtlGetDeviceFamilyInfoEnum(ULONGLONG *uap_info, DWORD *device_family, DWORD *device_form)
I think we currently prefer 'void' over 'VOID' and such.
Formatting: spaces around function arguments (see, e. g., RtlVerifyVersionInfo above).
+{
- ULONGLONG uap_info_temp;
Do you really need this temporary variable, any reason not to use *uap_info directly?
- if (device_form != NULL)
We usually check such just as 'if (device_form) ...'
- uap_info_temp |= (((ULONGLONG) current_version->dwMajorVersion & 0xffff) << 48); /* os version major */
Space after (ULONGLONG)
- uap_info_temp |= (((ULONGLONG) current_version->dwMinorVersion & 0xffff) << 32); /* os version minor */
- uap_info_temp |= (((ULONGLONG) current_version->dwBuildNumber & 0xffff) << 16); /* current build number */
- /* UBR not available */
- *uap_info = uap_info_temp;
+}
+/*********************************************************************
- RtlConvertDeviceFamilyInfoToString (NTDLL.@)
- NOTES
- Introduced in Windows 10 (NT10.0)
- */
+VOID WINAPI RtlConvertDeviceFamilyInfoToString(
- DWORD *device_family_bufsize,
- DWORD *device_form_bufsize,
- const LPWSTR device_family,
- const LPWSTR device_form
Parameters formatting. Also I think we currently prefer const WCHAR * over LPWSTR.
+) {
- if (device_family_bufsize != NULL)
*device_family_bufsize = (DWORD)wcslen(DEVICEFAMILYDEVICEFORM_DESKTOP_STR) + 1;
- if (device_family != NULL)
wcscpy(device_family, DEVICEFAMILYDEVICEFORM_DESKTOP_STR);
This looks suspicious. Does Windows really only sets buffer size but does not check it before copying the output? Also, not apparent without the test if bufsize is wide character count or buffer size in bytes.
Formatting; " wcscpy(device_family, DEVICEFAMILYDEVICEFORM_DESKTOP_STR);" -> " wcscpy( device_family, DEVICEFAMILYDEVICEFORM_DESKTOP_STR );"
- if (device_form_bufsize != NULL)
*device_form_bufsize = (DWORD)wcslen(DEVICEFAMILYINFOENUM_DESKTOP_STR) + 1;
(DWORD) cast is not needed