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