#include "stdafx.h" #include "LoaderPlugin.h" // This is the implementation of the class that has been exported. // See LoaderPlugin.h for the class definition. // The total number of kernels we will enumerate and support. #define PLUGIN_MAX_KERNELS 1 // SMBus slave addresses for EEPROM IO #define EEPROM_SMBUS_WRITE 0xA8 #define EEPROM_SMBUS_READ 0xA9 #define EEPROM_RW_BLOCK 2 #define EEPROM_TOTAL_MEMORY_SIZE 256 #define NT_SUCCESS(Status) (Status>= 0) // // The constructor method. LoaderPlugin::LoaderPlugin() { m_bDisabled = FALSE; m_pEepromCache = NULL; m_pEepromShadow = NULL; } HRESULT LoaderPlugin::OnInitialize(IComplexKernelHost* pHost, PluginDllArgs* pDllArgs) { strcpy(m_szDllName,pDllArgs->szFile); CHAR* pStop = strrchr( m_szDllName, '.'); *pStop = 0x00; sprintf(m_szStateFile, "%s%s.state", pDllArgs->szPath, m_szDllName); m_pHostOs = (IComplexHostOs*) pHost->QueryInterface("IComplexHostOs"); m_pHostConsole = (IComplexHostConsole*) pHost->QueryInterface("IComplexHostConsole"); m_pHostIo = (IComplexHostIo*) pHost->QueryInterface("IComplexHostIo"); DWORD dwFile = m_pHostIo->Open(m_szStateFile,"rb"); if (dwFile>0) { CHAR szStateBuffer[64]; szStateBuffer[64-1] = 0x00; m_pHostIo->Read(dwFile, (LPBYTE)szStateBuffer, 64-1); m_pHostIo->Close(dwFile); if (strstr(szStateBuffer,"SEARCH")!=NULL) { m_pHostConsole->SetColour(0xFFFF0000); m_pHostConsole->WriteLine("*NOTICE* COMPLEX region plugin is not compatible with your kernel, it has been disabled!"); Sleep(3000); m_bDisabled = TRUE; return E_FAIL; } m_pEepromShadow = (LPBYTE) strtoul(szStateBuffer,NULL,16); m_pHostConsole->WriteLine("COMPLEX region plugin installed."); return S_OK; } m_bIsRetail = !m_pHostOs->IsDebugBuild(); DWORD dwKernelBuild = m_pHostOs->GetKernelBuild(); if ( m_bIsRetail || (dwKernelBuild !=4627) ) { m_pHostConsole->SetColour(0xFFFF0000); m_pHostConsole->WriteLine("*WARNING* COMPLEX region plugin was not tested on your XBOX kernel!"); m_pHostConsole->WriteLine("If your system should freeze as a result of this plugin, it will be disabled!"); m_pHostConsole->SetColour(0xFFFFFFFF); Sleep(5000); } m_pEepromCache = new BYTE[EEPROM_TOTAL_MEMORY_SIZE]; if (FAILED( ReadEepromIntoCache(m_pEepromCache) )) { m_pHostConsole->SetColour(0xFFFF0000); m_pHostConsole->WriteLine("*WARNING* Unable to cache EEPROM!"); Sleep(3000); m_bDisabled = TRUE; return E_FAIL; } m_pHostConsole->WriteLine("COMPLEX region plugin ready."); return S_OK; } HRESULT LoaderPlugin::OnNotify(PluginEvent aEvent, LPVOID pNotificationArgs) { switch (aEvent) { case EVENT_LAUNCH: { PluginLaunchArgs* pArgs = (PluginLaunchArgs*) pNotificationArgs; OnLaunchEvent(pArgs); } } return S_OK; } HRESULT LoaderPlugin::OnLaunchEvent(PluginLaunchArgs* pLaunchArgs) { if (m_bDisabled) { return E_FAIL; } if (m_pEepromShadow==NULL) { DWORD dwFile = m_pHostIo->Open(m_szStateFile,"wb"); if (dwFile>0) { m_pHostIo->Write(dwFile, (LPBYTE)"SEARCH", 6); m_pHostIo->Close(dwFile); } m_pEepromShadow = SearchEeprom(m_pEepromCache, (LPBYTE) 0x80050000 ); if (dwFile>0) { m_pHostIo->Delete(m_szStateFile); dwFile = m_pHostIo->Open(m_szStateFile,"wb"); CHAR szAddress[64]; sprintf(szAddress,"%x",m_pEepromShadow); m_pHostIo->Write(dwFile, (LPBYTE)szAddress, strlen(szAddress)+1 ); m_pHostIo->Close(dwFile); } } PatchEepromShadow( m_pEepromShadow, pLaunchArgs->dwRegion ); return E_FAIL; } LPBYTE LoaderPlugin::SearchEeprom(LPBYTE pEeprom, LPBYTE pKernel) { _asm { ; ; Disable write protect ; mov eax, cr0 and eax, 0FFFEFFFFh mov cr0, eax } BOOL bFound; do { pKernel++; bFound = TRUE; for (int i=0; iReadSMBus(EEPROM_SMBUS_READ, (UCHAR)dwOffset, TRUE, dwValue) )) { return E_FAIL; } *p++ = (WORD) dwValue; } return S_OK; } HRESULT LoaderPlugin::PatchEepromShadow(LPBYTE pEepromShadow, DWORD dwRegion) { LPDWORD pdwMode = (LPDWORD) &pEepromShadow[88]; DWORD dwSystemRegion = ConvertModeToRegion(*pdwMode); if ((dwRegion & dwSystemRegion) == 0) { m_pHostConsole->SetColour(0xFF00FF00); m_pHostConsole->WriteLine("Changed video mode."); *pdwMode = ConvertRegionToMode(dwRegion); } return S_OK; }