[KERNEL32]
[reactos.git] / reactos / dll / win32 / kernel32 / client / sysinfo.c
1 /*
2 * PROJECT: ReactOS Win32 Base API
3 * LICENSE: See COPYING in the top level directory
4 * FILE: dll/win32/kernel32/client/sysinfo.c
5 * PURPOSE: System Information Functions
6 * PROGRAMMERS: Emanuele Aliberti
7 * Christoph von Wittich
8 * Thomas Weidenmueller
9 * Gunnar Andre Dalsnes
10 */
11
12 /* INCLUDES *******************************************************************/
13
14 #include <k32.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19 #define PV_NT351 0x00030033
20
21 /* PRIVATE FUNCTIONS **********************************************************/
22
23 VOID
24 WINAPI
25 GetSystemInfoInternal(IN PSYSTEM_BASIC_INFORMATION BasicInfo,
26 IN PSYSTEM_PROCESSOR_INFORMATION ProcInfo,
27 OUT LPSYSTEM_INFO SystemInfo)
28 {
29 RtlZeroMemory(SystemInfo, sizeof (SYSTEM_INFO));
30 SystemInfo->wProcessorArchitecture = ProcInfo->ProcessorArchitecture;
31 SystemInfo->wReserved = 0;
32 SystemInfo->dwPageSize = BasicInfo->PageSize;
33 SystemInfo->lpMinimumApplicationAddress = (PVOID)BasicInfo->MinimumUserModeAddress;
34 SystemInfo->lpMaximumApplicationAddress = (PVOID)BasicInfo->MaximumUserModeAddress;
35 SystemInfo->dwActiveProcessorMask = BasicInfo->ActiveProcessorsAffinityMask;
36 SystemInfo->dwNumberOfProcessors = BasicInfo->NumberOfProcessors;
37 SystemInfo->wProcessorLevel = ProcInfo->ProcessorLevel;
38 SystemInfo->wProcessorRevision = ProcInfo->ProcessorRevision;
39 SystemInfo->dwAllocationGranularity = BasicInfo->AllocationGranularity;
40
41 switch (ProcInfo->ProcessorArchitecture)
42 {
43 case PROCESSOR_ARCHITECTURE_INTEL:
44 switch (ProcInfo->ProcessorLevel)
45 {
46 case 3:
47 SystemInfo->dwProcessorType = PROCESSOR_INTEL_386;
48 break;
49 case 4:
50 SystemInfo->dwProcessorType = PROCESSOR_INTEL_486;
51 break;
52 default:
53 SystemInfo->dwProcessorType = PROCESSOR_INTEL_PENTIUM;
54 }
55 break;
56
57 case PROCESSOR_ARCHITECTURE_AMD64:
58 SystemInfo->dwProcessorType = PROCESSOR_AMD_X8664;
59 break;
60
61 case PROCESSOR_ARCHITECTURE_IA64:
62 SystemInfo->dwProcessorType = PROCESSOR_INTEL_IA64;
63 break;
64
65 default:
66 SystemInfo->dwProcessorType = 0;
67 break;
68 }
69
70 if (PV_NT351 > GetProcessVersion(0))
71 {
72 SystemInfo->wProcessorLevel = 0;
73 SystemInfo->wProcessorRevision = 0;
74 }
75 }
76
77 /* PUBLIC FUNCTIONS ***********************************************************/
78
79 /*
80 * @implemented
81 */
82 SIZE_T
83 WINAPI
84 GetLargePageMinimum(VOID)
85 {
86 return SharedUserData->LargePageMinimum;
87 }
88
89 /*
90 * @implemented
91 */
92 VOID
93 WINAPI
94 GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
95 {
96 SYSTEM_BASIC_INFORMATION BasicInfo;
97 SYSTEM_PROCESSOR_INFORMATION ProcInfo;
98 NTSTATUS Status;
99
100 Status = NtQuerySystemInformation(SystemBasicInformation,
101 &BasicInfo,
102 sizeof(BasicInfo),
103 0);
104 if (!NT_SUCCESS(Status)) return;
105
106 Status = NtQuerySystemInformation(SystemProcessorInformation,
107 &ProcInfo,
108 sizeof(ProcInfo),
109 0);
110 if (!NT_SUCCESS(Status)) return;
111
112 GetSystemInfoInternal(&BasicInfo, &ProcInfo, lpSystemInfo);
113 }
114
115 /*
116 * @implemented
117 */
118 BOOL
119 WINAPI
120 IsProcessorFeaturePresent(IN DWORD ProcessorFeature)
121 {
122 if (ProcessorFeature >= PROCESSOR_FEATURE_MAX) return FALSE;
123 return ((BOOL)SharedUserData->ProcessorFeatures[ProcessorFeature]);
124 }
125
126 /*
127 * @implemented
128 */
129 BOOL
130 WINAPI
131 GetSystemRegistryQuota(OUT PDWORD pdwQuotaAllowed,
132 OUT PDWORD pdwQuotaUsed)
133 {
134 SYSTEM_REGISTRY_QUOTA_INFORMATION QuotaInfo;
135 ULONG BytesWritten;
136 NTSTATUS Status;
137
138 Status = NtQuerySystemInformation(SystemRegistryQuotaInformation,
139 &QuotaInfo,
140 sizeof(QuotaInfo),
141 &BytesWritten);
142 if (NT_SUCCESS(Status))
143 {
144 if (pdwQuotaAllowed) *pdwQuotaAllowed = QuotaInfo.RegistryQuotaAllowed;
145 if (pdwQuotaUsed) *pdwQuotaUsed = QuotaInfo.RegistryQuotaUsed;
146 return TRUE;
147 }
148
149 BaseSetLastNTError(Status);
150 return FALSE;
151 }
152
153 /*
154 * @implemented
155 */
156 VOID
157 WINAPI
158 GetNativeSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
159 {
160 SYSTEM_BASIC_INFORMATION BasicInfo;
161 SYSTEM_PROCESSOR_INFORMATION ProcInfo;
162 NTSTATUS Status;
163
164 /* FIXME: Should be SystemNativeBasicInformation */
165 Status = NtQuerySystemInformation(SystemBasicInformation,
166 &BasicInfo,
167 sizeof(BasicInfo),
168 0);
169 if (!NT_SUCCESS(Status)) return;
170
171 /* FIXME: Should be SystemNativeProcessorInformation */
172 Status = NtQuerySystemInformation(SystemProcessorInformation,
173 &ProcInfo,
174 sizeof(ProcInfo),
175 0);
176 if (!NT_SUCCESS(Status)) return;
177
178 GetSystemInfoInternal(&BasicInfo, &ProcInfo, lpSystemInfo);
179 }
180
181 /*
182 * @implemented
183 */
184 BOOL
185 WINAPI
186 GetLogicalProcessorInformation(OUT PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer,
187 IN OUT PDWORD ReturnLength)
188 {
189 NTSTATUS Status;
190
191 if (!ReturnLength)
192 {
193 SetLastError(ERROR_INVALID_PARAMETER);
194 return FALSE;
195 }
196
197 Status = NtQuerySystemInformation(SystemLogicalProcessorInformation,
198 Buffer,
199 *ReturnLength,
200 ReturnLength);
201
202 /* Normalize the error to what Win32 expects */
203 if (Status == STATUS_INFO_LENGTH_MISMATCH) Status = STATUS_BUFFER_TOO_SMALL;
204 if (!NT_SUCCESS(Status))
205 {
206 BaseSetLastNTError(Status);
207 return FALSE;
208 }
209
210 return TRUE;
211 }
212
213 /*
214 * @implemented
215 */
216 BOOL
217 WINAPI
218 GetNumaHighestNodeNumber(OUT PULONG HighestNodeNumber)
219 {
220 NTSTATUS Status;
221 ULONG Length;
222 ULONG PartialInfo[2]; // First two members of SYSTEM_NUMA_INFORMATION
223
224 /* Query partial NUMA info */
225 Status = NtQuerySystemInformation(SystemNumaProcessorMap,
226 PartialInfo,
227 sizeof(PartialInfo),
228 &Length);
229 if (!NT_SUCCESS(Status))
230 {
231 BaseSetLastNTError(Status);
232 return FALSE;
233 }
234
235 if (Length < sizeof(ULONG))
236 {
237 SetLastError(ERROR_INVALID_PARAMETER);
238 return FALSE;
239 }
240
241 /* First member of the struct is the highest node number */
242 *HighestNodeNumber = PartialInfo[0];
243 return TRUE;
244 }
245
246 /*
247 * @implemented
248 */
249 BOOL
250 WINAPI
251 GetNumaNodeProcessorMask(IN UCHAR Node,
252 OUT PULONGLONG ProcessorMask)
253 {
254 NTSTATUS Status;
255 SYSTEM_NUMA_INFORMATION NumaInformation;
256 ULONG Length;
257
258 /* Query NUMA information */
259 Status = NtQuerySystemInformation(SystemNumaProcessorMap,
260 &NumaInformation,
261 sizeof(NumaInformation),
262 &Length);
263 if (!NT_SUCCESS(Status))
264 {
265 BaseSetLastNTError(Status);
266 return FALSE;
267 }
268
269 /* Validate input node number */
270 if (Node > NumaInformation.HighestNodeNumber)
271 {
272 SetLastError(ERROR_INVALID_PARAMETER);
273 return FALSE;
274 }
275
276 /* Return mask for that node */
277 *ProcessorMask = NumaInformation.ActiveProcessorsAffinityMask[Node];
278 return TRUE;
279 }
280
281 /*
282 * @implemented
283 */
284 BOOL
285 WINAPI
286 GetNumaProcessorNode(IN UCHAR Processor,
287 OUT PUCHAR NodeNumber)
288 {
289 NTSTATUS Status;
290 SYSTEM_NUMA_INFORMATION NumaInformation;
291 ULONG Length;
292 ULONG Node;
293 ULONGLONG Proc;
294
295 /* Can't handle processor number >= 32 */
296 if (Processor >= MAXIMUM_PROCESSORS)
297 {
298 *NodeNumber = -1;
299 SetLastError(ERROR_INVALID_PARAMETER);
300 return FALSE;
301 }
302
303 /* Query NUMA information */
304 Status = NtQuerySystemInformation(SystemNumaProcessorMap,
305 &NumaInformation,
306 sizeof(NumaInformation),
307 &Length);
308 if (!NT_SUCCESS(Status))
309 {
310 *NodeNumber = -1;
311 BaseSetLastNTError(Status);
312 return FALSE;
313 }
314
315 /* Find ourselves */
316 Node = 0;
317 Proc = 1ULL << Processor;
318 while ((Proc & NumaInformation.ActiveProcessorsAffinityMask[Node]) == 0ULL)
319 {
320 ++Node;
321 /* Out of options */
322 if (Node > NumaInformation.HighestNodeNumber)
323 {
324 *NodeNumber = -1;
325 SetLastError(ERROR_INVALID_PARAMETER);
326 return FALSE;
327 }
328 }
329
330 /* Return found node */
331 *NodeNumber = Node;
332 return TRUE;
333 }
334
335 /*
336 * @implemented
337 */
338 BOOL
339 WINAPI
340 GetNumaAvailableMemoryNode(IN UCHAR Node,
341 OUT PULONGLONG AvailableBytes)
342 {
343 NTSTATUS Status;
344 SYSTEM_NUMA_INFORMATION NumaInformation;
345 ULONG Length;
346
347 /* Query NUMA information */
348 Status = NtQuerySystemInformation(SystemNumaAvailableMemory,
349 &NumaInformation,
350 sizeof(NumaInformation),
351 &Length);
352 if (!NT_SUCCESS(Status))
353 {
354 BaseSetLastNTError(Status);
355 return FALSE;
356 }
357
358 /* Validate input node number */
359 if (Node > NumaInformation.HighestNodeNumber)
360 {
361 SetLastError(ERROR_INVALID_PARAMETER);
362 return FALSE;
363 }
364
365 /* Return available memory for that node */
366 *AvailableBytes = NumaInformation.AvailableMemory[Node];
367 return TRUE;
368 }
369
370 /*
371 * @unimplemented
372 */
373 DWORD
374 WINAPI
375 GetFirmwareEnvironmentVariableW(IN LPCWSTR lpName,
376 IN LPCWSTR lpGuid,
377 IN PVOID pValue,
378 IN DWORD nSize)
379 {
380 STUB;
381 return 0;
382 }
383
384 /*
385 * @unimplemented
386 */
387 BOOL
388 WINAPI
389 SetFirmwareEnvironmentVariableW(IN LPCWSTR lpName,
390 IN LPCWSTR lpGuid,
391 IN PVOID pValue,
392 IN DWORD nSize)
393 {
394 STUB;
395 return 0;
396 }
397
398 /*
399 * @unimplemented
400 */
401 DWORD
402 WINAPI
403 GetFirmwareEnvironmentVariableA(IN LPCSTR lpName,
404 IN LPCSTR lpGuid,
405 IN PVOID pValue,
406 IN DWORD nSize)
407 {
408 STUB;
409 return 0;
410 }
411
412 /*
413 * @unimplemented
414 */
415 BOOL
416 WINAPI
417 SetFirmwareEnvironmentVariableA(IN LPCSTR lpName,
418 IN LPCSTR lpGuid,
419 IN PVOID pValue,
420 IN DWORD nSize)
421 {
422 STUB;
423 return 0;
424 }
425
426 /*
427 * @unimplemented
428 */
429 UINT
430 WINAPI
431 EnumSystemFirmwareTables(IN DWORD FirmwareTableProviderSignature,
432 OUT PVOID pFirmwareTableBuffer,
433 IN DWORD BufferSize)
434 {
435 STUB;
436 return 0;
437 }
438
439 /*
440 * @unimplemented
441 */
442 UINT
443 WINAPI
444 GetSystemFirmwareTable(IN DWORD FirmwareTableProviderSignature,
445 IN DWORD FirmwareTableID,
446 OUT PVOID pFirmwareTableBuffer,
447 IN DWORD BufferSize)
448 {
449 STUB;
450 return 0;
451 }
452
453 /*
454 * @unimplemented
455 */
456 BOOL
457 WINAPI
458 GetSystemFileCacheSize(OUT PSIZE_T lpMinimumFileCacheSize,
459 OUT PSIZE_T lpMaximumFileCacheSize,
460 OUT PDWORD lpFlags)
461 {
462 STUB;
463 return FALSE;
464 }
465
466 /*
467 * @unimplemented
468 */
469 BOOL
470 WINAPI
471 SetSystemFileCacheSize(IN SIZE_T MinimumFileCacheSize,
472 IN SIZE_T MaximumFileCacheSize,
473 IN DWORD Flags)
474 {
475 STUB;
476 return FALSE;
477 }