#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, CheckEwf = 1, EwfDisabled = 2, GetSBR = 3, NormalBoot = 4, SystemUpdate2 = 5, SystemUpdate3 = 6, Done = 7, } StartupStep_t; #define VERSION_BUFFER 256 #define VERSION_FILE "C:\\System\\SystemVersion.txt" #define DEFAULT_VERSION_FILE "C:\\System\\DefaultSystemVersion.txt" #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" #define CACLS_REMPERM_EXECUTE "cacls c:\\system\\execute /t /e /p AppUser:N" #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 #define TC_PASSWORD_1 "3d550a335d2557055d2b3d1444153348" #define TC_PASSWORD_2 "36105d2e0b3c1b5f1336365f335a3f1c" #define TC_PASSWORD "segahardpassword" // These two sum to SYSTEM_KEYFILE_ADS #define SYSTEM_KEYFILE_1 "041443255b204a3f054d1b4c352a22292f211b29440e1237591f2e49375d093967614d" #define SYSTEM_KEYFILE_2 "3f26192e1e532a26680f2a2c3039534b363b2923082c41421a5537241408700d020b18" #define SYSTEM_KEYFILE_ADS "C:\\System\\Execute\\DLL:SystemKeyFile" // These two sum to OS_UPDATE_ADS #define OS_UPDATE_KEYFILE_1 "4019582c56283006300b40042110143d603b3d3b1d012b5c0d5423152235163f624a43" #define OS_UPDATE_KEYFILE_2 "03210427234b445f3d51057444536137052107112f392a14570d515029306307072222" #define OS_UPDATE_KEYFILE_ADS "C:\\System\\Execute\\DLL:UpdateKeyFile" int LOG_EN_PLATFORM = 0; void log(char* function, unsigned int line_number, char* fmt, ...) { va_list args; va_start(args, fmt); printf("%s: Line%d ", function, line_number); vprintf(fmt, args); va_end(args); } BOOL isDebugEnabled(void) { WIN32_FIND_DATAA find; HANDLE hFind; hFind = FindFirstFileA(".\\DebugEnable", &find); if (hFind != INVALID_HANDLE_VALUE) { FindClose(hFind); return TRUE; } FindClose(hFind); return FALSE; } 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; 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 */ bool GetVersionText(char* version, char* path) { char buffer[VERSION_BUFFER]; FILE* file; memset(buffer, 0, sizeof buffer); if (fopen_s(&file, path, "r") || file == NULL) { amiDebugLog("Error : GetVersionText error path = %s", path); return false; } fgets(buffer, sizeof buffer, file); fclose(file); strncpy_s(version, VERSION_BUFFER, buffer, VERSION_BUFFER); return true; } /* Get the currently running version of the system */ bool GetCurrentVersion(char* version) { return GetVersionText(version, VERSION_FILE); } /* Get the default version of the system */ bool GetDefaultVersion(char* version) { return GetVersionText(version, DEFAULT_VERSION_FILE); } /* 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); int ret = osuExecProcess(command); if (ret == 0) return true; amiDebugLog("Error : osuExecProcess error. ret = %d", ret); return false; } /* 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; Sleep(200); } return false; } /* Copies the file at src to dst */ 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 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 nRead; if (!ReadFile(hSrc, readBuffer, 255, &nRead, NULL)) { CloseHandle(hSrc); CloseHandle(hDst); amiDebugLog("Error : ReadFile error"); return false; } readBuffer[nRead] = '\0'; DWORD written; 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); }; bool SetDiskAccessPrivilege() { int i; for (i = 0; i < 100; i++) { if (osuExecProcess(CACLS_REMPERM_EXECUTE) != -140) break; Sleep(200); } if (i == 100) { amiDebugLog("Error : osuExecProcess error"); return false; } for (i = 0; i < 100; i++) { if (osuExecProcess(CACLS_REMPERM_Z) != -140) break; Sleep(200); } if (i == 100) { amiDebugLog("Error : osuExecProcess error"); return false; } for (i = 0; i < 100; i++) { if (osuExecProcess(CACLS_REMPERM_S) != -140) break; Sleep(200); } if (i == 100) { amiDebugLog("Error : osuExecProcess error"); return false; } return true; }; bool ExecuteMxMaster() { HINSTANCE ret = ShellExecuteA(NULL, NULL, NEXT_HOP_MXMASTER, NULL, NEXT_HOP_CWD, 0); if ((int)ret < 33) { amiDebugLog("Error : ShellExecute ret = %d", ret); return false; } return true; } 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(); if (!GetSystemKeyFile()) return MxError_NoKeyFile; AppendAsterisk(); if (!TryMountSystemVolume()) return MxError_SystemMount; AppendAsterisk(); if (!DeleteFileA(SYSTEM_KEY_FILE)) return MxError_SysKeyDelete; AppendAsterisk(); if (!SetDiskAccessPrivilege()) return MxError_DiskAccessPrivilege; AppendAsterisk(); if (!ExecuteMxMaster()) return MxError_MxMaster; return MxError_None; } int DoStartup() { StartupStep_t step = Init; MxError_t error = MxError_None; DWORD diskNumber = 0; while (step != Done) { printf("Step: %d (%d)\n", step, error); switch (step) { case Init: if (!MxInitStartup(&diskNumber)) step = CheckEwf; else step = Done; break; case CheckEwf: { AppendAsterisk(); EWF_STATE state; if (!CheckEwfState(&state)) { error = MxError_Ewf; step = Done; break; } if (state == EWF_ENABLED) step = NormalBoot; else step = EwfDisabled; break; } case EwfDisabled: { char versionString[VERSION_BUFFER]; char defaultVersionString[VERSION_BUFFER]; if (!GetCurrentVersion(versionString) || !GetDefaultVersion(defaultVersionString)) { error = MxError_Version; step = Done; break; } if (strcmp(versionString, defaultVersionString) == 0) step = GetSBR; else step = SystemUpdate3; break; } case GetSBR: { int updateState; AppendAsterisk(); if (!GetSBRSlotOSState(diskNumber, &updateState)) { error = MxError_SBR; step = Done; break; } if (updateState == 2) step = SystemUpdate2; else step = SystemUpdate3; break; } case NormalBoot: error = NormalBootStep(); step = Done; break; case SystemUpdate2: setStrForStep2(); error = SystemUpdateStep2(diskNumber); step = Done; break; case SystemUpdate3: setStrForStep3(); error = SystemUpdateStep3(diskNumber); step = Done; break; default: error = MxError_Unknown; step = Done; break; } } return error; } bool ExitGraphics(void) { 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); // TODO: Remove this nShowCmd = 1; if (!InitGraphics(hInstance, nShowCmd)) amiDebugLog("Error : InitGraphics failed."); 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; 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()) amiDebugLog("Error : ExitGraphics failed."); amLogFinalize(); return 0; } while (1) { DisplayError(err); Sleep(100000); } return 0; } int main() { return WinMain(NULL, NULL, NULL, 0); }