From 2daca626d4ba4f0ba5a28ee02bf5c94ecce7282a Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 22 Dec 2014 20:01:29 +0100 Subject: [PATCH] ntdll: Implement [Nt|Zw]QueryLicenseValue. --- dlls/ntdll/ntdll.spec | 2 ++ dlls/ntdll/reg.c | 64 ++++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/tests/reg.c | 2 +- include/winternl.h | 1 + 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 9355d049a66..c3307b242d3 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -255,6 +255,7 @@ @ stub NtQueryIntervalProfile @ stdcall NtQueryIoCompletion(long long ptr long ptr) @ stdcall NtQueryKey (long long ptr long ptr) +@ stdcall NtQueryLicenseValue(ptr ptr ptr long ptr) @ stdcall NtQueryMultipleValueKey(long ptr long ptr long ptr) @ stdcall NtQueryMutant(long long ptr long ptr) @ stdcall NtQueryObject(long long long long long) @@ -1134,6 +1135,7 @@ @ stub ZwQueryIntervalProfile @ stdcall ZwQueryIoCompletion(long long ptr long ptr) NtQueryIoCompletion @ stdcall ZwQueryKey(long long ptr long ptr) NtQueryKey +@ stdcall ZwQueryLicenseValue(ptr ptr ptr long ptr) NtQueryLicenseValue @ stdcall ZwQueryMultipleValueKey(long ptr long ptr long ptr) NtQueryMultipleValueKey @ stdcall ZwQueryMutant(long long ptr long ptr) NtQueryMutant @ stdcall ZwQueryObject(long long long long long) NtQueryObject diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c index cdca88aee97..a104c2e9cb9 100644 --- a/dlls/ntdll/reg.c +++ b/dlls/ntdll/reg.c @@ -1401,3 +1401,67 @@ NTSTATUS WINAPI RtlWriteRegistryValue( ULONG RelativeTo, PCWSTR path, PCWSTR nam return status; } + +/************************************************************************* + * NtQueryLicenseValue [NTDLL.@] + * + * NOTES + * On Windows all license properties are stored in a single key, but + * unless there is some app which explicitly depends on that, there is + * no good reason to reproduce that. + */ +NTSTATUS WINAPI NtQueryLicenseValue( const UNICODE_STRING *name, ULONG *result_type, + PVOID data, ULONG length, ULONG *result_len ) +{ + static const WCHAR LicenseInformationW[] = {'M','a','c','h','i','n','e','\\', + 'S','o','f','t','w','a','r','e','\\', + 'W','i','n','e','\\','L','i','c','e','n','s','e', + 'I','n','f','o','r','m','a','t','i','o','n',0}; + KEY_VALUE_PARTIAL_INFORMATION *info; + NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND; + DWORD info_length, count; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING keyW; + HANDLE hkey; + + if (!name || !name->Buffer || !name->Length || !result_len) + return STATUS_INVALID_PARAMETER; + + info_length = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + length; + info = RtlAllocateHeap( GetProcessHeap(), 0, info_length ); + if (!info) return STATUS_NO_MEMORY; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &keyW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + RtlInitUnicodeString( &keyW, LicenseInformationW ); + + /* @@ Wine registry key: HKLM\Software\Wine\LicenseInformation */ + if (!NtOpenKey( &hkey, KEY_READ, &attr )) + { + status = NtQueryValueKey( hkey, name, KeyValuePartialInformation, + info, info_length, &count ); + if (!status || status == STATUS_BUFFER_OVERFLOW) + { + if (result_type) + *result_type = info->Type; + + *result_len = info->DataLength; + + if (status == STATUS_BUFFER_OVERFLOW) + status = STATUS_BUFFER_TOO_SMALL; + else + memcpy( data, info->Data, info->DataLength ); + } + NtClose( hkey ); + } + + if (status == STATUS_OBJECT_NAME_NOT_FOUND) + FIXME( "License key %s not found\n", debugstr_w(name->Buffer) ); + + RtlFreeHeap( GetProcessHeap(), 0, info ); + return status; +} diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 4628f16c9a0..691a6b72f29 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -661,7 +661,7 @@ static void test_NtQueryLicenseKey(void) if (!pNtQueryLicenseValue) { - skip("NtQueryLicenseValue not found, skipping tests\n"); + win_skip("NtQueryLicenseValue not found, skipping tests\n"); return; } diff --git a/include/winternl.h b/include/winternl.h index 39923092ee9..6dc8c7412b1 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2189,6 +2189,7 @@ NTSYSAPI NTSTATUS WINAPI NtQuerySystemTime(PLARGE_INTEGER); NTSYSAPI NTSTATUS WINAPI NtQueryTimer(HANDLE,TIMER_INFORMATION_CLASS,PVOID,ULONG,PULONG); NTSYSAPI NTSTATUS WINAPI NtQueryTimerResolution(PULONG,PULONG,PULONG); NTSYSAPI NTSTATUS WINAPI NtQueryValueKey(HANDLE,const UNICODE_STRING *,KEY_VALUE_INFORMATION_CLASS,void *,DWORD,DWORD *); +NTSYSAPI NTSTATUS WINAPI NtQueryLicenseValue(const UNICODE_STRING *,ULONG *,PVOID,ULONG,ULONG *); NTSYSAPI NTSTATUS WINAPI NtQueryVirtualMemory(HANDLE,LPCVOID,MEMORY_INFORMATION_CLASS,PVOID,SIZE_T,SIZE_T*); NTSYSAPI NTSTATUS WINAPI NtQueryVolumeInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS); NTSYSAPI NTSTATUS WINAPI NtRaiseException(PEXCEPTION_RECORD,PCONTEXT,BOOL);