* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/misc.c
* PURPOSE: Various functions
*
* PROGRAMMERS:
*/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
extern ULONG NtGlobalFlag;
extern ULONG NtMajorVersion;
extern ULONG NtMinorVersion;
extern ULONG NtOSCSDVersion;
#define PRODUCT_TAG 'iPtR'
* @implemented
*/
ULONG
NTAPI
RtlGetNtGlobalFlags(VOID)
{
return NtGlobalFlag;
}
* @implemented
*/
NTSTATUS
NTAPI
RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
{
PAGED_CODE();
lpVersionInformation->dwMajorVersion = NtMajorVersion;
lpVersionInformation->dwMinorVersion = NtMinorVersion;
lpVersionInformation->dwBuildNumber = NtBuildNumber & 0x3FFF;
lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
if (lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW))
{
PRTL_OSVERSIONINFOEXW InfoEx = (PRTL_OSVERSIONINFOEXW)lpVersionInformation;
InfoEx->wServicePackMajor = (USHORT)(CmNtCSDVersion >> 8) & 0xFF;
InfoEx->wServicePackMinor = (USHORT)(CmNtCSDVersion & 0xFF);
InfoEx->wSuiteMask = (USHORT)(SharedUserData->SuiteMask & 0xFFFF);
InfoEx->wProductType = SharedUserData->NtProductType;
InfoEx->wReserved = 0;
}
return STATUS_SUCCESS;
}
* @brief
* Retrieves the NT type product of the operating system. This is the kernel-mode variant
* of this function.
*
* @param[out] ProductType
* The NT type product enumeration value returned by the call.
*
* @return
* The function returns TRUE when the call successfully returned the type product of the system.
* It'll return FALSE on failure otherwise. In the latter case the function will return WinNT
* as the default product type.
*
* @remarks
* The call expects to be called at PASSIVE_LEVEL. The function firstly checks if the product type is
* actually valid by checking the "ProductTypeIsValid" member of _KUSER_SHARED_DATA structure.
* Currently we do not implement code that is responsible for the management of this member, yet.
*
*/
BOOLEAN
NTAPI
RtlGetNtProductType(OUT PNT_PRODUCT_TYPE ProductType)
{
HANDLE Key;
BOOLEAN Success;
ULONG ReturnedLength;
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
PKEY_VALUE_PARTIAL_INFORMATION BufferKey;
ULONG BufferKeyLength = sizeof(PKEY_VALUE_PARTIAL_INFORMATION) + (256 * sizeof(WCHAR));
UNICODE_STRING NtProductType;
static UNICODE_STRING WorkstationProduct = RTL_CONSTANT_STRING(L"WinNT");
static UNICODE_STRING LanManProduct = RTL_CONSTANT_STRING(L"LanmanNT");
static UNICODE_STRING ServerProduct = RTL_CONSTANT_STRING(L"ServerNT");
static UNICODE_STRING KeyProduct = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions");
static UNICODE_STRING ValueNtProduct = RTL_CONSTANT_STRING(L"ProductType");
PAGED_CODE();
BufferKey = ExAllocatePoolWithTag(PagedPool, BufferKeyLength, PRODUCT_TAG);
if (!BufferKey)
{
DPRINT1("RtlGetNtProductType(): Memory pool allocation has failed!\n");
Success = FALSE;
goto Exit;
}
InitializeObjectAttributes(&ObjectAttributes,
&KeyProduct,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
Status = ZwOpenKey(&Key, KEY_QUERY_VALUE, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlGetNtProductType(): The ZwOpenKey() function has failed! (Status: 0x%lx)\n", Status);
Success = FALSE;
goto Exit;
}
Status = ZwQueryValueKey(Key,
&ValueNtProduct,
KeyValuePartialInformation,
BufferKey,
BufferKeyLength,
&ReturnedLength);
ZwClose(Key);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlGetNtProductType(): The ZwQueryValueKey() function has failed! (Status: 0x%lx)\n", Status);
Success = FALSE;
goto Exit;
}
* Do a sanity check before we get the product type of the operating system
* so that we're sure the type of the value we've got is actually correct.
*/
if (BufferKey->Type != REG_SZ)
{
DPRINT1("RtlGetNtProductType(): An invalid value type has been found!\n");
Success = FALSE;
goto Exit;
}
NtProductType.Length = NtProductType.MaximumLength = BufferKey->DataLength;
NtProductType.Buffer = (PWCHAR)BufferKey->Data;
if (NtProductType.Length > sizeof(WCHAR) && NtProductType.Buffer[NtProductType.Length /
sizeof(WCHAR) - 1] == UNICODE_NULL)
{
NtProductType.Length -= sizeof(WCHAR);
}
if (RtlCompareUnicodeString(&NtProductType, &WorkstationProduct, TRUE) == 0)
{
*ProductType = NtProductWinNt;
Success = TRUE;
}
else if (RtlCompareUnicodeString(&NtProductType, &LanManProduct, TRUE) == 0)
{
*ProductType = NtProductLanManNt;
Success = TRUE;
}
else if (RtlCompareUnicodeString(&NtProductType, &ServerProduct, TRUE) == 0)
{
*ProductType = NtProductServer;
Success = TRUE;
}
else
{
DPRINT1("RtlGetNtProductType(): Couldn't find a valid product type! Defaulting to WinNT...\n");
Success = FALSE;
goto Exit;
}
Exit:
if (!Success)
{
*ProductType = NtProductWinNt;
}
ExFreePoolWithTag(BufferKey, PRODUCT_TAG);
return Success;
}
#if !defined(_M_IX86)
VOID
FASTCALL
RtlPrefetchMemoryNonTemporal(IN PVOID Source,
IN SIZE_T Length)
{
UNREFERENCED_PARAMETER(Source);
UNREFERENCED_PARAMETER(Length);
}
#endif
VOID NTAPI
AVrfInternalHeapFreeNotification(PVOID AllocationBase, SIZE_T AllocationSize)
{
}