Reactos
at master 233 lines 7.3 kB view raw
1/* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: ntoskrnl/rtl/misc.c 5 * PURPOSE: Various functions 6 * 7 * PROGRAMMERS: 8 */ 9 10/* INCLUDES *****************************************************************/ 11 12#include <ntoskrnl.h> 13#define NDEBUG 14#include <debug.h> 15 16/* GLOBALS *******************************************************************/ 17 18extern ULONG NtGlobalFlag; 19extern ULONG NtMajorVersion; 20extern ULONG NtMinorVersion; 21extern ULONG NtOSCSDVersion; 22#define PRODUCT_TAG 'iPtR' 23 24/* FUNCTIONS *****************************************************************/ 25 26/* 27* @implemented 28*/ 29ULONG 30NTAPI 31RtlGetNtGlobalFlags(VOID) 32{ 33 return NtGlobalFlag; 34} 35 36/* 37 * @implemented 38 */ 39NTSTATUS 40NTAPI 41RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation) 42{ 43 PAGED_CODE(); 44 45 /* Return the basics */ 46 lpVersionInformation->dwMajorVersion = NtMajorVersion; 47 lpVersionInformation->dwMinorVersion = NtMinorVersion; 48 lpVersionInformation->dwBuildNumber = NtBuildNumber & 0x3FFF; 49 lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT; 50 51 /* Check if this is the extended version */ 52 if (lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW)) 53 { 54 PRTL_OSVERSIONINFOEXW InfoEx = (PRTL_OSVERSIONINFOEXW)lpVersionInformation; 55 InfoEx->wServicePackMajor = (USHORT)(CmNtCSDVersion >> 8) & 0xFF; 56 InfoEx->wServicePackMinor = (USHORT)(CmNtCSDVersion & 0xFF); 57 InfoEx->wSuiteMask = (USHORT)(SharedUserData->SuiteMask & 0xFFFF); 58 InfoEx->wProductType = SharedUserData->NtProductType; 59 InfoEx->wReserved = 0; 60 } 61 62 /* Always succeed */ 63 return STATUS_SUCCESS; 64} 65 66/** 67 * @brief 68 * Retrieves the NT type product of the operating system. This is the kernel-mode variant 69 * of this function. 70 * 71 * @param[out] ProductType 72 * The NT type product enumeration value returned by the call. 73 * 74 * @return 75 * The function returns TRUE when the call successfully returned the type product of the system. 76 * It'll return FALSE on failure otherwise. In the latter case the function will return WinNT 77 * as the default product type. 78 * 79 * @remarks 80 * The call expects to be called at PASSIVE_LEVEL. The function firstly checks if the product type is 81 * actually valid by checking the "ProductTypeIsValid" member of _KUSER_SHARED_DATA structure. 82 * Currently we do not implement code that is responsible for the management of this member, yet. 83 * 84 */ 85BOOLEAN 86NTAPI 87RtlGetNtProductType(OUT PNT_PRODUCT_TYPE ProductType) 88{ 89 HANDLE Key; 90 BOOLEAN Success; 91 ULONG ReturnedLength; 92 OBJECT_ATTRIBUTES ObjectAttributes; 93 NTSTATUS Status; 94 PKEY_VALUE_PARTIAL_INFORMATION BufferKey; 95 ULONG BufferKeyLength = sizeof(PKEY_VALUE_PARTIAL_INFORMATION) + (256 * sizeof(WCHAR)); 96 UNICODE_STRING NtProductType; 97 static UNICODE_STRING WorkstationProduct = RTL_CONSTANT_STRING(L"WinNT"); 98 static UNICODE_STRING LanManProduct = RTL_CONSTANT_STRING(L"LanmanNT"); 99 static UNICODE_STRING ServerProduct = RTL_CONSTANT_STRING(L"ServerNT"); 100 static UNICODE_STRING KeyProduct = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions"); 101 static UNICODE_STRING ValueNtProduct = RTL_CONSTANT_STRING(L"ProductType"); 102 103 PAGED_CODE(); 104 105 /* Before doing anything else we must allocate some buffer space in the pool */ 106 BufferKey = ExAllocatePoolWithTag(PagedPool, BufferKeyLength, PRODUCT_TAG); 107 if (!BufferKey) 108 { 109 /* We failed to allocate pool memory, bail out */ 110 DPRINT1("RtlGetNtProductType(): Memory pool allocation has failed!\n"); 111 Success = FALSE; 112 goto Exit; 113 } 114 115 /* Initialize the object attributes to open our key */ 116 InitializeObjectAttributes(&ObjectAttributes, 117 &KeyProduct, 118 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 119 NULL, 120 NULL); 121 122 /* Open the key */ 123 Status = ZwOpenKey(&Key, KEY_QUERY_VALUE, &ObjectAttributes); 124 if (!NT_SUCCESS(Status)) 125 { 126 DPRINT1("RtlGetNtProductType(): The ZwOpenKey() function has failed! (Status: 0x%lx)\n", Status); 127 Success = FALSE; 128 goto Exit; 129 } 130 131 /* Now it's time to query the value from the key to check what kind of product the OS is */ 132 Status = ZwQueryValueKey(Key, 133 &ValueNtProduct, 134 KeyValuePartialInformation, 135 BufferKey, 136 BufferKeyLength, 137 &ReturnedLength); 138 139 /* Free the key from the memory */ 140 ZwClose(Key); 141 142 if (!NT_SUCCESS(Status)) 143 { 144 DPRINT1("RtlGetNtProductType(): The ZwQueryValueKey() function has failed! (Status: 0x%lx)\n", Status); 145 Success = FALSE; 146 goto Exit; 147 } 148 149 /* 150 * Do a sanity check before we get the product type of the operating system 151 * so that we're sure the type of the value we've got is actually correct. 152 */ 153 if (BufferKey->Type != REG_SZ) 154 { 155 /* We've got something else, so bail out */ 156 DPRINT1("RtlGetNtProductType(): An invalid value type has been found!\n"); 157 Success = FALSE; 158 goto Exit; 159 } 160 161 /* Initialise the Unicode string with the data from the registry value */ 162 NtProductType.Length = NtProductType.MaximumLength = BufferKey->DataLength; 163 NtProductType.Buffer = (PWCHAR)BufferKey->Data; 164 165 if (NtProductType.Length > sizeof(WCHAR) && NtProductType.Buffer[NtProductType.Length / 166 sizeof(WCHAR) - 1] == UNICODE_NULL) 167 { 168 NtProductType.Length -= sizeof(WCHAR); 169 } 170 171 /* Now it's time to get the product based on the value data */ 172 if (RtlCompareUnicodeString(&NtProductType, &WorkstationProduct, TRUE) == 0) 173 { 174 /* The following product is an OS Workstation */ 175 *ProductType = NtProductWinNt; 176 Success = TRUE; 177 } 178 else if (RtlCompareUnicodeString(&NtProductType, &LanManProduct, TRUE) == 0) 179 { 180 /* The following product is an OS Advanced Server */ 181 *ProductType = NtProductLanManNt; 182 Success = TRUE; 183 } 184 else if (RtlCompareUnicodeString(&NtProductType, &ServerProduct, TRUE) == 0) 185 { 186 /* The following product is an OS Server */ 187 *ProductType = NtProductServer; 188 Success = TRUE; 189 } 190 else 191 { 192 /* None of the product types match so bail out */ 193 DPRINT1("RtlGetNtProductType(): Couldn't find a valid product type! Defaulting to WinNT...\n"); 194 Success = FALSE; 195 goto Exit; 196 } 197 198Exit: 199 if (!Success) 200 { 201 *ProductType = NtProductWinNt; 202 } 203 204 ExFreePoolWithTag(BufferKey, PRODUCT_TAG); 205 return Success; 206} 207 208#if !defined(_M_IX86) 209// 210// Stub for architectures which don't have this implemented 211// 212VOID 213FASTCALL 214RtlPrefetchMemoryNonTemporal(IN PVOID Source, 215 IN SIZE_T Length) 216{ 217 // 218 // Do nothing 219 // 220 UNREFERENCED_PARAMETER(Source); 221 UNREFERENCED_PARAMETER(Length); 222} 223#endif 224 225VOID NTAPI 226AVrfInternalHeapFreeNotification(PVOID AllocationBase, SIZE_T AllocationSize) 227{ 228 /* Stub for linking against rtl */ 229} 230 231 232 233/* EOF */