diff --git a/lib/ewfapi.h b/lib/ewfapi.h new file mode 100644 index 0000000..149bc0c --- /dev/null +++ b/lib/ewfapi.h @@ -0,0 +1,336 @@ +/**************************************************************************** + +Copyright (c) 2003 Microsoft Corporation + +Module Name: + + ewfapi.h + +Abstract: + + Defines the EWF APIs + +Environment: + + User mode + +Revision History: + + +****************************************************************************/ +#ifndef __EWFAPI_H__ +#define __EWFAPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef EWFIMP +#define EWFIMP __declspec(dllimport) +#endif + + +typedef struct _EWF_VOLUME_NAME_ENTRY +{ + struct _EWF_VOLUME_NAME_ENTRY * Next; + WCHAR Name[1]; +} EWF_VOLUME_NAME_ENTRY, *PEWF_VOLUME_NAME_ENTRY; + + +typedef enum +{ + EWF_NO_CMD = 0, // no pending command + EWF_ENABLE, // overlay will be enabled + EWF_DISABLE, // overlay will be disabled + EWF_SET_LEVEL, // overlay level will be set + EWF_COMMIT // current level will be committed to the protected volume +} EWF_CMD; + +typedef enum +{ + EWF_ENABLED, // The overlay is enabled on the volume + EWF_DISABLED // The overlay is disabled on the volume +} EWF_STATE; + +typedef enum +{ + EWF_DISK, // DISK overlay + EWF_RAM, // RAM overlay, with an associated overlay volume store + EWF_RAM_REG, // RAM overlay, without an associated overlay volume store +} EWF_TYPE, *PEWF_TYPE; + + +#define EWF_MAX_DEVICE_NAME_LENGTH (256) +#define EWF_VOLUME_ID_SIZE (16) + +typedef struct _EWF_VOLUME_DESC +{ + WCHAR DeviceName[EWF_MAX_DEVICE_NAME_LENGTH]; // Device name of the volume + UCHAR VolumeID[EWF_VOLUME_ID_SIZE]; // 16 byte volume identifier +} EWF_VOLUME_DESC, * PEWF_VOLUME_DESC; + + +// +// This is a variable size structure depending on how many protected overlay +// volumes there are. +// +typedef struct _EWF_OVERLAY_STORE_CONFIG +{ + ULONG FormatVersion; // Version of Overlay-Store format + LONGLONG VolumeSize; // Size of the overlay volume in bytes + + ULONG NumSegments; // Number of segments that the volume is divided into + ULONG FreeSegments; // Number of segments that are free + ULONG SegmentSize; // Size of each segment in bytes + + ULONG MaxVolumes; // Maximum number of protected volumes + ULONG NumVolumes; // Number of currently protected volumes + USHORT MaxLevels; // Maximum number of overlay levels + EWF_VOLUME_DESC VolumeDescArray[1]; + // The array holds NumVolume count volume descriptions +} EWF_OVERLAY_STORE_CONFIG, * PEWF_OVERLAY_STORE_CONFIG; + + +typedef struct _EWF_COMMAND +{ + EWF_CMD Command; // ENABLE, DISABLE, etc.. + ULONG Param1; // command first parameter. + ULONG Param2; // command second parameter. + +} EWF_COMMAND, *PEWF_COMMAND; + + +#define EWF_MAX_LEVEL_NAME_LENGTH (64) + +typedef struct _EWF_LEVEL_DESC +{ + WCHAR LevelName[EWF_MAX_LEVEL_NAME_LENGTH]; + // friendly name of the level + // If the length is equal to EWF_MAX_LEVEL_NAME_LENGTH + // then no null terminator is stored. + FILETIME LevelEndTime; // time at which the level was ended + LONGLONG LevelDataSize; // Size of the data in the level in bytes +} EWF_LEVEL_DESC, * PEWF_LEVEL_DESC; + + +#define EWF_MAX_PERSISTENT_DATA (32) // maximum number of bytes that can be persisted + + +typedef struct _EWF_VOLUME_CONFIG +{ + EWF_TYPE Type; // Type of overlay for this volume + EWF_STATE State; // state of the overlay for this volume, ENABLED or DISABLED + EWF_COMMAND BootCommand; // Command to execute on next restart + + UCHAR PersistentData[EWF_MAX_PERSISTENT_DATA]; + // Small amount of persistent data that survives a restore + + USHORT MaxLevels; // Maximum number of checkpoint levels for this volume + ULONG ClumpSize; // 512 bytes + USHORT CurrentLevel; // Current checkpoint level + + union + { + struct + { + LONGLONG DiskMapSize; // Size of the mapping data on disk + LONGLONG DiskDataSize; // Size of the data stored on disk for this protected volume + } DiskOverlay; + + struct + { + LONGLONG RamDataSize; // Size of the data stored in RAM for this protected volume + } RamOverlay; + }; + ULONG MemMapSize; // Size of the mapping data in memory + + EWF_VOLUME_DESC VolumeDesc; // volume device name, and volume ID + + EWF_LEVEL_DESC LevelDescArray[1]; // Level descripton and end time, and level data size + +} EWF_VOLUME_CONFIG, * PEWF_VOLUME_CONFIG; + + +EWFIMP +WCHAR +WINAPI +EwfMgrGetDriveLetterFromVolumeName( + IN LPCWSTR lpVolumeName + ); + + +EWFIMP +BOOL +WINAPI +EwfMgrVolumeNameListIsEmpty( + IN PEWF_VOLUME_NAME_ENTRY pVolumeNameList + ); + + +EWFIMP +VOID +WINAPI +EwfMgrVolumeNameEntryPop( + IN PEWF_VOLUME_NAME_ENTRY * ppVolumeNameList + ); + + +EWFIMP +VOID +WINAPI +EwfMgrVolumeNameListDelete( + IN PEWF_VOLUME_NAME_ENTRY pVolumeNameList + ); + + +EWFIMP +HANDLE +WINAPI +EwfMgrOpenProtected( + IN LPCWSTR lpVolume + ); + +EWFIMP +BOOL +WINAPI +EwfMgrClose( + IN HANDLE hDevice + ); + +EWFIMP +BOOL +WINAPI +EwfMgrClearCommand( + IN HANDLE hDevice + ); + + +EWFIMP +BOOL +WINAPI +EwfMgrSetPersistentData( + IN HANDLE hDevice, + IN LPBYTE lpPersistentData, + IN DWORD cbPersistentData + ); + + +EWFIMP +BOOL +WINAPI +EwfMgrGetPersistentData( + IN HANDLE hDevice, + OUT LPBYTE lpPersistentData, + IN DWORD cbPersistentData + ); + + + +EWFIMP +BOOL +WINAPI +EwfMgrCheckpoint( + IN HANDLE hDevice, + IN OPTIONAL LPCWSTR lpDescription + ); + + +EWFIMP +BOOL +WINAPI +EwfMgrRestore( + IN HANDLE hDevice + ); + +EWFIMP +BOOL +WINAPI +EwfMgrDisable( + IN HANDLE hDevice, + IN BOOL fCommit + ); + + +EWFIMP +BOOL +WINAPI +EwfMgrEnable( + IN HANDLE hDevice + ); + +EWFIMP +BOOL +WINAPI +EwfMgrCommit( + IN HANDLE hDevice + ); + +EWFIMP +BOOL +WINAPI +EwfMgrCommitAndDisableLive( + IN HANDLE hDevice + ); + +EWFIMP +BOOL +WINAPI +EwfMgrCommitFile( + IN HANDLE hDevice, + IN LPWSTR lpFile + ); + +EWFIMP +BOOL +WINAPI +EwfMgrSetLevel( + IN HANDLE hDevice, + IN OPTIONAL LPCWSTR lpDescription, + IN int Level, + IN BOOL fDeleteLevel + ); + +EWFIMP +PEWF_VOLUME_CONFIG +WINAPI +EwfMgrGetProtectedVolumeConfig( + IN HANDLE hDevice + ); + +EWFIMP +PEWF_VOLUME_NAME_ENTRY +WINAPI +EwfMgrGetProtectedVolumeList( + VOID + ); + +EWFIMP +HANDLE +WINAPI +EwfMgrOpenOverlayStore( + IN BOOL fOpenForAsyncIO + ); + +EWFIMP +PEWF_OVERLAY_STORE_CONFIG +WINAPI +EwfMgrGetOverlayStoreConfig( + IN HANDLE hDevice + ); + +EWFIMP +BOOL +WINAPI +EwfMgrRegisterLowSpaceNotification( + IN HANDLE hDevice, + IN LONGLONG FreeBytesRemaining, + IN LPOVERLAPPED lpOverlapped + ); + + +#ifdef __cplusplus +} +#endif + +#endif // __EWFAPI_H__ + diff --git a/lib/ewfapi.lib b/lib/ewfapi.lib new file mode 100644 index 0000000..82bbacd Binary files /dev/null and b/lib/ewfapi.lib differ diff --git a/meson.build b/meson.build index db2a844..bab49a9 100644 --- a/meson.build +++ b/meson.build @@ -39,6 +39,9 @@ else endif assert(openssl_lib.found(), 'Please download openssl!') +ewfapi_lib = meson.get_compiler('c').find_library('ewfapi', dirs: [ + join_paths(meson.source_root(), 'lib') +], required: true) freeglut_lib = meson.get_compiler('c').find_library('freeglut', dirs: [ join_paths(meson.source_root(), 'lib') ], required: true) diff --git a/src/micetools/amBackupStructs.h b/src/micetools/amBackupStructs.h index f6748ad..e5bac67 100644 --- a/src/micetools/amBackupStructs.h +++ b/src/micetools/amBackupStructs.h @@ -144,13 +144,9 @@ typedef struct { typedef struct { uint32_t m_Crc; - uint32_t m_Uk1; - uint32_t m_Uk2; - uint32_t m_Uk3; - uint32_t m_Uk4; - uint32_t m_Uk5; - uint32_t m_Uk6; - uint32_t m_Uk7; + uint8_t m_Uk04[4]; + char m_Name[16]; + uint8_t m_Uk18[8]; } AM_SYSDATAwH_ALPB_COMPUTER_NAME, *PAM_SYSDATAwH_ALPB_COMPUTER_NAME; #pragma pack(pop) diff --git a/src/micetools/dll/drivers/mxhwreset.c b/src/micetools/dll/drivers/mxhwreset.c index feb5fbe..c9d0f80 100644 --- a/src/micetools/dll/drivers/mxhwreset.c +++ b/src/micetools/dll/drivers/mxhwreset.c @@ -1,17 +1,16 @@ #include "mx.h" -BOOL WINAPI mxhwreset_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, - LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped) { +BOOL WINAPI mxhwreset_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCode, LPVOID lpInBuffer, + DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, + LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { switch (dwIoControlCode) { case IOCTL_MXHWRESET_RESET: if (lpBytesReturned) *lpBytesReturned = 0; - break; + ExitProcess(-1); default: log_warning(plfMxHwreset, "unhandled 0x%08x", dwIoControlCode); return FALSE; } - return TRUE; } void setup_mxhwreset() { diff --git a/src/micetools/dll/drivers/mxjvs.c b/src/micetools/dll/drivers/mxjvs.c index 683e006..de9dbf3 100644 --- a/src/micetools/dll/drivers/mxjvs.c +++ b/src/micetools/dll/drivers/mxjvs.c @@ -61,6 +61,8 @@ void mxjvs_handle(unsigned char* lpMaskedIn, short nMaskedCount, unsigned char* if ((++jvsDTHCount) > _countof(jvsDTHistory)) jvsDTHCount = _countof(jvsDTHistory); jvsRate = (jvsRateAccum > 0.0f) ? (1.0f / (jvsRateAccum / (float)jvsDTHCount)) : FLT_MAX; + + // log_game(plfAime, "jvs rate: %.2fHz", jvsRate); } last_tick = now; diff --git a/src/micetools/dll/gui/gui.c b/src/micetools/dll/gui/gui.c index 15a4062..c3562fe 100644 --- a/src/micetools/dll/gui/gui.c +++ b/src/micetools/dll/gui/gui.c @@ -168,7 +168,7 @@ void hud_fps() { igText("FPS: %.1f", io->Framerate); igText(" dT: %.2fms", 1000 / io->Framerate); - igText("JVS Rate: %.2f", jvsRate); + igText("JVS Rate: %.2fHz", jvsRate); } igEnd(); @@ -957,8 +957,7 @@ void tab_system_buttons() { igTextUnformatted(keyName, NULL); } igNextColumn(); - if (igButton("Bind##Bind1P", vec0)) - igOpenPopup_Str("BindSys1P", ImGuiPopupFlags_None); + if (igButton("Bind##Bind1P", vec0)) igOpenPopup_Str("BindSys1P", ImGuiPopupFlags_None); if (MiceConfig.keys.card_p1) { igSameLine(0, -1); if (igButton("Clear##Clear1P", vec0)) { @@ -984,8 +983,7 @@ void tab_system_buttons() { igTextUnformatted(keyName, NULL); } igNextColumn(); - if (igButton("Bind##Bind2P", vec0)) - igOpenPopup_Str("BindSys2P", ImGuiPopupFlags_None); + if (igButton("Bind##Bind2P", vec0)) igOpenPopup_Str("BindSys2P", ImGuiPopupFlags_None); if (MiceConfig.keys.card_p2) { igSameLine(0, -1); if (igButton("Clear##Clear2P", vec0)) { @@ -1090,11 +1088,12 @@ void hud_control(ImGuiKey open_key) { void __stdcall hud_gui(unsigned int hookType, IDirect3DDevice9* dev) { static bool lastAnyOpen = false; - bool anyOpen = showControl || showEeprom || showSram || showCardP1; + bool anyOpen = showControl || showEeprom || showSram || showCardP1 || showFps; if (anyOpen != lastAnyOpen) { changeCursorState = anyOpen ? 1 : 0; lastAnyOpen = anyOpen; } + // if (!anyOpen) return; static bool initialized = false; if (!initialized) { @@ -1123,8 +1122,10 @@ void __stdcall hud_gui(unsigned int hookType, IDirect3DDevice9* dev) { if (hookType == UI_HOOK_DX9) { igEndFrame(); - igRender(); - ImGui_ImplDX9_RenderDrawData(igGetDrawData()); + if (anyOpen) { + igRender(); + ImGui_ImplDX9_RenderDrawData(igGetDrawData()); + } } else if (hookType == UI_HOOK_GLUT) { igRender(); ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); diff --git a/src/micetools/dll/hooks/drive/drive.c b/src/micetools/dll/hooks/drive/drive.c index aadeffc..a4dc6ef 100644 --- a/src/micetools/dll/hooks/drive/drive.c +++ b/src/micetools/dll/hooks/drive/drive.c @@ -373,6 +373,7 @@ char matchWorkFilename[MAX_PATH + 1]; inline static BOOL matchVolume(disk_volume_t* volume, LPCSTR lpRootPathName, DWORD match) { if (match & VOL_MATCH_GUID) { strcpy_s(matchWorkFilename, sizeof matchWorkFilename, volume->m_FilenameA); + if (strcmp(matchWorkFilename, lpRootPathName) == 0) return TRUE; strcat_s(matchWorkFilename, sizeof matchWorkFilename, "\\"); if (strcmp(matchWorkFilename, lpRootPathName) == 0) return TRUE; } @@ -385,6 +386,12 @@ inline static BOOL matchVolume(disk_volume_t* volume, LPCSTR lpRootPathName, DWO "\\\\.\\%c:", char_upper(volume->m_MountPoint)); if (strstr(lpRootPathName, matchWorkFilename) == lpRootPathName) return TRUE; } + if (match & VOL_MATCH_PATH && volume->m_pDrive && volume->m_pPartition) { + sprintf_s(matchWorkFilename, sizeof matchWorkFilename, "\\device\\harddisk%d\\partition%d", + volume->m_pDrive->m_DriveNumber, volume->m_pPartition->m_PartitionNumber); + + if (_stricmp(lpRootPathName, matchWorkFilename) == 0) return TRUE; + } if (match & VOL_MATCH_DOS_DEVICE && volume->m_MountPoint) { if (char_lower(volume->m_MountPoint) == char_lower(lpRootPathName[0])) { if (lpRootPathName[1] == ':' && lpRootPathName[2] == '\0') return TRUE; @@ -779,6 +786,7 @@ void hook_drives() { NULL); hook("Kernel32.dll", "DeleteVolumeMountPointA", &FakeDeleteVolumeMountPointA, NULL); hook("Kernel32.dll", "SetVolumeMountPointA", &FakeSetVolumeMountPointA, NULL); + hook("Kernel32.dll", "DefineDosDeviceA", &FakeDefineDosDeviceA, NULL); hook("Kernel32.dll", "GetDriveTypeA", &FakeGetDriveTypeA, (void**)&TrueGetDriveTypeA); hook("Kernel32.dll", "GetDiskFreeSpaceExA", &FakeGetDiskFreeSpaceExA, (void**)&TrueGetDiskFreeSpaceExA); diff --git a/src/micetools/dll/hooks/drive/drive.h b/src/micetools/dll/hooks/drive/drive.h index 8ed8e79..12f5041 100644 --- a/src/micetools/dll/hooks/drive/drive.h +++ b/src/micetools/dll/hooks/drive/drive.h @@ -78,6 +78,7 @@ BOOL WINAPI FakeGetVolumePathNamesForVolumeNameA(LPCSTR lpszVolumeName, LPCH lps DWORD cchBufferLength, PDWORD lpcchReturnLength); BOOL WINAPI FakeDeleteVolumeMountPointA(LPCSTR lpszVolumeMountPoint); BOOL WINAPI FakeSetVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPCSTR lpszVolumeName); +BOOL WINAPI FakeDefineDosDeviceA(DWORD dwFlags, LPCSTR lpDeviceName, LPCSTR lpTargetPath); DWORD WINAPI FakeQueryDosDeviceA(LPCSTR lpDeviceName, LPSTR lpTargetPath, DWORD ucchMax); DWORD WINAPI FakeQueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax); BOOL WINAPI FakeDefineDosDeviceW(DWORD dwFlags, LPCWSTR lpDeviceName, LPCWSTR lpTargetPath); diff --git a/src/micetools/dll/hooks/drive/hooks.c b/src/micetools/dll/hooks/drive/hooks.c index 6593c0e..a1c18de 100644 --- a/src/micetools/dll/hooks/drive/hooks.c +++ b/src/micetools/dll/hooks/drive/hooks.c @@ -19,26 +19,28 @@ disk_volume_t* incrementFindIndex(HANDLE hFindVolume) { continue; } if (find_index->partition > 3) { - if (AVAILABLE_DISKS[find_index->disk].m_Disk - ->m_Extended[find_index->partition - 4] + if (AVAILABLE_DISKS[find_index->disk] + .m_Disk->m_Extended[find_index->partition - 4] .m_PartitionNumber == 0) { find_index->disk++; find_index->partition = 0; continue; } - return &(AVAILABLE_DISKS[find_index->disk].m_Disk - ->m_Extended[(find_index->partition++) - 4] + return &(AVAILABLE_DISKS[find_index->disk] + .m_Disk->m_Extended[(find_index->partition++) - 4] .m_Volume); } - if (AVAILABLE_DISKS[find_index->disk].m_Disk - ->m_Partitions[find_index->partition] + if (AVAILABLE_DISKS[find_index->disk] + .m_Disk->m_Partitions[find_index->partition] .m_PartitionNumber == 0) { find_index->partition = 4; continue; } - return &(AVAILABLE_DISKS[find_index->disk].m_Disk->m_Partitions[find_index->partition++].m_Volume); + return &(AVAILABLE_DISKS[find_index->disk] + .m_Disk->m_Partitions[find_index->partition++] + .m_Volume); } } @@ -182,9 +184,10 @@ BOOL WINAPI FakeDeleteVolumeMountPointA(LPCSTR lpszVolumeMountPoint) { return TRUE; } BOOL WINAPI FakeSetVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPCSTR lpszVolumeName) { - log_trace(plfDrive, "SetVolumeMountPointA(%s)", lpszVolumeMountPoint); + log_misc(plfDrive, "SetVolumeMountPointA(%s, %s)", lpszVolumeMountPoint, lpszVolumeName); disk_volume_t* volume = getVolumeByPath(lpszVolumeName, VOL_MATCH_GUID); if (volume == NULL) { + log_error(plfDrive, "No match found for %s", lpszVolumeName); SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; } @@ -197,6 +200,12 @@ BOOL WINAPI FakeSetVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPCSTR lpszVol volume->m_MountPoint = cMountPoint; return TRUE; } + if (sscanf_s(lpszVolumeMountPoint, "\\\\.\\%c:\\%n", &cMountPoint, 1, &nScan) == 1 && + nScan == 7) { + log_info(plfDrive, "Mounting %s at %c:\\", volume->m_Name, cMountPoint); + volume->m_MountPoint = cMountPoint; + return TRUE; + } if (sscanf_s(lpszVolumeMountPoint, "%c:\\%n", &cMountPoint, 1, &nScan) == 1 && nScan == 3) { log_info(plfDrive, "Mounting %s at %c:\\", volume->m_Name, cMountPoint); volume->m_MountPoint = cMountPoint; @@ -206,6 +215,32 @@ BOOL WINAPI FakeSetVolumeMountPointA(LPCSTR lpszVolumeMountPoint, LPCSTR lpszVol return FALSE; } +BOOL WINAPI FakeDefineDosDeviceA(DWORD dwFlags, LPCSTR lpDeviceName, LPCSTR lpTargetPath) { + disk_volume_t* volume = NULL; + if (dwFlags & DDD_REMOVE_DEFINITION) { + if (dwFlags & DDD_EXACT_MATCH_ON_REMOVE) { + volume = getVolumeByPath(lpTargetPath, VOL_MATCH_PATH); + } else { + volume = getVolumeByPath(lpDeviceName, VOL_MATCH_ALL); + } + if (!volume) { + log_trace(plfDrive, "DDDA-: Unmatched: %s | %s", lpTargetPath, lpDeviceName); + return FALSE; + } + + volume->m_MountPoint = '\0'; + return TRUE; + } + + volume = getVolumeByPath(lpTargetPath, VOL_MATCH_ALL); + if (!volume) { + log_error(plfDrive, "DDDA+: Unmatched: %s | %s", lpTargetPath, lpDeviceName); + return FALSE; + } + volume->m_MountPoint = lpDeviceName[0]; // Awful? Yes. + return TRUE; +} + DWORD WINAPI FakeQueryDosDeviceA(LPCSTR lpDeviceName, LPSTR lpTargetPath, DWORD ucchMax) { log_warning(plfDrive, "QueryDosDeviceA(%s, -, %d)", lpDeviceName, ucchMax); if (lpDeviceName != NULL) { @@ -338,8 +373,8 @@ BOOL WINAPI FakeGetDiskFreeSpaceExA(LPCSTR lpDirectoryName, // return FALSE; // } - // We're going to be remapping the drive to ./mice/dev/, so the free bytes are whatever the current - // real drive has free. No point claiming we have more than we do! + // We're going to be remapping the drive to ./mice/dev/, so the free bytes are whatever the + // current real drive has free. No point claiming we have more than we do! return TrueGetDiskFreeSpaceExA(NULL, lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes); } diff --git a/src/micetools/dll/hooks/files.c b/src/micetools/dll/hooks/files.c index 5717d76..dce9a4a 100644 --- a/src/micetools/dll/hooks/files.c +++ b/src/micetools/dll/hooks/files.c @@ -293,13 +293,48 @@ DWORD WINAPI FakeGetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize) { return file_hook->GetFileSizeEx(&(pHData->ctx), lpFileSize); } +CHAR stdoutBuffer[256]; +DWORD stdoutCount = 0; +CHAR stderrBuffer[256]; +DWORD stderrCount = 0; DWORD WINAPI FakeWriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) { - if (hFile == GetStdHandle(STD_OUTPUT_HANDLE) || hFile == GetStdHandle(STD_ERROR_HANDLE)) { - return TrueWriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, - lpOverlapped); + if (hFile == GetStdHandle(STD_OUTPUT_HANDLE)) { + for (DWORD_PTR i = 0; i < nNumberOfBytesToWrite; i++) { + stdoutBuffer[stdoutCount] = ((CHAR*)lpBuffer)[i]; + if (stdoutBuffer[stdoutCount] == '\n' || stdoutBuffer[stdoutCount] == '\r') { + if (stdoutCount) log_game(plfStdout, "%.*s", stdoutCount, stdoutBuffer); + stdoutCount = 0; + } else if (stdoutCount == _countof(stdoutBuffer)) { + log_game(plfStdout, "%.*s", _countof(stdoutBuffer), stdoutBuffer); + stdoutCount = 0; + } else { + stdoutCount++; + } + } + return TRUE; + } else if (hFile == GetStdHandle(STD_ERROR_HANDLE)) { + for (DWORD_PTR i = 0; i < nNumberOfBytesToWrite; i++) { + stderrBuffer[stderrCount] = ((CHAR*)lpBuffer)[i]; + if (stderrBuffer[stderrCount] == '\n' || stderrBuffer[stderrCount] == '\r') { + if (stderrCount) log_game(plfStderr, "%.*s", stderrCount, stderrBuffer); + stderrCount = 0; + } else if (stderrCount == _countof(stderrBuffer) - 1) { + log_game(plfStderr, "%.*s", _countof(stderrBuffer), stderrBuffer); + stderrCount = 0; + } else { + stderrCount++; + } + } + return TRUE; } + // if (hFile == GetStdHandle(STD_OUTPUT_HANDLE) || hFile == GetStdHandle(STD_ERROR_HANDLE)) { + // log_game(plfFile, "Temp STDIO %.*s", nNumberOfBytesToWrite, lpBuffer); + // return TrueWriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, + // lpOverlapped); + // } + open_hook_t* pHData = GetDataForHandle(hFile); if (pHData == NULL) { return TrueWriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, diff --git a/src/micetools/dll/hooks/gui.c b/src/micetools/dll/hooks/gui.c index 2016c52..e933756 100644 --- a/src/micetools/dll/hooks/gui.c +++ b/src/micetools/dll/hooks/gui.c @@ -104,6 +104,7 @@ extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam HWND mainWindow = NULL; static unsigned int hookType; +static IDirect3DDevice9* g_pd3dDevice = NULL; static HWND window; BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam) { @@ -178,7 +179,7 @@ BOOL UnadjustWindowRect(LPRECT prc, DWORD dwStyle, BOOL fMenu) { return fRc; } -BOOL GetD3D9Device(void** pTable, size_t Size) { +BOOL GetD3D9Device(IDirect3DDevice9Vtbl* pTable, size_t Size) { if (!pTable) return false; IDirect3D9* pD3D = @@ -214,7 +215,9 @@ BOOL GetD3D9Device(void** pTable, size_t Size) { return true; } -static HRESULT(WINAPI* TrueEndScene)(IDirect3DDevice9*); +static STDMETHOD(TruePresent)(IDirect3DDevice9* This, CONST RECT* pSourceRect, + CONST RECT* pDestRect, HWND hDestWindowOverride, + CONST RGNDATA* pDirtyRegion); void draw_rect(IDirect3DDevice9* dev, int x, int y, int w, int h, unsigned char r, unsigned char g, unsigned char b) { @@ -224,16 +227,22 @@ void draw_rect(IDirect3DDevice9* dev, int x, int y, int w, int h, unsigned char dev->lpVtbl->Clear(dev, 1, &BarRect, D3DCLEAR_TARGET | D3DCLEAR_TARGET, rectColor, 0, 0); } -HRESULT __stdcall hkEndScene(IDirect3DDevice9* pDevice) { - static bool showMenu = false; +HRESULT STDMETHODCALLTYPE hkPresent(IDirect3DDevice9* This, CONST RECT* pSourceRect, + CONST RECT* pDestRect, HWND hDestWindowOverride, + CONST RGNDATA* pDirtyRegion) { hookType = UI_HOOK_DX9; + if (g_pd3dDevice != NULL) g_pd3dDevice->lpVtbl->BeginScene(g_pd3dDevice); + end_scene_hook_t* head = end_scene_hook_list; while (head != NULL) { - head->hook(hookType, pDevice); + head->hook(hookType, This); head = head->next; } - return TrueEndScene(pDevice); + + if (g_pd3dDevice != NULL) g_pd3dDevice->lpVtbl->EndScene(g_pd3dDevice); + + return TruePresent(This, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); } void register_gui_hook(FnEndScene* end_scene) { @@ -326,18 +335,18 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UIN void post_win_create(HWND hWnd) { // Don't double-hook! - if (TrueEndScene != NULL) return; + if (TruePresent != NULL) return; mainWindow = hWnd; if (hookType == UI_HOOK_DX9) { - void* d3d9Device[119]; - if (GetD3D9Device(d3d9Device, sizeof(d3d9Device))) { - TrueEndScene = d3d9Device[42]; + IDirect3DDevice9Vtbl d3d9Device; + if (GetD3D9Device(&d3d9Device, sizeof(d3d9Device))) { + TruePresent = d3d9Device.Present; DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); - DetourAttach((PVOID*)&TrueEndScene, hkEndScene); + DetourAttach((PVOID*)&TruePresent, hkPresent); DetourTransactionCommit(); } // MiceInputInit will be called by our D3D9 hooks instead @@ -474,11 +483,13 @@ HRESULT STDMETHODCALLTYPE FakeCreateDevice(IDirect3D9* this, UINT Adapter, D3DDE IDirect3DDevice9** ppReturnedDeviceInterface) { if (MiceConfig.window.windowed) { pPresentationParameters->Windowed = TRUE; - pPresentationParameters->FullScreen_RefreshRateInHz = 0; - } else if (pPresentationParameters->Windowed) { + pPresentationParameters->PresentationInterval = D3DPRESENT_INTERVAL_ONE; + pPresentationParameters->FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + } else /* if (pPresentationParameters->Windowed) */ { D3DDISPLAYMODE d3ddm; this->lpVtbl->GetAdapterDisplayMode(this, Adapter, &d3ddm); pPresentationParameters->Windowed = FALSE; + pPresentationParameters->PresentationInterval = D3DPRESENT_INTERVAL_ONE; pPresentationParameters->FullScreen_RefreshRateInHz = d3ddm.RefreshRate; } @@ -520,6 +531,8 @@ HRESULT STDMETHODCALLTYPE FakeCreateDevice(IDirect3D9* this, UINT Adapter, D3DDE log_error(plfD3D9, "CreateDevice failed: %08x", res); break; } + } else { + g_pd3dDevice = *ppReturnedDeviceInterface; } log_info(plfD3D9, "Device created: %d", res); diff --git a/src/micetools/dll/hooks/logging.c b/src/micetools/dll/hooks/logging.c index 915100a..927937c 100644 --- a/src/micetools/dll/hooks/logging.c +++ b/src/micetools/dll/hooks/logging.c @@ -30,23 +30,34 @@ int WINAPIV Fakeprintf(const char* _Format, ...) { va_list args; va_start(args, _Format); - int ret = vlog_game(plfPrintf, _Format, args); + int ret = vlog_game(plfStdout, _Format, args); va_end(args); return ret; } int WINAPIV Fakefprintf(FILE* _File, const char* _Format, ...) { - size_t flen = strlen(_Format); - if (flen == strcspn(_Format, "\n") + 1 && flen < (sizeof format_buf)) { - strcpy_s(format_buf, WORK_FORMAT_MAX, _Format); - format_buf[flen - 1] = 0; - _Format = format_buf; - } va_list args; va_start(args, _Format); + int ret; - int ret = vlog_game(plfFprintf, _Format, args); + // log_game(plfStdout, "file: %d %p %p %p", _fileno(_File), _File, stdout, stderr); + // STDOUT_FILENO + // TODO: wtf. + _File = stdout; + + if (_File != stdout && _File != stderr) { + // ret = vfprintf(_File, _Format, args); + ret = 0; + } else { + size_t flen = strlen(_Format); + if (flen == strcspn(_Format, "\n") + 1 && flen < (sizeof format_buf)) { + strcpy_s(format_buf, WORK_FORMAT_MAX, _Format); + format_buf[flen - 1] = 0; + _Format = format_buf; + } + ret = vlog_game(_File == stdout ? plfStdout : plfStderr, _Format, args); + } va_end(args); return ret; diff --git a/src/micetools/dll/hooks/processes.c b/src/micetools/dll/hooks/processes.c index 22e09dc..ddbfb9f 100644 --- a/src/micetools/dll/hooks/processes.c +++ b/src/micetools/dll/hooks/processes.c @@ -120,8 +120,18 @@ BOOL WINAPI FakeGetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) { return TRUE; } +HINSTANCE WINAPI FakeShellExecuteA(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, + LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd) { + MiceFSRedirectPathA(lpFile, &lpFile); + if (lpDirectory) MiceFSRedirectPathA(lpDirectory, &lpDirectory); + return TrueShellExecuteA(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd); +} + void hook_processes() { hook("Kernel32.dll", "CreateProcessW", FakeCreateProcessW, (void**)&TrueCreateProcessW); hook("Kernel32.dll", "CreateProcessA", FakeCreateProcessA, (void**)&TrueCreateProcessA); hook("Kernel32.dll", "GetExitCodeProcess", FakeGetExitCodeProcess, NULL); + // hook("Shell32.dll", "ShellExecuteA", FakeShellExecuteA, (void**)TrueShellExecuteA); + + // TODO: ShellExecuteA } diff --git a/src/micetools/dll/hooks/processes.h b/src/micetools/dll/hooks/processes.h index 7f6659b..9ca22bc 100644 --- a/src/micetools/dll/hooks/processes.h +++ b/src/micetools/dll/hooks/processes.h @@ -15,5 +15,7 @@ static BOOL(WINAPI* TrueCreateProcessA)(LPCSTR lpApplicationName, LPSTR lpComman LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); +static HINSTANCE(WINAPI* TrueShellExecuteA)(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, + LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd); void hook_processes(); diff --git a/src/micetools/dll/hooks/system.c b/src/micetools/dll/hooks/system.c index 6c86df6..80bbaed 100644 --- a/src/micetools/dll/hooks/system.c +++ b/src/micetools/dll/hooks/system.c @@ -106,9 +106,11 @@ void hook_system() { // hook("User32.dll", "DeleteObject", FakeDeleteObject, NULL); const char* SystemVersion = "00691001\r\n"; + const char* DefaultSystemVersion = "00000303\r\n"; const char* UpdateVersion = "0000\r\n"; - HANDLE hGM = CreateFileA("GrooveMaster.ini", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + HANDLE hGM = CreateFileA("GrooveMaster.ini", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + 0, NULL); BOOL bGmIs1P = FALSE; if (hGM != INVALID_HANDLE_VALUE) { CHAR line[256]; @@ -137,7 +139,7 @@ void hook_system() { if (bGmIs1P) { const char* GrooveMaster1P = ("# TODO: Get maimai_deliver not rebooting the cab\r\n" - "NO_DELIVER 1\r\n" + // "NO_DELIVER 1\r\n" "# TODO: figure out how to do this without also needing a USB\r\n" "USB_DL_DISABLE 1\r\n" "# These are just easier to do via GM than a patch\r\n" @@ -149,14 +151,14 @@ void hook_system() { } else { const char* GrooveMaster = ("# TODO: Get maimai_deliver not rebooting the cab\r\n" - "NO_DELIVER 1\r\n" + // "NO_DELIVER 1\r\n" "# TODO: figure out how to do this without also needing a USB\r\n" "USB_DL_DISABLE 1\r\n" "# These are just easier to do via GM than a patch\r\n" "NO_REBOOT 1\r\n" "ROTATE 1\r\n"); - hook_file_with_buffer(L"GrooveMaster.ini", (LPBYTE)GrooveMaster, - strlen(GrooveMaster) + 1, GENERIC_READ); + hook_file_with_buffer(L"GrooveMaster.ini", (LPBYTE)GrooveMaster, strlen(GrooveMaster) + 1, + GENERIC_READ); } const char* RingmasterPub = @@ -172,6 +174,8 @@ void hook_system() { // more generic. hook_file_with_buffer(L"C:\\System\\SystemVersion.txt", (LPBYTE)SystemVersion, strlen(SystemVersion) + 1, GENERIC_READ); + hook_file_with_buffer(L"C:\\System\\DefaultSystemVersion.txt", (LPBYTE)DefaultSystemVersion, + strlen(DefaultSystemVersion) + 1, GENERIC_READ); hook_file_with_buffer(L"C:\\System\\UpdateVersion.txt", (LPBYTE)UpdateVersion, strlen(UpdateVersion) + 1, GENERIC_READ); hook_file_with_buffer(L"c:\\System\\Execute\\ringmaster_pub.pem", (LPBYTE)RingmasterPub, diff --git a/src/micetools/dll/micefs.c b/src/micetools/dll/micefs.c index cca070d..86de361 100644 --- a/src/micetools/dll/micefs.c +++ b/src/micetools/dll/micefs.c @@ -351,7 +351,7 @@ BOOL MiceFSRedirectPathA(LPCSTR lpFilename, LPCSTR* pszRedirected) { MultiByteToWideChar(0, 0, _redirected_path, -1, szwPath, _countof(szwPath)); - if (FileExistsW(szwPath)) { + if (FileOrFolderExistsW(szwPath)) { MiceReleaseLockShared(miceFsLockCount); return TRUE; } @@ -414,7 +414,7 @@ BOOL MiceFSDebugTraceRedirectPathA(LPCSTR lpFilename, LPCSTR* pszRedirected) { MultiByteToWideChar(0, 0, _redirected_path, -1, szwPath, _countof(szwPath)); printf("-> %s\n", _redirected_path); - if (FileExistsW(szwPath)) { + if (FileOrFolderExistsW(szwPath)) { MiceReleaseLockShared(miceFsLockCount); printf(":: Redirect ended with valid redirection found."); return TRUE; diff --git a/src/micetools/dll/util/_util.h b/src/micetools/dll/util/_util.h index 1b3068a..4c5a8cc 100644 --- a/src/micetools/dll/util/_util.h +++ b/src/micetools/dll/util/_util.h @@ -2,6 +2,7 @@ #include "hook.h" +BOOL FileOrFolderExistsW(const wchar_t* szPath); BOOL FileExistsW(const wchar_t* szPath); BOOL FileExistsA(const char* szPath); PVOID GetDataForHandle(HANDLE hObject); diff --git a/src/micetools/dll/util/misc.c b/src/micetools/dll/util/misc.c index 221f80a..9209f12 100644 --- a/src/micetools/dll/util/misc.c +++ b/src/micetools/dll/util/misc.c @@ -31,6 +31,10 @@ void PrintStack(void) { free(symbol); } +BOOL FileOrFolderExistsW(const wchar_t* szPath) { + DWORD dwAttrib = _GetFileAttributesW(szPath); + return (dwAttrib != INVALID_FILE_ATTRIBUTES); +} BOOL FileExistsW(const wchar_t* szPath) { DWORD dwAttrib = _GetFileAttributesW(szPath); return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); diff --git a/src/micetools/launcher/meson.build b/src/micetools/launcher/meson.build index ff1c55c..d4cee22 100644 --- a/src/micetools/launcher/meson.build +++ b/src/micetools/launcher/meson.build @@ -20,6 +20,7 @@ executable( dummyinstaller, dummygdeliver, dummynetwork, + dummystorage, amSerialId, ], diff --git a/src/micetools/launcher/spawn.c b/src/micetools/launcher/spawn.c index 1a3a51c..776eda1 100644 --- a/src/micetools/launcher/spawn.c +++ b/src/micetools/launcher/spawn.c @@ -9,6 +9,7 @@ spawn_t mxspawns[] = { { "installer", SPAWN_DUMMY, MdiThreadProc, NULL }, { "network", SPAWN_DUMMY, MdnThreadProc, NULL }, { "gdeliver", SPAWN_DUMMY, MdgdThreadProc, NULL }, + { "storage", SPAWN_DUMMY, MdsThreadProc, NULL }, }; int mxkMain(); @@ -17,6 +18,7 @@ int miceDummyMaster(unsigned short textPort, unsigned short binaryPort, bool glo int miceDummyInstaller(unsigned short textPort, unsigned short binaryPort, bool global); int miceDummyNetwork(unsigned short textPort, unsigned short binaryPort, bool global); int miceDummyGDeliver(unsigned short textPort, unsigned short binaryPort, bool global); +int miceDummyStorage(unsigned short textPort, unsigned short binaryPort, bool global); DWORD WINAPI MdkThreadProc(LPVOID lpParameter) { miceDummyKeychip(40106, 40107, false); return 0; @@ -41,6 +43,10 @@ DWORD WINAPI MdgdThreadProc(LPVOID lpParameter) { miceDummyGDeliver(40108, 40112, false); return 0; } +DWORD WINAPI MdsThreadProc(LPVOID lpParameter) { + miceDummyStorage(40114, 40115, false); + return 0; +} static inline void spawn_one(spawn_t* spawn) { if (spawn->mode == SPAWN_NONE) { diff --git a/src/micetools/launcher/spawn.h b/src/micetools/launcher/spawn.h index e294289..5839955 100644 --- a/src/micetools/launcher/spawn.h +++ b/src/micetools/launcher/spawn.h @@ -12,7 +12,7 @@ typedef struct { #define SPAWN_REAL 2 #define SPAWN_BOTH (SPAWN_DUMMY | SPAWN_REAL) -extern spawn_t mxspawns[5]; +extern spawn_t mxspawns[6]; DWORD WINAPI MxkThreadProc(LPVOID lpParameter); DWORD WINAPI MdkThreadProc(LPVOID lpParameter); @@ -20,5 +20,6 @@ DWORD WINAPI MdmThreadProc(LPVOID lpParameter); DWORD WINAPI MdiThreadProc(LPVOID lpParameter); DWORD WINAPI MdnThreadProc(LPVOID lpParameter); DWORD WINAPI MdgdThreadProc(LPVOID lpParameter); +DWORD WINAPI MdsThreadProc(LPVOID lpParameter); void spawn_pcp_processes(void); diff --git a/src/micetools/lib/_am.h b/src/micetools/lib/_am.h index f1569c9..381ecfe 100644 --- a/src/micetools/lib/_am.h +++ b/src/micetools/lib/_am.h @@ -1,3 +1,7 @@ +#ifndef MICE_VERSION +#define MICE_VERSION "Unk" +#endif + #define AM_LIB_C_HEADER(name, storage_type) \ int name##DebugLevel = 0; \ struct storage_type name; \ diff --git a/src/micetools/lib/am/am.h b/src/micetools/lib/am/am.h index dcc0805..a7ca3a4 100644 --- a/src/micetools/lib/am/am.h +++ b/src/micetools/lib/am/am.h @@ -4,3 +4,4 @@ #include "amOemstring.h" #include "amPlatform.h" #include "amSram.h" +#include "amLog.h" diff --git a/src/micetools/lib/am/amBackup.c b/src/micetools/lib/am/amBackup.c new file mode 100644 index 0000000..a4ad6a5 --- /dev/null +++ b/src/micetools/lib/am/amBackup.c @@ -0,0 +1,407 @@ +#include "amBackup.h" + +#include "../ami/amiCrc.h" +#include "../ami/amiDebug.h" + +AM_LIB_C_HEADER(amBackup, AM_BACKUP) + +AM_BACKUP_STATUS amBackupInit(void) { + if (amBackup.m_Init) return AM_BACKUP_STATUS_ALREADY_INIT; + + ZeroMemory(&amBackup, sizeof amBackup); + amiCrc32RCreateTable(amBackup.m_CrcTable); + + amBackup.m_Init = TRUE; + return AM_BACKUP_STATUS_OK; +} +AM_BACKUP_STATUS amBackupExit(void) { + if (!amBackup.m_Init) return AM_BACKUP_STATUS_NO_INIT; + ZeroMemory(&amBackup, sizeof amBackup); + return AM_BACKUP_STATUS_OK; +} + +static BOOL amBackupValidateAddress(AM_PLATFORM_NV_DEVICE_CONFIG *lpConfig, DWORD wAddress, + WORD wCount) { + if (lpConfig == NULL) return FALSE; + if (wAddress < lpConfig->m_Base) return FALSE; + if (wAddress + wCount > lpConfig->m_Base + lpConfig->m_Size) return FALSE; + + DWORD mask = lpConfig->m_BlockSize - 1; + if ((wAddress & mask) != 0) return FALSE; + if ((wCount & mask) != 0) return FALSE; + + if (wCount > lpConfig->m_Size) return FALSE; + + return TRUE; +} + +AM_BACKUP_STATUS amBackupWrite(AM_PLATFORM_NV_DEVICE_CONFIG *lpConfig, LPVOID lpBuffer, + WORD wAddress, WORD wCount) { + if (amBackup.m_Init == 0) return AM_BACKUP_STATUS_NO_INIT; + if (lpConfig == NULL || lpBuffer == NULL) return AM_BACKUP_STATUS_INVALID_PARAM; + + if (!amBackupValidateAddress(lpConfig, wAddress, wCount)) { + if (amBackupDebugLevel > 0) amiDebugLog("invalid address."); + return AM_BACKUP_STATUS_INVALID_ADDR; + } + if (lpConfig->m_WriteFunc == NULL) { + if (amBackupDebugLevel > 0) amiDebugLog("No Write Function Error!."); + return AM_BACKUP_STATUS_INVALID_STORAGE; + } + return (lpConfig->m_WriteFunc)(wAddress, lpBuffer, wCount); +} + +AM_BACKUP_STATUS amBackupRecordCheckValid(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer) { + if (!amBackup.m_Init) return AM_BACKUP_STATUS_NO_INIT; + if (lpConfig == NULL || lpBuffer == NULL) return AM_BACKUP_STATUS_INVALID_PARAM; + + LPDWORD bufferAsDW = (LPDWORD)lpBuffer; + + if (lpConfig->m_bHasCrc) { + DWORD calcCrc = + amiCrc32RGet(amBackup.m_CrcTable, lpConfig->m_wCount - 4, bufferAsDW + 1, 0); + if (calcCrc != bufferAsDW[0]) { + if (amBackupDebugLevel > 0) + amiDebugLog("crc error. NewCrc=%08X OrgCrc=%08X", calcCrc, bufferAsDW[0]); + return AM_BACKUP_STATUS_BAD_CRC; + } + bufferAsDW++; + } + if (lpConfig->m_bHasID) { + if (*(LPDWORD)(lpConfig->m_sID) != bufferAsDW[0]) { + if (amBackupDebugLevel > 0) + amiDebugLog("id error. NewId=%08x OrgId=%08x", *(LPDWORD)lpConfig->m_sID, + bufferAsDW[0]); + return AM_BACKUP_STATUS_BAD_ID; + } + } + return AM_BACKUP_STATUS_OK; +} + +AM_BACKUP_STATUS amBackupRead(AM_PLATFORM_NV_DEVICE_CONFIG *lpConfig, WORD wAddress, + LPVOID lpBuffer, WORD wCount) { + if (!amBackup.m_Init) return AM_BACKUP_STATUS_NO_INIT; + if (lpConfig == NULL || lpBuffer == NULL) return AM_BACKUP_STATUS_INVALID_PARAM; + + if (!amBackupValidateAddress(lpConfig, wAddress, wCount)) { + if (amBackupDebugLevel > 0) amiDebugLog("invalid address."); + return AM_BACKUP_STATUS_INVALID_ADDR; + } + if (lpConfig->m_ReadFunc == NULL) { + if (amBackupDebugLevel > 0) amiDebugLog("No Read Function Error!."); + return AM_BACKUP_STATUS_INVALID_STORAGE; + } + return (lpConfig->m_ReadFunc)(wAddress, lpBuffer, wCount); +} + +AM_BACKUP_STATUS amBackupRecordRead(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer) { + if (!amBackup.m_Init) return AM_BACKUP_STATUS_NO_INIT; + if (lpConfig == NULL || lpBuffer == NULL) return AM_BACKUP_STATUS_INVALID_PARAM; + + AM_PLATFORM_NV_DEVICE_CONFIG *device = amPlatformGetNvDevice(lpConfig->m_Device); + if (device == NULL) return AM_BACKUP_STATUS_NO_DEVICE; + + int err = amBackupRead(device, lpConfig->m_wAddress, lpBuffer, lpConfig->m_wCount); + if (err < 0) return err; + + err = amBackupRecordCheckValid(lpConfig, lpBuffer); + return err >= 0 ? AM_BACKUP_STATUS_OK : err; +} + +AM_BACKUP_STATUS amBackupRecordReadDup(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer) { + if (!amBackup.m_Init) return AM_BACKUP_STATUS_NO_INIT; + if (lpConfig == NULL || lpBuffer == NULL) return AM_BACKUP_STATUS_INVALID_PARAM; + + int err = amBackupRecordRead(lpConfig, lpBuffer); + if (err > -1) return AM_BACKUP_STATUS_OK; + + if (err < -19) { + err = amBackupRecordRead(lpConfig + 1, lpBuffer); + if (-1 < err) return amBackupRecordWrite(lpConfig, lpBuffer); + } + return err; +} + +AM_BACKUP_STATUS amBackupRecordValidate(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer) { + if (!amBackup.m_Init) return AM_BACKUP_STATUS_NO_INIT; + if (lpConfig == NULL || lpBuffer == NULL) return AM_BACKUP_STATUS_INVALID_PARAM; + + LPBYTE lpData = (LPBYTE)lpBuffer; + WORD wCount = lpConfig->m_wCount; + if (lpConfig->m_bHasCrc) { + wCount -= 4; + lpData += 4; + } + + if (lpConfig->m_bHasID) { + *((LPDWORD)lpData) = *(LPDWORD)lpConfig->m_sID; + lpData += 4; + wCount -= 4; + } + + if (lpConfig->m_bHasCrc) { + *((LPDWORD)lpBuffer) = amiCrc32RGet(amBackup.m_CrcTable, wCount, lpData, 0); + } + + return AM_BACKUP_STATUS_OK; +} + +AM_BACKUP_STATUS amBackupRecordWrite(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer) { + if (!amBackup.m_Init) return AM_BACKUP_STATUS_NO_INIT; + if (lpConfig == NULL || lpBuffer == NULL) return AM_BACKUP_STATUS_INVALID_PARAM; + + AM_PLATFORM_NV_DEVICE_CONFIG *device = amPlatformGetNvDevice(lpConfig->m_Device); + if (device == NULL) return AM_BACKUP_STATUS_NO_DEVICE; + + int err = amBackupRecordValidate(lpConfig, lpBuffer); + if (err < 0) return err; + + err = amBackupWrite(device, lpBuffer, lpConfig->m_wAddress, lpConfig->m_wCount); + return err >= 0 ? AM_BACKUP_STATUS_OK : err; +} + +AM_BACKUP_STATUS amBackupRecordWriteDup(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer) { + if (!amBackup.m_Init) return AM_BACKUP_STATUS_NO_INIT; + if (lpConfig == NULL || lpBuffer == NULL) return AM_BACKUP_STATUS_INVALID_PARAM; + + int err = amBackupRecordWrite(&(lpConfig[1]), lpBuffer); + if (err + 19 <= 18) return err; + + return amBackupRecordWrite(&(lpConfig[0]), lpBuffer); +} + +static AM_BACKUP_RECORD _amBackupStructs[12][2] = { + // AM_BACKUP_RECORD_STATIC + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x000, + .m_wCount = 0x20, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x200, + .m_wCount = 0x20, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, + // AM_BACKUP_RECORD_CREDIT + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x020, + .m_wCount = 0x20, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x220, + .m_wCount = 0x20, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, + // AM_BACKUP_RECORD_NETWORK_ETH0 + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x040, + .m_wCount = 0x20, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x240, + .m_wCount = 0x20, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, + // AM_BACKUP_RECORD_NETWORK_ETH1 + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x060, + .m_wCount = 0x20, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x260, + .m_wCount = 0x20, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, + // AM_BACKUP_RECORD_HISTORY + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x080, + .m_wCount = 0x10, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x280, + .m_wCount = 0x10, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, + // AM_BACKUP_RECORD_ALPB_CARD_ID + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x090, + .m_wCount = 0x10, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x290, + .m_wCount = 0x10, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, + // AM_BACKUP_RECORD_ALPB_COMPUTER_NAME + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x0a0, + .m_wCount = 0x20, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x2a0, + .m_wCount = 0x20, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, + // AM_BACKUP_RECORD_BACKUP + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_SRAM, + .m_wAddress = 0x0000, + .m_wCount = 0x200, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_SRAM, + .m_wAddress = 0x1000, + .m_wCount = 0x200, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, + // AM_BACKUP_RECORD_HM_PEAK + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_SRAM, + .m_wAddress = 0x0200, + .m_wCount = 0x200, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_SRAM, + .m_wAddress = 0x1200, + .m_wCount = 0x200, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, + // AM_BACKUP_RECORD_TIMEZONE + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_SRAM, + .m_wAddress = 0x0400, + .m_wCount = 0x200, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_SRAM, + .m_wAddress = 0x1400, + .m_wCount = 0x200, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, + // AM_BACKUP_RECORD_ERROR_LOG + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_SRAM, + .m_wAddress = 0x0600, + .m_wCount = 0x200, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_SRAM, + .m_wAddress = 0x1600, + .m_wCount = 0x200, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, + // AM_BACKUP_RECORD_ALPB_DEV_CONFIG + { + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x0c0, + .m_wCount = 0x40, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + { + .m_Device = AM_PLATFORM_NV_DEVICE_EEPROM, + .m_wAddress = 0x2c0, + .m_wCount = 0x40, + .m_bHasCrc = TRUE, + .m_bHasID = FALSE, + .m_sID = 0, + }, + }, +}; + +AM_BACKUP_RECORD *amBackupGetRecord(DWORD dwWhich) { + if (dwWhich < 12) return (AM_BACKUP_RECORD *)&(_amBackupStructs[dwWhich]); + return NULL; +} diff --git a/src/micetools/lib/am/amBackup.h b/src/micetools/lib/am/amBackup.h index cc18b5a..8980923 100644 --- a/src/micetools/lib/am/amBackup.h +++ b/src/micetools/lib/am/amBackup.h @@ -1,10 +1,67 @@ -void amBackupInit(void); -void amBackupExit(void); -void amBackupRead(void); -void amBackupRecordCheckValid(void); -void amBackupRecordReadDup(void); -void amBackupRecordWriteDup(void); -void amBackupRecordValidate(void); -void amBackupRecordWrite(void); -void amBackupRecordWriteDup(void); -void amBackupWrite(void); +#pragma once + +#include +#include + +#include "../_am.h" +#include "amPlatform.h" + +AM_LIB_H_HEADER(amBackup, AM_BACKUP) + +typedef struct AM_BACKUP { + BOOL m_Init; + uint32_t m_CrcTable[256]; +} AM_BACKUP; + +typedef enum AM_BACKUP_STATUS { + AM_BACKUP_STATUS_OK = 0, + AM_BACKUP_STATUS_NO_DEVICE = -21, + AM_BACKUP_STATUS_INVALID_ADDR = -22, + AM_BACKUP_STATUS_BAD_CRC = -23, + AM_BACKUP_STATUS_BAD_ID = -24, + AM_BACKUP_STATUS_INVALID_STORAGE = -25, + AM_BACKUP_STATUS_INVALID_PARAM = -27, + AM_BACKUP_STATUS_NO_INIT = -28, + AM_BACKUP_STATUS_ALREADY_INIT = -29, +} AM_BACKUP_STATUS; + +typedef struct AM_BACKUP_RECORD { + AM_PLATFORM_NV_DEVICE m_Device; + WORD m_wAddress; + WORD m_wCount; + BOOL m_bHasCrc; + BOOL m_bHasID; + CHAR m_sID[4]; +} AM_BACKUP_RECORD; + +typedef enum AM_BACKUP_RECORD_N { + AM_BACKUP_RECORD_STATIC = 0, + AM_BACKUP_RECORD_CREDIT = 1, + AM_BACKUP_RECORD_NETWORK_ETH0 = 2, + AM_BACKUP_RECORD_NETWORK_ETH1 = 3, + AM_BACKUP_RECORD_HISTORY = 4, + AM_BACKUP_RECORD_ALPB_CARD_ID = 5, + AM_BACKUP_RECORD_ALPB_COMPUTER_NAME = 6, + AM_BACKUP_RECORD_BACKUP = 7, + AM_BACKUP_RECORD_HM_PEAK = 8, + AM_BACKUP_RECORD_TIMEZONE = 9, + AM_BACKUP_RECORD_ERROR_LOG = 10, + AM_BACKUP_RECORD_ALPB_DEV_CONFIG = 11, +} AM_BACKUP_RECORD_N; + +AM_BACKUP_STATUS amBackupInit(void); +AM_BACKUP_STATUS amBackupExit(void); + +AM_BACKUP_STATUS amBackupWrite(AM_PLATFORM_NV_DEVICE_CONFIG *lpConfig, LPVOID lpBuffer, + WORD wAddress, WORD wCount); +AM_BACKUP_STATUS amBackupRecordWrite(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer); +AM_BACKUP_STATUS amBackupRecordWriteDup(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer); +AM_BACKUP_STATUS amBackupRecordValidate(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer); + +AM_BACKUP_STATUS amBackupRead(AM_PLATFORM_NV_DEVICE_CONFIG *lpConfig, WORD wAddress, + LPVOID lpBuffer, WORD wCount); +AM_BACKUP_STATUS amBackupRecordRead(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer); +AM_BACKUP_STATUS amBackupRecordReadDup(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer); +AM_BACKUP_STATUS amBackupRecordCheckValid(AM_BACKUP_RECORD *lpConfig, LPVOID lpBuffer); + +AM_BACKUP_RECORD *amBackupGetRecord(DWORD dwWhich); diff --git a/src/micetools/lib/am/amCmos.c b/src/micetools/lib/am/amCmos.c index bc65736..d18081d 100644 --- a/src/micetools/lib/am/amCmos.c +++ b/src/micetools/lib/am/amCmos.c @@ -1,25 +1,27 @@ #include "amCmos.h" +#include "../mice/ioctl.h" + AM_LIB_C_HEADER(amCmos, AM_CMOS) -AM_CMOS_STATUS amCmosInit(AM_CMOS_CONFIG *lpConfig) { +AM_CMOS_STATUS amCmosInit(AM_PLATFORM_CMOS_PARAM *lpParam) { if (amCmos.m_bInit != 0) return AM_CMOS_STATUS_ERR_ALREADY_INIT; - if (lpConfig == NULL) return AM_CMOS_STATUS_ERR_INVALID_PARAM; + if (lpParam == NULL) return AM_CMOS_STATUS_ERR_INVALID_PARAM; HANDLE hMutex = CreateMutexA(NULL, 0, "AM_CMOS_MUTEX"); if (hMutex == NULL) return AM_CMOS_STATUS_ERR_SYS; - HANDLE hCmos = CreateFileA("\\\\.\\mxcmos", 0xc0000000, 3, NULL, 3, 0, NULL); - if (hCmos == INVALID_HANDLE_VALUE) { + HANDLE hDriver = CreateFileA("\\\\.\\mxcmos", 0xc0000000, 3, NULL, 3, 0, NULL); + if (hDriver == INVALID_HANDLE_VALUE) { CloseHandle(hMutex); return AM_CMOS_STATUS_ERR_OPEN_FAILED; } amCmos.m_bInit = TRUE; amCmos.m_hMutex = hMutex; - amCmos.m_hCmos = hCmos; + amCmos.m_hDriver = hDriver; - memcpy(&amCmos.m_Config, lpConfig, sizeof *lpConfig); + memcpy(&amCmos.m_Param, lpParam, sizeof *lpParam); return AM_CMOS_STATUS_OK; } @@ -31,29 +33,28 @@ AM_CMOS_STATUS amCmosExit(void) { CloseHandle(amCmos.m_hMutex); amCmos.m_hMutex = NULL; } - if (amCmos.m_hCmos != INVALID_HANDLE_VALUE) { - CloseHandle(amCmos.m_hCmos); - amCmos.m_hCmos = INVALID_HANDLE_VALUE; + if (amCmos.m_hDriver != INVALID_HANDLE_VALUE) { + CloseHandle(amCmos.m_hDriver); + amCmos.m_hDriver = INVALID_HANDLE_VALUE; } amCmos.m_bInit = FALSE; return AM_CMOS_STATUS_OK; } -AM_CMOS_STATUS amCmosReadByteInRearpart(BYTE nIndex, LPBYTE lpData) { +AM_CMOS_STATUS amCmosReadByteInRearpart(BYTE addr, LPBYTE lpValue) { if (amCmos.m_bInit == 0) return AM_CMOS_STATUS_ERR_NO_INIT; - - if (lpData == NULL || nIndex > 0x7f) return AM_CMOS_STATUS_ERR_INVALID_PARAM; + if (lpValue == NULL || addr > 0x7f) return AM_CMOS_STATUS_ERR_INVALID_PARAM; if (WaitForSingleObject(amCmos.m_hMutex, 0) != WAIT_OBJECT_0) return AM_CMOS_STATUS_ERR_LOCK; BYTE request[2]; - request[0] = nIndex; + request[0] = addr; request[1] = 0; DWORD nBytesReturned; - BOOL bErr = DeviceIoControl(amCmos.m_hCmos, IOCTL_MXCMOS_READ, request, sizeof request, lpData, - 1, &nBytesReturned, NULL); + BOOL bErr = DeviceIoControl(amCmos.m_hDriver, IOCTL_MXCMOS_READ, request, sizeof request, + lpValue, 1, &nBytesReturned, NULL); int iRet = 0; if (!bErr) { @@ -69,3 +70,85 @@ AM_CMOS_STATUS amCmosReadByteInRearpart(BYTE nIndex, LPBYTE lpData) { } return iRet; } +AM_CMOS_STATUS amCmosWriteByteInRearpart(BYTE addr, BYTE value) { + if (amCmos.m_bInit == 0) return AM_CMOS_STATUS_ERR_NO_INIT; + if (addr > 0x7f) return AM_CMOS_STATUS_ERR_INVALID_PARAM; + + if (WaitForSingleObject(amCmos.m_hMutex, 0) != WAIT_OBJECT_0) return AM_CMOS_STATUS_ERR_LOCK; + + BYTE request[2]; + request[0] = addr; + request[1] = value; + + DWORD nBytesReturned; + BOOL bErr = DeviceIoControl(amCmos.m_hDriver, IOCTL_MXCMOS_READ, request, sizeof request, + NULL, 0, &nBytesReturned, NULL); + + if (!ReleaseMutex(amCmos.m_hMutex)) { + if (amCmosDebugLevel > 0) + amiDebugLog("ReleaseMutex Error!! Error Code is %ld!!", GetLastError()); + return AM_CMOS_STATUS_ERR_SYS; + } + return bErr ? AM_CMOS_STATUS_OK : AM_CMOS_STATUS_ERR_SYS; +} + +AM_CMOS_STATUS amCmosSetPartition(BYTE addr, BYTE bitOffset, BYTE mbrCount, BYTE partition) { + if (!amCmos.m_bInit) return AM_CMOS_STATUS_ERR_NO_INIT; + if (partition > 4) return AM_CMOS_STATUS_ERR_INVALID_PARAM; + if (addr == 0 || bitOffset > 8) return AM_CMOS_STATUS_NG; + + BYTE bValue; + AM_CMOS_STATUS err = amCmosReadByteInRearpart(addr, &bValue); + if (amCmosReadByteInRearpart(addr, &bValue)) { + if (amCmosDebugLevel >= 1) amiDebugLog("Error: amCmosReadByteInRearpart()"); + return err; + } + + if (partition < mbrCount) partition += 5; + + /* + parition range: 0, 1, 2, 3, 4, [5] + mbrCount values: 0, 1 + + -> if partition == 0 && mbrCount == 1 ::-> partition = 5 + + value range: 0, 1, 2, 3, 4 + + bO | mask + 0 | 11111000 <-- + 1 | 11110001 + 2 | 11100011 + 3 | 11000111 + 4 | 10001111 + 5 | 00011111 <-- + 6 | 00111111 + 7 | 01111111 + + bO | value + 0 | 00 01 02 03 04 <-- + 1 | 00 02 04 06 08 + 2 | 00 04 08 0c 10 + 3 | 00 08 10 18 20 + 4 | 00 10 20 30 40 + 5 | 00 20 40 60 80 <-- + 6 | 00 40 80 c0 00 + 7 | 00 80 00 80 00 + */ + + byte value = partition - mbrCount; + byte mask = 0b11111000; + for (int uVar4 = bitOffset; uVar4 != 0; uVar4--) { + mask = (mask << 1) | 1; + value <<= 1; + } + return amCmosWriteByteInRearpart(addr, (bValue & mask) | value); +} + +AM_CMOS_STATUS amCmosSetPartition_0(byte partition) { + return amCmosSetPartition(amCmos.m_Param.index[0][0], amCmos.m_Param.index[0][1], + amCmos.m_Param.m_MbrCount, partition); +} +AM_CMOS_STATUS amCmosSetPartition_1(byte partition) { + return amCmosSetPartition(amCmos.m_Param.index[1][0], amCmos.m_Param.index[1][1], + amCmos.m_Param.m_MbrCount, partition); +} diff --git a/src/micetools/lib/am/amCmos.h b/src/micetools/lib/am/amCmos.h index 71e70e5..dbc3482 100644 --- a/src/micetools/lib/am/amCmos.h +++ b/src/micetools/lib/am/amCmos.h @@ -4,6 +4,7 @@ #include "../../dll/smbus.h" #include "../_am.h" +#include "./amPlatform.h" AM_LIB_H_HEADER(amCmos, AM_CMOS) @@ -18,22 +19,20 @@ typedef enum { AM_CMOS_STATUS_ERR_LOCK = -7, } AM_CMOS_STATUS; -typedef struct AM_CMOS_CONFIG { - BYTE index[4]; - BYTE m_MbrCount; -} AM_CMOS_CONFIG; - typedef struct AM_CMOS { BOOL m_bInit; HANDLE m_hMutex; - HANDLE m_hCmos; - AM_CMOS_CONFIG m_Config; + HANDLE m_hDriver; + AM_PLATFORM_CMOS_PARAM m_Param; } AM_CMOS; - -AM_CMOS_STATUS amCmosInit(AM_CMOS_CONFIG* lpConfig); +AM_CMOS_STATUS amCmosInit(AM_PLATFORM_CMOS_PARAM* lpParam); AM_CMOS_STATUS amCmosExit(void); -AM_CMOS_STATUS amCmosReadByteInRearpart(BYTE param_1, LPBYTE param_2); -void amCmosWriteByteInRearpart(void); -void amCmosSetPartition(void); +AM_CMOS_STATUS amCmosReadByteInRearpart(BYTE addr, LPBYTE lpValue); +AM_CMOS_STATUS amCmosWriteByteInRearpart(BYTE addr, BYTE value); + +AM_CMOS_STATUS amCmosSetPartition(BYTE addr, BYTE bitOffset, BYTE mbrCount, BYTE partition); + +AM_CMOS_STATUS amCmosSetPartition_0(byte partition); +AM_CMOS_STATUS amCmosSetPartition_1(byte partition); diff --git a/src/micetools/lib/am/amEeprom.c b/src/micetools/lib/am/amEeprom.c index d18cdec..7cc7c53 100644 --- a/src/micetools/lib/am/amEeprom.c +++ b/src/micetools/lib/am/amEeprom.c @@ -18,8 +18,7 @@ HANDLE amEepromCreateDeviceFile(const GUID *guid, LPCSTR resource, DWORD member_ HDEVINFO DeviceInfoSet = SetupDiGetClassDevsA(guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (DeviceInfoSet == INVALID_HANDLE_VALUE) { - if (amEepromDebugLevel > 0) - amiDebugLog("SetupDiGetClassDevs Error(%ld).", GetLastError()); + if (amEepromDebugLevel > 0) amiDebugLog("SetupDiGetClassDevs Error(%ld).", GetLastError()); return INVALID_HANDLE_VALUE; } @@ -96,8 +95,7 @@ AM_EEPROM_STATUS amEepromCreateMutex(AM_EEPROM *device) { idAuth.Value[5] = 1; if (!AllocateAndInitializeSid(&idAuth, 1, 0, 0, 0, 0, 0, 0, 0, 0, pSid)) { - if (amEepromDebugLevel > 0) - amiDebugLog("AllocateAndInitializeSid Error in amEepromInit."); + if (amEepromDebugLevel > 0) amiDebugLog("AllocateAndInitializeSid Error in amEepromInit."); *pSid = NULL; goto amEepromCreateMutexError; } @@ -109,8 +107,7 @@ AM_EEPROM_STATUS amEepromCreateMutex(AM_EEPROM *device) { } if (!SetSecurityDescriptorDacl(&securityDescriptor, TRUE, NULL, FALSE)) { - if (amEepromDebugLevel > 0) - amiDebugLog("SetSecurityDescriptorDacl Error in amEepromInit."); + if (amEepromDebugLevel > 0) amiDebugLog("SetSecurityDescriptorDacl Error in amEepromInit."); goto amEepromCreateMutexError; } @@ -159,8 +156,7 @@ AM_EEPROM_STATUS amEepromInit(AM_EEPROM_TIMEOUT *timeout) { amEeprom.m_superio = amEepromCreateDeviceFile(&MXSMBUS_GUID, 0, 0); if (amEeprom.m_superio == INVALID_HANDLE_VALUE) { - if (amEepromDebugLevel > 0) - amiDebugLog("amEepromCreateDeviceFile Error in amEepromInit."); + if (amEepromDebugLevel > 0) amiDebugLog("amEepromCreateDeviceFile Error in amEepromInit."); ret = AM_EEPROM_STATUS_ERR_SYS; goto amEepromInitError; } @@ -176,7 +172,7 @@ AM_EEPROM_STATUS amEepromInit(AM_EEPROM_TIMEOUT *timeout) { if (amEepromDebugLevel > 0) amiDebugLog( "Unknown SMBUS Driver Protocol(0x%08x). Please update SMBUS driver or user " - "program.\n", + "program.", driverVersion); ret = AM_EEPROM_STATUS_ERR_PROTOCOL_VER; @@ -238,8 +234,8 @@ BOOL amEepromI2CReadBlock(AM_EEPROM *device, WORD reg, BYTE nBytes, LPBYTE buffe if (packet.status != 0) { if (amEepromDebugLevel > 0) - amiDebugLog(" .. SMBus read error. prt=0x%02x addr=0x%02x reg=0x%04x", - packet.command, packet.v_addr, packet.command_code); + amiDebugLog(" .. SMBus read error. prt=0x%02x addr=0x%02x reg=0x%04x", packet.command, + packet.v_addr, packet.command_code); return false; } @@ -269,9 +265,8 @@ BOOL amEepromI2CWriteBlock(AM_EEPROM *device, WORD reg, BYTE nBytes, LPBYTE buff if (packet.status != 0) { if (amEepromDebugLevel > 0) - amiDebugLog( - " .. SMBus write error. status=0x%02x, prt=0x%02x addr=0x%02x reg=0x%04x\n", - packet.status, packet.command, packet.v_addr, packet.command_code); + amiDebugLog(" .. SMBus write error. status=0x%02x, prt=0x%02x addr=0x%02x reg=0x%04x\n", + packet.status, packet.command, packet.v_addr, packet.command_code); return false; } @@ -314,16 +309,14 @@ AM_EEPROM_STATUS amEepromRead(WORD reg, LPBYTE buf, DWORD length) { DWORD err = WaitForSingleObject(amEeprom.m_mutex, 256); if (err == WAIT_FAILED) { - if (amEepromDebugLevel > 0) - amiDebugLog("WaitForSingleObject Error(%ld).", GetLastError()); + if (amEepromDebugLevel > 0) amiDebugLog("WaitForSingleObject Error(%ld).", GetLastError()); return AM_EEPROM_STATUS_ERR_SYS; } if (err == WAIT_TIMEOUT) return AM_EEPROM_STATUS_ERR_GET_MUTEX; if (!(err == WAIT_OBJECT_0 || err == WAIT_ABANDONED)) { if (amEepromDebugLevel > 0) - amiDebugLog("WaitForSingleObject Error(%ld). Return Value is %d.", GetLastError(), - err); + amiDebugLog("WaitForSingleObject Error(%ld). Return Value is %d.", GetLastError(), err); return AM_EEPROM_STATUS_ERR_SYS; } @@ -359,16 +352,14 @@ AM_EEPROM_STATUS amEepromWrite(WORD reg, LPBYTE buf, DWORD length) { DWORD err = WaitForSingleObject(amEeprom.m_mutex, 256); if (err == WAIT_FAILED) { - if (amEepromDebugLevel > 0) - amiDebugLog("WaitForSingleObject Error(%ld).", GetLastError()); + if (amEepromDebugLevel > 0) amiDebugLog("WaitForSingleObject Error(%ld).", GetLastError()); return AM_EEPROM_STATUS_ERR_SYS; } if (err == WAIT_TIMEOUT) return AM_EEPROM_STATUS_ERR_GET_MUTEX; if (!(err == WAIT_OBJECT_0 || err == WAIT_ABANDONED)) { if (amEepromDebugLevel > 0) - amiDebugLog("WaitForSingleObject Error(%ld). Return Value is %d.", GetLastError(), - err); + amiDebugLog("WaitForSingleObject Error(%ld). Return Value is %d.", GetLastError(), err); return AM_EEPROM_STATUS_ERR_SYS; } diff --git a/src/micetools/lib/am/amLog.c b/src/micetools/lib/am/amLog.c new file mode 100644 index 0000000..247fec1 --- /dev/null +++ b/src/micetools/lib/am/amLog.c @@ -0,0 +1,69 @@ +#include "amLog.h" + +AM_LIB_C_HEADER(amLog, AM_LOG) + +int amLogInit(void) { + if (amLog.m_Init) return AM_LOG_STATUS_ERR_ALREADY_INIT; + + amLog.m_Option.m_EventSource = "am"; + amLog.m_Option.m_EventType = 1; + amLog.m_Option.m_EventCategory = 0; + amLog.m_Option.m_EventId = 0; + amLog.m_Init = TRUE; + return AM_LOG_STATUS_OK; +} + +int amLogFinalize(void) { + if (!amLog.m_Init) return AM_LOG_STATUS_ERR_INVALID_PARAM; + + amLog.m_Option.m_EventSource = NULL; + amLog.m_Option.m_EventType = 0; + amLog.m_Option.m_EventCategory = 0; + amLog.m_Option.m_EventId = 0; + amLog.m_Init = FALSE; + return AM_LOG_STATUS_OK; +} + +int amLogSetEventOption(AM_LOG_OPTION* lpOption) { + if (!amLog.m_Init) return AM_LOG_STATUS_ERR_INVALID_PARAM; + if (lpOption == NULL) return AM_LOG_STATUS_ERR_NO_INIT; + memcpy_s(&amLog.m_Option, sizeof amLog.m_Option, lpOption, sizeof *lpOption); + return AM_LOG_STATUS_OK; +} + +int amLogReportEvent(LPCSTR lpMsg) { + if (!amLog.m_Init) return AM_LOG_STATUS_ERR_INVALID_PARAM; + if (lpMsg == NULL) return AM_LOG_STATUS_ERR_NO_INIT; + + HANDLE hEventLog = RegisterEventSourceA(NULL, amLog.m_Option.m_EventSource); + if (hEventLog == INVALID_HANDLE_VALUE) return AM_LOG_STATUS_ERR_REGISTER; + + WORD wType; + switch (amLog.m_Option.m_EventType) { + case 0: + wType = 0; + break; + default: + wType = 1; + break; + case 2: + wType = 2; + break; + case 3: + wType = 4; + break; + case 4: + wType = 8; + break; + case 5: + wType = 16; + } + BOOL suc = ReportEventA(hEventLog, wType, amLog.m_Option.m_EventCategory, + amLog.m_Option.m_EventId, NULL, 1, 0, &lpMsg, NULL); + if (!suc) { + DeregisterEventSource(hEventLog); + return AM_LOG_STATUS_ERR_REPORT; + } + DeregisterEventSource(hEventLog); + return AM_LOG_STATUS_OK; +} diff --git a/src/micetools/lib/am/amLog.h b/src/micetools/lib/am/amLog.h index 39b8fcf..92eb750 100644 --- a/src/micetools/lib/am/amLog.h +++ b/src/micetools/lib/am/amLog.h @@ -1,2 +1,34 @@ -void amLogInit(void); -void amLogSetEventOption(void); +#pragma once + +#include + +#include "../_am.h" + +AM_LIB_H_HEADER(amLog, AM_LOG) + +typedef struct AM_LOG_OPTION { + LPCSTR m_EventSource; + DWORD m_EventType; + WORD m_EventId; + WORD m_EventCategory; +} AM_LOG_OPTION; + +typedef struct AM_LOG { + BOOL m_Init; + AM_LOG_OPTION m_Option; +} AM_LOG; + +typedef enum { + AM_LOG_STATUS_OK = 0, + AM_LOG_STATUS_NG = -1, + AM_LOG_STATUS_ERR_INVALID_PARAM = -2, + AM_LOG_STATUS_ERR_NO_INIT = -3, + AM_LOG_STATUS_ERR_ALREADY_INIT = -4, + AM_LOG_STATUS_ERR_REGISTER = -5, + AM_LOG_STATUS_ERR_REPORT = -6, +} AM_LOG_STATUS; + +int amLogInit(void); +int amLogFinalize(void); +int amLogSetEventOption(AM_LOG_OPTION* lpOption); +int amLogReportEvent(LPCSTR lpMsg); diff --git a/src/micetools/lib/am/amOemstring.h b/src/micetools/lib/am/amOemstring.h index 78eca42..91d3d17 100644 --- a/src/micetools/lib/am/amOemstring.h +++ b/src/micetools/lib/am/amOemstring.h @@ -22,6 +22,8 @@ typedef struct AM_OEMSTRING { CHAR m_strings[5][32]; } AM_OEMSTRING; +#define OEMSTRING_PLATFORM 2 +#define OEMSTRING_BOARD_TYPE 4 typedef enum { AM_OEMSTRING_STATUS_OK = 0, @@ -30,7 +32,6 @@ typedef enum { AM_OEMSTRING_STATUS_ERR_SYS = -3, } AM_OEMSTRING_STATUS; - void amiOemstringLocateDMITable(HANDLE hColumba, LPDWORD lpDmiBase, LPWORD lpDmiLength); void amiOemstringStoreString(BYTE type, int stringno, LPSTR string); BOOL amiOemstringLoadStrings(void); diff --git a/src/micetools/lib/am/amPlatform.c b/src/micetools/lib/am/amPlatform.c index 56ab2db..2e73201 100644 --- a/src/micetools/lib/am/amPlatform.c +++ b/src/micetools/lib/am/amPlatform.c @@ -16,94 +16,94 @@ AM_PLATFORM_NV_DEVICE_CONFIG amPlatformNvDevices[3][4] = { // RingEdge 1 { { - .m_base = 0x0, - .m_size = 0x1000, - .m_blockSize = 1, - .m_read = _amEepromRead, - .m_write = _amEepromWrite, + .m_Base = 0x0, + .m_Size = 0x1000, + .m_BlockSize = 1, + .m_ReadFunc = _amEepromRead, + .m_WriteFunc = _amEepromWrite, }, { - .m_base = 0x1000, - .m_size = 0x1000, - .m_blockSize = 1, - .m_read = _amEepromRead, - .m_write = _amEepromWrite, + .m_Base = 0x1000, + .m_Size = 0x1000, + .m_BlockSize = 1, + .m_ReadFunc = _amEepromRead, + .m_WriteFunc = _amEepromWrite, }, { - .m_base = 0, - .m_size = 0x4000, - .m_blockSize = 512, - .m_read = _amSramRead, - .m_write = _amSramWrite, + .m_Base = 0, + .m_Size = 0x4000, + .m_BlockSize = 512, + .m_ReadFunc = _amSramRead, + .m_WriteFunc = _amSramWrite, }, { - .m_base = 0x4000, - .m_size = 0x1FC000, - .m_blockSize = 512, - .m_read = _amSramRead, - .m_write = _amSramWrite, + .m_Base = 0x4000, + .m_Size = 0x1FC000, + .m_BlockSize = 512, + .m_ReadFunc = _amSramRead, + .m_WriteFunc = _amSramWrite, }, }, // RingEdge 2 { { - .m_base = 0x0, - .m_size = 0x1000, - .m_blockSize = 1, - .m_read = _amEepromRead, - .m_write = _amEepromWrite, + .m_Base = 0x0, + .m_Size = 0x1000, + .m_BlockSize = 1, + .m_ReadFunc = _amEepromRead, + .m_WriteFunc = _amEepromWrite, }, { - .m_base = 0x1000, - .m_size = 0x1000, - .m_blockSize = 1, - .m_read = _amEepromRead, - .m_write = _amEepromWrite, + .m_Base = 0x1000, + .m_Size = 0x1000, + .m_BlockSize = 1, + .m_ReadFunc = _amEepromRead, + .m_WriteFunc = _amEepromWrite, }, { - .m_base = 0, - .m_size = 0x4000, - .m_blockSize = 4, - .m_read = _amSramRead, - .m_write = _amSramWrite, + .m_Base = 0, + .m_Size = 0x4000, + .m_BlockSize = 4, + .m_ReadFunc = _amSramRead, + .m_WriteFunc = _amSramWrite, }, { - .m_base = 0x4000, - .m_size = 0x1FC000, - .m_blockSize = 4, - .m_read = _amSramRead, - .m_write = _amSramWrite, + .m_Base = 0x4000, + .m_Size = 0x1FC000, + .m_BlockSize = 4, + .m_ReadFunc = _amSramRead, + .m_WriteFunc = _amSramWrite, }, }, // RingWide { { - .m_base = 0x0, - .m_size = 0x1000, - .m_blockSize = 1, - .m_read = _amEepromRead, - .m_write = _amEepromWrite, + .m_Base = 0x0, + .m_Size = 0x1000, + .m_BlockSize = 1, + .m_ReadFunc = _amEepromRead, + .m_WriteFunc = _amEepromWrite, }, { - .m_base = 0x1000, - .m_size = 0x1000, - .m_blockSize = 1, - .m_read = _amEepromRead, - .m_write = _amEepromWrite, + .m_Base = 0x1000, + .m_Size = 0x1000, + .m_BlockSize = 1, + .m_ReadFunc = _amEepromRead, + .m_WriteFunc = _amEepromWrite, }, { - .m_base = 0, - .m_size = 0x4000, - .m_blockSize = 512, - .m_read = _amSramRead, - .m_write = _amSramWrite, + .m_Base = 0, + .m_Size = 0x4000, + .m_BlockSize = 512, + .m_ReadFunc = _amSramRead, + .m_WriteFunc = _amSramWrite, }, { - .m_base = 0x4000, - .m_size = 0x3C000, - .m_blockSize = 512, - .m_read = _amSramRead, - .m_write = _amSramWrite, + .m_Base = 0x4000, + .m_Size = 0x3C000, + .m_BlockSize = 512, + .m_ReadFunc = _amSramRead, + .m_WriteFunc = _amSramWrite, }, }, }; @@ -135,21 +135,21 @@ AM_PLATFORM_STATUS amPlatformGetPlatformId(AM_PLATFORM_PLATFORM_ID *platformId) char oemstringManufacturer[32]; /** - * If platform starts with "AAM" (RW) or "AAL" (RE): + * If platform starts with PLATFORM_RINGWIDE (RW) or PLATFORM_RINGEDGE (RE): * copy it into m_platformId verbatim * Otherwise * fetch the manufacturer name - * If manufacturer is "NEC" - * m_platformId = "AAL" (RE) - * If manufacturer if "Supermicro" or "Advantech" - * m_platformId = "AAM" (RW) + * If manufacturer is MANUFACTURER_RE + * m_platformId = PLATFORM_RINGEDGE (RE) + * If manufacturer if MANUFACTURER_RW_1 or MANUFACTURER_RW_2 + * m_platformId = PLATFORM_RINGWIDE (RW) */ if (!amPlatform.m_platformIdCached) { - if (amOemstringGetOemstring(oemstringPlatform, 2) != AM_OEMSTRING_STATUS_OK) { + if (amOemstringGetOemstring(oemstringPlatform, OEMSTRING_PLATFORM) != + AM_OEMSTRING_STATUS_OK) { if (amPlatformDebugLevel > 0) - amiDebugLog("amOemstringGetOemstring Error!! (%d)", - AM_PLATFORM_STATUS_ERR_SYS); + amiDebugLog("amOemstringGetOemstring Error!! (%d)", AM_PLATFORM_STATUS_ERR_SYS); return AM_PLATFORM_STATUS_ERR_SYS; } @@ -214,7 +214,8 @@ AM_PLATFORM_STATUS amPlatformGetBoardType(AM_PLATFORM_BOARD_TYPE *boardType) { if (strcmp(oemstringManufacturer, MANUFACTURER_RE) == 0) { ZeroMemory(oemstring4, sizeof oemstring4); - if (amOemstringGetOemstring(oemstring4, 4) != AM_OEMSTRING_STATUS_OK) { + if (amOemstringGetOemstring(oemstring4, OEMSTRING_BOARD_TYPE) != + AM_OEMSTRING_STATUS_OK) { *boardType = amPlatform.m_boardType = AM_PLATFORM_BOARD_TYPE_UNKNOWN; return AM_PLATFORM_STATUS_ERR_SYS; } @@ -237,3 +238,220 @@ AM_PLATFORM_STATUS amPlatformGetBoardType(AM_PLATFORM_BOARD_TYPE *boardType) { amPlatform.m_boardTypeCached = TRUE; return AM_PLATFORM_STATUS_OK; } + +AM_PLATFORM_STATUS amPlatformGetPlatformIdEx(AM_PLATFORM_PLATFORM_ID_EX *lpPlatform) { + char oemstring[32]; + char manufacturer[32]; + + if (lpPlatform == NULL) { + if (amPlatformDebugLevel > 0) amiDebugLog("PARAM Error!!"); + return AM_PLATFORM_STATUS_ERR_INVALID_PARAM; + } + + static char m_strPlatformId[4]; + static DWORD m_dwPlatformId; + static bool m_platformIdCached = false; + + int err; + + ZeroMemory(oemstring, sizeof oemstring); + if (!m_platformIdCached) { + err = amOemstringGetOemstring(oemstring, OEMSTRING_PLATFORM); + if (err != AM_OEMSTRING_STATUS_OK) { + if (amPlatformDebugLevel > 0) amiDebugLog("amOemstringGetOemstring Error!! (%d)", err); + goto oemstring_bad; + } + + if (strcmp(oemstring, PLATFORM_RINGEDGE) == 0 || + strcmp(oemstring, PLATFORM_RINGWIDE) == 0) { + strncpy_s(m_strPlatformId, sizeof m_strPlatformId, oemstring, 0xFFFFFFFF); + } else if (!amOemstringGetManufacturer(manufacturer)) { + if (strcmp(manufacturer, MANUFACTURER_RE) == 0) { + strncpy_s(m_strPlatformId, sizeof m_strPlatformId, PLATFORM_RINGEDGE, 0xFFFFFFFF); + } else if (strcmp(manufacturer, MANUFACTURER_RW_1) == 0 || + strcmp(manufacturer, MANUFACTURER_RW_2) == 0) { + strncpy_s(m_strPlatformId, sizeof m_strPlatformId, PLATFORM_RINGWIDE, 0xFFFFFFFF); + } + } + + oemstring[0] = 0; + err = amOemstringGetOemstring(oemstring, OEMSTRING_BOARD_TYPE); + if (err != AM_OEMSTRING_STATUS_OK) { + if (amPlatformDebugLevel > 0) amiDebugLog("amOemstringGetOemstring Error!! (%d)", err); + goto oemstring_bad; + } + + size_t boardTypeLen = strlen(oemstring); + m_dwPlatformId = 0; + if (strcmp(m_strPlatformId, PLATFORM_RINGEDGE) == 0) { + if (boardTypeLen == 0) { + m_dwPlatformId = 1; + m_platformIdCached = true; + goto LABEL_11; + } else if (boardTypeLen == 1) { + if (strcmp(oemstring, " ") == 0) { + m_dwPlatformId = 1; + m_platformIdCached = true; + goto LABEL_11; + } + if (amPlatformDebugLevel > 0) amiDebugLog("Oemstring length Error!!"); + goto oemstring_bad; + } + } else if (strcmp(m_strPlatformId, PLATFORM_RINGWIDE) == 0 && boardTypeLen == 0) { + m_dwPlatformId = 1; + m_platformIdCached = true; + goto LABEL_11; + } + + if (boardTypeLen < 3) { + if (amPlatformDebugLevel > 0) amiDebugLog("Oemstring length Error!!"); + goto oemstring_bad; + } + if (strncmp(m_strPlatformId, oemstring, 3) != 0) { + if (amPlatformDebugLevel > 0) amiDebugLog("Oemstring compare Error!!"); + goto oemstring_bad; + } + + if (boardTypeLen > 3) { + for (size_t i = 3; i < boardTypeLen; i++) { + if (oemstring[i] < '0' || oemstring[i] > '9') { + if (amPlatformDebugLevel > 0) amiDebugLog("Oemstring format Error!!"); + goto oemstring_bad; + } + } + } + + m_dwPlatformId = atoi(&oemstring[3]); + if (!m_dwPlatformId) goto oemstring_bad; + m_platformIdCached = true; + } + +LABEL_11: + memcpy(lpPlatform->strPlatformId, m_strPlatformId, 4); + lpPlatform->platformId = m_dwPlatformId; + return m_platformIdCached ? AM_PLATFORM_STATUS_OK : AM_PLATFORM_STATUS_ERR_SYS; + +oemstring_bad: + if (!m_platformIdCached) { + ZeroMemory(m_strPlatformId, sizeof m_strPlatformId); + m_dwPlatformId = 0; + } + goto LABEL_11; +} + +int amPlatformGetBiosInfo(AM_PLATFORM_BIOS_INFO *lpInfo) { + if (lpInfo == NULL) { + if (amPlatformDebugLevel > 0) amiDebugLog("PARAM Error!!"); + return AM_PLATFORM_STATUS_ERR_INVALID_PARAM; + } + + CHAR biosVer[32]; + int err = amOemstringGetSBiosVer(biosVer); + if (err < 0) { + if (amPlatformDebugLevel > 0) amiDebugLog("amOemstringGetSBiosVer Error!! (%d)", err); + return AM_PLATFORM_STATUS_ERR_SYS; + } + + CHAR biosReleaseDate[12]; + err = amOemstringGetSBiosReleaseDate(biosReleaseDate); + if (err < 0) { + if (amPlatformDebugLevel > 0) + amiDebugLog("amOemstringGetSBiosReleaseDate Error!! (%d)", err); + return AM_PLATFORM_STATUS_ERR_SYS; + } + + strncpy_s(lpInfo->m_BiosVer, sizeof lpInfo->m_BiosVer, biosVer, 0xffffffff); + strncpy_s(lpInfo->m_BiosReleaseDate, sizeof lpInfo->m_BiosReleaseDate, biosReleaseDate, + 0xffffffff); + return AM_PLATFORM_STATUS_OK; +} + +int amPlatformGetOsVersion(DWORD *lpVersion) { + if (lpVersion == NULL) { + if (amPlatformDebugLevel > 0) amiDebugLog("PARAM Error!!"); + return AM_PLATFORM_STATUS_ERR_INVALID_PARAM; + } + + static DWORD osVersion = 0; + + if (osVersion == 0) { + HANDLE hSysver = CreateFileW(L"C:\\System\\SystemVersion.txt", GENERIC_READ, 1, NULL, + OPEN_EXISTING, FILE_SHARE_READ, NULL); + if (hSysver == INVALID_HANDLE_VALUE) { + if (amPlatformDebugLevel > 0) + amiDebugLog("CreateFile Error!! Error Code is %d", GetLastError()); + } else { + DWORD nRead = 0; + char buffer[8]; + + if (!ReadFile(hSysver, buffer, 8, &nRead, NULL)) { + if (amPlatformDebugLevel > 0) + amiDebugLog("ReadFile Error!! Error Code is %d", GetLastError()); + } else if (nRead != 8) { + if (amPlatformDebugLevel > 0) + amiDebugLog("ReadFile Error!! Error Code is %d", GetLastError()); + } else { + WORD ver1 = (((buffer[0] - '0') * 1000) + ((buffer[1] - '0') * 100) + + (buffer[2] - '0') * 10 + (buffer[3] - '0')); + BYTE ver2 = (buffer[4] - '0') * 10 + (buffer[5] - '0'); + BYTE ver3 = (buffer[6] - '0') * 10 + (buffer[7] - '0'); + + osVersion = (((ver1 << 16) | ver2) << 8) | ver3; + } + CloseHandle(hSysver); + } + } + + *lpVersion = osVersion; + return osVersion == 0 ? AM_PLATFORM_STATUS_ERR_SYS : AM_PLATFORM_STATUS_OK; +} + +int amPlatformGetMemorySize(PLARGE_INTEGER size) { + if (size == NULL) { + if (amPlatformDebugLevel > 0) amiDebugLog("PARAM Error!!"); + return AM_PLATFORM_STATUS_ERR_INVALID_PARAM; + } + + MEMORYSTATUSEX statex; + statex.dwLength = sizeof statex; + if (!GlobalMemoryStatusEx((LPMEMORYSTATUSEX)&statex)) { + if (amPlatformDebugLevel > 0) + amiDebugLog("GlobalMemoryStatusEx Error!! (%d)", GetLastError()); + size->QuadPart = 0; + return AM_PLATFORM_STATUS_ERR_SYS; + } + + size->QuadPart = statex.ullTotalPhys; + return AM_PLATFORM_STATUS_OK; +} + +static AM_PLATFORM_CMOS_PARAM _cmosParam[5] = { + // RE + { + .index = { { 0x60, 0x00 }, { 0x61, 0x00 } }, + .m_MbrCount = 0, + }, + // RW 1 + { + .index = { { 0x3a, 0x05 }, { 0x3a, 0x02 } }, + .m_MbrCount = 1, + }, + // RW 2 + { + .index = { { 0x28, 0x00 }, { 0x28, 0x00 } }, + .m_MbrCount = 1, + }, + // RE 2 + { + .index = { { 0x60, 0x00 }, { 0x61, 0x00 } }, + .m_MbrCount = 1, + }, + { + .index = { { 0x00, 0x00 }, { 0x00, 0x00 } }, + .m_MbrCount = 0, + }, +}; +AM_PLATFORM_CMOS_PARAM *amPlatformGetCmosParam(AM_PLATFORM_BOARD_TYPE boardType) { + if (boardType < 5) return &_cmosParam[boardType]; + return NULL; +} diff --git a/src/micetools/lib/am/amPlatform.h b/src/micetools/lib/am/amPlatform.h index ddcac21..9cff32a 100644 --- a/src/micetools/lib/am/amPlatform.h +++ b/src/micetools/lib/am/amPlatform.h @@ -17,6 +17,10 @@ AM_LIB_H_HEADER(amPlatform, AM_PLATFORM) typedef struct { char strPlatformId[4]; } AM_PLATFORM_PLATFORM_ID; +typedef struct { + char strPlatformId[4]; + int platformId; +} AM_PLATFORM_PLATFORM_ID_EX; typedef enum { AM_PLATFORM_BOARD_TYPE_RINGEDGE = 0, @@ -33,7 +37,7 @@ typedef struct AM_PLATFORM { AM_PLATFORM_PLATFORM_ID m_platformId; } AM_PLATFORM; -typedef struct { +typedef struct AM_PLATFORM_ID_GROUP { char strVendorId[5]; char strDeviceId[5]; char strSubId[9]; @@ -67,24 +71,42 @@ typedef enum { typedef int(amPlatformRead_t)(WORD addr, LPBYTE buf, DWORD length); typedef int(amPlatformWrite_t)(WORD addr, LPBYTE buf, DWORD length); -typedef struct { - DWORD m_base; - DWORD m_size; - DWORD m_blockSize; - amPlatformRead_t* m_read; - amPlatformWrite_t* m_write; +typedef struct AM_PLATFORM_NV_DEVICE_CONFIG { + DWORD m_Base; + DWORD m_Size; + DWORD m_BlockSize; + amPlatformRead_t* m_ReadFunc; + amPlatformWrite_t* m_WriteFunc; } AM_PLATFORM_NV_DEVICE_CONFIG; +typedef struct AM_PLATFORM_BIOS_INFO { + CHAR m_BiosVer[64]; + CHAR m_BiosReleaseDate[11]; +} AM_PLATFORM_BIOS_INFO; + +typedef struct AM_PLATFORM_CMOS_PARAM { + // [address, bit offset][2] + BYTE index[2][2]; + BYTE m_MbrCount; +} AM_PLATFORM_CMOS_PARAM; + AM_PLATFORM_NV_DEVICE_CONFIG* amPlatformGetNvDevice(AM_PLATFORM_NV_DEVICE device); AM_PLATFORM_STATUS amPlatformGetBoardType(AM_PLATFORM_BOARD_TYPE* boardType); AM_PLATFORM_STATUS amPlatformGetPlatformId(AM_PLATFORM_PLATFORM_ID* platformId); +AM_PLATFORM_STATUS amPlatformGetPlatformIdEx(AM_PLATFORM_PLATFORM_ID_EX* platformId); + +int amPlatformGetBiosInfo(AM_PLATFORM_BIOS_INFO* lpInfo); +int amPlatformGetOsVersion(DWORD* lpVersion); // Reads SystemVersion.txt +int amPlatformGetMemorySize(PLARGE_INTEGER size); + +AM_PLATFORM_CMOS_PARAM* amPlatformGetCmosParam(AM_PLATFORM_BOARD_TYPE boardType); // TODO: - -void amPlatformAsyncClose(void); -void amPlatformAsyncReqUsbDeviceCount(void); -void amPlatformAsyncResUsbDeviceCount(void); +// usbDongle.exe -> see in maimai 1.90 folder +void amPlatformAsyncClose(void); // usbDongle.exe +void amPlatformAsyncReqUsbDeviceCount(void); // usbDongle.exe +void amPlatformAsyncResUsbDeviceCount(void); // usbDongle.exe void amPlatformChangeDisplayModeAmd(void); void amPlatformChangeDisplayModeNvidia(void); void amPlatformChangeDisplayModeNvidiaEx(void); @@ -93,23 +115,19 @@ void amPlatformChangeDisplayResolutionNvidia(void); void amPlatformChangeDisplayResolutionNvidiaEx(void); void amPlatformChangeDisplayResolutionWinAPI(void); void amPlatformDestroyCheckInterfaceHandle(void); -void amPlatformGetAvailableAmdDriver(void); -void amPlatformGetAvailableNvidiaDriver(void); -void amPlatformGetBiosInfo(void); -void amPlatformGetCheckInterfaceHandle(void); -void amPlatformGetComInfo(void); -void amPlatformGetDevInfo(void); -void amPlatformGetGpuPstate(void); -void amPlatformGetGraphicInfo(void); -void amPlatformGetMemorySize(void); -void amPlatformGetOsVersion(void); -void amPlatformGetPartitionInfo(void); -void amPlatformGetPlatformIdEx(void); -void amPlatformGetPortName(void); -void amPlatformGetSearchDevInfo(void); -void amPlatformGetSoundInfo(void); -void amPlatformGetStorageInfo(void); -void amPlatformNvapiInit(void); +void amPlatformGetAvailableAmdDriver(void); // usbDongle.exe +void amPlatformGetAvailableNvidiaDriver(void); // usbDongle.exe +void amPlatformGetCheckInterfaceHandle(void); // usbDongle.exe +void amPlatformGetComInfo(void); // usbDongle.exe +void amPlatformGetDevInfo(void); // usbDongle.exe +void amPlatformGetGpuPstate(void); // usbDongle.exe +void amPlatformGetGraphicInfo(void); // usbDongle.exe +void amPlatformGetPartitionInfo(void); // usbDongle.exe +void amPlatformGetPortName(void); // usbDongle.exe +void amPlatformGetSearchDevInfo(void); // usbDongle.exe +void amPlatformGetSoundInfo(void); // usbDongle.exe +void amPlatformGetStorageInfo(void); // usbDongle.exe +void amPlatformNvapiInit(void); // usbDongle.exe void amPlatformSetDisplayMode(void); void amPlatformSetDisplayResolution(void); void amPlatformSetDisplayResolutionAndMode(void); diff --git a/src/micetools/lib/am/meson.build b/src/micetools/lib/am/meson.build index aed63d7..39a6100 100644 --- a/src/micetools/lib/am/meson.build +++ b/src/micetools/lib/am/meson.build @@ -13,6 +13,7 @@ amEeprom = static_library( link_with: [ amiDebug, amiCrc, + amiTimer, ], ) @@ -35,6 +36,7 @@ amPlatform = static_library( amiDebug, amSram, amEeprom, + amOemstring, ], ) @@ -78,3 +80,20 @@ amCmos = static_library( amiDebug, ], ) + +amLog = static_library( + 'amLog', + sources: [ + 'amLog.c', + ], +) +amBackup = static_library( + 'amBackup', + sources: [ + 'amBackup.c', + ], + link_with: [ + amiDebug, + amiCrc, + ], +) diff --git a/src/micetools/lib/libpcp/pcpa.c b/src/micetools/lib/libpcp/pcpa.c index 87c885d..f39c9bf 100644 --- a/src/micetools/lib/libpcp/pcpa.c +++ b/src/micetools/lib/libpcp/pcpa.c @@ -449,7 +449,8 @@ e_pcpa_t pcpaServer(pcpa_t *stream, timeout_t timeout_ms) { case 10: // TODO: Figure out why recv_buf is empty at this point in the FSM if (stream->before_cb != NULL) - stream->before_cb(stream, stream->pcpp.sock.recv_buf); + stream->before_cb(stream, (char *)stream->pcpp.sock.recv_buf, + *stream->pcpp.sock.recv_buf_count); if (stream->callback_table == NULL) { amiDebugLog("error Callback_table buffer isn't set"); diff --git a/src/micetools/lib/libpcp/pcpa.h b/src/micetools/lib/libpcp/pcpa.h index 2f25979..0e27878 100644 --- a/src/micetools/lib/libpcp/pcpa.h +++ b/src/micetools/lib/libpcp/pcpa.h @@ -45,6 +45,7 @@ e_pcpa_t _pcpaGetErrorFromPcpp(e_pcpp_t err); struct pcpa; typedef void(pcpa_callback)(struct pcpa* stream, void* data); +typedef void(pcpa_log_callback)(struct pcpa* stream, char* data, size_t nData); typedef struct pcpa_cb_table { char keyword[PCP_KEYWORD_MAX]; @@ -73,7 +74,7 @@ typedef struct pcpa { pcp_send_data_t send_data; // Our additions - pcpa_callback* before_cb; + pcpa_log_callback* before_cb; } pcpa_t; void pcpaClose(pcpa_t* stream); @@ -81,7 +82,8 @@ void pcpaCloseBinary(pcpa_t* stream); char* pcpaGetKeyword(pcpa_t* stream, uint keyword_num); e_pcpa_t pcpaInitStream(pcpa_t* stream); e_pcpa_t pcpaOpenClient(pcpa_t* stream, char* ipAddr, ushort port, uint param_4, timeout_t timeout); -e_pcpa_t pcpaOpenServerWithBinary(pcpa_t* stream, int open_mode, ushort port, ushort binary_port, timeout_t param_5); +e_pcpa_t pcpaOpenServerWithBinary(pcpa_t* stream, int open_mode, ushort port, ushort binary_port, + timeout_t param_5); e_pcpa_t pcpaRecvBinary(pcpa_t* stream, timeout_t something); e_pcpa_t pcpaSendBinary(pcpa_t* stream, timeout_t something); e_pcpa_t pcpaServer(pcpa_t* stream, timeout_t timeout_ms); @@ -89,15 +91,16 @@ e_pcpa_t pcpaSetAfterBinaryModeCallBackFunc(pcpa_t* stream, pcpa_callback* callb e_pcpa_t pcpaSetBeforeBinaryModeCallBackFunc(pcpa_t* stream, pcpa_callback* callback, void* data); e_pcpa_t pcpaSetBinaryMode(pcpa_t* stream, binary_mode_t binary_mode); e_pcpa_t pcpaSetCallbackFunc(pcpa_t* stream, char* keyword, pcpa_callback* callback, void* data); -e_pcpa_t pcpaSetCallbackFuncBuffer(pcpa_t* stream, pcpa_cb_table_t* callback_table, uint callbacks_max); +e_pcpa_t pcpaSetCallbackFuncBuffer(pcpa_t* stream, pcpa_cb_table_t* callback_table, + uint callbacks_max); e_pcpa_t pcpaSetRecvBinaryBuffer(pcpa_t* stream, unsigned char* recv_buffer, size_t len); e_pcpa_t pcpaSetSendBinaryBuffer(pcpa_t* stream, const unsigned char* send_buffer, size_t len); pcp_send_data_t* pcpaSetSendPacket(pcpa_t* stream, char* keyword, char* value); -pcp_send_data_t *pcpaAddSendPacket(pcpa_t *stream, char *keyword, char *value); +pcp_send_data_t* pcpaAddSendPacket(pcpa_t* stream, char* keyword, char* value); char* pcpaGetCommand(pcpa_t* pcpa, char* command); -e_pcpa_t pcpaIsBusy(pcpa_t *pcpa, timeout_t timeout); -e_pcpa_t pcpaSendRequest(pcpa_t *stream, timeout_t timeout); -e_pcpa_t pcpaRecvResponse(pcpa_t *stream, timeout_t timeout); -e_pcpa_t pcpaOpenBinaryClient(pcpa_t *stream, ushort port, timeout_t timeout); +e_pcpa_t pcpaIsBusy(pcpa_t* pcpa, timeout_t timeout); +e_pcpa_t pcpaSendRequest(pcpa_t* stream, timeout_t timeout); +e_pcpa_t pcpaRecvResponse(pcpa_t* stream, timeout_t timeout); +e_pcpa_t pcpaOpenBinaryClient(pcpa_t* stream, ushort port, timeout_t timeout); e_pcpa_t pcpaAccessClient(pcpa_t* stream, timeout_t timeout); diff --git a/src/micetools/lib/libpcp/util.c b/src/micetools/lib/libpcp/util.c index 3796b00..51a5379 100644 --- a/src/micetools/lib/libpcp/util.c +++ b/src/micetools/lib/libpcp/util.c @@ -56,10 +56,8 @@ void pcpaPrint(pcpa_t* stream) { printf(" %d commands:\n", stream->recv_data.cmd_count); for (size_t i = 0; i < stream->recv_data.cmd_count; i++) { byte kwd = stream->recv_data.keywords[i]; - if (kwd != 0) kwd++; printf(" & %02d '%s'\n", kwd, stream->recv_data.strings + kwd); byte value = stream->recv_data.values[i]; - if (value != 0) value++; printf(" = %02d '%s'\n", value, stream->recv_data.strings + value); if (stream->recv_data.strings[kwd] == 0) break; } diff --git a/src/micetools/lib/mice/log_facilities.def b/src/micetools/lib/mice/log_facilities.def index 33666b1..8aa139f 100644 --- a/src/micetools/lib/mice/log_facilities.def +++ b/src/micetools/lib/mice/log_facilities.def @@ -3,7 +3,8 @@ _LF(Internal, Hooks, "hooks") _LF(Internal, Misc, "misc") _LF(Misc, Tea, "tea") -_LF(Misc, Printf, "printf") +_LF(Misc, Stdout, "stdout") +_LF(Misc, Stderr, "stderr") _LF(Misc, Fprintf, "fprintf") _LF(Misc, Fprintf_s, "fprintf_s") _LF(Misc, Vfprintf_s, "vfprintf_s") diff --git a/src/micetools/miceboot/meson.build b/src/micetools/miceboot/meson.build index ec15ff7..548e330 100644 --- a/src/micetools/miceboot/meson.build +++ b/src/micetools/miceboot/meson.build @@ -11,6 +11,21 @@ executable( win_subsystem: subsystem, sources: [ 'mxstartup.c', + 'osu.c', + 'osg.c', + ], + link_with: [ + amLog, + amiDebug, + amiCrc, + amBackup, + amEeprom, + amBackup, + amCmos, + amPlatform, + ], + dependencies: [ + ewfapi_lib, ], ) diff --git a/src/micetools/miceboot/mxstartup.c b/src/micetools/miceboot/mxstartup.c index e8e89d7..82fa015 100644 --- a/src/micetools/miceboot/mxstartup.c +++ b/src/micetools/miceboot/mxstartup.c @@ -1,26 +1,48 @@ #include #include +#include #include #include #include #include +#include +#include "../amBackupStructs.h" +#include "../lib/am/amBackup.h" +#include "../lib/am/amEeprom.h" +#include "../lib/am/amLog.h" +#include "../lib/am/amPlatform.h" +#include "../lib/ami/amiCrc.h" +#include "../lib/ami/amiDebug.h" #include "ewfapi.h" +#include "osg.h" +#include "osu.h" typedef enum { MxError_Unknown = -1, MxError_None = 0, + MxError_SecurityCheck = 500, MxError_Ewf = 501, MxError_Version = 502, MxError_NoKeyFile = 503, MxError_DiskAccessPrivilege = 504, MxError_SystemMount = 505, - + MxError_MountUpdate = 506, MxError_MxMaster = 507, - + MxError_OSUpdateKeyFile = 508, + MxError_ExecuteOSUpdate = 509, + MxError_EWFEnable = 510, MxError_SBR = 511, MxError_SysKeyDelete = 512, + MxError_MountDriver = 513, + MxError_RingRegistry = 514, + + MxError_UnMountVolume = 540, + MxError_MountRecovery = 541, + MxError_ChangeActivePartition = 543, + MxError_Reboot = 545, + MxError_GetCD = 546, } MxError_t; typedef enum { Init = 0, @@ -41,7 +63,15 @@ typedef enum { #define SYSTEM_KEY_FILE "Z:\\SystemKeyFile" #define OS_UPDATE_KEY_FILE "Z:\\UpdateKeyFile" #define SYSTEM_VOLUME "C:\\System\\Execute\\System" +#define DEFAULT_DRIVERS "Z:\\Minint\\System32\\DEFAULT_DRIVERS" #define SYSTEM_MOUNT "S:" +#define UPDATE_MOUNT "W:" +#define UPDATE_MOUNT_SLASH "W:\\" +#define DRIVERS_MOUNT "V:" +#define DRIVERS_MOUNT_SLASH "V:\\" +#define OS_UPDATE_CONF "W:\\OSupdate2.conf" +#define DRIVERS_UPDATE_EXE "V:\\MXOSUpdate.exe" +#define UPDATE_EXE "W:\\MXOSUpdate.exe" #define NEXT_HOP_CWD SYSTEM_MOUNT "\\" #define NEXT_HOP_MXMASTER NEXT_HOP_CWD "mxmaster.exe" @@ -50,6 +80,8 @@ typedef enum { #define CACLS_REMPERM_Z "cacls z:\\ /t /e /p appuser:N" #define CACLS_REMPERM_S "cacls s:\\ /t /e /p appuser:N" +#define TRUECRYPT "TrueCrypt" + // Rather than implement these sums in code, we're just going to use the // presummed versions, because we have nothing to gain by obfuscating this. // These two sum to TC_PASSWORD @@ -67,8 +99,6 @@ typedef enum { int LOG_EN_PLATFORM = 0; -#define MX_LOG(...) log(__FUNCTION__, __LINE__, __VA_ARGS__) - void log(char* function, unsigned int line_number, char* fmt, ...) { va_list args; va_start(args, fmt); @@ -77,43 +107,109 @@ void log(char* function, unsigned int line_number, char* fmt, ...) { va_end(args); } -// TODO: These two -bool InitGraphics() { return true; } -bool PopulateEventInfo() { return true; } +BOOL isDebugEnabled(void) { + WIN32_FIND_DATAA find; + HANDLE hFind; -// TODO: These three -void AppendAsterisk(void){}; -void setStrForStep2(void){}; -void setStrForStep3(void){}; - -int osuExecProcess(char* command) { - PROCESS_INFORMATION processInformation = { 0 }; - STARTUPINFOA startupInfo = { - .cb = 68, - .dwFlags = STARTF_USESHOWWINDOW, - .wShowWindow = SW_HIDE, - }; - - if (command == NULL) return -150; - - BOOL spanwed = CreateProcessA(NULL, command, NULL, NULL, 0, 0, NULL, NULL, &startupInfo, &processInformation); - DWORD wait = WaitForSingleObject(processInformation.hProcess, INFINITE); - - int ret; - if (!spanwed) { - ret = -140; - } else if (wait == WAIT_OBJECT_0) { - DWORD exitCode; - GetExitCodeProcess(processInformation.hProcess, &exitCode); - ret = exitCode == 0 ? 0 : -141; - } else { - ret = -141; + hFind = FindFirstFileA(".\\DebugEnable", &find); + if (hFind != INVALID_HANDLE_VALUE) { + FindClose(hFind); + return TRUE; } + FindClose(hFind); + return FALSE; +} - CloseHandle(processInformation.hProcess); - CloseHandle(processInformation.hThread); +colour GetBGColour(void) { + HKEY hkResult; + LSTATUS status; + status = + RegOpenKeyExA(HKEY_USERS, ".Default\\Control Panel\\Colors", 0, KEY_ALL_ACCESS, &hkResult); + if (status != ERROR_SUCCESS) return White; - return ret; + BYTE data[16]; + DWORD cbData = sizeof data; + status = RegQueryValueExA(hkResult, "BackGround", NULL, NULL, data, &cbData); + if (status == ERROR_SUCCESS) { + RegCloseKey(hkResult); + return (memcmp(data, "100 100 100", 13) == 0) ? Grey : White; + } else { + RegCloseKey(hkResult); + return White; + } +} + +OSU_TOP g_Top; +OSU_BOTTOM g_Bottom; +OSU g_Osu; + +#define LINE5_LEN 32 +bool InitGraphics(HINSTANCE hInstance, int nShowCmd) { + g_Top.show_top = 0; + g_Top.debugEnable = isDebugEnabled(); + g_Top.top_text_colour = White; + g_Top.top_text_font = 2; + g_Top.str1 = "SYSTEM UPDATE"; + g_Bottom.backgroundColour = GetBGColour(); + colour bg_invert = g_Bottom.backgroundColour == White ? Black : White; + g_Bottom.line5_colour = bg_invert; + g_Bottom.power_colour = bg_invert; + g_Bottom.status_colour = bg_invert; + g_Bottom.status_font = 2; + g_Bottom.status_str = "NOW LOADING"; + g_Bottom.status_use_counter = 1; + g_Bottom.str2 = ""; + static char line5[LINE5_LEN]; + line5[0] = '\0'; + g_Bottom.line5 = line5; + g_Bottom.hide_power = 0; + g_Bottom.power_font = 0; + g_Osu.hInstance = hInstance; + g_Osu.nShowCmd = nShowCmd; + g_Osu.s1 = &g_Top; + g_Osu.s2 = &g_Bottom; + + BOOL ret = osgInitDraw(&g_Osu); + if (!ret) amiDebugLog("Error : osgInitDraw error"); + return ret != 0; +} + +void AppendAsterisk(void) { + EnterCriticalSection(&g_Top.criticalSection); + strcat_s(g_Bottom.line5, LINE5_LEN, "*"); + LeaveCriticalSection(&g_Top.criticalSection); +} +void setStrForStep2(void) { + EnterCriticalSection(&g_Top.criticalSection); + // TODO: Wtf was this line? + // FUN_00402c40((basic_string,class_std::allocator_> + // *) + // &g_Bottom.line5); + g_Top.show_top = 1; + g_Top.str2 = "STEP 2"; + g_Bottom.status_font = 0; + g_Bottom.status_str = ""; + g_Bottom.status_use_counter = 0; + g_Bottom.str2 = "DO NOT TURN OFF THE POWER."; + g_Bottom.hide_power = 1; + g_Bottom.power_font = 0; + LeaveCriticalSection(&g_Top.criticalSection); +} +void setStrForStep3(void) { + EnterCriticalSection(&g_Top.criticalSection); + // TODO: Wtf was this line? + // FUN_00402c40((basic_string,class_std::allocator_> + // *) + // &g_Bottom.line5); + g_Top.show_top = 1; + g_Top.str2 = "STEP 3"; + g_Bottom.status_font = 0; + g_Bottom.status_str = ""; + g_Bottom.status_use_counter = 0; + g_Bottom.str2 = "DO NOT TURN OFF THE POWER."; + g_Bottom.hide_power = 1; + g_Bottom.power_font = 0; + LeaveCriticalSection(&g_Top.criticalSection); } /* Read a version from a text file */ @@ -123,7 +219,7 @@ bool GetVersionText(char* version, char* path) { memset(buffer, 0, sizeof buffer); if (fopen_s(&file, path, "r") || file == NULL) { - MX_LOG("Error : GetVersionText error path = %s\n", path); + amiDebugLog("Error : GetVersionText error path = %s", path); return false; } @@ -140,15 +236,15 @@ bool GetDefaultVersion(char* version) { return GetVersionText(version, DEFAULT_V /* Mount the system volume */ bool MountSystemVolume(void) { char command[256]; - snprintf(command, sizeof command, "TrueCrypt /p %s /k %s /v %s /l %s /w /s /q", TC_PASSWORD, SYSTEM_KEY_FILE, - SYSTEM_VOLUME, SYSTEM_MOUNT); + snprintf(command, sizeof command, TRUECRYPT " /p %s /k %s /v %s /l %s /w /s /q", TC_PASSWORD, + SYSTEM_KEY_FILE, SYSTEM_VOLUME, SYSTEM_MOUNT); int ret = osuExecProcess(command); if (ret == 0) return true; - MX_LOG("Error : osuExecProcess error. ret = %d\n", ret); + amiDebugLog("Error : osuExecProcess error. ret = %d", ret); return false; -}; -/* Try to mount the system volume with up to 100 retries */ +} +/* Try to mount the system volume with up to 100 retries (20 seconds) */ bool TryMountSystemVolume(void) { for (int i = 0; i < 100; i++) { if (MountSystemVolume()) return true; @@ -158,38 +254,42 @@ bool TryMountSystemVolume(void) { } /* Copies the file at src to dst */ -bool GetKeyFile(LPCSTR src, LPCSTR dst) { - HANDLE file_1 = CreateFileA(src, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if (file_1 == INVALID_HANDLE_VALUE) { - MX_LOG("CreaterFile Src error\n"); +bool GetKeyFile(LPCSTR pszSrc, LPCSTR pszDst) { + HANDLE hSrc = CreateFileA(pszSrc, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hSrc == INVALID_HANDLE_VALUE) { + amiDebugLog("Error : CreateFile Src error"); return false; } - HANDLE file_2 = CreateFileA(dst, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (file_2 == INVALID_HANDLE_VALUE) { - CloseHandle(file_1); - MX_LOG("Error : CreateFile Dst error\n"); + HANDLE hDst = + CreateFileA(pszDst, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hDst == INVALID_HANDLE_VALUE) { + CloseHandle(hSrc); + amiDebugLog("Error : CreateFile Dst error"); return false; } CHAR readBuffer[260]; - DWORD bytesRead; - - if (!ReadFile(file_1, readBuffer, 255, &bytesRead, NULL)) { - CloseHandle(file_1); - CloseHandle(file_2); - MX_LOG("Error : ReadFile error\n"); + DWORD nRead; + if (!ReadFile(hSrc, readBuffer, 255, &nRead, NULL)) { + CloseHandle(hSrc); + CloseHandle(hDst); + amiDebugLog("Error : ReadFile error"); return false; } - readBuffer[bytesRead] = '\0'; + readBuffer[nRead] = '\0'; DWORD written; - bool ret = WriteFile(file_2, readBuffer, strlen(readBuffer), &written, NULL) != 0; - if (!ret) MX_LOG("Error : WriteFile error\n"); - CloseHandle(file_1); - CloseHandle(file_2); + bool ret = WriteFile(hDst, readBuffer, strlen(readBuffer), &written, NULL) != 0; + if (!ret) amiDebugLog("Error : WriteFile error"); + CloseHandle(hSrc); + CloseHandle(hDst); return ret; } +void DeleteMounteDevices(void) { + if (RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SYSTEM\\MountedDevices") != ERROR_SUCCESS) + amiDebugLog("Error : RegDeleteKeyA failed."); +} bool GetSystemKeyFile() { return GetKeyFile(SYSTEM_KEYFILE_ADS, SYSTEM_KEY_FILE); }; bool GetOSUpdateKeyFile() { return GetKeyFile(OS_UPDATE_KEYFILE_ADS, OS_UPDATE_KEY_FILE); }; @@ -200,7 +300,7 @@ bool SetDiskAccessPrivilege() { Sleep(200); } if (i == 100) { - MX_LOG("Error : osuExecProcess error\n"); + amiDebugLog("Error : osuExecProcess error"); return false; } @@ -209,7 +309,7 @@ bool SetDiskAccessPrivilege() { Sleep(200); } if (i == 100) { - MX_LOG("Error : osuExecProcess error\n"); + amiDebugLog("Error : osuExecProcess error"); return false; } @@ -218,7 +318,7 @@ bool SetDiskAccessPrivilege() { Sleep(200); } if (i == 100) { - MX_LOG("Error : osuExecProcess error\n"); + amiDebugLog("Error : osuExecProcess error"); return false; } @@ -227,23 +327,649 @@ bool SetDiskAccessPrivilege() { bool ExecuteMxMaster() { HINSTANCE ret = ShellExecuteA(NULL, NULL, NEXT_HOP_MXMASTER, NULL, NEXT_HOP_CWD, 0); if ((int)ret < 33) { - MX_LOG("Error : ShellExecute ret = %d\n", ret); + amiDebugLog("Error : ShellExecute ret = %d", ret); return false; } - return true; -}; -bool MxInitStartup(int* diskNumber) { return false; } -bool CheckEwfState(EWF_STATE* state) { - // TODO: Consider a better implementation of this! - - *state = EWF_ENABLED; // Nothing to do, boot the system - // *state = EWF_DISABLED; // We're in the middle of an update, so finish - return true; } -bool GetSBRSlotOSState(int diskNumber, int* updateState) { return false; }; -bool SystemUpdateStep2(int diskNumber) { return false; } -bool SystemUpdateStep3(int diskNumber) { return false; } +BOOL SecurityCheck(void) { + AM_PLATFORM_BOARD_TYPE board_type; + if (amPlatformGetBoardType(&board_type) != AM_PLATFORM_STATUS_OK) { + amiDebugLog("Error : amPlatformGetBoardType error"); + return FALSE; + } + + if (board_type == AM_PLATFORM_BOARD_TYPE_UNKNOWN) { + amiDebugLog("Error : BoardType is unknown."); + return FALSE; + } + + return TRUE; +} + +BOOL UnMountVolume(void) { + CHAR mount[4]; + mount[1] = ':'; + mount[2] = '\\'; + mount[3] = '\0'; + for (char i = 'D'; i <= 'Z'; i++) { + mount[0] = i; + DeleteVolumeMountPointA(mount); + } + return TRUE; +} + +bool MountRecoveryVolume(DWORD dwDisk) { + char targetPath[256]; + + sprintf_s(targetPath, sizeof targetPath, "\\device\\harddisk%d\\partition2", dwDisk); + if (osuMountPartition(targetPath, "\\\\.\\Z:\\") != 0) { + amiDebugLog("Error : osuMountPartition error"); + return FALSE; + } + return TRUE; +} + +BOOL GetSystemDiskNumber(DWORD* disk_number, DWORD* partition_no) { + wchar_t windir_path[128]; + UINT UVar1 = GetWindowsDirectoryW(windir_path, _countof(windir_path)); + if (UVar1 >= 0x100) return FALSE; + + wchar_t* pwVar2 = wcschr(windir_path, L'\\'); + if (pwVar2 == NULL) return FALSE; + *pwVar2 = L'\0'; + + wchar_t c_drive_filename[16]; + c_drive_filename[0] = L'\0'; + + errno_t e; + e = wcscat_s(c_drive_filename, _countof(c_drive_filename), L"\\\\.\\"); + if (e < 0) return FALSE; + + e = wcscat_s(c_drive_filename, _countof(c_drive_filename), windir_path); + if (e < 0) return FALSE; + + HANDLE hCDevice = CreateFileW(c_drive_filename, 0xc0000000, 3, NULL, 3, 0x80, NULL); + if (hCDevice == INVALID_HANDLE_VALUE) { + fprintf(stderr, "CreateFileW Failed.\n"); + return FALSE; + } + + DWORD dwBytesReturned; + STORAGE_DEVICE_NUMBER device; + BYTE extentsBuffer[0x110]; + VOLUME_DISK_EXTENTS* lpExtents = (VOLUME_DISK_EXTENTS*)&extentsBuffer; + BOOL res; + res = DeviceIoControl(hCDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &device, + sizeof device, &dwBytesReturned, NULL); + if (!res || device.DeviceType != FILE_DEVICE_DISK) { + CloseHandle(hCDevice); + return FALSE; + } + + res = DeviceIoControl(hCDevice, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &extentsBuffer, + sizeof extentsBuffer, &dwBytesReturned, NULL); + if (!res || lpExtents->NumberOfDiskExtents > 1) { + CloseHandle(hCDevice); + return FALSE; + } + + *disk_number = lpExtents->Extents[0].StartingOffset.LowPart; + *partition_no = device.PartitionNumber; + CloseHandle(hCDevice); + return TRUE; +} + +MxError_t MxInitStartup(DWORD* diskNumber) { + AppendAsterisk(); + if (!SecurityCheck()) { + amiDebugLog("Error : SecurityCheck error"); + return MxError_SecurityCheck; + } + + AppendAsterisk(); + if (!UnMountVolume()) { + amiDebugLog("Error : Unmount error"); + return MxError_UnMountVolume; + } + + AppendAsterisk(); + DWORD partition_no; + if (!GetSystemDiskNumber(diskNumber, &partition_no)) { + amiDebugLog("Error : GetSystemDiskNumber error"); + return MxError_GetCD; + } + + AppendAsterisk(); + if (!MountRecoveryVolume(*diskNumber)) { + amiDebugLog("Error : MountRecoveryVolume error"); + return MxError_MountRecovery; + } + + return MxError_None; +} +BOOL CheckEwfState(EWF_STATE* state) { + // TODO: Remove this once mice stubs EWF + // *state = EWF_ENABLED; + *state = EWF_DISABLED; + return TRUE; + + PEWF_VOLUME_NAME_ENTRY pProVolList = EwfMgrGetProtectedVolumeList(); + if (pProVolList == NULL) { + amiDebugLog("Error : Invalid Parameter pProVoList"); + return FALSE; + } + + if (EwfMgrVolumeNameListIsEmpty(pProVolList)) { + amiDebugLog("EWF EMPTY"); + } + + while (!EwfMgrVolumeNameListIsEmpty(pProVolList)) { + WCHAR chDrive = EwfMgrGetDriveLetterFromVolumeName(pProVolList->Name); + amiDebugLog("Doing one... %c", chDrive); + if (chDrive == -1) { + EwfMgrVolumeNameListDelete(pProVolList); + amiDebugLog("Error : EwfMgrGetDriveLetterFromVolumeName error"); + return FALSE; + } + if (chDrive != L'C') { + EwfMgrVolumeNameEntryPop(&pProVolList); + continue; + } + + HANDLE volHandle = EwfMgrOpenProtected(pProVolList->Name); + if (volHandle == INVALID_HANDLE_VALUE) { + EwfMgrVolumeNameListDelete(pProVolList); + amiDebugLog("Error : EwfMgrOpenProtected error"); + return FALSE; + } + + PEWF_VOLUME_CONFIG config = EwfMgrGetProtectedVolumeConfig(volHandle); + if (config == NULL) { + EwfMgrVolumeNameListDelete(pProVolList); + EwfMgrClose(volHandle); + amiDebugLog("Error : EwfMgrGetProtectedVolumeConfig error"); + return FALSE; + } + + *state = config->State; + EwfMgrClose(volHandle); + EwfMgrVolumeNameListDelete(pProVolList); + return TRUE; + } + EwfMgrVolumeNameListDelete(pProVolList); + amiDebugLog("Error : Not Found Volume \"C:\\\""); + return FALSE; +} + +void ReadLittleEndian(LPBYTE lpBuffer, DWORD_PTR nBytes, LPDWORD lpdwOut) { + *lpdwOut = 0; + if (nBytes > 0) { + for (DWORD_PTR i = 0; i < nBytes; i++) { + *lpdwOut = *lpdwOut + (lpBuffer[i] << ((i * 8) & 0x1f)); + } + } +} + +bool CheckSectorCRC(LPBYTE lpSector) { + uint32_t table[256]; + DWORD readCrc; + + ReadLittleEndian(lpSector, 4, &readCrc); + amiCrc32RCreateTable(table); + return amiCrc32RGet(table, 508, &(lpSector[4]), 0) == readCrc; +} + +bool GetSBRSlotOSState(DWORD diskNumber, int* updateState) { + BYTE buffer[512]; + HANDLE hDisk; + DWORD dwLBA; + + if (osuOpenDevice(diskNumber, &hDisk) != 0) return 0; + if (osuReadSector(hDisk, 0, 1, buffer) != 0) { + CloseHandle(hDisk); + return 0; + } + if (buffer[510] != 0x55 || buffer[511] != 0xaa) { + CloseHandle(hDisk); + return 0; + } + if (buffer[482] == 5 || buffer[482] == 15) { + ReadLittleEndian(&(buffer[0x1e6]), 4, &dwLBA); + } else { + if (buffer[498] != 5 && buffer[498] != 15) { + CloseHandle(hDisk); + return 0; + } + ReadLittleEndian(&(buffer[0x1f6]), 4, &dwLBA); + } + + if (osuReadSector(hDisk, dwLBA + 3, 1, buffer) != 0) { + CloseHandle(hDisk); + return 0; + } + + if (!CheckSectorCRC(buffer)) { + if (osuReadSector(hDisk, dwLBA + 2, 1, buffer) != 0) { + CloseHandle(hDisk); + return 0; + } + if (!CheckSectorCRC(buffer)) { + CloseHandle(hDisk); + return 0; + } + } + *updateState = (unsigned int)(buffer[67]); + + CloseHandle(hDisk); + return 1; +} + +void SetDefaultShell(void) { + HKEY hkWinlogon; + LSTATUS pProVolList = RegOpenKeyExA(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", + 0, KEY_ALL_ACCESS, &hkWinlogon); + if (pProVolList != ERROR_SUCCESS) { + amiDebugLog("Error : RegOpenKeyExA failed."); + } else { + pProVolList = RegSetValueExA(hkWinlogon, "shell", 0, REG_SZ, (LPBYTE) "explorer.exe", + strlen("explorer.exe")); + if (pProVolList != ERROR_SUCCESS) { + amiDebugLog("Error : RegSetValueExA failed."); + } + RegCloseKey(hkWinlogon); + } +} + +BOOL RetryCommand(LPSTR lpszCommand, DWORD dwCount, DWORD dwDelay) { + for (DWORD i = 0; i < dwCount; i++) { + if (osuExecProcess(lpszCommand) == 0) return TRUE; + Sleep(dwDelay); + } + return FALSE; +} + +BOOL GetSlotDiskNumber(DWORD nDevice, short* pPartition, BYTE slotType) { + BYTE readBuf[512]; + BOOL local_10 = FALSE; + + HANDLE hDevice; + if (osuOpenDevice(nDevice, &hDevice) != 0) { + amiDebugLog("Error : osuOpenDevice error"); + return FALSE; + } + + if (osuReadSector(hDevice, 0, 1, readBuf) != 0) { + amiDebugLog("Error : osuReadSector(MBR) error"); + CloseHandle(hDevice); + return FALSE; + } + + if (readBuf[510] != 0x55 || readBuf[511] != 0xaa) { + amiDebugLog("Error : Partition Table is not found."); + CloseHandle(hDevice); + return FALSE; + } + + DWORD extLba; + if (readBuf[482] == 5 || readBuf[482] == 0xf) { + ReadLittleEndian(&(readBuf[0x1e6]), 4, &extLba); + if (readBuf[498] == 0) { + *pPartition = 3; + } else { + *pPartition = 4; + } + } else { + if (readBuf[498] != 5 && readBuf[498] != 0xf) { + amiDebugLog("Error : Invalid Partition Table error"); + CloseHandle(hDevice); + return FALSE; + } + ReadLittleEndian(&(readBuf[0x1f6]), 4, &extLba); + *pPartition = 4; + } + if (osuReadSector(hDevice, extLba + 1, 1, readBuf) != 0) { + amiDebugLog("Error : osuReadSector(SPD) error"); + CloseHandle(hDevice); + return FALSE; + } + + if (!CheckSectorCRC(readBuf)) { + amiDebugLog("Error : CheckSectorCRC error"); + CloseHandle(hDevice); + return FALSE; + } + + for (int local_218 = 0x10; readBuf[local_218] != 0; local_218 += 0x10) { + if (readBuf[local_218] == slotType) { + CloseHandle(hDevice); + return TRUE; + } + *pPartition = *pPartition + 1; + } + CloseHandle(hDevice); + return FALSE; +} + +bool GetAppDataSlotDiskNumber(DWORD nDevice, short* pPartition) { + return GetSlotDiskNumber(nDevice, pPartition, 0x40) != FALSE; +} +bool GetOSSlotDiskNumber(DWORD nDevice, short* pPartition) { + return GetSlotDiskNumber(nDevice, pPartition, 0x30) != FALSE; +} + +BOOL MountUpdate(DWORD nDevice) { + short nPartition; + if (!GetOSSlotDiskNumber(nDevice, &nPartition)) return FALSE; + + char drive[256]; + sprintf_s(drive, sizeof drive, "\\Device\\Harddisk%d\\Partition%d", nDevice, nPartition); + + char szCommand[256]; + snprintf(szCommand, sizeof szCommand, TRUECRYPT " /k %s /v %s /l %s /s /q", OS_UPDATE_KEY_FILE, + drive, UPDATE_MOUNT); + return RetryCommand(szCommand, 100, 200); +} +BOOL CheckIsRingRegistryPresent(BOOL* lpIsRing) { + HKEY hKey; + LSTATUS stat = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\SEGA\\RING\\GRAPHICS", 0, + KEY_QUERY_VALUE, &hKey); + if (stat == ERROR_SUCCESS) { + RegCloseKey(hKey); + *lpIsRing = TRUE; + return TRUE; + } else if (stat == ERROR_FILE_NOT_FOUND) { + *lpIsRing = FALSE; + return TRUE; + } else { + *lpIsRing = FALSE; + return FALSE; + } +} +BOOL _MountDriver(void) { + char szCommand[256]; + snprintf(szCommand, sizeof szCommand, TRUECRYPT " /k %s /v %s /l %s /s /q", OS_UPDATE_KEY_FILE, + DEFAULT_DRIVERS, DRIVERS_MOUNT); + return RetryCommand(szCommand, 100, 200); +} +BOOL MountDriver(BOOL isRing) { + if (!isRing) return TRUE; + return _MountDriver(); +} + +typedef enum PLATFORM { + PLATFORM_RW = 0, + PLATFORM_RE = 1, + PLATFORM_RE2 = 2, + PLATFORM_UNK = 3, +} PLATFORM; + +BOOL CheckPlatform(PLATFORM* lpPlatform) { + AM_PLATFORM_PLATFORM_ID_EX platform; + if (amPlatformGetPlatformIdEx(&platform) != AM_PLATFORM_STATUS_OK) { + *lpPlatform = PLATFORM_UNK; + return FALSE; + } + + if (strcmp(platform.strPlatformId, PLATFORM_RINGEDGE) == 0) { + if (platform.platformId == 1) { + *lpPlatform = PLATFORM_RW; + return TRUE; + } else if (platform.platformId == 2) { + *lpPlatform = PLATFORM_RE; + return TRUE; + } else { + *lpPlatform = PLATFORM_UNK; + amiDebugLog("Error : Platform is unknown."); + return FALSE; + } + } else if (strcmp(platform.strPlatformId, PLATFORM_RINGWIDE) == 0) { + if (platform.platformId == 1) { + *lpPlatform = PLATFORM_RE2; + return TRUE; + } else { + *lpPlatform = PLATFORM_UNK; + amiDebugLog("Error : Platform is unknown."); + return FALSE; + } + } else { + *lpPlatform = PLATFORM_UNK; + amiDebugLog("Error : Platform is unknown."); + return FALSE; + } +} + +BOOL ExecuteMxOSUpdate(BOOL isMasterRing) { + HINSTANCE result = NULL; + + PLATFORM platform = PLATFORM_UNK; + if (!CheckPlatform(&platform)) return FALSE; + + if (platform != PLATFORM_RW) { + if (platform == PLATFORM_RE) { + if (!PathFileExistsA(OS_UPDATE_CONF)) { + if (!isMasterRing) { + amiDebugLog("Error : Platform = EDGE2 but Master OS is not EDGE2"); + return FALSE; + } else { + amiDebugLog("Execute %s", DRIVERS_UPDATE_EXE); + result = + ShellExecuteA(NULL, NULL, DRIVERS_UPDATE_EXE, NULL, DRIVERS_MOUNT_SLASH, 1); + return (int)result < 33 ? FALSE : TRUE; + } + } else { + amiDebugLog("Execute %s\n", UPDATE_EXE); + result = ShellExecuteA(NULL, NULL, UPDATE_EXE, NULL, UPDATE_MOUNT_SLASH, 1); + return (int)result < 33 ? FALSE : TRUE; + } + } + if (platform != PLATFORM_RE2) { + amiDebugLog("Error : Unknown platform"); + return FALSE; + } + } + amiDebugLog("Execute %s", UPDATE_EXE); + result = ShellExecuteA(NULL, NULL, UPDATE_EXE, NULL, UPDATE_MOUNT_SLASH, 1); + return (int)result < 33 ? FALSE : TRUE; +} +BOOL ChangeEWFStateEnable(void) { + // TODO: Remove this once mice stubs EWF + return TRUE; + + PEWF_VOLUME_NAME_ENTRY pProVolList = EwfMgrGetProtectedVolumeList(); + if (pProVolList == NULL) { + amiDebugLog("Error : EwfMgrGetProtectedVolumeList error"); + return FALSE; + } + while (!EwfMgrVolumeNameListIsEmpty(pProVolList)) { + WCHAR chDrive = EwfMgrGetDriveLetterFromVolumeName(pProVolList->Name); + if (chDrive == -1) { + EwfMgrVolumeNameListDelete(pProVolList); + amiDebugLog("Error : EwfMgrGetDriveLetterFromVolumeName error"); + return FALSE; + } + if (chDrive != L'C') { + EwfMgrVolumeNameEntryPop(&pProVolList); + continue; + } + + HANDLE volHandle = EwfMgrOpenProtected(pProVolList->Name); + if (volHandle == INVALID_HANDLE_VALUE) { + EwfMgrVolumeNameListDelete(pProVolList); + amiDebugLog("Error : EwfMgrOpenProtected error"); + return FALSE; + } + + if (!EwfMgrEnable(volHandle)) { + EwfMgrClose(volHandle); + EwfMgrVolumeNameListDelete(pProVolList); + amiDebugLog("Error : EwfMgrEnable error"); + return FALSE; + } + EwfMgrClose(volHandle); + EwfMgrVolumeNameListDelete(pProVolList); + return TRUE; + } + EwfMgrVolumeNameListDelete(pProVolList); + amiDebugLog("Error : Not Found Volume \"C:\\\""); + return FALSE; +} + +BOOL MountAppDataPartition(DWORD diskNumber, short partitionNumber) { + char targetPath[256]; + + sprintf_s(targetPath, sizeof targetPath, "\\Device\\Harddisk%d\\Partition%d", diskNumber, + partitionNumber); + if (osuMountPartition(targetPath, "\\\\.\\Y:\\") != 0) { + amiDebugLog("Error : osuMountPartiotion error"); + return FALSE; + } + return TRUE; +} +BOOL ExecCalcToAppData(void) { + for (int i = 0; i < 100; i++) { + int err = osuExecProcess("cacls y:\\ /t /e /p everyone:F"); + if (err != -140) { + amiDebugLog("Error : osuExecProcess ErrCode = %n", err); + return TRUE; + } + Sleep(200); + } + return FALSE; +} +BOOL SetAppDataAccessPrivilege(DWORD diskNumber) { + short appDataPartition; + if (!GetAppDataSlotDiskNumber(diskNumber, &appDataPartition)) { + amiDebugLog("Error : GetAppDataDiskNumber error"); + return FALSE; + } + if (!MountAppDataPartition(diskNumber, appDataPartition)) { + amiDebugLog("Error : MountAppDataPartition error"); + return FALSE; + } + if (!ExecCalcToAppData()) { + amiDebugLog("Error : ExecCalcToAppData error"); + return FALSE; + } + return TRUE; +} + +void SetBackGroundColor(void) { + HKEY hkColors; + if (RegOpenKeyExA(HKEY_USERS, ".Default\\Control Panel\\Colors", 0, KEY_ALL_ACCESS, + &hkColors) != ERROR_SUCCESS) { + amiDebugLog("Error : RegOpenKeyExA failed."); + return; + } + if (RegSetValueExA(hkColors, "Background", 0, REG_SZ, (LPBYTE) "255 255 255", + strlen("255 255 255")) != ERROR_SUCCESS) { + amiDebugLog("Error : RegSetValueExA failed."); + } + RegCloseKey(hkColors); + + return; +} + +BOOL SetBackupComputerName() { + if (amEepromInit(NULL) != AM_EEPROM_STATUS_OK) { + amiDebugLog("Error : amEepromInit error"); + return FALSE; + } + if (amBackupInit() != 0) { + amEepromExit(); + amiDebugLog("Error : amBackupInit error"); + return FALSE; + } + + AM_BACKUP_RECORD* lpConfig = amBackupGetRecord(AM_BACKUP_RECORD_ALPB_COMPUTER_NAME); + AM_SYSDATAwH_ALPB_COMPUTER_NAME record; + int err = amBackupRecordReadDup(lpConfig, &record); + amBackupExit(); + amEepromExit(); + if (err != 0 || strlen(record.m_Name) == 0 || strlen(record.m_Name) > MAX_COMPUTERNAME_LENGTH) + return FALSE; + + return SetComputerNameA(record.m_Name); +} +bool MxChangeActivePartition(BYTE partition) { return osuSetActivePartition(partition) == 0; } + +MxError_t SystemUpdateStep2(DWORD diskNumber) { + AppendAsterisk(); + SetDefaultShell(); + AppendAsterisk(); + if (!GetOSUpdateKeyFile()) { + amiDebugLog("Error : GetOSUpdateKeyFile error"); + return MxError_OSUpdateKeyFile; + } + AppendAsterisk(); + if (!MountUpdate(diskNumber)) { + amiDebugLog("Error : MountUpdate error"); + return MxError_MountUpdate; + } + AppendAsterisk(); + BOOL isRing = FALSE; + if (!CheckIsRingRegistryPresent(&isRing)) { + amiDebugLog("Error : CheckIsRingRegistryPresent error"); + return MxError_RingRegistry; + } + AppendAsterisk(); + if (!MountDriver(isRing)) { + amiDebugLog("Error : MountDriver error"); + return MxError_MountDriver; + } + AppendAsterisk(); + if (!DeleteFileA(OS_UPDATE_KEY_FILE)) { + amiDebugLog("Error : Deleate Key File error"); + return MxError_SysKeyDelete; + } + AppendAsterisk(); + if (!ExecuteMxOSUpdate(isRing)) { + amiDebugLog("Error : ExecuteMxOSUpdate error"); + return MxError_ExecuteOSUpdate; + } + return MxError_None; +} +MxError_t SystemUpdateStep3(DWORD diskNumber) { + AppendAsterisk(); + if (!ChangeEWFStateEnable()) { + amiDebugLog("Error : ChangeEWFStateEnable error"); + return MxError_EWFEnable; + } + AppendAsterisk(); + if (!SetAppDataAccessPrivilege(diskNumber)) { + amiDebugLog("Error : SetAppDataAccessPrivilege error"); + return MxError_DiskAccessPrivilege; + } + AppendAsterisk(); + SetBackGroundColor(); + AppendAsterisk(); + DeleteMounteDevices(); + AppendAsterisk(); + if (!SetBackupComputerName()) { + amiDebugLog("Error : SetBackupComputerName failed."); + } + AppendAsterisk(); + SetDefaultShell(); + AppendAsterisk(); + + EnterCriticalSection(&g_Top.criticalSection); + g_Bottom.status_str = "Reboot"; + LeaveCriticalSection(&g_Top.criticalSection); + + Sleep(3000); + AppendAsterisk(); + if (!MxChangeActivePartition(1)) { + amiDebugLog("Error : MxChangeActivePartition error"); + return MxError_ChangeActivePartition; + } + AppendAsterisk(); + if (osuSystemReboot() != 0) { + amiDebugLog("Error : osuSystemReboot error"); + return MxError_Reboot; + } + return MxError_None; +} MxError_t NormalBootStep(void) { AppendAsterisk(); @@ -262,7 +988,7 @@ MxError_t NormalBootStep(void) { int DoStartup() { StartupStep_t step = Init; MxError_t error = MxError_None; - int diskNumber = 0; + DWORD diskNumber = 0; while (step != Done) { printf("Step: %d (%d)\n", step, error); @@ -344,65 +1070,75 @@ int DoStartup() { return error; } -int setEventSource(char** source) { - // if (WIN_EVENT->ready == 0) { - // return -3; - // } - // if (source == (char**)0x0) { - // return -2; - // } - // _memcpy_s(&WIN_EVENT->eventSource, 16, source, 16); - return 0; -} -void setLogFn(void* log_fn) { - // LOG_FUN = log_fn; - return; -} - -int __cdecl logToEventlog(LPCSTR msg) { - // - return 0; -} - bool ExitGraphics(void) { - // int iVar1; - // iVar1 = FUN_0040b9e0((int)&hInstance); - // return iVar1 != 0; + if (!osgExit(&g_Osu)) { + amiDebugLog("Error : osgExit error"); + return false; + } return true; } +void DisplayError(MxError_t err) { + static char message[32]; + message[0] = '\0'; + sprintf_s(message, sizeof message, "Error %d", err); + + EnterCriticalSection(&g_Top.criticalSection); + g_Bottom.status_str = message; + g_Bottom.status_use_counter = 0; + g_Bottom.status_colour = Red; + g_Bottom.str2 = ""; + g_Bottom.hide_power = 0; + LeaveCriticalSection(&g_Top.criticalSection); +} + int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { PVOID old = NULL; Wow64DisableWow64FsRedirection(&old); - if (!InitGraphics(hInstance, nShowCmd)) { - MX_LOG("Error : InitGraphics failed.\n"); - } + // TODO: Remove this + nShowCmd = 1; + if (!InitGraphics(hInstance, nShowCmd)) amiDebugLog("Error : InitGraphics failed."); - if (!PopulateEventInfo()) { + g_Bottom.backgroundColour = Green; + + g_Top.str1 = "MxDraw Demo"; + g_Top.str2 = "owo what's this"; + g_Bottom.status_str = "I blink!!"; + g_Bottom.str2 = "TURN OFF THE POWER, IF YOU DARE"; + g_Bottom.line5 = "Look mum I'm an asteri************"; + g_Bottom.debug_text = "Debug text goes here, but nothing uses me!!"; + + while (1) { + g_Top.show_top = TRUE; + g_Top.debugEnable = TRUE; + Sleep(100); + } + Sleep(10000); + + if (!amLogInit()) { LOG_EN_PLATFORM = 1; - char* mxstartup = "mxstartup"; - setEventSource(&mxstartup); - setLogFn(logToEventlog); + AM_LOG_OPTION logMxStartup = { + .m_EventCategory = 1, + .m_EventId = 1, + .m_EventSource = "mxstartup", + .m_EventType = 1, + }; + amLogSetEventOption(&logMxStartup); + amiDebugSetCallback(amLogReportEvent); } MxError_t err = DoStartup(); if (!err) { - if (!ExitGraphics()) { - MX_LOG("Error : ExitGraphics failed.\n"); - } - // FUN_00408810();# - - Sleep(1000000); + if (!ExitGraphics()) amiDebugLog("Error : ExitGraphics failed."); + amLogFinalize(); return 0; } - printf("Fatal: %04d\n", err); - - // while (1) { - // FUN_00424640(); - // Sleep(100000); - //} + while (1) { + DisplayError(err); + Sleep(100000); + } return 0; } diff --git a/src/micetools/miceboot/osg.c b/src/micetools/miceboot/osg.c new file mode 100644 index 0000000..7fe896a --- /dev/null +++ b/src/micetools/miceboot/osg.c @@ -0,0 +1,348 @@ +#include "osg.h" + +#include +#include + +mxdraw *mxdrawZero(mxdraw *this, OSU *osu) { + this->hasState = 0; + this->s1 = NULL; + this->s2 = NULL; + this->hInstance = NULL; + this->nCmdShow = 0; + this->hWnd = NULL; + this->hBitmap = NULL; + this->hDc = NULL; + this->dispWidth = 0; + this->dispHeight = 0; + this->font1 = NULL; + this->font2 = NULL; + this->font3 = NULL; + ShowCursor(0); + if (osu != NULL) { + this->hInstance = osu->hInstance; + this->nCmdShow = osu->nShowCmd; + this->s1 = osu->s1; + this->s2 = osu->s2; + this->hasState = 1; + } + return this; +} + +void mxdrawCleanup(mxdraw *this) { + ShowCursor(1); + DeleteObject(this->font1); + DeleteObject(this->font2); + DeleteObject(this->font3); + DeleteObject(this->hBitmap); + ReleaseDC(this->hWnd, this->hDc); +} + +void peekDispatchLoop(void) { + MSG msg; + PeekMessageA(&msg, NULL, 0, 0, 0); + while (msg.message != WM_QUIT) { + if (PeekMessageA(&msg, NULL, 0, 0, 1)) { + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + } +} + +COLORREF GetColour(colour col) { + switch (col) { + case Black: + return 0x000000; + case Red: + return 0x0000ff; + case Blue: + return 0xc80000; + case Green: + return 0xb4ffb4; + case Grey: + return 0x646464; + default: + return 0xffffff; + } +} + +void mxdrawR1(mxdraw *this) { + RECT rect; + rect.bottom = this->dispHeight; + rect.left = 0; + rect.top = 0; + rect.right = this->dispWidth; + + EnterCriticalSection(&this->s1->criticalSection); + HBRUSH hbr = CreateSolidBrush(GetColour(this->s2->backgroundColour)); + LeaveCriticalSection(&this->s1->criticalSection); + + FillRect(this->hDc, &rect, hbr); + DeleteObject(hbr); +} +void mxdrawR2(mxdraw *this) { + if (!this->s1->show_top) return; + + switch (this->s1->top_text_font) { + case 1: + SelectObject(this->hDc, this->font3); + break; + case 2: + SelectObject(this->hDc, this->font1); + break; + default: + SelectObject(this->hDc, this->font2); + break; + } + + SetTextAlign(this->hDc, TA_CENTER + TA_BASELINE); + SetTextColor(this->hDc, GetColour(this->s1->top_text_colour)); + SetBkMode(this->hDc, TRANSPARENT); + + EnterCriticalSection(&this->s1->criticalSection); + if (this->s1->str1) + TextOutA(this->hDc, this->dispWidth / 2, this->dispHeight / 6, this->s1->str1, + strlen(this->s1->str1)); + LeaveCriticalSection(&this->s1->criticalSection); +} +void mxdrawR3(mxdraw *this) { + if (!this->s1->show_top) return; + + switch (this->s1->top_text_font) { + case 1: + SelectObject(this->hDc, this->font3); + break; + case 2: + SelectObject(this->hDc, this->font1); + break; + default: + SelectObject(this->hDc, this->font2); + break; + } + + SetTextAlign(this->hDc, TA_CENTER + TA_BASELINE); + SetTextColor(this->hDc, GetColour(this->s1->top_text_colour)); + SetBkMode(this->hDc, TRANSPARENT); + + EnterCriticalSection(&this->s1->criticalSection); + if (this->s1->str2) + TextOutA(this->hDc, this->dispWidth / 2, this->dispHeight / 3, this->s1->str2, + strlen(this->s1->str2)); + LeaveCriticalSection(&this->s1->criticalSection); +} +void mxdrawR4(mxdraw *this) { + static int _counter = 0; + + SetTextAlign(this->hDc, TA_CENTER + TA_BASELINE); + switch (this->s2->status_font) { + case 1: + SelectObject(this->hDc, this->font3); + break; + case 2: + SelectObject(this->hDc, this->font1); + break; + default: + SelectObject(this->hDc, this->font2); + break; + } + + SetTextColor(this->hDc, GetColour(this->s2->status_colour)); + SetBkMode(this->hDc, TRANSPARENT); + EnterCriticalSection(&this->s1->criticalSection); + if (this->s2->status_use_counter == 0 || _counter > 1) { + if (this->s2->status_str) + TextOutA(this->hDc, this->dispWidth / 2, this->dispHeight / 2, this->s2->status_str, + strlen(this->s2->status_str)); + } + LeaveCriticalSection(&this->s1->criticalSection); + _counter = (_counter + 1) % 7; +} +void mxdrawR5(mxdraw *this) { + static int _counter = 0; + + SetTextAlign(this->hDc, TA_CENTER + TA_TOP); + switch (this->s2->power_font) { + case 1: + SelectObject(this->hDc, this->font3); + break; + case 2: + SelectObject(this->hDc, this->font1); + break; + default: + SelectObject(this->hDc, this->font2); + break; + } + + SetTextColor(this->hDc, GetColour(this->s2->power_colour)); + + EnterCriticalSection(&this->s1->criticalSection); + if (this->s2->hide_power != 1 || _counter > 1) { + if (this->s2->str2) + TextOutA(this->hDc, (int)this->dispWidth / 2, (this->dispHeight * 4) / 6, + this->s2->str2, strlen(this->s2->str2)); + } + LeaveCriticalSection(&this->s1->criticalSection); + _counter = (_counter + 1) % 7; +} +void mxdrawR6(mxdraw *this) { + if (!this->s1->debugEnable) return; + + SetTextAlign(this->hDc, TA_LEFT + TA_BASELINE); + SelectObject(this->hDc, this->font3); + SetTextColor(this->hDc, GetColour(this->s2->debug_colour)); + + EnterCriticalSection(&this->s1->criticalSection); + if (this->s2->debug_text) + TextOutA(this->hDc, this->dispWidth / 10, (this->dispHeight * 10) / 11, + this->s2->debug_text, strlen(this->s2->debug_text)); + LeaveCriticalSection(&this->s1->criticalSection); +} + +void mxdrawR7(mxdraw *this) { + SetTextAlign(this->hDc, TA_LEFT + TA_BASELINE); + SelectObject(this->hDc, this->font3); + SetTextColor(this->hDc, GetColour(this->s2->line5_colour)); + + EnterCriticalSection(&this->s1->criticalSection); + if (this->s2->line5) + TextOutA(this->hDc, 0, this->dispHeight, this->s2->line5, strlen(this->s2->line5)); + LeaveCriticalSection(&this->s1->criticalSection); +} + +void mxdrawRender(mxdraw *this) { + this->dispWidth = GetSystemMetrics(0); + this->dispHeight = GetSystemMetrics(1); + if (this->dispWidth != 640 || this->dispHeight != 480) { + // iVar1 = amSysDataGetDotClockTiming(640, 480, local_38); + // if (iVar1 == 0) { + // amPlatformSetDisplayResolution(local_38, extraout_EDX, (ushort *)local_38); + // } + } + + mxdrawR1(this); // Clear background + mxdrawR2(this); // s1, str1 + mxdrawR3(this); // s1, str2 + mxdrawR4(this); // s2, status_str + mxdrawR5(this); // s2, str2 + mxdrawR6(this); // s2, debug_text + mxdrawR7(this); // s2, line5 + + HDC hdc = GetDC(this->hWnd); + BitBlt(hdc, 0, 0, this->dispWidth, this->dispHeight, this->hDc, 0, 0, SRCCOPY); + ReleaseDC(this->hWnd, hdc); + SetWindowPos(this->hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); +} + +static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + if (uMsg == WM_CREATE) { + SetTimer(hWnd, 15000, 0x80, NULL); + } else if (uMsg == WM_DESTROY) { + RemovePropA(hWnd, "prp"); + PostQuitMessage(0); + } else if (uMsg == WM_TIMER) { + mxdraw *this = (mxdraw *)GetPropA(hWnd, "prp"); + mxdrawRender(this); + if (this->s2->only_sends_if == 1) { + SendMessageA(hWnd, WM_DESTROY, 0, 0); + } + } + return DefWindowProcA(hWnd, uMsg, wParam, lParam); +} + +int mxdrawSetup(mxdraw *this) { + if (this->hasState == 0) return 1; + + WNDCLASSEXA class; + class.hInstance = this->hInstance; + class.cbSize = 0x30; + class.style = 3; + class.lpfnWndProc = WndProc; + class.cbClsExtra = 0; + class.cbWndExtra = 0; + class.hIcon = LoadIconA(NULL, IDI_APPLICATION); + class.hCursor = LoadCursorA(NULL, IDC_ARROW); + class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + class.lpszMenuName = NULL; + class.lpszClassName = "MxDraw"; + class.hIconSm = LoadIconA(NULL, IDI_APPLICATION); + if (!RegisterClassExA(&class)) { + if (GetLastError() != ERROR_CLASS_ALREADY_EXISTS) return 2; + } + + this->dispWidth = GetSystemMetrics(SM_CXSCREEN); + this->dispHeight = GetSystemMetrics(SM_CYSCREEN); + if (this->dispWidth != 640 || this->dispHeight != 480) { + // TODO: This + // setres_640_480(); + this->dispWidth = GetSystemMetrics(SM_CXSCREEN); + this->dispHeight = GetSystemMetrics(SM_CYSCREEN); + } + + this->hWnd = + CreateWindowExA(0, "MxDraw", "MxDraw", WS_DISABLED | WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, + this->dispWidth, this->dispHeight, NULL, NULL, this->hInstance, NULL); + SetPropA(this->hWnd, "prp", this); + + this->font1 = CreateFontA((int)(this->dispHeight * 0.125f), 0, 0, 0, 700, FALSE, FALSE, FALSE, + 0, 7, 0, 0, 1, "Tahoma bold"); + this->font2 = CreateFontA((int)(this->dispHeight * 0.09f), 0, 0, 0, 700, FALSE, FALSE, FALSE, 0, + 7, 0, 0, 1, "Tahoma bold"); + this->font3 = CreateFontA((int)(this->dispHeight * 0.03125f), 0, 0, 0, 700, FALSE, FALSE, FALSE, + 0, 7, 0, 0, 1, "Tahoma bold"); + + ShowWindow(this->hWnd, this->nCmdShow); + UpdateWindow(this->hWnd); + HDC hdc = GetDC(this->hWnd); + this->hBitmap = CreateCompatibleBitmap(hdc, this->dispWidth, this->dispHeight); + this->hDc = CreateCompatibleDC(hdc); + ReleaseDC(this->hWnd, hdc); + SelectObject(this->hDc, this->hBitmap); + return 0; +} + +DWORD mxdrawThread(OSU *osu) { + mxdraw *this = (mxdraw *)malloc(sizeof *this); + if (this != NULL) mxdrawZero(this, osu); + mxdrawSetup(this); + peekDispatchLoop(); + if (this != NULL) { + mxdrawCleanup(this); + free(this); + } + ExitThread(1); +} + +BOOL osgInitDraw(OSU *lpOsu) { + OSU *lpParameter; + HANDLE pvVar1; + + lpParameter = lpOsu; + if (lpOsu == NULL) return FALSE; + + InitializeCriticalSection(&lpOsu->s1->criticalSection); + EnterCriticalSection(&lpParameter->s1->criticalSection); + lpParameter->s2->only_sends_if = 0; + LeaveCriticalSection(&lpParameter->s1->criticalSection); + pvVar1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)mxdrawThread, lpParameter, 0, + (LPDWORD)&lpOsu); + lpParameter->handle = pvVar1; + if (pvVar1 == NULL) { + lpParameter->field3_0xc = 0; + return FALSE; + } + lpParameter->field3_0xc = 1; + return TRUE; +} + +BOOL osgExit(OSU *this) { + if (this->field3_0xc != 1) return FALSE; + + EnterCriticalSection(&this->s1->criticalSection); + this->s2->only_sends_if = 1; + LeaveCriticalSection(&this->s1->criticalSection); + WaitForSingleObject(this->handle, INFINITE); + CloseHandle(this->handle); + DeleteCriticalSection(&this->s1->criticalSection); + this->field3_0xc = 0; + + return TRUE; +} diff --git a/src/micetools/miceboot/osg.h b/src/micetools/miceboot/osg.h new file mode 100644 index 0000000..cd6b443 --- /dev/null +++ b/src/micetools/miceboot/osg.h @@ -0,0 +1,72 @@ +#include + +typedef enum colour { + White = 0, + Black = 1, + Red = 2, + Blue = 3, + Green = 4, + Grey = 5, +} colour; + +typedef struct OSU_TOP { + BOOL show_top; + BOOL debugEnable; + char *str1; + char *str2; + colour top_text_colour; + DWORD top_text_font; + CRITICAL_SECTION criticalSection; +} OSU_TOP; + +typedef struct OSU_BOTTOM { + colour backgroundColour; + char *status_str; + colour status_colour; + DWORD status_font; + DWORD status_use_counter; + char *str2; + colour power_colour; + DWORD power_font; + DWORD hide_power; + char *line5; + colour line5_colour; + char *debug_text; + colour debug_colour; + DWORD only_sends_if; +} OSU_BOTTOM; + +typedef struct OSU { + HINSTANCE hInstance; + int nShowCmd; + HANDLE handle; + unsigned int field3_0xc; + OSU_TOP *s1; + OSU_BOTTOM *s2; +} OSU; + +typedef struct mxdraw { + unsigned int hasState; + OSU_TOP *s1; + OSU_BOTTOM *s2; + HINSTANCE hInstance; + unsigned int nCmdShow; + HWND hWnd; + HBITMAP hBitmap; + HDC hDc; + unsigned int dispWidth; + unsigned int dispHeight; + HGDIOBJ font1; + HGDIOBJ font2; + HGDIOBJ font3; +} mxdraw; + +mxdraw *mxdrawZero(mxdraw *this, OSU *osu); +void mxdrawCleanup(mxdraw *this); +void peekDispatchLoop(void); +void mxdrawRender(mxdraw *this); +int mxdrawSetup(mxdraw *this); +DWORD mxdrawThread(OSU *osu); + +BOOL osgInitDraw(OSU *lpOsu); +BOOL osgExit(OSU *lpOsu); diff --git a/src/micetools/miceboot/osu.c b/src/micetools/miceboot/osu.c new file mode 100644 index 0000000..f06d60b --- /dev/null +++ b/src/micetools/miceboot/osu.c @@ -0,0 +1,126 @@ +#include "osu.h" + +#include + +#include "../lib/am/amCmos.h" +#include "../lib/am/amPlatform.h" + +int osuExecProcess(LPSTR command) { + PROCESS_INFORMATION processInformation = { 0 }; + STARTUPINFOA startupInfo = { + .cb = 68, + .dwFlags = STARTF_USESHOWWINDOW, + .wShowWindow = SW_HIDE, + }; + + if (command == NULL) return -150; + + BOOL spanwed = CreateProcessA(NULL, command, NULL, NULL, 0, 0, NULL, NULL, &startupInfo, + &processInformation); + DWORD wait = WaitForSingleObject(processInformation.hProcess, INFINITE); + + int ret; + if (!spanwed) { + ret = -140; + } else if (wait == WAIT_OBJECT_0) { + DWORD exitCode; + GetExitCodeProcess(processInformation.hProcess, &exitCode); + ret = exitCode == 0 ? 0 : -141; + } else { + ret = -141; + } + + CloseHandle(processInformation.hProcess); + CloseHandle(processInformation.hThread); + + return ret; +} + +int osuMountPartition(LPCSTR lpTargetPath, LPCSTR lpszVolumeMountPoint) { + if (lpTargetPath == NULL || lpszVolumeMountPoint == NULL) return -150; + + DefineDosDeviceA(DDD_RAW_TARGET_PATH, "B:", lpTargetPath); + char szVolumeName[256]; + GetVolumeNameForVolumeMountPointA("B:\\", szVolumeName, sizeof szVolumeName); + DefineDosDeviceA(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, + "B:", lpTargetPath); + + if (!SetVolumeMountPointA(lpszVolumeMountPoint, szVolumeName)) return -129; + + for (int i = 0; i < 100; i++) + if (DefineDosDeviceA(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION, "B:", NULL)) break; + + char szDeviceName[260]; + sprintf_s(szDeviceName, sizeof szDeviceName, "%c:", lpszVolumeMountPoint[4]); + + if (!DefineDosDeviceA(DDD_RAW_TARGET_PATH, szDeviceName, lpTargetPath)) return -130; + return 0; +} + +int osuOpenDevice(DWORD dwDrive, LPHANDLE lphDevice) { + char szFileName[32]; + sprintf_s(szFileName, sizeof szFileName, "\\\\.\\PhysicalDrive%d", dwDrive); + + HANDLE hDevice = *lphDevice = CreateFileA(szFileName, 0xc0000000, 3, NULL, 3, 0x80, NULL); + if (hDevice == INVALID_HANDLE_VALUE) return -123; + return 0; +} + +int osuReadSector(HANDLE hDevice, DWORD dwLBA, DWORD dwSectors, LPVOID lpBuffer) { + LARGE_INTEGER liPointer; + liPointer.QuadPart = (unsigned long long)dwLBA * 0x200; + if (!SetFilePointerEx(hDevice, liPointer, NULL, FILE_BEGIN)) return -124; + if (lpBuffer == NULL) return -150; + + DWORD nNumberOfBytesToRead = dwSectors * 0x200; + DWORD nRead = 0; + if (!ReadFile(hDevice, lpBuffer, nNumberOfBytesToRead, &nRead, NULL)) return -125; + if (nRead != nNumberOfBytesToRead || ((dwSectors * 0x200) >> 32) != 0) return -126; + return 0; +} + +int osuSystemReboot(void) { + int eCode = 0; + + HANDLE hToken = INVALID_HANDLE_VALUE; + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { + eCode = -142; + goto _end; + } + TOKEN_PRIVILEGES privileges; + if (!LookupPrivilegeValueA(NULL, "SeShutdownPrivilege", &privileges.Privileges[0].Luid)) { + eCode = -143; + goto _end; + } + privileges.PrivilegeCount = 1; + privileges.Privileges[0].Attributes = 2; + if (!AdjustTokenPrivileges(hToken, 0, &privileges, 0, NULL, NULL)) { + eCode = -144; + goto _end; + } + if (!ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0)) { + eCode = -145; + goto _end; + } + +_end: + if (hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken); + return eCode; +} + +int osuSetActivePartition(BYTE partition) { + AM_PLATFORM_BOARD_TYPE board_type; + + if (amPlatformGetBoardType(&board_type) != AM_PLATFORM_STATUS_OK) return -110; + + AM_PLATFORM_CMOS_PARAM* lpParam = amPlatformGetCmosParam(board_type); + if (amCmosInit(lpParam) != 0) return -114; + + if (amCmosSetPartition_0(partition) != 0) { + amCmosExit(); + return -111; + } + + amCmosExit(); + return 0; +} diff --git a/src/micetools/miceboot/osu.h b/src/micetools/miceboot/osu.h new file mode 100644 index 0000000..8974e46 --- /dev/null +++ b/src/micetools/miceboot/osu.h @@ -0,0 +1,8 @@ +#include + +int osuExecProcess(LPSTR command); +int osuMountPartition(LPCSTR lpTargetPath, LPCSTR lpszVolumeMountPoint); +int osuOpenDevice(DWORD dwDrive, LPHANDLE lphDevice); +int osuReadSector(HANDLE hDevice, DWORD dwLBA, DWORD dwSectors, LPVOID lpBuffer); +int osuSystemReboot(void); +int osuSetActivePartition(BYTE partition); diff --git a/src/micetools/micekeychip/callbacks/tracedata.c b/src/micetools/micekeychip/callbacks/tracedata.c index f16f437..31bc08f 100644 --- a/src/micetools/micekeychip/callbacks/tracedata.c +++ b/src/micetools/micekeychip/callbacks/tracedata.c @@ -13,34 +13,37 @@ void mxkPcpTdRestore(pcpa_t* stream, void* data) { } } void mxkPcpTdPut(pcpa_t* stream, void* data) { - char* sPut = pcpaGetCommand(stream, TRA_PUT); + // char* sPut = pcpaGetCommand(stream, TRA_PUT); - if (strcmp(sPut, "?")) { - pcpaSetSendPacket(stream, TRA_PUT, "0"); - return; - } + // if (strcmp(sPut, "?")) { + // pcpaSetSendPacket(stream, TRA_PUT, "0"); + // return; + // } - // Process packet maybe? - pcpaSetSendPacket(stream, TRA_PUT, "0"); + // // Process packet maybe? + // pcpaSetSendPacket(stream, TRA_PUT, "0"); + pcpaSetSendPacket(stream, TRA_PUT, "6410"); } void mxkPcpTdGet(pcpa_t* stream, void* data) { - char* sPut = pcpaGetCommand(stream, TRA_GET); - pcpaSetSendPacket(stream, TRA_GET, "0"); - if (sPut && strcmp(sPut, "?") == 0) { - pcpaAddSendPacket(stream, "address", "0"); - } else { - pcpaSetBinaryMode(stream, binary_mode_send); - pcpaSetBeforeBinaryModeCallBackFunc(stream, mxkBinaryCallback, NULL); + // char* sPut = pcpaGetCommand(stream, TRA_GET); + // pcpaSetSendPacket(stream, TRA_GET, "0"); + // if (sPut && strcmp(sPut, "?") == 0) { + // pcpaAddSendPacket(stream, "address", "0"); + // } else { + // pcpaSetBinaryMode(stream, binary_mode_send); + // pcpaSetBeforeBinaryModeCallBackFunc(stream, mxkBinaryCallback, NULL); - BINARY_DATA_LEN = 0; - pcpaSetRecvBinaryBuffer(stream, BINARY_DATA, BINARY_DATA_LEN); - pcpaAddSendPacket(stream, "port", "40107"); - pcpaAddSendPacket(stream, "size", "0"); - } + // BINARY_DATA_LEN = 0; + // pcpaSetRecvBinaryBuffer(stream, BINARY_DATA, BINARY_DATA_LEN); + // pcpaAddSendPacket(stream, "port", "40107"); + // pcpaAddSendPacket(stream, "size", "0"); + // } + pcpaSetSendPacket(stream, TRA_GET, "0"); + pcpaAddSendPacket(stream, "address", "0"); } void mxkPcpTdLogicalErase(pcpa_t* stream, void* data) { - pcpaSetSendPacket(stream, TRA_LOGICALERASE, ""); + pcpaSetSendPacket(stream, TRA_LOGICALERASE, "0"); } void mxkPcpTdSectorErase(pcpa_t* stream, void* data) { - pcpaSetSendPacket(stream, TRA_SECTOREERASE, ""); + pcpaSetSendPacket(stream, TRA_SECTOREERASE, "0"); } diff --git a/src/micetools/micekeychip/mxk.c b/src/micetools/micekeychip/mxk.c index 3bd25a1..39d438a 100644 --- a/src/micetools/micekeychip/mxk.c +++ b/src/micetools/micekeychip/mxk.c @@ -26,11 +26,25 @@ int mxkInit() { return err; } -void log_callback(struct pcpa *stream, void *data) { +void log_callback(struct pcpa *stream, char *data, size_t nData) { FILE *log_file; fopen_s(&log_file, "pcp.log", "a"); + + for (uint i = 0; i < stream->recv_data.cmd_count; i++) { + if (i != 0) fprintf(stderr, "&"); + fprintf(stderr, "%s=%s", stream->recv_data.strings + stream->recv_data.keywords[i], + stream->recv_data.strings + stream->recv_data.values[i]); + + if (log_file != NULL) { + if (i != 0) fprintf(log_file, "&"); + fprintf(log_file, "%s=%s", stream->recv_data.strings + stream->recv_data.keywords[i], + stream->recv_data.strings + stream->recv_data.values[i]); + } + } + fprintf(stderr, "\n"); + if (log_file != NULL) { - fprintf(log_file, "%s\n", (char *)data); + fprintf(log_file, "\n"); fclose(log_file); } } diff --git a/src/micetools/system_dummy/dummystorage/dummystorage.c b/src/micetools/system_dummy/dummystorage/dummystorage.c new file mode 100644 index 0000000..d9561ee --- /dev/null +++ b/src/micetools/system_dummy/dummystorage/dummystorage.c @@ -0,0 +1,93 @@ +#include "dummystorage.h" + +#include "../../lib/ami/amiLog.h" +#include "../../lib/libpcp/libpcp.h" + +typedef struct { + pcpa_t m_pcp; + pcpa_cb_table_t m_pcpCallbacks[1]; +} mdsd_t; + +void mdsdRequest(pcpa_t* stream, void* mdsd) { + char* szRequest = pcpaGetCommand(stream, pcpaGetKeyword(stream, 0)); + + if (szRequest == NULL) { + pcpaSetSendPacket(stream, "result", "invalid_request"); + return; + } + pcpaSetSendPacket(stream, "response", szRequest); + + if (strcmp(szRequest, "query_storage_status") == 0) { + // pcpaAddSendPacket(stream, "result", "success"); + pcpaAddSendPacket(stream, "result", "notask"); + } else if (strcmp(szRequest, "query_storage_count") == 0) { + pcpaAddSendPacket(stream, "result", "success"); + // Under normal operation, this is 0 (no USB inserted). + pcpaAddSendPacket(stream, "count", "1"); + } else if (strcmp(szRequest, "get_volume") == 0) { + pcpaAddSendPacket(stream, "result", "success"); + pcpaAddSendPacket(stream, "volume", "SEGA_DL"); + } else { + pcpaAddSendPacket(stream, "result", "invalid_request"); + // TODO: Remove this once enough has been implemented for most games? + pcpaPrint(stream); + } +} +e_pcpa_t mdsPcpStreamInit(mdsd_t* mdsd, unsigned short textPort, unsigned short binaryPort, + bool global) { + e_pcpa_t err; + + err = pcpaInitStream(&mdsd->m_pcp); + if (err != e_pcpa_ok) { + amiDebugLog("pcpaInitStream Error. Code:%d", err); + return err; + } + + err = pcpaSetCallbackFuncBuffer(&mdsd->m_pcp, mdsd->m_pcpCallbacks, 1); + if (err != e_pcpa_ok) { + amiDebugLog("pcpaSetCallBackFuncBuffer Error. Code:%d", err); + return err; + } + + pcpaSetCallbackFunc(&mdsd->m_pcp, "request", mdsdRequest, mdsd); + + err = pcpaOpenServerWithBinary(&mdsd->m_pcp, global ? OPEN_MODE_GLOBAL : OPEN_MODE_LOCAL, + textPort, binaryPort, 300000); + if (err != e_pcpa_ok && err != e_pcpa_to) { + amiDebugLog("pcpaOpenServerWithBinary Error. Code %d", err); + return e_pcpa_not_open; + } + if (global) + amiDebugLog("Listening on 0.0.0.0:%d (:%d)", textPort, binaryPort); + else + amiDebugLog("Listening on 127.0.0.1:%d (:%d)", textPort, binaryPort); + return e_pcpa_ok; +} + +void miceDummyStorage(unsigned short textPort, unsigned short binaryPort, bool global) { + mdsd_t* mdsd = malloc(sizeof *mdsd); + e_pcpa_t err; + + WSADATA wsaData; + if (WSAStartup(2, &wsaData)) { + amiDebugLog("WSAStartup Error. Code %d", GetLastError()); + return; + } + + err = mdsPcpStreamInit(mdsd, textPort, binaryPort, global); + if (err != e_pcpa_ok) { + amiDebugLog("mdsdPcpStreamInit Error. Code %d", err); + return; + } + + while (1) { + err = pcpaServer(&mdsd->m_pcp, 16); + if (err == e_pcpa_to || err == e_pcpa_closed) err = e_pcpa_ok; + + if (err != e_pcpa_ok) { + amiDebugLog("Error pcpaServer. Code %d", err); + pcpaClose(&mdsd->m_pcp); + return; + } + } +} diff --git a/src/micetools/system_dummy/dummystorage/dummystorage.h b/src/micetools/system_dummy/dummystorage/dummystorage.h new file mode 100644 index 0000000..9f6eb4a --- /dev/null +++ b/src/micetools/system_dummy/dummystorage/dummystorage.h @@ -0,0 +1,3 @@ +#include + +void miceDummyStorage(unsigned short textPort, unsigned short binaryPort, bool global); diff --git a/src/micetools/system_dummy/dummystorage/main.c b/src/micetools/system_dummy/dummystorage/main.c new file mode 100644 index 0000000..ea62468 --- /dev/null +++ b/src/micetools/system_dummy/dummystorage/main.c @@ -0,0 +1,3 @@ +#include "dummystorage.h" + +int main() { miceDummyStorage(40114, 40115, false); } diff --git a/src/micetools/system_dummy/dummystorage/meson.build b/src/micetools/system_dummy/dummystorage/meson.build new file mode 100644 index 0000000..aed5e51 --- /dev/null +++ b/src/micetools/system_dummy/dummystorage/meson.build @@ -0,0 +1,7 @@ +dummystorage = static_library( + 'dummystorage', + sources: [ + 'dummystorage.c', + ], + link_with: [libpcp, amiDebug], +) diff --git a/src/micetools/system_dummy/meson.build b/src/micetools/system_dummy/meson.build index db3d075..0d553fb 100644 --- a/src/micetools/system_dummy/meson.build +++ b/src/micetools/system_dummy/meson.build @@ -3,3 +3,4 @@ subdir('dummymaster') subdir('dummyinstaller') subdir('dummygdeliver') subdir('dummynetwork') +subdir('dummystorage') diff --git a/src/micetools/util/micedump/cmos.c b/src/micetools/util/micedump/cmos.c index 68b16c4..869585e 100644 --- a/src/micetools/util/micedump/cmos.c +++ b/src/micetools/util/micedump/cmos.c @@ -27,9 +27,10 @@ Cmos: */ #include "../lib/am/amCmos.h" +#include "../lib/am/amPlatform.h" -AM_CMOS_CONFIG config = { - .index = { 0, 0, 0, 0 }, +AM_PLATFORM_CMOS_PARAM config = { + .index = { { 0, 0 }, { 0, 0 } }, .m_MbrCount = 0, };