|
22 | 22 |
|
23 | 23 | /* PRIVATE VARIABLES **********************************************************/
|
24 | 24 |
|
| 25 | +#define CMOS_RAM_FILE "cmos.ram" |
| 26 | + |
25 | 27 | static HANDLE hCmosRam = INVALID_HANDLE_VALUE;
|
26 | 28 | static CMOS_MEMORY CmosMemory;
|
27 | 29 |
|
@@ -438,41 +440,88 @@ BOOLEAN IsNmiEnabled(VOID)
|
438 | 440 | return NmiEnabled;
|
439 | 441 | }
|
440 | 442 |
|
| 443 | +static inline BOOL |
| 444 | +CmosWriteFile( |
| 445 | + _In_ HANDLE FileHandle, |
| 446 | + _In_ PVOID Buffer, |
| 447 | + _In_ ULONG BufferSize, |
| 448 | + _Out_opt_ PULONG BytesWritten) |
| 449 | +{ |
| 450 | + BOOL Success; |
| 451 | + ULONG Written; |
| 452 | + |
| 453 | + SetFilePointer(FileHandle, 0, NULL, FILE_BEGIN); |
| 454 | + Success = WriteFile(FileHandle, Buffer, BufferSize, &Written, NULL); |
| 455 | + if (BytesWritten) |
| 456 | + *BytesWritten = (Success ? Written : 0); |
| 457 | + return Success; |
| 458 | +} |
| 459 | + |
441 | 460 | VOID CmosInitialize(VOID)
|
442 | 461 | {
|
443 |
| - DWORD CmosSize = sizeof(CmosMemory); |
| 462 | + BOOL Success; |
| 463 | + WCHAR CmosPath[_countof(NtVdmPath) + _countof("\\" CMOS_RAM_FILE)]; |
444 | 464 |
|
445 |
| - /* File must not be opened before */ |
| 465 | + /* CMOS file must not be opened before */ |
446 | 466 | ASSERT(hCmosRam == INVALID_HANDLE_VALUE);
|
447 | 467 |
|
| 468 | + /* Always open (and if needed, create) a RAM file with shared access */ |
| 469 | + Success = NT_SUCCESS(RtlStringCbPrintfW(CmosPath, |
| 470 | + sizeof(CmosPath), |
| 471 | + L"%s\\" L(CMOS_RAM_FILE), |
| 472 | + NtVdmPath)); |
| 473 | + if (!Success) |
| 474 | + DPRINT1("Could not create CMOS file path!\n"); |
| 475 | + |
| 476 | + if (Success) |
| 477 | + { |
| 478 | + SetLastError(ERROR_SUCCESS); |
| 479 | + hCmosRam = CreateFileW(CmosPath, |
| 480 | + GENERIC_READ | GENERIC_WRITE, |
| 481 | + FILE_SHARE_READ | FILE_SHARE_WRITE, |
| 482 | + NULL, |
| 483 | + OPEN_ALWAYS, |
| 484 | + FILE_ATTRIBUTE_NORMAL, |
| 485 | + NULL); |
| 486 | + Success = (hCmosRam != INVALID_HANDLE_VALUE); |
| 487 | + if (!Success) |
| 488 | + DPRINT1("CMOS opening failed (Error: %u)\n", GetLastError()); |
| 489 | + } |
| 490 | + |
448 | 491 | /* Clear the CMOS memory */
|
449 | 492 | RtlZeroMemory(&CmosMemory, sizeof(CmosMemory));
|
450 | 493 |
|
451 |
| - /* Always open (and if needed, create) a RAM file with shared access */ |
452 |
| - SetLastError(0); // For debugging purposes |
453 |
| - hCmosRam = CreateFileW(L"cmos.ram", |
454 |
| - GENERIC_READ | GENERIC_WRITE, |
455 |
| - FILE_SHARE_READ | FILE_SHARE_WRITE, |
456 |
| - NULL, |
457 |
| - OPEN_ALWAYS, |
458 |
| - FILE_ATTRIBUTE_NORMAL, |
459 |
| - NULL); |
460 |
| - DPRINT1("CMOS opening %s (Error: %u)\n", hCmosRam != INVALID_HANDLE_VALUE ? "succeeded" : "failed", GetLastError()); |
461 |
| - |
462 |
| - if (hCmosRam != INVALID_HANDLE_VALUE) |
| 494 | + /* Load the file only if it already existed and was opened, not newly created */ |
| 495 | + if (Success) |
463 | 496 | {
|
464 |
| - BOOL Success; |
465 |
| - |
466 |
| - /* Attempt to fill the CMOS memory with the RAM file */ |
467 |
| - SetLastError(0); // For debugging purposes |
468 |
| - Success = ReadFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize, NULL); |
469 |
| - if (CmosSize != sizeof(CmosMemory)) |
| 497 | + if ((GetLastError() == ERROR_ALREADY_EXISTS) /* || (GetLastError() == ERROR_FILE_EXISTS) */) |
| 498 | + { |
| 499 | + /* Attempt to load the CMOS memory from the RAM file */ |
| 500 | + DWORD CmosSize = sizeof(CmosMemory); |
| 501 | + Success = ReadFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize, NULL); |
| 502 | + if (!Success) |
| 503 | + { |
| 504 | + DPRINT1("CMOS loading failed (Error: %u)\n", GetLastError()); |
| 505 | + } |
| 506 | + else if (CmosSize != sizeof(CmosMemory)) |
| 507 | + { |
| 508 | + /* Invalid CMOS RAM file; reinitialize the CMOS memory */ |
| 509 | + DPRINT1("Invalid CMOS file, read %u bytes, expected %u bytes\n", |
| 510 | + CmosSize, sizeof(CmosMemory)); |
| 511 | + Success = FALSE; |
| 512 | + } |
| 513 | + if (!Success) |
| 514 | + { |
| 515 | + /* Reset the CMOS memory and its RAM file */ |
| 516 | + RtlZeroMemory(&CmosMemory, sizeof(CmosMemory)); |
| 517 | + CmosWriteFile(hCmosRam, &CmosMemory, sizeof(CmosMemory), NULL); |
| 518 | + } |
| 519 | + } |
| 520 | + else |
470 | 521 | {
|
471 |
| - /* Bad CMOS RAM file. Reinitialize the CMOS memory. */ |
472 |
| - DPRINT1("Invalid CMOS file, read bytes %u, expected bytes %u\n", CmosSize, sizeof(CmosMemory)); |
473 |
| - RtlZeroMemory(&CmosMemory, sizeof(CmosMemory)); |
| 522 | + /* Reset the CMOS RAM file */ |
| 523 | + CmosWriteFile(hCmosRam, &CmosMemory, sizeof(CmosMemory), NULL); |
474 | 524 | }
|
475 |
| - DPRINT1("CMOS loading %s (Error: %u)\n", Success ? "succeeded" : "failed", GetLastError()); |
476 | 525 | SetFilePointer(hCmosRam, 0, NULL, FILE_BEGIN);
|
477 | 526 | }
|
478 | 527 |
|
@@ -518,19 +567,25 @@ VOID CmosInitialize(VOID)
|
518 | 567 |
|
519 | 568 | VOID CmosCleanup(VOID)
|
520 | 569 | {
|
521 |
| - DWORD CmosSize = sizeof(CmosMemory); |
522 |
| - |
523 |
| - if (hCmosRam == INVALID_HANDLE_VALUE) return; |
524 |
| - |
525 | 570 | DestroyHardwareTimer(PeriodicTimer);
|
526 | 571 | DestroyHardwareTimer(ClockTimer);
|
527 | 572 |
|
528 |
| - /* Flush the CMOS memory back to the RAM file and close it */ |
529 |
| - SetFilePointer(hCmosRam, 0, NULL, FILE_BEGIN); |
530 |
| - WriteFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize, NULL); |
| 573 | + if (hCmosRam != INVALID_HANDLE_VALUE) |
| 574 | + { |
| 575 | + /* Flush the CMOS memory back to the RAM file and close it */ |
| 576 | + BOOL Success; |
| 577 | + DWORD CmosSize = sizeof(CmosMemory); |
531 | 578 |
|
532 |
| - CloseHandle(hCmosRam); |
533 |
| - hCmosRam = INVALID_HANDLE_VALUE; |
| 579 | + Success = CmosWriteFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize); |
| 580 | + if (!Success || (CmosSize != sizeof(CmosMemory))) |
| 581 | + { |
| 582 | + DPRINT1("CMOS saving failed (Error: %u), written %u bytes, expected %u bytes\n", |
| 583 | + GetLastError(), CmosSize, sizeof(CmosMemory)); |
| 584 | + } |
| 585 | + |
| 586 | + CloseHandle(hCmosRam); |
| 587 | + hCmosRam = INVALID_HANDLE_VALUE; |
| 588 | + } |
534 | 589 | }
|
535 | 590 |
|
536 | 591 | /* EOF */
|
0 commit comments