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 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 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 133 GetLargePageMinimum(VOID) 134 { 135 return SharedUserData->LargePageMinimum; 136 } 137 138 /* 139 * @implemented 140 */ 141 VOID 142 WINAPI 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 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 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 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 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 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 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 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 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 NTSTATUS Status; 428 UNICODE_STRING VariableName, Namespace; 429 GUID VendorGuid; 430 ULONG Length; 431 432 /* Check input parameters and build NT strings */ 433 if (!lpName || !lpGuid) 434 { 435 SetLastError(ERROR_INVALID_PARAMETER); 436 return 0; 437 } 438 RtlInitUnicodeString(&VariableName, lpName); 439 RtlInitUnicodeString(&Namespace, lpGuid); 440 Status = RtlGUIDFromString(&Namespace, &VendorGuid); 441 if (!NT_SUCCESS(Status)) 442 { 443 BaseSetLastNTError(Status); 444 return 0; 445 } 446 447 /* Query firmware system environment variable value */ 448 Length = nSize; 449 Status = NtQuerySystemEnvironmentValueEx(&VariableName, 450 &VendorGuid, 451 pBuffer, 452 &Length, 453 pdwAttribubutes); 454 if (!NT_SUCCESS(Status)) 455 { 456 BaseSetLastNTError(Status); 457 return 0; 458 } 459 460 return Length; 461 } 462 463 _Success_(return > 0) 464 DWORD 465 WINAPI 466 GetFirmwareEnvironmentVariableExA( 467 _In_ LPCSTR lpName, 468 _In_ LPCSTR lpGuid, 469 _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer, 470 _In_ DWORD nSize, 471 _Out_opt_ PDWORD pdwAttribubutes) 472 { 473 NTSTATUS Status; 474 DWORD Length; 475 UNICODE_STRING VariableName, Namespace; 476 ANSI_STRING AnsiVariableName, AnsiNamespace; 477 478 /* Check input parameters and build NT strings */ 479 if (!lpName || !lpGuid) 480 { 481 SetLastError(ERROR_INVALID_PARAMETER); 482 return 0; 483 } 484 RtlInitString(&AnsiVariableName, lpName); 485 Status = RtlAnsiStringToUnicodeString(&VariableName, &AnsiVariableName, TRUE); 486 if (!NT_SUCCESS(Status)) 487 { 488 BaseSetLastNTError(Status); 489 return 0; 490 } 491 RtlInitString(&AnsiNamespace, lpGuid); 492 Status = RtlAnsiStringToUnicodeString(&Namespace, &AnsiNamespace, TRUE); 493 if (!NT_SUCCESS(Status)) 494 { 495 RtlFreeUnicodeString(&VariableName); 496 BaseSetLastNTError(Status); 497 return 0; 498 } 499 500 /* Call unicode version interface */ 501 Length = GetFirmwareEnvironmentVariableExW(VariableName.Buffer, 502 Namespace.Buffer, 503 pBuffer, 504 nSize, 505 pdwAttribubutes); 506 507 /* Cleanup and return */ 508 RtlFreeUnicodeString(&Namespace); 509 RtlFreeUnicodeString(&VariableName); 510 return Length; 511 } 512 513 _Success_(return > 0) 514 DWORD 515 WINAPI 516 GetFirmwareEnvironmentVariableW( 517 _In_ LPCWSTR lpName, 518 _In_ LPCWSTR lpGuid, 519 _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer, 520 _In_ DWORD nSize) 521 { 522 return GetFirmwareEnvironmentVariableExW(lpName, lpGuid, pBuffer, nSize, NULL); 523 } 524 525 _Success_(return > 0) 526 DWORD 527 WINAPI 528 GetFirmwareEnvironmentVariableA( 529 _In_ LPCSTR lpName, 530 _In_ LPCSTR lpGuid, 531 _Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer, 532 _In_ DWORD nSize) 533 { 534 return GetFirmwareEnvironmentVariableExA(lpName, lpGuid, pBuffer, nSize, NULL); 535 } 536 537 BOOL 538 WINAPI 539 SetFirmwareEnvironmentVariableExW( 540 _In_ LPCWSTR lpName, 541 _In_ LPCWSTR lpGuid, 542 _In_reads_bytes_opt_(nSize) PVOID pValue, 543 _In_ DWORD nSize, 544 _In_ DWORD dwAttributes) 545 { 546 NTSTATUS Status; 547 UNICODE_STRING VariableName, Namespace; 548 GUID VendorGuid; 549 550 /* Check input parameters and build NT strings */ 551 if (!lpName || !lpGuid) 552 { 553 SetLastError(ERROR_INVALID_PARAMETER); 554 return FALSE; 555 } 556 RtlInitUnicodeString(&VariableName, lpName); 557 RtlInitUnicodeString(&Namespace, lpGuid); 558 Status = RtlGUIDFromString(&Namespace, &VendorGuid); 559 if (!NT_SUCCESS(Status)) 560 { 561 BaseSetLastNTError(Status); 562 return FALSE; 563 } 564 565 /* Set firmware system environment variable value */ 566 Status = NtSetSystemEnvironmentValueEx(&VariableName, 567 &VendorGuid, 568 pValue, 569 nSize, 570 dwAttributes); 571 if (!NT_SUCCESS(Status)) 572 { 573 BaseSetLastNTError(Status); 574 return FALSE; 575 } 576 577 return TRUE; 578 } 579 580 BOOL 581 WINAPI 582 SetFirmwareEnvironmentVariableExA( 583 _In_ LPCSTR lpName, 584 _In_ LPCSTR lpGuid, 585 _In_reads_bytes_opt_(nSize) PVOID pValue, 586 _In_ DWORD nSize, 587 _In_ DWORD dwAttributes) 588 { 589 NTSTATUS Status; 590 BOOL Result; 591 UNICODE_STRING VariableName, Namespace; 592 ANSI_STRING AnsiVariableName, AnsiNamespace; 593 594 /* Check input parameters and build NT strings */ 595 if (!lpName || !lpGuid) 596 { 597 SetLastError(ERROR_INVALID_PARAMETER); 598 return FALSE; 599 } 600 RtlInitString(&AnsiVariableName, lpName); 601 Status = RtlAnsiStringToUnicodeString(&VariableName, &AnsiVariableName, TRUE); 602 if (!NT_SUCCESS(Status)) 603 { 604 BaseSetLastNTError(Status); 605 return FALSE; 606 } 607 RtlInitString(&AnsiNamespace, lpGuid); 608 Status = RtlAnsiStringToUnicodeString(&Namespace, &AnsiNamespace, TRUE); 609 if (!NT_SUCCESS(Status)) 610 { 611 RtlFreeUnicodeString(&VariableName); 612 BaseSetLastNTError(Status); 613 return FALSE; 614 } 615 616 /* Call unicode version interface */ 617 Result = SetFirmwareEnvironmentVariableExW(VariableName.Buffer, 618 Namespace.Buffer, 619 pValue, 620 nSize, 621 dwAttributes); 622 623 /* Cleanup and return */ 624 RtlFreeUnicodeString(&Namespace); 625 RtlFreeUnicodeString(&VariableName); 626 return Result; 627 } 628 629 BOOL 630 WINAPI 631 SetFirmwareEnvironmentVariableW( 632 _In_ LPCWSTR lpName, 633 _In_ LPCWSTR lpGuid, 634 _In_reads_bytes_opt_(nSize) PVOID pValue, 635 _In_ DWORD nSize) 636 { 637 return SetFirmwareEnvironmentVariableExW(lpName, 638 lpGuid, 639 pValue, 640 nSize, 641 VARIABLE_ATTRIBUTE_NON_VOLATILE); 642 } 643 644 BOOL 645 WINAPI 646 SetFirmwareEnvironmentVariableA( 647 _In_ LPCSTR lpName, 648 _In_ LPCSTR lpGuid, 649 _In_reads_bytes_opt_(nSize) PVOID pValue, 650 _In_ DWORD nSize) 651 { 652 return SetFirmwareEnvironmentVariableExA(lpName, 653 lpGuid, 654 pValue, 655 nSize, 656 VARIABLE_ATTRIBUTE_NON_VOLATILE); 657 } 658 659 /** 660 * @name EnumSystemFirmwareTables 661 * @implemented 662 * 663 * Obtains firmware table identifiers. 664 * https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-enumsystemfirmwaretables 665 * 666 * @param FirmwareTableProviderSignature 667 * Can be either ACPI, FIRM, or RSMB. 668 * 669 * @param pFirmwareTableBuffer 670 * Pointer to the output buffer, can be NULL. 671 * 672 * @param BufferSize 673 * Size of the output buffer. 674 * 675 * @return 676 * Actual size of the data in case of success, 0 otherwise. 677 * 678 * @remarks 679 * Data would be written to buffer only if the specified size is 680 * larger or equal to the actual size, in the other case Last Error 681 * value would be set to ERROR_INSUFFICIENT_BUFFER. 682 * In case of incorrect provider signature, Last Error value would be 683 * set to ERROR_INVALID_FUNCTION. 684 * 685 */ 686 UINT 687 WINAPI 688 EnumSystemFirmwareTables( 689 _In_ DWORD FirmwareTableProviderSignature, 690 _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableEnumBuffer, 691 _In_ DWORD BufferSize) 692 { 693 return BaseQuerySystemFirmware(FirmwareTableProviderSignature, 694 0, 695 pFirmwareTableEnumBuffer, 696 BufferSize, 697 SystemFirmwareTable_Enumerate); 698 } 699 700 /** 701 * @name GetSystemFirmwareTable 702 * @implemented 703 * 704 * Obtains the firmware table data. 705 * https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemfirmwaretable 706 * 707 * @param FirmwareTableProviderSignature 708 * Can be either ACPI, FIRM, or RSMB. 709 * 710 * @param FirmwareTableID 711 * Correct table identifier. 712 * 713 * @param pFirmwareTableBuffer 714 * Pointer to the output buffer, can be NULL. 715 * 716 * @param BufferSize 717 * Size of the output buffer. 718 * 719 * @return 720 * Actual size of the data in case of success, 0 otherwise. 721 * 722 * @remarks 723 * Data would be written to buffer only if the specified size is 724 * larger or equal to the actual size, in the other case Last Error 725 * value would be set to ERROR_INSUFFICIENT_BUFFER. 726 * In case of incorrect provider signature, Last Error value would be 727 * set to ERROR_INVALID_FUNCTION. 728 * Also Last Error value becomes ERROR_NOT_FOUND if incorrect 729 * table identifier was specified along with ACPI provider, and 730 * ERROR_INVALID_PARAMETER along with FIRM provider. The RSMB provider 731 * accepts any table identifier. 732 * 733 */ 734 UINT 735 WINAPI 736 GetSystemFirmwareTable( 737 _In_ DWORD FirmwareTableProviderSignature, 738 _In_ DWORD FirmwareTableID, 739 _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableBuffer, 740 _In_ DWORD BufferSize) 741 { 742 return BaseQuerySystemFirmware(FirmwareTableProviderSignature, 743 FirmwareTableID, 744 pFirmwareTableBuffer, 745 BufferSize, 746 SystemFirmwareTable_Get); 747 } 748 749 /* 750 * @unimplemented 751 */ 752 BOOL 753 WINAPI 754 GetSystemFileCacheSize(OUT PSIZE_T lpMinimumFileCacheSize, 755 OUT PSIZE_T lpMaximumFileCacheSize, 756 OUT PDWORD lpFlags) 757 { 758 STUB; 759 return FALSE; 760 } 761 762 /* 763 * @unimplemented 764 */ 765 BOOL 766 WINAPI 767 SetSystemFileCacheSize(IN SIZE_T MinimumFileCacheSize, 768 IN SIZE_T MaximumFileCacheSize, 769 IN DWORD Flags) 770 { 771 STUB; 772 return FALSE; 773 } 774 775 /* 776 * @unimplemented 777 */ 778 LONG 779 WINAPI 780 GetCurrentPackageId(UINT32 *BufferLength, 781 BYTE *Buffer) 782 { 783 STUB; 784 return APPMODEL_ERROR_NO_PACKAGE; 785 } 786