xref: /reactos/dll/win32/kernel32/client/sysinfo.c (revision 1cf8759d)
1 /*
2  * PROJECT:         ReactOS Win32 Base API
3  * LICENSE:         GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:         System Information Functions
5  * COPYRIGHT:       Emanuele Aliberti
6  *                  Christoph von Wittich
7  *                  Thomas Weidenmueller
8  *                  Gunnar Andre Dalsnes
9  *                  Stanislav Motylkov (x86corez@gmail.com)
10  *                  Mark Jansen (mark.jansen@reactos.org)
11  *                  Copyright 2023 Ratin Gao <ratin@knsoft.org>
12  */
13 
14 /* INCLUDES *******************************************************************/
15 
16 #include <k32.h>
17 
18 #define NDEBUG
19 #include <debug.h>
20 
21 #define PV_NT351 0x00030033
22 
23 /* PRIVATE FUNCTIONS **********************************************************/
24 
25 VOID
26 WINAPI
GetSystemInfoInternal(IN PSYSTEM_BASIC_INFORMATION BasicInfo,IN PSYSTEM_PROCESSOR_INFORMATION ProcInfo,OUT LPSYSTEM_INFO SystemInfo)27 GetSystemInfoInternal(IN PSYSTEM_BASIC_INFORMATION BasicInfo,
28                       IN PSYSTEM_PROCESSOR_INFORMATION ProcInfo,
29                       OUT LPSYSTEM_INFO SystemInfo)
30 {
31     RtlZeroMemory(SystemInfo, sizeof (SYSTEM_INFO));
32     SystemInfo->wProcessorArchitecture = ProcInfo->ProcessorArchitecture;
33     SystemInfo->wReserved = 0;
34     SystemInfo->dwPageSize = BasicInfo->PageSize;
35     SystemInfo->lpMinimumApplicationAddress = (PVOID)BasicInfo->MinimumUserModeAddress;
36     SystemInfo->lpMaximumApplicationAddress = (PVOID)BasicInfo->MaximumUserModeAddress;
37     SystemInfo->dwActiveProcessorMask = BasicInfo->ActiveProcessorsAffinityMask;
38     SystemInfo->dwNumberOfProcessors = BasicInfo->NumberOfProcessors;
39     SystemInfo->wProcessorLevel = ProcInfo->ProcessorLevel;
40     SystemInfo->wProcessorRevision = ProcInfo->ProcessorRevision;
41     SystemInfo->dwAllocationGranularity = BasicInfo->AllocationGranularity;
42 
43     switch (ProcInfo->ProcessorArchitecture)
44     {
45         case PROCESSOR_ARCHITECTURE_INTEL:
46             switch (ProcInfo->ProcessorLevel)
47             {
48                 case 3:
49                     SystemInfo->dwProcessorType = PROCESSOR_INTEL_386;
50                     break;
51                 case 4:
52                     SystemInfo->dwProcessorType = PROCESSOR_INTEL_486;
53                     break;
54                 default:
55                     SystemInfo->dwProcessorType = PROCESSOR_INTEL_PENTIUM;
56             }
57             break;
58 
59         case PROCESSOR_ARCHITECTURE_AMD64:
60             SystemInfo->dwProcessorType = PROCESSOR_AMD_X8664;
61             break;
62 
63         case PROCESSOR_ARCHITECTURE_IA64:
64             SystemInfo->dwProcessorType = PROCESSOR_INTEL_IA64;
65             break;
66 
67         default:
68             SystemInfo->dwProcessorType = 0;
69             break;
70     }
71 
72     if (PV_NT351 > GetProcessVersion(0))
73     {
74         SystemInfo->wProcessorLevel = 0;
75         SystemInfo->wProcessorRevision = 0;
76     }
77 }
78 
79 static
80 UINT
BaseQuerySystemFirmware(_In_ DWORD FirmwareTableProviderSignature,_In_ DWORD FirmwareTableID,_Out_writes_bytes_to_opt_ (BufferSize,return)PVOID pFirmwareTableBuffer,_In_ DWORD BufferSize,_In_ SYSTEM_FIRMWARE_TABLE_ACTION Action)81 BaseQuerySystemFirmware(
82     _In_ DWORD FirmwareTableProviderSignature,
83     _In_ DWORD FirmwareTableID,
84     _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableBuffer,
85     _In_ DWORD BufferSize,
86     _In_ SYSTEM_FIRMWARE_TABLE_ACTION Action)
87 {
88     SYSTEM_FIRMWARE_TABLE_INFORMATION* SysFirmwareInfo;
89     ULONG Result = 0, ReturnedSize;
90     ULONG TotalSize = BufferSize + sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION);
91     NTSTATUS Status;
92 
93     SysFirmwareInfo = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, TotalSize);
94     if (!SysFirmwareInfo)
95     {
96         SetLastError(ERROR_INVALID_PARAMETER);
97         return 0;
98     }
99     _SEH2_TRY
100     {
101         SysFirmwareInfo->ProviderSignature = FirmwareTableProviderSignature;
102         SysFirmwareInfo->TableID = FirmwareTableID;
103         SysFirmwareInfo->Action = Action;
104         SysFirmwareInfo->TableBufferLength = BufferSize;
105 
106         Status = NtQuerySystemInformation(SystemFirmwareTableInformation, SysFirmwareInfo, TotalSize, &ReturnedSize);
107 
108         if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL)
109             Result = SysFirmwareInfo->TableBufferLength;
110 
111         if (NT_SUCCESS(Status) && pFirmwareTableBuffer)
112         {
113             RtlCopyMemory(pFirmwareTableBuffer, SysFirmwareInfo->TableBuffer, SysFirmwareInfo->TableBufferLength);
114         }
115     }
116     _SEH2_FINALLY
117     {
118         RtlFreeHeap(RtlGetProcessHeap(), 0, SysFirmwareInfo);
119     }
120     _SEH2_END;
121 
122     BaseSetLastNTError(Status);
123     return Result;
124 }
125 
126 /* PUBLIC FUNCTIONS ***********************************************************/
127 
128 /*
129  * @implemented
130  */
131 SIZE_T
132 WINAPI
GetLargePageMinimum(VOID)133 GetLargePageMinimum(VOID)
134 {
135     return SharedUserData->LargePageMinimum;
136 }
137 
138 /*
139  * @implemented
140  */
141 VOID
142 WINAPI
GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)143 GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
144 {
145     SYSTEM_BASIC_INFORMATION BasicInfo;
146     SYSTEM_PROCESSOR_INFORMATION ProcInfo;
147     NTSTATUS Status;
148 
149     Status = NtQuerySystemInformation(SystemBasicInformation,
150                                       &BasicInfo,
151                                       sizeof(BasicInfo),
152                                       0);
153     if (!NT_SUCCESS(Status)) return;
154 
155     Status = NtQuerySystemInformation(SystemProcessorInformation,
156                                       &ProcInfo,
157                                       sizeof(ProcInfo),
158                                       0);
159     if (!NT_SUCCESS(Status)) return;
160 
161     GetSystemInfoInternal(&BasicInfo, &ProcInfo, lpSystemInfo);
162 }
163 
164 /*
165  * @implemented
166  */
167 BOOL
168 WINAPI
IsProcessorFeaturePresent(IN DWORD ProcessorFeature)169 IsProcessorFeaturePresent(IN DWORD ProcessorFeature)
170 {
171     if (ProcessorFeature >= PROCESSOR_FEATURE_MAX) return FALSE;
172     return ((BOOL)SharedUserData->ProcessorFeatures[ProcessorFeature]);
173 }
174 
175 /*
176  * @implemented
177  */
178 BOOL
179 WINAPI
GetSystemRegistryQuota(OUT PDWORD pdwQuotaAllowed,OUT PDWORD pdwQuotaUsed)180 GetSystemRegistryQuota(OUT PDWORD pdwQuotaAllowed,
181                        OUT PDWORD pdwQuotaUsed)
182 {
183     SYSTEM_REGISTRY_QUOTA_INFORMATION QuotaInfo;
184     ULONG BytesWritten;
185     NTSTATUS Status;
186 
187     Status = NtQuerySystemInformation(SystemRegistryQuotaInformation,
188                                       &QuotaInfo,
189                                       sizeof(QuotaInfo),
190                                       &BytesWritten);
191     if (NT_SUCCESS(Status))
192     {
193       if (pdwQuotaAllowed) *pdwQuotaAllowed = QuotaInfo.RegistryQuotaAllowed;
194       if (pdwQuotaUsed) *pdwQuotaUsed = QuotaInfo.RegistryQuotaUsed;
195       return TRUE;
196     }
197 
198     BaseSetLastNTError(Status);
199     return FALSE;
200 }
201 
202 /*
203  * @implemented
204  */
205 VOID
206 WINAPI
GetNativeSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)207 GetNativeSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
208 {
209     SYSTEM_BASIC_INFORMATION BasicInfo;
210     SYSTEM_PROCESSOR_INFORMATION ProcInfo;
211     NTSTATUS Status;
212 
213     Status = RtlGetNativeSystemInformation(SystemBasicInformation,
214                                            &BasicInfo,
215                                            sizeof(BasicInfo),
216                                            0);
217     if (!NT_SUCCESS(Status)) return;
218 
219     Status = RtlGetNativeSystemInformation(SystemProcessorInformation,
220                                            &ProcInfo,
221                                            sizeof(ProcInfo),
222                                            0);
223     if (!NT_SUCCESS(Status)) return;
224 
225     GetSystemInfoInternal(&BasicInfo, &ProcInfo, lpSystemInfo);
226 }
227 
228 /*
229  * @implemented
230  */
231 BOOL
232 WINAPI
GetLogicalProcessorInformation(OUT PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer,IN OUT PDWORD ReturnLength)233 GetLogicalProcessorInformation(OUT PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer,
234                                IN OUT PDWORD ReturnLength)
235 {
236     NTSTATUS Status;
237 
238     if (!ReturnLength)
239     {
240         SetLastError(ERROR_INVALID_PARAMETER);
241         return FALSE;
242     }
243 
244     Status = NtQuerySystemInformation(SystemLogicalProcessorInformation,
245                                       Buffer,
246                                       *ReturnLength,
247                                       ReturnLength);
248 
249     /* Normalize the error to what Win32 expects */
250     if (Status == STATUS_INFO_LENGTH_MISMATCH) Status = STATUS_BUFFER_TOO_SMALL;
251     if (!NT_SUCCESS(Status))
252     {
253         BaseSetLastNTError(Status);
254         return FALSE;
255     }
256 
257     return TRUE;
258 }
259 
260 /*
261  * @implemented
262  */
263 BOOL
264 WINAPI
GetNumaHighestNodeNumber(OUT PULONG HighestNodeNumber)265 GetNumaHighestNodeNumber(OUT PULONG HighestNodeNumber)
266 {
267     NTSTATUS Status;
268     ULONG Length;
269     ULONG PartialInfo[2]; // First two members of SYSTEM_NUMA_INFORMATION
270 
271     /* Query partial NUMA info */
272     Status = NtQuerySystemInformation(SystemNumaProcessorMap,
273                                       PartialInfo,
274                                       sizeof(PartialInfo),
275                                       &Length);
276     if (!NT_SUCCESS(Status))
277     {
278         BaseSetLastNTError(Status);
279         return FALSE;
280     }
281 
282     if (Length < sizeof(ULONG))
283     {
284         SetLastError(ERROR_INVALID_PARAMETER);
285         return FALSE;
286     }
287 
288     /* First member of the struct is the highest node number */
289     *HighestNodeNumber = PartialInfo[0];
290     return TRUE;
291 }
292 
293 /*
294  * @implemented
295  */
296 BOOL
297 WINAPI
GetNumaNodeProcessorMask(IN UCHAR Node,OUT PULONGLONG ProcessorMask)298 GetNumaNodeProcessorMask(IN UCHAR Node,
299                          OUT PULONGLONG ProcessorMask)
300 {
301     NTSTATUS Status;
302     SYSTEM_NUMA_INFORMATION NumaInformation;
303     ULONG Length;
304 
305     /* Query NUMA information */
306     Status = NtQuerySystemInformation(SystemNumaProcessorMap,
307                                       &NumaInformation,
308                                       sizeof(NumaInformation),
309                                       &Length);
310     if (!NT_SUCCESS(Status))
311     {
312         BaseSetLastNTError(Status);
313         return FALSE;
314     }
315 
316     /* Validate input node number */
317     if (Node > NumaInformation.HighestNodeNumber)
318     {
319         SetLastError(ERROR_INVALID_PARAMETER);
320         return FALSE;
321     }
322 
323     /* Return mask for that node */
324     *ProcessorMask = NumaInformation.ActiveProcessorsAffinityMask[Node];
325     return TRUE;
326 }
327 
328 /*
329  * @implemented
330  */
331 BOOL
332 WINAPI
GetNumaProcessorNode(IN UCHAR Processor,OUT PUCHAR NodeNumber)333 GetNumaProcessorNode(IN UCHAR Processor,
334                      OUT PUCHAR NodeNumber)
335 {
336     NTSTATUS Status;
337     SYSTEM_NUMA_INFORMATION NumaInformation;
338     ULONG Length;
339     ULONG Node;
340     ULONGLONG Proc;
341 
342     /* Can't handle processor number >= 32 */
343     if (Processor >= MAXIMUM_PROCESSORS)
344     {
345         *NodeNumber = -1;
346         SetLastError(ERROR_INVALID_PARAMETER);
347         return FALSE;
348     }
349 
350     /* Query NUMA information */
351     Status = NtQuerySystemInformation(SystemNumaProcessorMap,
352                                       &NumaInformation,
353                                       sizeof(NumaInformation),
354                                       &Length);
355     if (!NT_SUCCESS(Status))
356     {
357         *NodeNumber = -1;
358         BaseSetLastNTError(Status);
359         return FALSE;
360     }
361 
362     /* Find ourselves */
363     Node = 0;
364     Proc = 1ULL << Processor;
365     while ((Proc & NumaInformation.ActiveProcessorsAffinityMask[Node]) == 0ULL)
366     {
367         ++Node;
368         /* Out of options */
369         if (Node > NumaInformation.HighestNodeNumber)
370         {
371             *NodeNumber = -1;
372             SetLastError(ERROR_INVALID_PARAMETER);
373             return FALSE;
374         }
375     }
376 
377     /* Return found node */
378     *NodeNumber = Node;
379     return TRUE;
380 }
381 
382 /*
383  * @implemented
384  */
385 BOOL
386 WINAPI
GetNumaAvailableMemoryNode(IN UCHAR Node,OUT PULONGLONG AvailableBytes)387 GetNumaAvailableMemoryNode(IN UCHAR Node,
388                            OUT PULONGLONG AvailableBytes)
389 {
390     NTSTATUS Status;
391     SYSTEM_NUMA_INFORMATION NumaInformation;
392     ULONG Length;
393 
394     /* Query NUMA information */
395     Status = NtQuerySystemInformation(SystemNumaAvailableMemory,
396                                       &NumaInformation,
397                                       sizeof(NumaInformation),
398                                       &Length);
399     if (!NT_SUCCESS(Status))
400     {
401         BaseSetLastNTError(Status);
402         return FALSE;
403     }
404 
405     /* Validate input node number */
406     if (Node > NumaInformation.HighestNodeNumber)
407     {
408         SetLastError(ERROR_INVALID_PARAMETER);
409         return FALSE;
410     }
411 
412     /* Return available memory for that node */
413     *AvailableBytes = NumaInformation.AvailableMemory[Node];
414     return TRUE;
415 }
416 
417 _Success_(return > 0)
418 DWORD
419 WINAPI
420 GetFirmwareEnvironmentVariableExW(
421     _In_ LPCWSTR lpName,
422     _In_ LPCWSTR lpGuid,
423     _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
424     _In_ DWORD nSize,
425     _Out_opt_ PDWORD pdwAttribubutes);
426 
427 _Success_(return > 0)
428 DWORD
429 WINAPI
430 GetFirmwareEnvironmentVariableExA(
431     _In_ LPCSTR lpName,
432     _In_ LPCSTR lpGuid,
433     _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
434     _In_ DWORD nSize,
435     _Out_opt_ PDWORD pdwAttribubutes);
436 
437 BOOL
438 WINAPI
439 SetFirmwareEnvironmentVariableExW(
440     _In_ LPCWSTR lpName,
441     _In_ LPCWSTR lpGuid,
442     _In_reads_bytes_opt_(nSize) PVOID pValue,
443     _In_ DWORD nSize,
444     _In_ DWORD dwAttributes);
445 
446 BOOL
447 WINAPI
448 SetFirmwareEnvironmentVariableExA(
449     _In_ LPCSTR lpName,
450     _In_ LPCSTR lpGuid,
451     _In_reads_bytes_opt_(nSize) PVOID pValue,
452     _In_ DWORD nSize,
453     _In_ DWORD dwAttributes);
454 
455 _Success_(return > 0)
456 DWORD
457 WINAPI
GetFirmwareEnvironmentVariableW(_In_ LPCWSTR lpName,_In_ LPCWSTR lpGuid,_Out_writes_bytes_to_opt_ (nSize,return)PVOID pBuffer,_In_ DWORD nSize)458 GetFirmwareEnvironmentVariableW(
459     _In_ LPCWSTR lpName,
460     _In_ LPCWSTR lpGuid,
461     _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
462     _In_ DWORD nSize)
463 {
464     return GetFirmwareEnvironmentVariableExW(lpName, lpGuid, pBuffer, nSize, NULL);
465 }
466 
467 _Success_(return > 0)
468 DWORD
469 WINAPI
GetFirmwareEnvironmentVariableA(_In_ LPCSTR lpName,_In_ LPCSTR lpGuid,_Out_writes_bytes_to_opt_ (nSize,return)PVOID pBuffer,_In_ DWORD nSize)470 GetFirmwareEnvironmentVariableA(
471     _In_ LPCSTR lpName,
472     _In_ LPCSTR lpGuid,
473     _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
474     _In_ DWORD nSize)
475 {
476     return GetFirmwareEnvironmentVariableExA(lpName, lpGuid, pBuffer, nSize, NULL);
477 }
478 
479 BOOL
480 WINAPI
SetFirmwareEnvironmentVariableW(_In_ LPCWSTR lpName,_In_ LPCWSTR lpGuid,_In_reads_bytes_opt_ (nSize)PVOID pValue,_In_ DWORD nSize)481 SetFirmwareEnvironmentVariableW(
482     _In_ LPCWSTR lpName,
483     _In_ LPCWSTR lpGuid,
484     _In_reads_bytes_opt_(nSize) PVOID pValue,
485     _In_ DWORD nSize)
486 {
487     return SetFirmwareEnvironmentVariableExW(lpName,
488                                              lpGuid,
489                                              pValue,
490                                              nSize,
491                                              VARIABLE_ATTRIBUTE_NON_VOLATILE);
492 }
493 
494 BOOL
495 WINAPI
SetFirmwareEnvironmentVariableA(_In_ LPCSTR lpName,_In_ LPCSTR lpGuid,_In_reads_bytes_opt_ (nSize)PVOID pValue,_In_ DWORD nSize)496 SetFirmwareEnvironmentVariableA(
497     _In_ LPCSTR lpName,
498     _In_ LPCSTR lpGuid,
499     _In_reads_bytes_opt_(nSize) PVOID pValue,
500     _In_ DWORD nSize)
501 {
502     return SetFirmwareEnvironmentVariableExA(lpName,
503                                              lpGuid,
504                                              pValue,
505                                              nSize,
506                                              VARIABLE_ATTRIBUTE_NON_VOLATILE);
507 }
508 
509 /**
510  * @name EnumSystemFirmwareTables
511  * @implemented
512  *
513  * Obtains firmware table identifiers.
514  * https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-enumsystemfirmwaretables
515  *
516  * @param FirmwareTableProviderSignature
517  * Can be either ACPI, FIRM, or RSMB.
518  *
519  * @param pFirmwareTableBuffer
520  * Pointer to the output buffer, can be NULL.
521  *
522  * @param BufferSize
523  * Size of the output buffer.
524  *
525  * @return
526  * Actual size of the data in case of success, 0 otherwise.
527  *
528  * @remarks
529  * Data would be written to buffer only if the specified size is
530  * larger or equal to the actual size, in the other case Last Error
531  * value would be set to ERROR_INSUFFICIENT_BUFFER.
532  * In case of incorrect provider signature, Last Error value would be
533  * set to ERROR_INVALID_FUNCTION.
534  *
535  */
536 UINT
537 WINAPI
EnumSystemFirmwareTables(_In_ DWORD FirmwareTableProviderSignature,_Out_writes_bytes_to_opt_ (BufferSize,return)PVOID pFirmwareTableEnumBuffer,_In_ DWORD BufferSize)538 EnumSystemFirmwareTables(
539     _In_ DWORD FirmwareTableProviderSignature,
540     _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableEnumBuffer,
541     _In_ DWORD BufferSize)
542 {
543     return BaseQuerySystemFirmware(FirmwareTableProviderSignature,
544                                    0,
545                                    pFirmwareTableEnumBuffer,
546                                    BufferSize,
547                                    SystemFirmwareTable_Enumerate);
548 }
549 
550 /**
551  * @name GetSystemFirmwareTable
552  * @implemented
553  *
554  * Obtains the firmware table data.
555  * https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemfirmwaretable
556  *
557  * @param FirmwareTableProviderSignature
558  * Can be either ACPI, FIRM, or RSMB.
559  *
560  * @param FirmwareTableID
561  * Correct table identifier.
562  *
563  * @param pFirmwareTableBuffer
564  * Pointer to the output buffer, can be NULL.
565  *
566  * @param BufferSize
567  * Size of the output buffer.
568  *
569  * @return
570  * Actual size of the data in case of success, 0 otherwise.
571  *
572  * @remarks
573  * Data would be written to buffer only if the specified size is
574  * larger or equal to the actual size, in the other case Last Error
575  * value would be set to ERROR_INSUFFICIENT_BUFFER.
576  * In case of incorrect provider signature, Last Error value would be
577  * set to ERROR_INVALID_FUNCTION.
578  * Also Last Error value becomes ERROR_NOT_FOUND if incorrect
579  * table identifier was specified along with ACPI provider, and
580  * ERROR_INVALID_PARAMETER along with FIRM provider. The RSMB provider
581  * accepts any table identifier.
582  *
583  */
584 UINT
585 WINAPI
GetSystemFirmwareTable(_In_ DWORD FirmwareTableProviderSignature,_In_ DWORD FirmwareTableID,_Out_writes_bytes_to_opt_ (BufferSize,return)PVOID pFirmwareTableBuffer,_In_ DWORD BufferSize)586 GetSystemFirmwareTable(
587     _In_ DWORD FirmwareTableProviderSignature,
588     _In_ DWORD FirmwareTableID,
589     _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableBuffer,
590     _In_ DWORD BufferSize)
591 {
592     return BaseQuerySystemFirmware(FirmwareTableProviderSignature,
593                                    FirmwareTableID,
594                                    pFirmwareTableBuffer,
595                                    BufferSize,
596                                    SystemFirmwareTable_Get);
597 }
598 
599 /*
600  * @unimplemented
601  */
602 BOOL
603 WINAPI
GetSystemFileCacheSize(OUT PSIZE_T lpMinimumFileCacheSize,OUT PSIZE_T lpMaximumFileCacheSize,OUT PDWORD lpFlags)604 GetSystemFileCacheSize(OUT PSIZE_T lpMinimumFileCacheSize,
605                        OUT PSIZE_T lpMaximumFileCacheSize,
606                        OUT PDWORD lpFlags)
607 {
608     STUB;
609     return FALSE;
610 }
611 
612 /*
613  * @unimplemented
614  */
615 BOOL
616 WINAPI
SetSystemFileCacheSize(IN SIZE_T MinimumFileCacheSize,IN SIZE_T MaximumFileCacheSize,IN DWORD Flags)617 SetSystemFileCacheSize(IN SIZE_T MinimumFileCacheSize,
618                        IN SIZE_T MaximumFileCacheSize,
619                        IN DWORD Flags)
620 {
621     STUB;
622     return FALSE;
623 }
624 
625 /*
626  * @unimplemented
627  */
628 LONG
629 WINAPI
GetCurrentPackageId(UINT32 * BufferLength,BYTE * Buffer)630 GetCurrentPackageId(UINT32 *BufferLength,
631                     BYTE *Buffer)
632 {
633     STUB;
634     return APPMODEL_ERROR_NO_PACKAGE;
635 }
636