diff --git a/frontend/drivers/platform_xdk.c b/frontend/drivers/platform_xdk.c index 461b84c523..82e68124f0 100644 --- a/frontend/drivers/platform_xdk.c +++ b/frontend/drivers/platform_xdk.c @@ -46,1031 +46,10 @@ #endif #include "../../verbosity.h" -#ifdef _XBOX360 - -#define AURORA_LAUNCHDATA_APPID 'AUOA' -#define AURORA_LAUNCHDATA_EXECUTABLE_FUNCID 'ROMS' -#define AURORA_LAUNCHDATA_EXECUTABLE_VERSION 1 - -typedef struct _AURORA_LAUNCHDATA_EXECUTABLE -{ - DWORD ApplicationId; // AURORA_LAUNCHDATA_APPID - DWORD FunctionId; // AURORA_LAUNCHDATA_EXECUTABLE_FUNCID - DWORD FunctionVersion; // AURORA_LAUNCHDATA_EXECUTABLE_VERSION - CHAR SystemPath[0x40]; // /System/Harddisk0/Parition0 - CHAR RelativePath[0x104]; // /SomeCore/Content/ - CHAR Exectutable[0x28]; // SomeContent.zip - CHAR Reserved[0x100]; // Reserved for future use -} AURORA_LAUNCHDATA_EXECUTABLE, *PAURORA_LAUNCH_DATA_EXECUTABLE; - -#endif - -#ifdef _XBOX1 - -#include - -// Don't do __declspec(dllimport) for things like emulators -#if defined(NTSYSAPI) && defined(DONT_IMPORT_INTERNAL) -#undef NTSYSAPI -#endif -#ifdef DONT_IMPORT_INTERNAL -#define NTSYSAPI -#endif - -// The normal headers don't have this...? -#define FASTCALL __fastcall - -// The usual NTSTATUS -typedef LONG NTSTATUS; - -// The usual NT_SUCCESS -#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) - -// Just for documentation -#define EXPORTNUM(x) - - -// Needed for object structures and related things -typedef CONST SHORT CSHORT; - - -// String types -typedef CHAR *PSZ; -typedef CONST CHAR *PCSZ; - -// ANSI_STRING -// Differences from NT: None. -typedef struct _STRING { - USHORT Length; - USHORT MaximumLength; - PCHAR Buffer; -} STRING; -typedef STRING *PSTRING; - -typedef STRING ANSI_STRING; -typedef PSTRING PANSI_STRING; - - -// IO Status Block type (UNVERIFIED) -// Differences from NT: None. -typedef struct _IO_STATUS_BLOCK { - union { - NTSTATUS Status; - PVOID Pointer; - }; - - ULONG_PTR Information; -} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; - -// APC routine -typedef -VOID -(NTAPI *PIO_APC_ROUTINE) ( - IN PVOID ApcContext, - IN PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG Reserved - ); - - -// Header for dispatcher objects -// Differences from NT: None. -typedef struct _DISPATCHER_HEADER { - UCHAR Type; - UCHAR Absolute; - UCHAR Size; - UCHAR Inserted; - LONG SignalState; - LIST_ENTRY WaitListHead; -} DISPATCHER_HEADER; - - -// Object types -#define NotificationTimerObject 8 -#define SynchronizationTimerObject 9 -#define DpcObject 19 - - -// Object Attributes type -// Differences from NT: There are no Length, SecurityDescriptor, or -// SecurityQualityOfService fields. Also, ObjectName is ANSI, not -// Unicode. -typedef struct _OBJECT_ATTRIBUTES { - HANDLE RootDirectory; - PANSI_STRING ObjectName; - ULONG Attributes; -} OBJECT_ATTRIBUTES; -typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; - -// Flags for OBJECT_ATTRIBUTES::Attributes -#define OBJ_INHERIT 0x00000002L -#define OBJ_PERMANENT 0x00000010L -#define OBJ_EXCLUSIVE 0x00000020L -#define OBJ_CASE_INSENSITIVE 0x00000040L -#define OBJ_OPENIF 0x00000080L -#define OBJ_OPENLINK 0x00000100L -#define OBJ_KERNEL_HANDLE 0x00000200L -#define OBJ_VALID_ATTRIBUTES 0x000003F2L - -// CreateDisposition values for NtCreateFile() -#define FILE_SUPERSEDE 0x00000000 -#define FILE_OPEN 0x00000001 -#define FILE_CREATE 0x00000002 -#define FILE_OPEN_IF 0x00000003 -#define FILE_OVERWRITE 0x00000004 -#define FILE_OVERWRITE_IF 0x00000005 -#define FILE_MAXIMUM_DISPOSITION 0x00000005 - -// CreateOption values for NtCreateFile() -// FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT is what CreateFile -// uses for most things when translating to NtCreateFile. -#define FILE_DIRECTORY_FILE 0x00000001 -#define FILE_WRITE_THROUGH 0x00000002 -#define FILE_SEQUENTIAL_ONLY 0x00000004 -#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 -#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 -#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 -#define FILE_NON_DIRECTORY_FILE 0x00000040 -#define FILE_CREATE_TREE_CONNECTION 0x00000080 -#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 -#define FILE_NO_EA_KNOWLEDGE 0x00000200 -#define FILE_OPEN_FOR_RECOVERY 0x00000400 -#define FILE_RANDOM_ACCESS 0x00000800 -#define FILE_DELETE_ON_CLOSE 0x00001000 -#define FILE_OPEN_BY_FILE_ID 0x00002000 -#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 -#define FILE_NO_COMPRESSION 0x00008000 -#define FILE_RESERVE_OPFILTER 0x00100000 -#define FILE_OPEN_REPARSE_POINT 0x00200000 -#define FILE_OPEN_NO_RECALL 0x00400000 -#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 -#define FILE_COPY_STRUCTURED_STORAGE 0x00000041 -#define FILE_STRUCTURED_STORAGE 0x00000441 -#define FILE_VALID_OPTION_FLAGS 0x00ffffff -#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032 -#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032 -#define FILE_VALID_SET_FLAGS 0x00000036 - - -// NtQueryVolumeInformation / NtSetVolumeInformation stuff -// Type of information to retrieve; FileFsSizeInformation and -// FileFsDeviceInformation are the only ones confirmed to work. -typedef enum _FSINFOCLASS { - FileFsVolumeInformation = 1, - FileFsLabelInformation, - FileFsSizeInformation, - FileFsDeviceInformation, - FileFsAttributeInformation, - FileFsControlInformation, - FileFsFullSizeInformation, - FileFsObjectInformation -} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; - -// Structure of FileFsSizeInformation -typedef struct _FILE_FS_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER AvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; - -#define DEVICE_TYPE ULONG - -// Structure of FileFsDeviceInformation -typedef struct _FILE_FS_DEVICE_INFORMATION { - DEVICE_TYPE DeviceType; - ULONG Characteristics; -} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; - -// DEVICE_TYPEs (I took a guess as to which the XBOX might have.) -#define FILE_DEVICE_CD_ROM 0x00000002 -#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 -#define FILE_DEVICE_CONTROLLER 0x00000004 -#define FILE_DEVICE_DISK 0x00000007 -#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 -#define FILE_DEVICE_FILE_SYSTEM 0x00000009 -#define FILE_DEVICE_NULL 0x00000015 -#define FILE_DEVICE_SCREEN 0x0000001c -#define FILE_DEVICE_SOUND 0x0000001d -#define FILE_DEVICE_UNKNOWN 0x00000022 -#define FILE_DEVICE_VIDEO 0x00000023 -#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 -#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 - -// Characteristics -#define FILE_REMOVABLE_MEDIA 0x00000001 -#define FILE_READ_ONLY_DEVICE 0x00000002 -#define FILE_FLOPPY_DISKETTE 0x00000004 -#define FILE_WRITE_ONCE_MEDIA 0x00000008 -#define FILE_REMOTE_DEVICE 0x00000010 -#define FILE_DEVICE_IS_MOUNTED 0x00000020 -#define FILE_VIRTUAL_VOLUME 0x00000040 -#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 -#define FILE_DEVICE_SECURE_OPEN 0x00000100 - -/* Physical address - * Differences from NT: 32 bit address instead of 64. */ -typedef ULONG PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; - -/* NtCreateFile/NtOpenFile stuff */ -#define FILE_SUPERSEDED 0x00000000 -#define FILE_OPENED 0x00000001 -#define FILE_CREATED 0x00000002 -#define FILE_OVERWRITTEN 0x00000003 -#define FILE_EXISTS 0x00000004 -#define FILE_DOES_NOT_EXIST 0x00000005 - -// NtReadFile/NtWriteFile stuff -#define FILE_WRITE_TO_END_OF_FILE 0xffffffff -#define FILE_USE_FILE_POINTER_POSITION 0xfffffffe - -// Device types -#define FILE_DEVICE_CD_ROM 0x00000002 -#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 -#define FILE_DEVICE_CONTROLLER 0x00000004 -#define FILE_DEVICE_SCSI FILE_DEVICE_CONTROLLER -#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER -#define FILE_DEVICE_DISK 0x00000007 -#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 -#define FILE_DEVICE_DVD 0x00000033 - -// Access types -#define FILE_ANY_ACCESS 0 -#define FILE_READ_ACCESS 0x0001 /* file & pipe */ -#define FILE_WRITE_ACCESS 0x0002 /* file & pipe */ - -// Method types -#define METHOD_BUFFERED 0 -#define METHOD_IN_DIRECT 1 -#define METHOD_OUT_DIRECT 2 -#define METHOD_NEITHER 3 - -// The all-important CTL_CODE -#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ - ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ -) - -// IDE/SCSI codes -// IOCTL_SCSI_PASS_THROUGH_DIRECT is the only one known to be used. -// Differences from NT: None. -#define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) -#define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) -#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) -#define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_RESCAN_BUS CTL_CODE(IOCTL_SCSI_BASE, 0x0407, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_GET_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0408, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_SCSI_FREE_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0409, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_IDE_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x040a, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) - -// Special XBOX code? -#define IOCTL_CDROM_AUTHENTICATE_DISK CTL_CODE(FILE_DEVICE_CD_ROM, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS) - -/* Structure for IOCTL_SCSI_PASS_THROUGH_DIRECT - * Differences from NT: None, believe it or not. */ -typedef struct _SCSI_PASS_THROUGH_DIRECT { - /*000*/ USHORT Length; - /*002*/ UCHAR ScsiStatus; - /*003*/ UCHAR PathId; - /*004*/ UCHAR TargetId; - /*005*/ UCHAR Lun; - /*006*/ UCHAR CdbLength; - /*007*/ UCHAR SenseInfoLength; - /*008*/ UCHAR DataIn; - /*00C*/ ULONG DataTransferLength; - /*010*/ ULONG TimeOutValue; - /*014*/ PVOID DataBuffer; - /*018*/ ULONG SenseInfoOffset; - /*01C*/ UCHAR Cdb[16]; -}SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; - -/* DataIn fields for IOCTL_SCSI_PASS_THROUGH_DIRECT */ -#define SCSI_IOCTL_DATA_OUT 0 -#define SCSI_IOCTL_DATA_IN 1 -#define SCSI_IOCTL_DATA_UNSPECIFIED 2 - -/* Kernel object type (unsure about the structure...) */ -typedef struct _OBJECT_TYPE -{ - // Same prototype as ExAllocatePoolWithTag, because that's the usual one - PVOID - (NTAPI *AllocationFunction)( - SIZE_T NumberOfBytes, - ULONG Tag - ); - - // Same prototype as ExFreePool, because that's the usual one - VOID - (NTAPI *FreeFunction)( - IN PVOID P - ); - - // The prototypes of these are unknown - void *CloseFunction; - void *DeleteFunction; - void *ParseFunction; - - // Unknown DWORD... Size of this object type maybe? - void *DefaultObjectMaybe; - - // 4 letter tag for this object type - CHAR Tag[4]; -} OBJECT_TYPE; -typedef OBJECT_TYPE *POBJECT_TYPE; - -// Object types -extern POBJECT_TYPE IoFileObjectType; -extern POBJECT_TYPE ExEventObjectType; -extern POBJECT_TYPE ExSemaphoreObjectType; -extern POBJECT_TYPE IoCompletionObjectType; -extern POBJECT_TYPE IoDeviceObjectType; - - -// *_OBJECT and related structures (mostly opaque since I'm lazy) -typedef struct _DRIVER_OBJECT { - CSHORT Type; - CSHORT Size; - struct _DEVICE_OBJECT *DeviceObject; - // ... -} DRIVER_OBJECT; -typedef DRIVER_OBJECT *PDRIVER_OBJECT; - -typedef struct _DEVICE_OBJECT { - CSHORT Type; - USHORT Size; - LONG ReferenceCount; - PDRIVER_OBJECT DriverObject; - // ... -} DEVICE_OBJECT; -typedef DEVICE_OBJECT *PDEVICE_OBJECT; - -typedef struct _FILE_OBJECT { - CSHORT Type; - CSHORT Size; - PDEVICE_OBJECT DeviceObject; - // ... -} FILE_OBJECT; -typedef FILE_OBJECT *PFILE_OBJECT; - - -/* Thread information structures */ - -/* IRQL */ -typedef UCHAR KIRQL, *PKIRQL; -#define PASSIVE_LEVEL 0 // Passive release level -#define LOW_LEVEL 0 // Lowest interrupt level -#define APC_LEVEL 1 // APC interrupt level -#define DISPATCH_LEVEL 2 // Dispatcher level - -// Thread entry point -// NOTE: This is not a standard call! You can't call this function from C code! -// You push registers like stdcall, but ebp + 4 must point to the first argument before the call! -// -// Differences from NT: 2 parameters instead of 1; strange calling convention -typedef -VOID -(NTAPI *PKSTART_ROUTINE) ( - IN PVOID StartContext1, - IN PVOID StartContext2 - ); - -// Structure of a critical section -// Same as the XBOX's RTL_CRITICAL_SECTION, but with the more explicit header -typedef struct _KCRITICAL_SECTION -{ - // 000 Dispatcher header - DISPATCHER_HEADER Header; - // 010 Lock count of the critical section - LONG LockCount; - // 014 Recursion count of the critical section - LONG RecursionCount; - // 018 Thread ID of the thread that currently owns this critical section - ULONG OwningThread; -} KCRITICAL_SECTION, *PKCRITICAL_SECTION; - -// Structure of a thread object -typedef struct _KTHREAD -{ - // 000 Dispatcher header - DISPATCHER_HEADER Header; - // 010 Unknown - BYTE unknown[0x18]; - // 028 Pointer to TLS data - PVOID TlsData; - // ??? just padding - real size is unknown - BYTE unknown2[0x100]; -} KTHREAD, *PKTHREAD; - -// Structure of the data at FS -typedef struct _FS_STRUCTURE -{ - // 000 Current exception handler information - PVOID *ExceptionFrame; - // 004 Pointer to current TLS data top - PVOID TlsDataTop; - // 008 - BYTE unknown2[0x1C]; - // 024 Current IRQL of the OS - KIRQL CurrentIrql; - // 028 Thread structure of the current thread - PKTHREAD ThreadObject; - // ??? just padding - real size is unknown - BYTE unknown3[0x100]; -} FS_STRUCTURE, *PFS_STRUCTURE; - -// DPC routine -typedef -VOID -(*PKDEFERRED_ROUTINE) ( - IN struct _KDPC *Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2 - ); - -// DPC information -// It's not known which of these fields are used on XBOX. -typedef struct _KDPC { - CSHORT Type; - UCHAR Number; - UCHAR Importance; - LIST_ENTRY DpcListEntry; - PKDEFERRED_ROUTINE DeferredRoutine; - PVOID DeferredContext; - PVOID SystemArgument1; - PVOID SystemArgument2; - PULONG_PTR Lock; -} KDPC, *PKDPC; - - -// Timers -typedef enum _TIMER_TYPE { - NotificationTimer, - SynchronizationTimer - } TIMER_TYPE; - -typedef struct _KTIMER { - DISPATCHER_HEADER Header; - ULARGE_INTEGER DueTime; - LIST_ENTRY TimerListEntry; - struct _KDPC *Dpc; - LONG Period; -} KTIMER, *PKTIMER; - -/* XBE stuff - * Not used in any exported kernel calls, but still useful. - */ - -/* XBE header information */ -typedef struct _XBE_HEADER -{ - // 000 "XBEH" - CHAR Magic[4]; - // 004 RSA digital signature of the entire header area - UCHAR HeaderSignature[256]; - // 104 Base address of XBE image (must be 0x00010000?) - PVOID BaseAddress; - // 108 Size of all headers combined - other headers must be within this - ULONG HeaderSize; - // 10C Size of entire image - ULONG ImageSize; - // 110 Size of this header (always 0x178?) - ULONG XbeHeaderSize; - // 114 Image timestamp - unknown format - ULONG Timestamp; - // 118 Pointer to certificate data (must be within HeaderSize) - struct _XBE_CERTIFICATE *Certificate; - // 11C Number of sections - DWORD NumSections; - // 120 Pointer to section headers (must be within HeaderSize) - struct _XBE_SECTION *Sections; - // 124 Initialization flags - ULONG InitFlags; - // 128 Entry point (XOR'd; see xboxhacker.net) - PVOID EntryPoint; - // 12C Pointer to TLS directory - struct _XBE_TLS_DIRECTORY *TlsDirectory; - // 130 Stack commit size - ULONG StackCommit; - // 134 Heap reserve size - ULONG HeapReserve; - // 138 Heap commit size - ULONG HeapCommit; - // 13C PE base address (?) - PVOID PeBaseAddress; - // 140 PE image size (?) - ULONG PeImageSize; - // 144 PE checksum (?) - ULONG PeChecksum; - // 148 PE timestamp (?) - ULONG PeTimestamp; - // 14C PC path and filename to EXE file from which XBE is derived - PCSZ PcExePath; - // 150 PC filename (last part of PcExePath) from which XBE is derived - PCSZ PcExeFilename; - // 154 PC filename (Unicode version of PcExeFilename) - PWSTR PcExeFilenameUnicode; - // 158 Pointer to kernel thunk table (XOR'd; EFB1F152 debug) - ULONG_PTR *KernelThunkTable; - // 15C Non-kernel import table (debug only) - PVOID DebugImportTable; - // 160 Number of library headers - ULONG NumLibraries; - // 164 Pointer to library headers - struct _XBE_LIBRARY *Libraries; - // 168 Pointer to kernel library header - struct _XBE_LIBRARY *KernelLibrary; - // 16C Pointer to XAPI library - struct _XBE_LIBRARY *XapiLibrary; - // 170 Pointer to logo bitmap (NULL = use default of Microsoft) - PVOID LogoBitmap; - // 174 Size of logo bitmap - ULONG LogoBitmapSize; - // 178 -} XBE_HEADER, *PXBE_HEADER; - -// Certificate structure -typedef struct _XBE_CERTIFICATE { - // 000 Size of certificate - ULONG Size; - // 004 Certificate timestamp (unknown format) - ULONG Timestamp; - // 008 Title ID - ULONG TitleId; - // 00C Name of the game (Unicode) - WCHAR TitleName[40]; - // 05C Alternate title ID's (0-terminated) - ULONG AlternateTitleIds[16]; - // 09C Allowed media types - 1 bit match between XBE and media = boots - ULONG MediaTypes; - // 0A0 Allowed game regions - 1 bit match between this and XBOX = boots - ULONG GameRegion; - // 0A4 Allowed game ratings - 1 bit match between this and XBOX = boots - ULONG GameRating; - // 0A8 Disk number (?) - ULONG DiskNumber; - // 0AC Version (?) - ULONG Version; - // 0B0 LAN key for this game - UCHAR LanKey[16]; - // 0C0 Signature key for this game - UCHAR SignatureKey[16]; - // 0D0 Signature keys for the alternate title ID's - UCHAR AlternateSignatureKeys[16][16]; - // 1D0 -} XBE_CERTIFICATE, *PXBE_CERTIFICATE; - -// Section headers -typedef struct _XBE_SECTION { - // 000 Flags - ULONG Flags; - // 004 Virtual address (where this section loads in RAM) - PVOID VirtualAddress; - // 008 Virtual size (size of section in RAM; after FileSize it's 00'd) - ULONG VirtualSize; - // 00C File address (where in the file from which this section comes) - ULONG FileAddress; - // 010 File size (size of the section in the XBE file) - ULONG FileSize; - // 014 Pointer to section name - PCSZ SectionName; - // 018 Section reference count - when >= 1, section is loaded - LONG SectionReferenceCount; - // 01C Pointer to head shared page reference count - WORD *HeadReferenceCount; - // 020 Pointer to tail shared page reference count - WORD *TailReferenceCount; - // 024 SHA hash. Hash DWORD containing FileSize, then hash section. - DWORD ShaHash[5]; - // 038 -} XBE_SECTION, *PXBE_SECTION; - -/* TLS directory information needed later - * Library version data needed later */ - -/* Initialization flags */ -#define XBE_INIT_MOUNT_UTILITY 0x00000001 -#define XBE_INIT_FORMAT_UTILITY 0x00000002 -#define XBE_INIT_64M_RAM_ONLY 0x00000004 -#define XBE_INIT_DONT_SETUP_HDD 0x00000008 - -/* Region codes */ -#define XBE_REGION_US_CANADA 0x00000001 -#define XBE_REGION_JAPAN 0x00000002 -#define XBE_REGION_ELSEWHERE 0x00000004 -#define XBE_REGION_DEBUG 0x80000000 - -/* Media types */ -#define XBE_MEDIA_HDD 0x00000001 -#define XBE_MEDIA_XBOX_DVD 0x00000002 -#define XBE_MEDIA_ANY_CD_OR_DVD 0x00000004 -#define XBE_MEDIA_CD 0x00000008 -#define XBE_MEDIA_1LAYER_DVDROM 0x00000010 -#define XBE_MEDIA_2LAYER_DVDROM 0x00000020 -#define XBE_MEDIA_1LAYER_DVDR 0x00000040 -#define XBE_MEDIA_2LAYER_DVDR 0x00000080 -#define XBE_MEDIA_USB 0x00000100 -#define XBE_MEDIA_ALLOW_UNLOCKED_HDD 0x40000000 - -/* Section flags */ -#define XBE_SEC_WRITABLE 0x00000001 -#define XBE_SEC_PRELOAD 0x00000002 -#define XBE_SEC_EXECUTABLE 0x00000004 -#define XBE_SEC_INSERTED_FILE 0x00000008 -#define XBE_SEC_RO_HEAD_PAGE 0x00000010 -#define XBE_SEC_RO_TAIL_PAGE 0x00000020 - -/* x86 page size */ -#define PAGE_SIZE 0x1000 - -/* Native NT API calls on the XBOX */ - -/* PAGE_ALIGN: - * Returns an address rounded down to the nearest page boundary. - * - * Differences from NT: None. - */ -#define PAGE_ALIGN(Va) ((PVOID)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1))) - -// NtReadFile: -// Reads a file. -// -// Differences from NT: There is no Key parameter. -NTSYSAPI -EXPORTNUM(219) -NTSTATUS -NTAPI -NtReadFile( - IN HANDLE FileHandle, - IN HANDLE Event OPTIONAL, - IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - IN PVOID ApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PVOID Buffer, - IN ULONG Length, - IN PLARGE_INTEGER ByteOffset - ); - -// NtWriteFile: -// Writes a file. -// -// Differences from NT: There is no Key parameter. -NTSYSAPI -EXPORTNUM(236) -NTSTATUS -NTAPI -NtWriteFile( - IN HANDLE FileHandle, - IN HANDLE Event OPTIONAL, - IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - IN PVOID ApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PVOID Buffer, - IN ULONG Length, - IN PLARGE_INTEGER ByteOffset - ); - -// NtQueryVolumeInformation: -// Queries information about a file system. This is not documented by -// Microsoft even under NT. -// -// Differences from NT: None known. -NTSYSAPI -EXPORTNUM(218) -NTSTATUS -NTAPI -NtQueryVolumeInformationFile( - IN HANDLE FileHandle, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PVOID VolumeInformation, - IN ULONG VolumeInformationLength, - IN FS_INFORMATION_CLASS VolumeInformationClass - ); - -// NtClose: -// Closes a file or other handle. -// -// Differences from NT: None. -NTSYSAPI -EXPORTNUM(187) -NTSTATUS -NTAPI -NtClose( - IN HANDLE Handle - ); - -// NtAllocateVirtualMemory: -// Allocates virtual memory. -// -// Differences from NT: There is no ProcessHandle parameter. -NTSYSAPI -EXPORTNUM(184) -NTSTATUS -NTAPI -NtAllocateVirtualMemory( - IN OUT PVOID *BaseAddress, - IN ULONG ZeroBits, - IN OUT PULONG AllocationSize, - IN ULONG AllocationType, - IN ULONG Protect - ); - -// NtFreeVirtualMemory: -// Frees virtual memory. -// -// Differences from NT: There is no ProcessHandle parameter. -NTSYSAPI -EXPORTNUM(199) -NTSTATUS -NTAPI -NtFreeVirtualMemory( - IN OUT PVOID *BaseAddress, - IN OUT PULONG FreeSize, - IN ULONG FreeType - ); - - -// Kernel-level routines - -// MmMapIoSpace: -// Maps a physical address area into the virtual address space. -// DO NOT USE MEMORY MAPPED WITH THIS AS A BUFFER TO OTHER CALLS. For -// example, don't WriteFile or NtWriteFile these buffers. Copy them first. -// -// Differences from NT: PhysicalAddress is 32 bit, not 64. ProtectionType -// specifies the page protections, but it's a Win32 PAGE_ macro instead -// of the normal NT enumeration. PAGE_READWRITE is probably what you -// want... -NTSYSAPI -EXPORTNUM(177) -PVOID -NTAPI -MmMapIoSpace( - IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG NumberOfBytes, - IN ULONG ProtectionType - ); - -// MmGetPhysicalAddress: -// Translates a virtual address into a physical address. -// -// Differences from NT: PhysicalAddress is 32 bit, not 64. -NTSYSAPI -EXPORTNUM(173) -PHYSICAL_ADDRESS -NTAPI -MmGetPhysicalAddress( - IN PVOID BaseAddress - ); - -// MmUnmapIoSpace: -// Unmaps a virtual address mapping made by MmMapIoSpace. -// -// Differences from NT: None. -NTSYSAPI -EXPORTNUM(183) -PVOID -NTAPI -MmUnmapIoSpace( - IN PVOID BaseAddress, - IN ULONG NumberOfBytes - ); - -// MmAllocateContiguousMemory: -// Allocates a range of physically contiguous, cache-aligned memory from the -// non-paged pool (= main pool on XBOX). -// -// Differences from NT: HighestAcceptableAddress was deleted, opting instead -// to not care about the highest address. -NTSYSAPI -EXPORTNUM(165) -PVOID -NTAPI -MmAllocateContiguousMemory( - IN ULONG NumberOfBytes - ); - -// MmFreeContiguousMemory: -// Frees memory allocated with MmAllocateContiguousMemory. -// -// Differences from NT: None. -NTSYSAPI -EXPORTNUM(171) -VOID -NTAPI -MmFreeContiguousMemory( - IN PVOID BaseAddress - ); - -// IoCreateSymbolicLink: -// Creates a symbolic link in the object namespace. -// NtCreateSymbolicLinkObject is much harder to use than this simple -// function, so just use this one. -// -// Differences from NT: Uses ANSI_STRING instead of UNICODE_STRING. -NTSYSAPI -EXPORTNUM(67) -NTSTATUS -NTAPI -IoCreateSymbolicLink( - IN PANSI_STRING SymbolicLinkName, - IN PANSI_STRING DeviceName - ); - -// IoDeleteSymbolicLink: -// Creates a symbolic link in the object namespace. Deleting symbolic links -// through the Nt* functions is a pain, so use this instead. -// -// Differences from NT: Uses ANSI_STRING instead of UNICODE_STRING. -NTSYSAPI -EXPORTNUM(69) -NTSTATUS -NTAPI -IoDeleteSymbolicLink( - IN PANSI_STRING SymbolicLinkName - ); - - -// ObReferenceObjectByHandle: -// Turns a handle into a kernel object pointer. The ObjectType parameter -// specifies what type of object it is. This function also increments the -// object's reference count. -// -// Differences from NT: There are no DesiredAccess, AccessMode, or -// HandleInformation parameters. -NTSYSAPI -EXPORTNUM(246) -NTSTATUS -NTAPI -ObReferenceObjectByHandle( - IN HANDLE Handle, - IN POBJECT_TYPE ObjectType OPTIONAL, - OUT PVOID *Object - ); - -// ObfReferenceObject/ObReferenceObject: -// Increments the object's reference count. -// -// Differences from NT: None. -#define ObReferenceObject(Object) ObfReferenceObject(Object) -NTSYSAPI -EXPORTNUM(251) -VOID -FASTCALL -ObfReferenceObject( - IN PVOID Object - ); - -// ObfDereferenceObject/ObDereferenceObject: -// Decrements the object's reference count, deleting it if it is now unused. -// -// Differences from NT: None. -#define ObDereferenceObject(a) ObfDereferenceObject(a) -NTSYSAPI -EXPORTNUM(250) -VOID -FASTCALL -ObfDereferenceObject( - IN PVOID Object - ); - -// Kernel routines only in the XBOX - -// HalEnableSecureTrayEject: -// Notifies the SMBUS that ejecting the DVD-ROM should not reset the system. -// Note that this function can't really be called directly... -// -// New to the XBOX. -NTSYSAPI -EXPORTNUM(365) -VOID -NTAPI -HalEnableSecureTrayEject( - VOID - ); - -// XeLoadSection: -// Adds one to the reference count of the specified section and loads if the -// count is now above zero. -// -// New to the XBOX. -NTSYSAPI -EXPORTNUM(327) -NTSTATUS -NTAPI -XeLoadSection( - IN OUT PXBE_SECTION section - ); - -/* Error codes */ -#define STATUS_SUCCESS 0x00000000 -#define STATUS_UNSUCCESSFUL 0xC0000001 -#define STATUS_UNRECOGNIZED_MEDIA 0xC0000014 - -/* The SCSI input buffer was too large (not necessarily an error!) */ -#define STATUS_DATA_OVERRUN 0xC000003C -#define STATUS_INVALID_IMAGE_FORMAT 0xC000007B -#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A -#define STATUS_TOO_MANY_SECRETS 0xC0000156 -#define STATUS_REGION_MISMATCH 0xC0050001 - -#include - - // Thanks and credit go to Woodoo - extern VOID WINAPI HalWriteSMBusValue(BYTE, BYTE, BOOL, BYTE); - extern VOID WINAPI HalReadSMCTrayState(DWORD* state, DWORD* count); - - // Thanks and credit go to Team Evox - extern VOID WINAPI HalReturnToFirmware(DWORD); - - extern INT WINAPI XNetLoadConfigParams(LPBYTE); - extern INT WINAPI XNetSaveConfigParams(LPBYTE); - - extern INT WINAPI XWriteTitleInfoNoReboot(LPVOID,LPVOID,DWORD,DWORD,LPVOID); - - extern DWORD* LaunchDataPage; -#endif +#include "platform_xdk.h" static enum frontend_fork xdk_fork_mode = FRONTEND_FORK_NONE; -#ifdef _XBOX360 -typedef struct _STRING -{ - USHORT Length; - USHORT MaximumLength; - PCHAR Buffer; -} STRING, *PSTRING; - -VOID RtlInitAnsiString(PSTRING DestinationString, PCHAR SourceString); -HRESULT ObDeleteSymbolicLink(PSTRING SymbolicLinkName); -HRESULT ObCreateSymbolicLink(PSTRING SymbolicLinkName, PSTRING DeviceName); - -static HRESULT xbox_io_mount(const char* szDrive, char* szDevice) -{ - STRING DeviceName, LinkName; - char szDestinationDrive[PATH_MAX_LENGTH]; - - snprintf(szDestinationDrive, sizeof(szDestinationDrive), - "\\??\\%s", szDrive); - RtlInitAnsiString(&DeviceName, szDevice); - RtlInitAnsiString(&LinkName, (PCHAR)szDestinationDrive); - ObDeleteSymbolicLink(&LinkName); - return (HRESULT)ObCreateSymbolicLink(&LinkName, &DeviceName); -} -#endif - -#ifdef _XBOX1 -static HRESULT xbox_io_mount(char *szDrive, char *szDevice) -{ - STRING DeviceName, LinkName; -#ifndef IS_SALAMANDER - bool original_verbose = verbosity_is_enabled(); -#endif - char szSourceDevice[48] = {0}; - char szDestinationDrive[16] = {0}; - - snprintf(szSourceDevice, sizeof(szSourceDevice), - "\\Device\\%s", szDevice); - snprintf(szDestinationDrive, sizeof(szDestinationDrive), - "\\??\\%s", szDrive); - - DeviceName.Length = strlen(szSourceDevice); - DeviceName.MaximumLength = strlen(szSourceDevice) + 1; - DeviceName.Buffer = szSourceDevice; - - LinkName.Length = strlen(szDestinationDrive); - LinkName.MaximumLength = strlen(szDestinationDrive) + 1; - LinkName.Buffer = szDestinationDrive; - - IoCreateSymbolicLink(&LinkName, &DeviceName); - -#ifndef IS_SALAMANDER - if (original_verbose) - verbosity_enable(); - else - verbosity_disable(); -#endif - return S_OK; -} - -static HRESULT xbox_io_unmount(char *szDrive) -{ - STRING LinkName; - char szDestinationDrive[16] = {0}; - - snprintf(szDestinationDrive, sizeof(szDestinationDrive), - "\\??\\%s", szDrive); - - LinkName.Length = strlen(szDestinationDrive); - LinkName.MaximumLength = strlen(szDestinationDrive) + 1; - LinkName.Buffer = szDestinationDrive; - - IoDeleteSymbolicLink(&LinkName); - - return S_OK; -} -#endif - static void frontend_xdk_get_environment_settings(int *argc, char *argv[], void *args, void *params_data) { @@ -1189,19 +168,11 @@ static void frontend_xdk_get_environment_settings(int *argc, char *argv[], { char *extracted_path = (char*)calloc(dwLaunchDataSize, sizeof(char)); BYTE* pLaunchData = (BYTE*)calloc(dwLaunchDataSize, sizeof(BYTE)); - AURORA_LAUNCHDATA_EXECUTABLE* aurora = (AURORA_LAUNCHDATA_EXECUTABLE*)pLaunchData; XGetLaunchData(pLaunchData, dwLaunchDataSize); memset(extracted_path, 0, dwLaunchDataSize); - if (aurora->ApplicationId == AURORA_LAUNCHDATA_APPID && aurora->FunctionId == AURORA_LAUNCHDATA_EXECUTABLE_FUNCID) - { - if (xbox_io_mount("aurora:", aurora->SystemPath) >= 0) - snprintf(extracted_path, dwLaunchDataSize, - "aurora:%s%s", aurora->RelativePath, aurora->Exectutable); - } - else - strlcpy(extracted_path, pLaunchData, dwLaunchDataSize); + strlcpy(extracted_path, pLaunchData, dwLaunchDataSize); /* Auto-start game */ if (!string_is_empty(extracted_path)) diff --git a/frontend/drivers/platform_xdk.h b/frontend/drivers/platform_xdk.h new file mode 100644 index 0000000000..fa6121fca6 --- /dev/null +++ b/frontend/drivers/platform_xdk.h @@ -0,0 +1,1000 @@ +#ifdef _XBOX1 +#include + +// Don't do __declspec(dllimport) for things like emulators +#if defined(NTSYSAPI) && defined(DONT_IMPORT_INTERNAL) +#undef NTSYSAPI +#endif +#ifdef DONT_IMPORT_INTERNAL +#define NTSYSAPI +#endif + +// The normal headers don't have this...? +#define FASTCALL __fastcall + +// The usual NTSTATUS +typedef LONG NTSTATUS; + +// The usual NT_SUCCESS +#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) + +// Just for documentation +#define EXPORTNUM(x) + + +// Needed for object structures and related things +typedef CONST SHORT CSHORT; + + +// String types +typedef CHAR *PSZ; +typedef CONST CHAR *PCSZ; + +// ANSI_STRING +// Differences from NT: None. +typedef struct _STRING { + USHORT Length; + USHORT MaximumLength; + PCHAR Buffer; +} STRING; +typedef STRING *PSTRING; + +typedef STRING ANSI_STRING; +typedef PSTRING PANSI_STRING; + + +// IO Status Block type (UNVERIFIED) +// Differences from NT: None. +typedef struct _IO_STATUS_BLOCK { + union { + NTSTATUS Status; + PVOID Pointer; + }; + + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + +// APC routine +typedef +VOID +(NTAPI *PIO_APC_ROUTINE) ( + IN PVOID ApcContext, + IN PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG Reserved + ); + + +// Header for dispatcher objects +// Differences from NT: None. +typedef struct _DISPATCHER_HEADER { + UCHAR Type; + UCHAR Absolute; + UCHAR Size; + UCHAR Inserted; + LONG SignalState; + LIST_ENTRY WaitListHead; +} DISPATCHER_HEADER; + + +// Object types +#define NotificationTimerObject 8 +#define SynchronizationTimerObject 9 +#define DpcObject 19 + + +// Object Attributes type +// Differences from NT: There are no Length, SecurityDescriptor, or +// SecurityQualityOfService fields. Also, ObjectName is ANSI, not +// Unicode. +typedef struct _OBJECT_ATTRIBUTES { + HANDLE RootDirectory; + PANSI_STRING ObjectName; + ULONG Attributes; +} OBJECT_ATTRIBUTES; +typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; + +// Flags for OBJECT_ATTRIBUTES::Attributes +#define OBJ_INHERIT 0x00000002L +#define OBJ_PERMANENT 0x00000010L +#define OBJ_EXCLUSIVE 0x00000020L +#define OBJ_CASE_INSENSITIVE 0x00000040L +#define OBJ_OPENIF 0x00000080L +#define OBJ_OPENLINK 0x00000100L +#define OBJ_KERNEL_HANDLE 0x00000200L +#define OBJ_VALID_ATTRIBUTES 0x000003F2L + +// CreateDisposition values for NtCreateFile() +#define FILE_SUPERSEDE 0x00000000 +#define FILE_OPEN 0x00000001 +#define FILE_CREATE 0x00000002 +#define FILE_OPEN_IF 0x00000003 +#define FILE_OVERWRITE 0x00000004 +#define FILE_OVERWRITE_IF 0x00000005 +#define FILE_MAXIMUM_DISPOSITION 0x00000005 + +// CreateOption values for NtCreateFile() +// FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT is what CreateFile +// uses for most things when translating to NtCreateFile. +#define FILE_DIRECTORY_FILE 0x00000001 +#define FILE_WRITE_THROUGH 0x00000002 +#define FILE_SEQUENTIAL_ONLY 0x00000004 +#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 +#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 +#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 +#define FILE_NON_DIRECTORY_FILE 0x00000040 +#define FILE_CREATE_TREE_CONNECTION 0x00000080 +#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 +#define FILE_NO_EA_KNOWLEDGE 0x00000200 +#define FILE_OPEN_FOR_RECOVERY 0x00000400 +#define FILE_RANDOM_ACCESS 0x00000800 +#define FILE_DELETE_ON_CLOSE 0x00001000 +#define FILE_OPEN_BY_FILE_ID 0x00002000 +#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 +#define FILE_NO_COMPRESSION 0x00008000 +#define FILE_RESERVE_OPFILTER 0x00100000 +#define FILE_OPEN_REPARSE_POINT 0x00200000 +#define FILE_OPEN_NO_RECALL 0x00400000 +#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 +#define FILE_COPY_STRUCTURED_STORAGE 0x00000041 +#define FILE_STRUCTURED_STORAGE 0x00000441 +#define FILE_VALID_OPTION_FLAGS 0x00ffffff +#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032 +#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032 +#define FILE_VALID_SET_FLAGS 0x00000036 + + +// NtQueryVolumeInformation / NtSetVolumeInformation stuff +// Type of information to retrieve; FileFsSizeInformation and +// FileFsDeviceInformation are the only ones confirmed to work. +typedef enum _FSINFOCLASS { + FileFsVolumeInformation = 1, + FileFsLabelInformation, + FileFsSizeInformation, + FileFsDeviceInformation, + FileFsAttributeInformation, + FileFsControlInformation, + FileFsFullSizeInformation, + FileFsObjectInformation +} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; + +// Structure of FileFsSizeInformation +typedef struct _FILE_FS_SIZE_INFORMATION { + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER AvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; + +#define DEVICE_TYPE ULONG + +// Structure of FileFsDeviceInformation +typedef struct _FILE_FS_DEVICE_INFORMATION { + DEVICE_TYPE DeviceType; + ULONG Characteristics; +} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; + +// DEVICE_TYPEs (I took a guess as to which the XBOX might have.) +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_FILE_SYSTEM 0x00000009 +#define FILE_DEVICE_NULL 0x00000015 +#define FILE_DEVICE_SCREEN 0x0000001c +#define FILE_DEVICE_SOUND 0x0000001d +#define FILE_DEVICE_UNKNOWN 0x00000022 +#define FILE_DEVICE_VIDEO 0x00000023 +#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 +#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 + +// Characteristics +#define FILE_REMOVABLE_MEDIA 0x00000001 +#define FILE_READ_ONLY_DEVICE 0x00000002 +#define FILE_FLOPPY_DISKETTE 0x00000004 +#define FILE_WRITE_ONCE_MEDIA 0x00000008 +#define FILE_REMOTE_DEVICE 0x00000010 +#define FILE_DEVICE_IS_MOUNTED 0x00000020 +#define FILE_VIRTUAL_VOLUME 0x00000040 +#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 +#define FILE_DEVICE_SECURE_OPEN 0x00000100 + +/* Physical address + * Differences from NT: 32 bit address instead of 64. */ +typedef ULONG PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; + +/* NtCreateFile/NtOpenFile stuff */ +#define FILE_SUPERSEDED 0x00000000 +#define FILE_OPENED 0x00000001 +#define FILE_CREATED 0x00000002 +#define FILE_OVERWRITTEN 0x00000003 +#define FILE_EXISTS 0x00000004 +#define FILE_DOES_NOT_EXIST 0x00000005 + +// NtReadFile/NtWriteFile stuff +#define FILE_WRITE_TO_END_OF_FILE 0xffffffff +#define FILE_USE_FILE_POINTER_POSITION 0xfffffffe + +// Device types +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_SCSI FILE_DEVICE_CONTROLLER +#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_DVD 0x00000033 + +// Access types +#define FILE_ANY_ACCESS 0 +#define FILE_READ_ACCESS 0x0001 /* file & pipe */ +#define FILE_WRITE_ACCESS 0x0002 /* file & pipe */ + +// Method types +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +// The all-important CTL_CODE +#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ +) + +// IDE/SCSI codes +// IOCTL_SCSI_PASS_THROUGH_DIRECT is the only one known to be used. +// Differences from NT: None. +#define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_RESCAN_BUS CTL_CODE(IOCTL_SCSI_BASE, 0x0407, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_GET_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0408, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_FREE_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0409, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_IDE_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x040a, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + +// Special XBOX code? +#define IOCTL_CDROM_AUTHENTICATE_DISK CTL_CODE(FILE_DEVICE_CD_ROM, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS) + +/* Structure for IOCTL_SCSI_PASS_THROUGH_DIRECT + * Differences from NT: None, believe it or not. */ +typedef struct _SCSI_PASS_THROUGH_DIRECT { + /*000*/ USHORT Length; + /*002*/ UCHAR ScsiStatus; + /*003*/ UCHAR PathId; + /*004*/ UCHAR TargetId; + /*005*/ UCHAR Lun; + /*006*/ UCHAR CdbLength; + /*007*/ UCHAR SenseInfoLength; + /*008*/ UCHAR DataIn; + /*00C*/ ULONG DataTransferLength; + /*010*/ ULONG TimeOutValue; + /*014*/ PVOID DataBuffer; + /*018*/ ULONG SenseInfoOffset; + /*01C*/ UCHAR Cdb[16]; +}SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; + +/* DataIn fields for IOCTL_SCSI_PASS_THROUGH_DIRECT */ +#define SCSI_IOCTL_DATA_OUT 0 +#define SCSI_IOCTL_DATA_IN 1 +#define SCSI_IOCTL_DATA_UNSPECIFIED 2 + +/* Kernel object type (unsure about the structure...) */ +typedef struct _OBJECT_TYPE +{ + // Same prototype as ExAllocatePoolWithTag, because that's the usual one + PVOID + (NTAPI *AllocationFunction)( + SIZE_T NumberOfBytes, + ULONG Tag + ); + + // Same prototype as ExFreePool, because that's the usual one + VOID + (NTAPI *FreeFunction)( + IN PVOID P + ); + + // The prototypes of these are unknown + void *CloseFunction; + void *DeleteFunction; + void *ParseFunction; + + // Unknown DWORD... Size of this object type maybe? + void *DefaultObjectMaybe; + + // 4 letter tag for this object type + CHAR Tag[4]; +} OBJECT_TYPE; +typedef OBJECT_TYPE *POBJECT_TYPE; + +// Object types +extern POBJECT_TYPE IoFileObjectType; +extern POBJECT_TYPE ExEventObjectType; +extern POBJECT_TYPE ExSemaphoreObjectType; +extern POBJECT_TYPE IoCompletionObjectType; +extern POBJECT_TYPE IoDeviceObjectType; + + +// *_OBJECT and related structures (mostly opaque since I'm lazy) +typedef struct _DRIVER_OBJECT { + CSHORT Type; + CSHORT Size; + struct _DEVICE_OBJECT *DeviceObject; + // ... +} DRIVER_OBJECT; +typedef DRIVER_OBJECT *PDRIVER_OBJECT; + +typedef struct _DEVICE_OBJECT { + CSHORT Type; + USHORT Size; + LONG ReferenceCount; + PDRIVER_OBJECT DriverObject; + // ... +} DEVICE_OBJECT; +typedef DEVICE_OBJECT *PDEVICE_OBJECT; + +typedef struct _FILE_OBJECT { + CSHORT Type; + CSHORT Size; + PDEVICE_OBJECT DeviceObject; + // ... +} FILE_OBJECT; +typedef FILE_OBJECT *PFILE_OBJECT; + + +/* Thread information structures */ + +/* IRQL */ +typedef UCHAR KIRQL, *PKIRQL; +#define PASSIVE_LEVEL 0 // Passive release level +#define LOW_LEVEL 0 // Lowest interrupt level +#define APC_LEVEL 1 // APC interrupt level +#define DISPATCH_LEVEL 2 // Dispatcher level + +// Thread entry point +// NOTE: This is not a standard call! You can't call this function from C code! +// You push registers like stdcall, but ebp + 4 must point to the first argument before the call! +// +// Differences from NT: 2 parameters instead of 1; strange calling convention +typedef +VOID +(NTAPI *PKSTART_ROUTINE) ( + IN PVOID StartContext1, + IN PVOID StartContext2 + ); + +// Structure of a critical section +// Same as the XBOX's RTL_CRITICAL_SECTION, but with the more explicit header +typedef struct _KCRITICAL_SECTION +{ + // 000 Dispatcher header + DISPATCHER_HEADER Header; + // 010 Lock count of the critical section + LONG LockCount; + // 014 Recursion count of the critical section + LONG RecursionCount; + // 018 Thread ID of the thread that currently owns this critical section + ULONG OwningThread; +} KCRITICAL_SECTION, *PKCRITICAL_SECTION; + +// Structure of a thread object +typedef struct _KTHREAD +{ + // 000 Dispatcher header + DISPATCHER_HEADER Header; + // 010 Unknown + BYTE unknown[0x18]; + // 028 Pointer to TLS data + PVOID TlsData; + // ??? just padding - real size is unknown + BYTE unknown2[0x100]; +} KTHREAD, *PKTHREAD; + +// Structure of the data at FS +typedef struct _FS_STRUCTURE +{ + // 000 Current exception handler information + PVOID *ExceptionFrame; + // 004 Pointer to current TLS data top + PVOID TlsDataTop; + // 008 + BYTE unknown2[0x1C]; + // 024 Current IRQL of the OS + KIRQL CurrentIrql; + // 028 Thread structure of the current thread + PKTHREAD ThreadObject; + // ??? just padding - real size is unknown + BYTE unknown3[0x100]; +} FS_STRUCTURE, *PFS_STRUCTURE; + +// DPC routine +typedef +VOID +(*PKDEFERRED_ROUTINE) ( + IN struct _KDPC *Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 + ); + +// DPC information +// It's not known which of these fields are used on XBOX. +typedef struct _KDPC { + CSHORT Type; + UCHAR Number; + UCHAR Importance; + LIST_ENTRY DpcListEntry; + PKDEFERRED_ROUTINE DeferredRoutine; + PVOID DeferredContext; + PVOID SystemArgument1; + PVOID SystemArgument2; + PULONG_PTR Lock; +} KDPC, *PKDPC; + + +// Timers +typedef enum _TIMER_TYPE { + NotificationTimer, + SynchronizationTimer + } TIMER_TYPE; + +typedef struct _KTIMER { + DISPATCHER_HEADER Header; + ULARGE_INTEGER DueTime; + LIST_ENTRY TimerListEntry; + struct _KDPC *Dpc; + LONG Period; +} KTIMER, *PKTIMER; + +/* XBE stuff + * Not used in any exported kernel calls, but still useful. + */ + +/* XBE header information */ +typedef struct _XBE_HEADER +{ + // 000 "XBEH" + CHAR Magic[4]; + // 004 RSA digital signature of the entire header area + UCHAR HeaderSignature[256]; + // 104 Base address of XBE image (must be 0x00010000?) + PVOID BaseAddress; + // 108 Size of all headers combined - other headers must be within this + ULONG HeaderSize; + // 10C Size of entire image + ULONG ImageSize; + // 110 Size of this header (always 0x178?) + ULONG XbeHeaderSize; + // 114 Image timestamp - unknown format + ULONG Timestamp; + // 118 Pointer to certificate data (must be within HeaderSize) + struct _XBE_CERTIFICATE *Certificate; + // 11C Number of sections + DWORD NumSections; + // 120 Pointer to section headers (must be within HeaderSize) + struct _XBE_SECTION *Sections; + // 124 Initialization flags + ULONG InitFlags; + // 128 Entry point (XOR'd; see xboxhacker.net) + PVOID EntryPoint; + // 12C Pointer to TLS directory + struct _XBE_TLS_DIRECTORY *TlsDirectory; + // 130 Stack commit size + ULONG StackCommit; + // 134 Heap reserve size + ULONG HeapReserve; + // 138 Heap commit size + ULONG HeapCommit; + // 13C PE base address (?) + PVOID PeBaseAddress; + // 140 PE image size (?) + ULONG PeImageSize; + // 144 PE checksum (?) + ULONG PeChecksum; + // 148 PE timestamp (?) + ULONG PeTimestamp; + // 14C PC path and filename to EXE file from which XBE is derived + PCSZ PcExePath; + // 150 PC filename (last part of PcExePath) from which XBE is derived + PCSZ PcExeFilename; + // 154 PC filename (Unicode version of PcExeFilename) + PWSTR PcExeFilenameUnicode; + // 158 Pointer to kernel thunk table (XOR'd; EFB1F152 debug) + ULONG_PTR *KernelThunkTable; + // 15C Non-kernel import table (debug only) + PVOID DebugImportTable; + // 160 Number of library headers + ULONG NumLibraries; + // 164 Pointer to library headers + struct _XBE_LIBRARY *Libraries; + // 168 Pointer to kernel library header + struct _XBE_LIBRARY *KernelLibrary; + // 16C Pointer to XAPI library + struct _XBE_LIBRARY *XapiLibrary; + // 170 Pointer to logo bitmap (NULL = use default of Microsoft) + PVOID LogoBitmap; + // 174 Size of logo bitmap + ULONG LogoBitmapSize; + // 178 +} XBE_HEADER, *PXBE_HEADER; + +// Certificate structure +typedef struct _XBE_CERTIFICATE { + // 000 Size of certificate + ULONG Size; + // 004 Certificate timestamp (unknown format) + ULONG Timestamp; + // 008 Title ID + ULONG TitleId; + // 00C Name of the game (Unicode) + WCHAR TitleName[40]; + // 05C Alternate title ID's (0-terminated) + ULONG AlternateTitleIds[16]; + // 09C Allowed media types - 1 bit match between XBE and media = boots + ULONG MediaTypes; + // 0A0 Allowed game regions - 1 bit match between this and XBOX = boots + ULONG GameRegion; + // 0A4 Allowed game ratings - 1 bit match between this and XBOX = boots + ULONG GameRating; + // 0A8 Disk number (?) + ULONG DiskNumber; + // 0AC Version (?) + ULONG Version; + // 0B0 LAN key for this game + UCHAR LanKey[16]; + // 0C0 Signature key for this game + UCHAR SignatureKey[16]; + // 0D0 Signature keys for the alternate title ID's + UCHAR AlternateSignatureKeys[16][16]; + // 1D0 +} XBE_CERTIFICATE, *PXBE_CERTIFICATE; + +// Section headers +typedef struct _XBE_SECTION { + // 000 Flags + ULONG Flags; + // 004 Virtual address (where this section loads in RAM) + PVOID VirtualAddress; + // 008 Virtual size (size of section in RAM; after FileSize it's 00'd) + ULONG VirtualSize; + // 00C File address (where in the file from which this section comes) + ULONG FileAddress; + // 010 File size (size of the section in the XBE file) + ULONG FileSize; + // 014 Pointer to section name + PCSZ SectionName; + // 018 Section reference count - when >= 1, section is loaded + LONG SectionReferenceCount; + // 01C Pointer to head shared page reference count + WORD *HeadReferenceCount; + // 020 Pointer to tail shared page reference count + WORD *TailReferenceCount; + // 024 SHA hash. Hash DWORD containing FileSize, then hash section. + DWORD ShaHash[5]; + // 038 +} XBE_SECTION, *PXBE_SECTION; + +/* TLS directory information needed later + * Library version data needed later */ + +/* Initialization flags */ +#define XBE_INIT_MOUNT_UTILITY 0x00000001 +#define XBE_INIT_FORMAT_UTILITY 0x00000002 +#define XBE_INIT_64M_RAM_ONLY 0x00000004 +#define XBE_INIT_DONT_SETUP_HDD 0x00000008 + +/* Region codes */ +#define XBE_REGION_US_CANADA 0x00000001 +#define XBE_REGION_JAPAN 0x00000002 +#define XBE_REGION_ELSEWHERE 0x00000004 +#define XBE_REGION_DEBUG 0x80000000 + +/* Media types */ +#define XBE_MEDIA_HDD 0x00000001 +#define XBE_MEDIA_XBOX_DVD 0x00000002 +#define XBE_MEDIA_ANY_CD_OR_DVD 0x00000004 +#define XBE_MEDIA_CD 0x00000008 +#define XBE_MEDIA_1LAYER_DVDROM 0x00000010 +#define XBE_MEDIA_2LAYER_DVDROM 0x00000020 +#define XBE_MEDIA_1LAYER_DVDR 0x00000040 +#define XBE_MEDIA_2LAYER_DVDR 0x00000080 +#define XBE_MEDIA_USB 0x00000100 +#define XBE_MEDIA_ALLOW_UNLOCKED_HDD 0x40000000 + +/* Section flags */ +#define XBE_SEC_WRITABLE 0x00000001 +#define XBE_SEC_PRELOAD 0x00000002 +#define XBE_SEC_EXECUTABLE 0x00000004 +#define XBE_SEC_INSERTED_FILE 0x00000008 +#define XBE_SEC_RO_HEAD_PAGE 0x00000010 +#define XBE_SEC_RO_TAIL_PAGE 0x00000020 + +/* x86 page size */ +#define PAGE_SIZE 0x1000 + +/* Native NT API calls on the XBOX */ + +/* PAGE_ALIGN: + * Returns an address rounded down to the nearest page boundary. + * + * Differences from NT: None. + */ +#define PAGE_ALIGN(Va) ((PVOID)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1))) + +// NtReadFile: +// Reads a file. +// +// Differences from NT: There is no Key parameter. +NTSYSAPI +EXPORTNUM(219) +NTSTATUS +NTAPI +NtReadFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset + ); + +// NtWriteFile: +// Writes a file. +// +// Differences from NT: There is no Key parameter. +NTSYSAPI +EXPORTNUM(236) +NTSTATUS +NTAPI +NtWriteFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset + ); + +// NtQueryVolumeInformation: +// Queries information about a file system. This is not documented by +// Microsoft even under NT. +// +// Differences from NT: None known. +NTSYSAPI +EXPORTNUM(218) +NTSTATUS +NTAPI +NtQueryVolumeInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID VolumeInformation, + IN ULONG VolumeInformationLength, + IN FS_INFORMATION_CLASS VolumeInformationClass + ); + +// NtClose: +// Closes a file or other handle. +// +// Differences from NT: None. +NTSYSAPI +EXPORTNUM(187) +NTSTATUS +NTAPI +NtClose( + IN HANDLE Handle + ); + +// NtAllocateVirtualMemory: +// Allocates virtual memory. +// +// Differences from NT: There is no ProcessHandle parameter. +NTSYSAPI +EXPORTNUM(184) +NTSTATUS +NTAPI +NtAllocateVirtualMemory( + IN OUT PVOID *BaseAddress, + IN ULONG ZeroBits, + IN OUT PULONG AllocationSize, + IN ULONG AllocationType, + IN ULONG Protect + ); + +// NtFreeVirtualMemory: +// Frees virtual memory. +// +// Differences from NT: There is no ProcessHandle parameter. +NTSYSAPI +EXPORTNUM(199) +NTSTATUS +NTAPI +NtFreeVirtualMemory( + IN OUT PVOID *BaseAddress, + IN OUT PULONG FreeSize, + IN ULONG FreeType + ); + + +// Kernel-level routines + +// MmMapIoSpace: +// Maps a physical address area into the virtual address space. +// DO NOT USE MEMORY MAPPED WITH THIS AS A BUFFER TO OTHER CALLS. For +// example, don't WriteFile or NtWriteFile these buffers. Copy them first. +// +// Differences from NT: PhysicalAddress is 32 bit, not 64. ProtectionType +// specifies the page protections, but it's a Win32 PAGE_ macro instead +// of the normal NT enumeration. PAGE_READWRITE is probably what you +// want... +NTSYSAPI +EXPORTNUM(177) +PVOID +NTAPI +MmMapIoSpace( + IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG NumberOfBytes, + IN ULONG ProtectionType + ); + +// MmGetPhysicalAddress: +// Translates a virtual address into a physical address. +// +// Differences from NT: PhysicalAddress is 32 bit, not 64. +NTSYSAPI +EXPORTNUM(173) +PHYSICAL_ADDRESS +NTAPI +MmGetPhysicalAddress( + IN PVOID BaseAddress + ); + +// MmUnmapIoSpace: +// Unmaps a virtual address mapping made by MmMapIoSpace. +// +// Differences from NT: None. +NTSYSAPI +EXPORTNUM(183) +PVOID +NTAPI +MmUnmapIoSpace( + IN PVOID BaseAddress, + IN ULONG NumberOfBytes + ); + +// MmAllocateContiguousMemory: +// Allocates a range of physically contiguous, cache-aligned memory from the +// non-paged pool (= main pool on XBOX). +// +// Differences from NT: HighestAcceptableAddress was deleted, opting instead +// to not care about the highest address. +NTSYSAPI +EXPORTNUM(165) +PVOID +NTAPI +MmAllocateContiguousMemory( + IN ULONG NumberOfBytes + ); + +// MmFreeContiguousMemory: +// Frees memory allocated with MmAllocateContiguousMemory. +// +// Differences from NT: None. +NTSYSAPI +EXPORTNUM(171) +VOID +NTAPI +MmFreeContiguousMemory( + IN PVOID BaseAddress + ); + +// IoCreateSymbolicLink: +// Creates a symbolic link in the object namespace. +// NtCreateSymbolicLinkObject is much harder to use than this simple +// function, so just use this one. +// +// Differences from NT: Uses ANSI_STRING instead of UNICODE_STRING. +NTSYSAPI +EXPORTNUM(67) +NTSTATUS +NTAPI +IoCreateSymbolicLink( + IN PANSI_STRING SymbolicLinkName, + IN PANSI_STRING DeviceName + ); + +// IoDeleteSymbolicLink: +// Creates a symbolic link in the object namespace. Deleting symbolic links +// through the Nt* functions is a pain, so use this instead. +// +// Differences from NT: Uses ANSI_STRING instead of UNICODE_STRING. +NTSYSAPI +EXPORTNUM(69) +NTSTATUS +NTAPI +IoDeleteSymbolicLink( + IN PANSI_STRING SymbolicLinkName + ); + + +// ObReferenceObjectByHandle: +// Turns a handle into a kernel object pointer. The ObjectType parameter +// specifies what type of object it is. This function also increments the +// object's reference count. +// +// Differences from NT: There are no DesiredAccess, AccessMode, or +// HandleInformation parameters. +NTSYSAPI +EXPORTNUM(246) +NTSTATUS +NTAPI +ObReferenceObjectByHandle( + IN HANDLE Handle, + IN POBJECT_TYPE ObjectType OPTIONAL, + OUT PVOID *Object + ); + +// ObfReferenceObject/ObReferenceObject: +// Increments the object's reference count. +// +// Differences from NT: None. +#define ObReferenceObject(Object) ObfReferenceObject(Object) +NTSYSAPI +EXPORTNUM(251) +VOID +FASTCALL +ObfReferenceObject( + IN PVOID Object + ); + +// ObfDereferenceObject/ObDereferenceObject: +// Decrements the object's reference count, deleting it if it is now unused. +// +// Differences from NT: None. +#define ObDereferenceObject(a) ObfDereferenceObject(a) +NTSYSAPI +EXPORTNUM(250) +VOID +FASTCALL +ObfDereferenceObject( + IN PVOID Object + ); + +// Kernel routines only in the XBOX + +// HalEnableSecureTrayEject: +// Notifies the SMBUS that ejecting the DVD-ROM should not reset the system. +// Note that this function can't really be called directly... +// +// New to the XBOX. +NTSYSAPI +EXPORTNUM(365) +VOID +NTAPI +HalEnableSecureTrayEject( + VOID + ); + +// XeLoadSection: +// Adds one to the reference count of the specified section and loads if the +// count is now above zero. +// +// New to the XBOX. +NTSYSAPI +EXPORTNUM(327) +NTSTATUS +NTAPI +XeLoadSection( + IN OUT PXBE_SECTION section + ); + +/* Error codes */ +#define STATUS_SUCCESS 0x00000000 +#define STATUS_UNSUCCESSFUL 0xC0000001 +#define STATUS_UNRECOGNIZED_MEDIA 0xC0000014 + +/* The SCSI input buffer was too large (not necessarily an error!) */ +#define STATUS_DATA_OVERRUN 0xC000003C +#define STATUS_INVALID_IMAGE_FORMAT 0xC000007B +#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A +#define STATUS_TOO_MANY_SECRETS 0xC0000156 +#define STATUS_REGION_MISMATCH 0xC0050001 + +#include + + // Thanks and credit go to Woodoo + extern VOID WINAPI HalWriteSMBusValue(BYTE, BYTE, BOOL, BYTE); + extern VOID WINAPI HalReadSMCTrayState(DWORD* state, DWORD* count); + + // Thanks and credit go to Team Evox + extern VOID WINAPI HalReturnToFirmware(DWORD); + + extern INT WINAPI XNetLoadConfigParams(LPBYTE); + extern INT WINAPI XNetSaveConfigParams(LPBYTE); + + extern INT WINAPI XWriteTitleInfoNoReboot(LPVOID,LPVOID,DWORD,DWORD,LPVOID); + + extern DWORD* LaunchDataPage; + +static HRESULT xbox_io_mount(char *szDrive, char *szDevice) +{ + STRING DeviceName, LinkName; +#ifndef IS_SALAMANDER + bool original_verbose = verbosity_is_enabled(); +#endif + char szSourceDevice[48] = {0}; + char szDestinationDrive[16] = {0}; + + snprintf(szSourceDevice, sizeof(szSourceDevice), + "\\Device\\%s", szDevice); + snprintf(szDestinationDrive, sizeof(szDestinationDrive), + "\\??\\%s", szDrive); + + DeviceName.Length = strlen(szSourceDevice); + DeviceName.MaximumLength = strlen(szSourceDevice) + 1; + DeviceName.Buffer = szSourceDevice; + + LinkName.Length = strlen(szDestinationDrive); + LinkName.MaximumLength = strlen(szDestinationDrive) + 1; + LinkName.Buffer = szDestinationDrive; + + IoCreateSymbolicLink(&LinkName, &DeviceName); + +#ifndef IS_SALAMANDER + if (original_verbose) + verbosity_enable(); + else + verbosity_disable(); +#endif + return S_OK; +} + +static HRESULT xbox_io_unmount(char *szDrive) +{ + STRING LinkName; + char szDestinationDrive[16] = {0}; + + snprintf(szDestinationDrive, sizeof(szDestinationDrive), + "\\??\\%s", szDrive); + + LinkName.Length = strlen(szDestinationDrive); + LinkName.MaximumLength = strlen(szDestinationDrive) + 1; + LinkName.Buffer = szDestinationDrive; + + IoDeleteSymbolicLink(&LinkName); + + return S_OK; +} +#endif + +#ifdef _XBOX360 +typedef struct _STRING +{ + USHORT Length; + USHORT MaximumLength; + PCHAR Buffer; +} STRING, *PSTRING; + +VOID RtlInitAnsiString(PSTRING DestinationString, PCHAR SourceString); +HRESULT ObDeleteSymbolicLink(PSTRING SymbolicLinkName); +HRESULT ObCreateSymbolicLink(PSTRING SymbolicLinkName, PSTRING DeviceName); + +static HRESULT xbox_io_mount(const char* szDrive, char* szDevice) +{ + STRING DeviceName, LinkName; + char szDestinationDrive[PATH_MAX_LENGTH]; + + snprintf(szDestinationDrive, sizeof(szDestinationDrive), + "\\??\\%s", szDrive); + RtlInitAnsiString(&DeviceName, szDevice); + RtlInitAnsiString(&LinkName, (PCHAR)szDestinationDrive); + ObDeleteSymbolicLink(&LinkName); + return (HRESULT)ObCreateSymbolicLink(&LinkName, &DeviceName); +} +#endif