diff --git a/lib/hal/xbox.c b/lib/hal/xbox.c index 37bb967c3..d8d8de090 100644 --- a/lib/hal/xbox.c +++ b/lib/hal/xbox.c @@ -9,51 +9,78 @@ #define KernelMode 0 +#define LaunchDataPageSize 0x1000 + void XReboot() { - HalReturnToFirmware(HalRebootRoutine); + HalReturnToFirmware(HalRebootRoutine); +} + +int XGetLaunchInfo(unsigned long *launchDataType, const unsigned char **launchData) +{ + *launchDataType = LDT_NONE; + *launchData = NULL; + + if (LaunchDataPage == NULL) { + LaunchDataPage = MmAllocateContiguousMemory(LaunchDataPageSize); + if (LaunchDataPage == NULL) { + return -1; + } + memset(LaunchDataPage, 0, LaunchDataPageSize); + LaunchDataPage->Header.dwLaunchDataType = LDT_FROM_DASHBOARD; + } + + *launchDataType = LaunchDataPage->Header.dwLaunchDataType; + *launchData = LaunchDataPage->LaunchData; + return 0; +} + +void XLaunchXBE(const char *xbePath) +{ + XLaunchXBEEx(xbePath, NULL); } -/** - * Launches an XBE. Examples of xbePath might be: - * c:\\blah.xbe - * c:/foo/bar.xbe - * If the XBE is able to be launched, this method will - * not return. If there is a problem, then it return. - */ -void XLaunchXBE(char *xbePath) +void XLaunchXBEEx(const char *xbePath, const void *launchData) { -#if 0 - struct stat statbuf; - if (stat(xbePath, &statbuf) < 0) - return; -#endif - - if (LaunchDataPage == NULL) - LaunchDataPage = MmAllocateContiguousMemory(0x1000); - - if (LaunchDataPage == NULL) - return; - - MmPersistContiguousMemory(LaunchDataPage, 0x1000, TRUE); - - memset((void*)LaunchDataPage, 0, 0x1000); - - LaunchDataPage->Header.dwLaunchDataType = 0xFFFFFFFF; - LaunchDataPage->Header.dwTitleId = 0; - XConvertDOSFilenameToXBOX(xbePath, LaunchDataPage->Header.szLaunchPath); - - // one last thing... xbePath now looks like: - // \Device\Harddisk0\Partition2\blah\doom.xbe - // but it has to look like: - // \Device\Harddisk0\Partition2\blah;doom.xbe - char *lastSlash = strrchr(LaunchDataPage->Header.szLaunchPath, '\\'); - if (lastSlash != NULL) - { - *lastSlash = ';'; - HalReturnToFirmware(HalQuickRebootRoutine); - } - - // if we couldn't find a trailing slash, the conversion to - // the xbox path mustn't have worked, so we will return + if (LaunchDataPage == NULL) { + LaunchDataPage = MmAllocateContiguousMemory(LaunchDataPageSize); + if (LaunchDataPage == NULL) { + return; + } + } + + // For ease of debugging. + PLAUNCH_DATA_PAGE launchDataPage = LaunchDataPage; + + MmPersistContiguousMemory(launchDataPage, LaunchDataPageSize, TRUE); + memset((void*)launchDataPage, 0, LaunchDataPageSize); + + launchDataPage->Header.dwLaunchDataType = LDT_TITLE; + launchDataPage->Header.dwTitleId = CURRENT_XBE_HEADER->CertificateHeader->TitleID; + launchDataPage->Header.dwFlags = 0x0000; + + if (!xbePath) { + launchDataPage->Header.dwLaunchDataType = LDT_LAUNCH_DASHBOARD; + } else { + XConvertDOSFilenameToXBOX(xbePath, launchDataPage->Header.szLaunchPath); + + // one last thing... xbePath now looks like: + // \Device\Harddisk0\Partition2\blah\doom.xbe + // but it has to look like: + // \Device\Harddisk0\Partition2\blah;doom.xbe + char *lastSlash = strrchr(launchDataPage->Header.szLaunchPath, '\\'); + if (!lastSlash) { + // if we couldn't find a trailing slash, the conversion to + // the xbox path mustn't have worked, so we will return + return; + } + + *lastSlash = ';'; + } + + if (launchData) { + memcpy(launchDataPage->LaunchData, launchData, sizeof(launchDataPage->LaunchData)); + } + + HalReturnToFirmware(HalQuickRebootRoutine); } diff --git a/lib/hal/xbox.h b/lib/hal/xbox.h index bd8f62f60..bf2233b9f 100644 --- a/lib/hal/xbox.h +++ b/lib/hal/xbox.h @@ -9,7 +9,35 @@ extern "C" void XReboot(void); -void XLaunchXBE(char *xbePath); +/** + * Retrieves information persisted by the process that launched the current XBE. + * + * launchDataType will (likely) be one of the LDT_* defines in xboxkrnl.h + * + * Returns non-zero in the case of failure. + */ +int XGetLaunchInfo(unsigned long *launchDataType, const unsigned char **launchData); + +/** + * Launches an XBE. Examples of xbePath might be: + * c:\\blah.xbe + * c:/foo/bar.xbe + * If the XBE is able to be launched, this method will + * not return. If there is a problem, then it return. + */ +void XLaunchXBE(const char *xbePath); + +/** + * Launches an XBE and sets the LAUNCH_DATA_PAGE's LaunchData, which is + * retrievable by the newly launched process. + * + * Examples of xbePath might be: + * c:\\blah.xbe + * c:/foo/bar.xbe + * If the XBE is able to be launched, this method will + * not return. If there is a problem, then it return. + */ +void XLaunchXBEEx(const char *xbePath, const void *launchData); #ifdef __cplusplus } diff --git a/lib/xboxkrnl/xboxkrnl.h b/lib/xboxkrnl/xboxkrnl.h index 285456421..bdb51fbdb 100644 --- a/lib/xboxkrnl/xboxkrnl.h +++ b/lib/xboxkrnl/xboxkrnl.h @@ -691,7 +691,9 @@ typedef struct _LAUNCH_DATA_PAGE UCHAR LaunchData[3072]; } LAUNCH_DATA_PAGE, *PLAUNCH_DATA_PAGE; -#define LDT_LAUNCH_DASHBOARD 1 +#define LDT_TITLE 0 +#define LDT_LAUNCH_DASHBOARD 1 +#define LDT_FROM_DASHBOARD 2 #define LDT_NONE 0xFFFFFFFF typedef struct _DISPATCHER_HEADER