diff --git a/build/win32/Cxbx.vcxproj b/build/win32/Cxbx.vcxproj index 512abaef7..da5c06cc7 100644 --- a/build/win32/Cxbx.vcxproj +++ b/build/win32/Cxbx.vcxproj @@ -163,7 +163,6 @@ - @@ -177,6 +176,7 @@ + @@ -215,12 +215,6 @@ %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) - - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) diff --git a/import/OpenXDK/include/xboxkrnl/nt.h b/import/OpenXDK/include/xboxkrnl/nt.h index 154a14259..4c8f6b493 100644 --- a/import/OpenXDK/include/xboxkrnl/nt.h +++ b/import/OpenXDK/include/xboxkrnl/nt.h @@ -270,8 +270,8 @@ XBSYSAPI VOID *NtQueryEvent; // ****************************************************************** XBSYSAPI EXPORTNUM(210) NTSTATUS NTAPI NtQueryFullAttributesFile ( - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PVOID Attributes + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PFILE_NETWORK_OPEN_INFORMATION Attributes ); // ****************************************************************** diff --git a/import/OpenXDK/include/xboxkrnl/xboxkrnl.h b/import/OpenXDK/include/xboxkrnl/xboxkrnl.h index 638ae69de..c5d1ae740 100644 --- a/import/OpenXDK/include/xboxkrnl/xboxkrnl.h +++ b/import/OpenXDK/include/xboxkrnl/xboxkrnl.h @@ -512,6 +512,30 @@ FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; #define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032 #define FILE_VALID_SET_FLAGS 0x00000036 +// ****************************************************************** +// * File attribute flags +// ****************************************************************** +#define FILE_ATTRIBUTE_READONLY 0x00000001 +#define FILE_ATTRIBUTE_HIDDEN 0x00000002 +#define FILE_ATTRIBUTE_SYSTEM 0x00000004 +#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 +#define FILE_ATTRIBUTE_DEVICE 0x00000040 +#define FILE_ATTRIBUTE_NORMAL 0x00000080 +#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 +#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 +#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 +#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 +#define FILE_ATTRIBUTE_OFFLINE 0x00001000 +#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 +#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 + +#define FILE_ATTRIBUTE_CONTENT_INDEXED FILE_ATTRIBUTE_NOT_CONTENT_INDEXED + +#define FILE_ATTRIBUTE_VALID_FLAGS 0x00007fb7 +#define FILE_ATTRIBUTE_VALID_SET_FLAGS 0x000031a7 + + // ****************************************************************** // * OBJECT_ATTRIBUTES // ****************************************************************** @@ -597,20 +621,281 @@ FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; // ****************************************************************** typedef struct _FILE_DIRECTORY_INFORMATION { - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - CHAR FileName[1]; // Offset: 0x40 + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + CHAR FileName[1]; // Offset: 0x40 } FILE_DIRECTORY_INFORMATION; +// ****************************************************************** +// * FILE_RENAME_INFORMATION +// ****************************************************************** +typedef struct _FILE_RENAME_INFORMATION +{ + BOOLEAN ReplaceIfExists; + HANDLE RootDirectory; + OBJECT_STRING FileName; +} +FILE_RENAME_INFORMATION; + +// ****************************************************************** +// * FILE_LINK_INFORMATION +// ****************************************************************** +typedef struct _FILE_LINK_INFORMATION { + BOOLEAN ReplaceIfExists; + HANDLE RootDirectory; + ULONG FileNameLength; + CHAR FileName[1]; +} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION; + +// ****************************************************************** +// * FILE_NETWORK_OPEN_INFORMATION +// ****************************************************************** +typedef struct _FILE_NETWORK_OPEN_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; +} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; + +// ****************************************************************** +// * FILE_FULL_EA_INFORMATION +// ****************************************************************** +typedef struct _FILE_FULL_EA_INFORMATION { + ULONG NextEntryOffset; + UCHAR Flags; + UCHAR EaNameLength; + USHORT EaValueLength; + CHAR EaName[1]; +} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION; + +// ****************************************************************** +// * FILE_BASIC_INFORMATION +// ****************************************************************** +typedef struct _FILE_BASIC_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + ULONG FileAttributes; +} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; + +// ****************************************************************** +// * FILE_STANDARD_INFORMATION +// ****************************************************************** +typedef struct _FILE_STANDARD_INFORMATION { + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; +} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; + +// ****************************************************************** +// * FILE_INTERNAL_INFORMATION +// ****************************************************************** +typedef struct _FILE_INTERNAL_INFORMATION { + LARGE_INTEGER IndexNumber; +} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION; + +// ****************************************************************** +// * FILE_EA_INFORMATION +// ****************************************************************** +typedef struct _FILE_EA_INFORMATION { + ULONG EaSize; +} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION; + +// ****************************************************************** +// * FILE_ACCESS_INFORMATION +// ****************************************************************** +typedef struct _FILE_ACCESS_INFORMATION { + ACCESS_MASK AccessFlags; +} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION; + +// ****************************************************************** +// * FILE_POSITION_INFORMATION +// ****************************************************************** +typedef struct _FILE_POSITION_INFORMATION { + LARGE_INTEGER CurrentByteOffset; +} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; + +// ****************************************************************** +// * FILE_MODE_INFORMATION +// ****************************************************************** +typedef struct _FILE_MODE_INFORMATION { + ULONG Mode; +} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; + +// ****************************************************************** +// * FILE_ALIGNMENT_INFORMATION +// ****************************************************************** +typedef struct _FILE_ALIGNMENT_INFORMATION { + ULONG AlignmentRequirement; +} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; + +// ****************************************************************** +// * FILE_NAME_INFORMATION +// ****************************************************************** +typedef struct _FILE_NAME_INFORMATION { + ULONG FileNameLength; + CHAR FileName[1]; +} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; + +// ****************************************************************** +// * FILE_ALL_INFORMATION +// ****************************************************************** +typedef struct _FILE_ALL_INFORMATION { + FILE_BASIC_INFORMATION BasicInformation; + FILE_STANDARD_INFORMATION StandardInformation; + FILE_INTERNAL_INFORMATION InternalInformation; + FILE_EA_INFORMATION EaInformation; + FILE_ACCESS_INFORMATION AccessInformation; + FILE_POSITION_INFORMATION PositionInformation; + FILE_MODE_INFORMATION ModeInformation; + FILE_ALIGNMENT_INFORMATION AlignmentInformation; + FILE_NAME_INFORMATION NameInformation; +} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; + +// ****************************************************************** +// * FILE_DISPOSITION_INFORMATION +// ****************************************************************** +typedef struct _FILE_DISPOSITION_INFORMATION { + BOOLEAN DeleteFile; +} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; + +// ****************************************************************** +// * FILE_ALLOCATION_INFORMATION +// ****************************************************************** +typedef struct _FILE_ALLOCATION_INFORMATION { + LARGE_INTEGER AllocationSize; +} FILE_ALLOCATION_INFORMATION, *PFILE_ALLOCATION_INFORMATION; + +// ****************************************************************** +// * FILE_COMPRESSION_INFORMATION +// ****************************************************************** +typedef struct _FILE_COMPRESSION_INFORMATION { + LARGE_INTEGER CompressedFileSize; + USHORT CompressionFormat; + UCHAR CompressionUnitShift; + UCHAR ChunkShift; + UCHAR ClusterShift; + UCHAR Reserved[3]; +} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION; + +// ****************************************************************** +// * FILE_END_OF_FILE_INFORMATION +// ****************************************************************** +typedef struct _FILE_END_OF_FILE_INFORMATION { + LARGE_INTEGER EndOfFile; +} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; + +// ****************************************************************** +// * FILE_MOVE_CLUSTER_INFORMATION +// ****************************************************************** +typedef struct _FILE_MOVE_CLUSTER_INFORMATION { + ULONG ClusterCount; + HANDLE RootDirectory; + ULONG FileNameLength; + CHAR FileName[1]; +} FILE_MOVE_CLUSTER_INFORMATION, *PFILE_MOVE_CLUSTER_INFORMATION; + +// ****************************************************************** +// * FILE_STREAM_INFORMATION +// ****************************************************************** +typedef struct _FILE_STREAM_INFORMATION { + ULONG NextEntryOffset; + ULONG StreamNameLength; + LARGE_INTEGER StreamSize; + LARGE_INTEGER StreamAllocationSize; + CHAR StreamName[1]; +} FILE_STREAM_INFORMATION, *PFILE_STREAM_INFORMATION; + +// ****************************************************************** +// * FILE_TRACKING_INFORMATION +// ****************************************************************** +typedef struct _FILE_TRACKING_INFORMATION { + HANDLE DestinationFile; + ULONG ObjectInformationLength; + CHAR ObjectInformation[1]; +} FILE_TRACKING_INFORMATION, *PFILE_TRACKING_INFORMATION; + +// ****************************************************************** +// * FILE_COMPLETION_INFORMATION +// ****************************************************************** +typedef struct _FILE_COMPLETION_INFORMATION { + HANDLE Port; + PVOID Key; +} FILE_COMPLETION_INFORMATION, *PFILE_COMPLETION_INFORMATION; + +// ****************************************************************** +// * FILE_PIPE_INFORMATION +// ****************************************************************** +typedef struct _FILE_PIPE_INFORMATION { + ULONG ReadMode; + ULONG CompletionMode; +} FILE_PIPE_INFORMATION, *PFILE_PIPE_INFORMATION; + +// ****************************************************************** +// * FILE_PIPE_LOCAL_INFORMATION +// ****************************************************************** +typedef struct _FILE_PIPE_LOCAL_INFORMATION { + ULONG NamedPipeType; + ULONG NamedPipeConfiguration; + ULONG MaximumInstances; + ULONG CurrentInstances; + ULONG InboundQuota; + ULONG ReadDataAvailable; + ULONG OutboundQuota; + ULONG WriteQuotaAvailable; + ULONG NamedPipeState; + ULONG NamedPipeEnd; +} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; + +// ****************************************************************** +// * FILE_PIPE_REMOTE_INFORMATION +// ****************************************************************** +typedef struct _FILE_PIPE_REMOTE_INFORMATION { + LARGE_INTEGER CollectDataTime; + ULONG MaximumCollectionCount; +} FILE_PIPE_REMOTE_INFORMATION, *PFILE_PIPE_REMOTE_INFORMATION; + +// ****************************************************************** +// * FILE_MAILSLOT_QUERY_INFORMATION +// ****************************************************************** +typedef struct _FILE_MAILSLOT_QUERY_INFORMATION { + ULONG MaximumMessageSize; + ULONG MailslotQuota; + ULONG NextMessageSize; + ULONG MessagesAvailable; + LARGE_INTEGER ReadTimeout; +} FILE_MAILSLOT_QUERY_INFORMATION, *PFILE_MAILSLOT_QUERY_INFORMATION; + +// ****************************************************************** +// * FILE_MAILSLOT_SET_INFORMATION +// ****************************************************************** +typedef struct _FILE_MAILSLOT_SET_INFORMATION { + PLARGE_INTEGER ReadTimeout; +} FILE_MAILSLOT_SET_INFORMATION, *PFILE_MAILSLOT_SET_INFORMATION; + +// ****************************************************************** +// * FILE_REPARSE_POINT_INFORMATION +// ****************************************************************** +typedef struct _FILE_REPARSE_POINT_INFORMATION { + LONGLONG FileReference; + ULONG Tag; +} FILE_REPARSE_POINT_INFORMATION, *PFILE_REPARSE_POINT_INFORMATION; + // ****************************************************************** // * KSYSTEM_TIME // ****************************************************************** diff --git a/resource/Cxbx.aps b/resource/Cxbx.aps index 148c2461c..482115be9 100644 Binary files a/resource/Cxbx.aps and b/resource/Cxbx.aps differ diff --git a/resource/Cxbx.rc b/resource/Cxbx.rc index 66a70fb9b..f767baae5 100644 --- a/resource/Cxbx.rc +++ b/resource/Cxbx.rc @@ -9,21 +9,15 @@ // #include "WinResrc.h" -#ifndef IDC_STATIC -#define IDC_STATIC -1 -#endif // IDC_STATIC - ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources +// English (United States) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) -#endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // @@ -53,7 +47,6 @@ END 3 TEXTINCLUDE BEGIN - "\r\n" "\0" END @@ -72,15 +65,12 @@ IDB_LOGO BITMAP "Logo.bmp" // Menu // -IDR_MAINMENU MENU +IDR_MAINMENU MENU BEGIN POPUP "&File" BEGIN MENUITEM "&Open Xbe...", ID_FILE_OPEN_XBE - MENUITEM "&Close xbe", ID_FILE_CLOSE_XBE, GRAYED - MENUITEM SEPARATOR - MENUITEM "&Import Exe...", ID_FILE_IMPORTFROMEXE - MENUITEM "&Export Exe...", ID_FILE_EXPORTTOEXE, GRAYED + MENUITEM "&Close Xbe", ID_FILE_CLOSE_XBE, GRAYED MENUITEM SEPARATOR MENUITEM "&Save Xbe", ID_FILE_SAVEXBEFILE, GRAYED MENUITEM "Save Xbe &As...", ID_FILE_SAVEXBEFILEAS, GRAYED @@ -98,19 +88,6 @@ BEGIN MENUITEM "&8 : Recent Placeholder", ID_FILE_RXBE_8 MENUITEM "&9 : Recent Placeholder", ID_FILE_RXBE_9 END - POPUP "Recent Exe &Files" - BEGIN - MENUITEM "&0 : Recent Placeholder", ID_FILE_REXE_0 - MENUITEM "&1 : Recent Placeholder", ID_FILE_REXE_1 - MENUITEM "&2 : Recent Placeholder", ID_FILE_REXE_2 - MENUITEM "&3 : Recent Placeholder", ID_FILE_REXE_3 - MENUITEM "&4 : Recent Placeholder", ID_FILE_REXE_4 - MENUITEM "&5 : Recent Placeholder", ID_FILE_REXE_5 - MENUITEM "&6 : Recent Placeholder", ID_FILE_REXE_6 - MENUITEM "&7 : Recent Placeholder", ID_FILE_REXE_7 - MENUITEM "&8 : Recent Placeholder", ID_FILE_REXE_8 - MENUITEM "&9 : Recent Placeholder", ID_FILE_REXE_9 - END MENUITEM SEPARATOR MENUITEM "E&xit", ID_FILE_EXIT END @@ -151,13 +128,6 @@ BEGIN MENUITEM "Config &Controller...", ID_SETTINGS_CONFIG_CONTROLLER MENUITEM "Config &Audio...", ID_SETTINGS_CONFIGURESOUND, GRAYED MENUITEM "Config &Video...", ID_SETTINGS_CONFIG_VIDEO - MENUITEM SEPARATOR - POPUP "Executable &Generation" - BEGIN - MENUITEM "&Automatic (&Windows Temp)", ID_SETTINGS_GENWT - MENUITEM "Automatic (&Xbe Path)", ID_SETTINGS_GENXP - MENUITEM "&Manual", ID_SETTINGS_GENMA - END END POPUP "E&mulation" BEGIN @@ -179,7 +149,7 @@ END // #ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO +GUIDELINES DESIGNINFO BEGIN IDD_CONTROLLER_CFG, DIALOG BEGIN @@ -273,18 +243,7 @@ END IDR_JPEG_ABOUT JPEG "About.jpg" IDR_JPEG_SPLASH JPEG "Splash.jpg" -#endif // English (U.S.) resources +#endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/src/Common/Xbe.cpp b/src/Common/Xbe.cpp index 869dd3413..f260f346a 100644 --- a/src/Common/Xbe.cpp +++ b/src/Common/Xbe.cpp @@ -32,7 +32,6 @@ // * // ****************************************************************** #include "Xbe.h" -#include "Exe.h" #include "CxbxUtil.h" #include @@ -322,500 +321,6 @@ cleanup: return; } -// construct via Exe file object -Xbe::Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail) -{ - ConstructorInit(); - - time_t CurrentTime; - - time(&CurrentTime); - - printf("Xbe::Xbe: Pass 1 (Simple Pass)..."); - - // pass 1 - { - // standard Xbe magic number - m_Header.dwMagic = *(uint32*)"XBEH"; - - // nobody has the private key yet, so zero this out - memset(m_Header.pbDigitalSignature, 0, 256); - - // we'll only allow 0x00010000 for now - m_Header.dwBaseAddr = 0x00010000; - - // this is a constant value - m_Header.dwSizeofImageHeader = sizeof(m_Header); - - // we'll have the same number of sections as the Exe - m_Header.dwSections = x_Exe->m_Header.m_sections; - - // TODO: allow configuration - { - memset(&m_Header.dwInitFlags, 0, sizeof(m_Header.dwInitFlags)); - - m_Header.dwInitFlags.bLimit64MB = 1; - m_Header.dwInitFlags.bDontSetupHarddisk = 0; - m_Header.dwInitFlags.bMountUtilityDrive = 1; - } - - // various PE copies - { - m_Header.dwPeStackCommit = 0x00010000; //x_Exe->m_OptionalHeader.m_sizeof_stack_commit; - m_Header.dwPeHeapReserve = x_Exe->m_OptionalHeader.m_sizeof_heap_reserve; - m_Header.dwPeHeapCommit = x_Exe->m_OptionalHeader.m_sizeof_heap_commit; - m_Header.dwPeSizeofImage = x_Exe->m_OptionalHeader.m_sizeof_image; - m_Header.dwPeChecksum = 0x00000000; - m_Header.dwPeTimeDate = x_Exe->m_Header.m_timedate; - } - - // build time/date - m_Header.dwTimeDate = (uint32)CurrentTime; - - // TODO: generate valid addr if necessary - m_Header.dwNonKernelImportDirAddr = 0; - - // TODO: generate these values - m_Header.dwLibraryVersions = 0; - m_Header.dwLibraryVersionsAddr = 0; - m_Header.dwKernelLibraryVersionAddr = 0; - m_Header.dwXAPILibraryVersionAddr = 0; - } - - printf("OK\n"); - - printf("Xbe::Xbe: Pass 2 (Calculating Requirements)..."); - - // pass 2 - { - // make-room cursor - uint32 mrc = m_Header.dwBaseAddr + sizeof(m_Header); - - // make room for certificate - { - m_Header.dwCertificateAddr = mrc; - - mrc += sizeof(m_Certificate); - } - - // make room for section headers - { - m_Header.dwSectionHeadersAddr = mrc; - - mrc += m_Header.dwSections * (sizeof(*m_SectionHeader)); - - // make room for head/tail reference count words - mrc += (m_Header.dwSections+1)*2; - - // make room for section names - for(uint32 v=0;vm_SectionHeader[v].m_name[s] != '\0') - s++; - - mrc += s + 1; - } - } - - // TODO: make room for library versions - { - } - - // make room for debug path / debug file names - { - // TODO: allow this to be configured, right now we will just null out these values - m_Header.dwDebugUnicodeFilenameAddr = mrc; - m_Header.dwDebugPathnameAddr = mrc; - m_Header.dwDebugFilenameAddr = mrc; - - mrc += 2; - } - - // make room for largest possible logo bitmap - { - mrc = RoundUp(mrc, 0x10); - - m_Header.dwLogoBitmapAddr = mrc; - m_Header.dwSizeofLogoBitmap = 100*17; // Max Possible - - mrc += m_Header.dwSizeofLogoBitmap; - } - - // update size of headers - m_Header.dwSizeofHeaders = mrc - m_Header.dwBaseAddr; - } - - printf("OK\n"); - - printf("Xbe::Xbe: Pass 3 (Generating Xbe)...\n"); - - // pass 3 - { - m_Header.dwPeBaseAddr = m_Header.dwBaseAddr + RoundUp(m_Header.dwSizeofHeaders, 0x1000) - x_Exe->m_SectionHeader[0].m_virtual_addr; - - // encode entry point - { - printf("Xbe::Xbe: Encoding %s Entry Point...", x_bRetail?"Retail":"Debug"); - - uint32 ep = x_Exe->m_OptionalHeader.m_entry + m_Header.dwPeBaseAddr; - - if(x_bRetail) - ep ^= XOR_EP_RETAIL; - else - ep ^= XOR_EP_DEBUG; - - m_Header.dwEntryAddr = ep; - - printf("OK (0x%.08X)\n", ep); - } - - // header write cursor - uint32 hwc = m_Header.dwBaseAddr + sizeof(m_Header); - - // check if we need to store extra header bytes (we always will) - if(m_Header.dwSizeofHeaders > sizeof(m_Header)) - { - printf("Xbe::Xbe: Found Extra Header Bytes..."); - - uint32 ExSize = RoundUp(m_Header.dwSizeofHeaders - sizeof(m_Header), 0x1000); - - m_HeaderEx = new char[ExSize]; - - printf("OK\n"); - } - - // start a write buffer inside of m_HeaderEx - char *szBuffer = m_HeaderEx; - - // write certificate - { - // certificate size is a constant - m_Certificate.dwSize = sizeof(m_Certificate); - - m_Certificate.dwTimeDate = (uint32)CurrentTime; - - // TODO: generate in the form CX-9999 - m_Certificate.dwTitleId = 0xFFFF0002; - - // title name - memset(m_Certificate.wszTitleName, 0, 40 * sizeof(wchar_t)); - mbstowcs(m_Certificate.wszTitleName, x_szTitle, 40); - - // zero out alternate ids - { - for(uint32 c=0;c<0x10;c++) - m_Certificate.dwAlternateTitleId[c] = 0; - } - - // for now we'll just allow any media you could want - m_Certificate.dwAllowedMedia = XBEIMAGE_MEDIA_TYPE_HARD_DISK | XBEIMAGE_MEDIA_TYPE_DVD_CD | XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD; - - // TODO: allow configuration - m_Certificate.dwGameRegion = XBEIMAGE_GAME_REGION_MANUFACTURING | XBEIMAGE_GAME_REGION_NA | XBEIMAGE_GAME_REGION_JAPAN | XBEIMAGE_GAME_REGION_RESTOFWORLD; - - // TODO: allow configuration - m_Certificate.dwGameRatings = 0xFFFFFFFF; - - // always disk 0, AFAIK - m_Certificate.dwDiskNumber = 0; - - // TODO: allow configuration - m_Certificate.dwVersion = 0; - - // generate blank LAN, signature, and alternate signature keys - { - for(uint32 v=0;v<0x10;v++) - m_Certificate.bzLanKey[v] = m_Certificate.bzSignatureKey[v] = 0; - - for(uint32 x=0;x<0x10;x++) - for(uint32 y=0;y<0x10;y++) - m_Certificate.bzTitleAlternateSignatureKey[x][y] = 0; - - } - - // write certificate - { - memcpy(szBuffer, &m_Certificate, sizeof(m_Certificate)); - - szBuffer += sizeof(m_Certificate); - - hwc += sizeof(m_Certificate); - } - } - - // generate ascii title from certificate title name - setlocale( LC_ALL, "English" ); - wcstombs(m_szAsciiTitle, m_Certificate.wszTitleName, 40); - - // write section headers / section names - { - m_szSectionName = new char[m_Header.dwSections][9]; - - m_SectionHeader = new SectionHeader[m_Header.dwSections]; - - uint32 SectionCursor = RoundUp(m_Header.dwSizeofHeaders, 0x1000); - - // head/tail reference count write buffer - uint16 *htrc = (uint16*)(szBuffer + m_Header.dwSections*sizeof(*m_SectionHeader)); - - // section write buffer - char *secn = (char*)((uint32)htrc + (m_Header.dwSections+1)*2); - - // head/tail reference count write cursor - uint32 hwc_htrc = hwc + m_Header.dwSections*sizeof(*m_SectionHeader); - - // section write cursor - uint32 hwc_secn = hwc_htrc + (m_Header.dwSections+1)*2; - - printf("Xbe::Xbe: Generating Section Headers...\n"); - - for(uint32 v=0;vm_SectionHeader[v].m_characteristics; - - memset(&m_SectionHeader[v].dwFlags, 0, sizeof(m_SectionHeader->dwFlags)); - - if(characteristics & IMAGE_SCN_MEM_WRITE) - m_SectionHeader[v].dwFlags.bWritable = 1; - - if( (characteristics & IMAGE_SCN_MEM_EXECUTE) || (characteristics & IMAGE_SCN_CNT_CODE) ) - m_SectionHeader[v].dwFlags.bExecutable = 1; - - m_SectionHeader[v].dwFlags.bPreload = 1; - m_SectionHeader[v].dwVirtualAddr = x_Exe->m_SectionHeader[v].m_virtual_addr + m_Header.dwPeBaseAddr; - - if(v < m_Header.dwSections-1) - m_SectionHeader[v].dwVirtualSize = x_Exe->m_SectionHeader[v+1].m_virtual_addr - x_Exe->m_SectionHeader[v].m_virtual_addr; - else - m_SectionHeader[v].dwVirtualSize = RoundUp(x_Exe->m_SectionHeader[v].m_virtual_size, 4); - - m_SectionHeader[v].dwRawAddr = SectionCursor; - - // calculate sizeof_raw by locating the last non-zero value in the raw section data - { - uint32 r = x_Exe->m_SectionHeader[v].m_sizeof_raw - 1; - - while(r > 0) - { - if(x_Exe->m_bzSection[v][r--] != 0) - break; - } - - // word aligned - m_SectionHeader[v].dwSizeofRaw = RoundUp(r+2, 4); - } - - SectionCursor += RoundUp(m_SectionHeader[v].dwSizeofRaw, 0x1000); - - // head/tail reference count - { - m_SectionHeader[v].dwHeadSharedRefCountAddr = hwc_htrc; - htrc[v] = 0; - - hwc_htrc += 2; - - m_SectionHeader[v].dwTailSharedRefCountAddr = hwc_htrc; - htrc[v+1] = 0; - } - - // section name - { - uint32 s = 0; - - memset(secn, 0, 8); - - m_SectionHeader[v].dwSectionNameAddr = hwc_secn; - while(s < 8 && x_Exe->m_SectionHeader[v].m_name[s] != '\0') - { - m_szSectionName[v][s] = secn[s] = x_Exe->m_SectionHeader[v].m_name[s]; - s++; - } - - m_szSectionName[v][s] = '\0'; - - secn += s+1; - hwc_secn += s+1; - } - - m_SectionHeader[v].dwSectionRefCount = 0; - - // write section digest (just zeros) - memset(m_SectionHeader[v].bzSectionDigest, 0, 20); - - // write section header - memcpy(szBuffer, &m_SectionHeader[v], sizeof(*m_SectionHeader)); - - szBuffer += sizeof(*m_SectionHeader); - - printf("OK\n"); - } - - hwc = hwc_secn; - } - - // write debug path / debug file names - { - *(uint16*)szBuffer = 0x0000; - - szBuffer += 2; - hwc += 2; - } - - // write default "OpenXDK" logo bitmap - { - printf("Xbe::Xbe: Generating \"OpenXDK\" Logo Bitmap..."); - - uint08 *RawAddr = GetAddr(m_Header.dwLogoBitmapAddr); - - memset(RawAddr, 0, 100*17); - - memcpy(RawAddr, OpenXDK, dwSizeOfOpenXDK); - - m_Header.dwSizeofLogoBitmap = dwSizeOfOpenXDK; - - printf("OK\n"); - } - - // write sections - { - printf("Xbe::Xbe: Generating Sections...\n"); - - m_bzSection = new uint08*[m_Header.dwSections]; - - memset(m_bzSection, 0, m_Header.dwSections); - - for(uint32 v=0;vm_bzSection[v], RawSize); - - printf("OK\n"); - } - } - } - - printf("Xbe::Xbe: Pass 4 (Finalizing)...\n"); - - // pass 4 - { - m_Header.dwSizeofImage = m_SectionHeader[m_Header.dwSections-1].dwVirtualAddr + m_SectionHeader[m_Header.dwSections-1].dwVirtualSize - m_Header.dwBaseAddr; - - m_Header.dwTLSAddr = 0; - - // relocate to base : 0x00010000 - { - printf("Xbe::Xbe: Relocating to Base 0x00010000..."); - - uint32 fixCount = 0; - - uint32 relo_addr = x_Exe->m_OptionalHeader.m_image_data_directory[5].m_virtual_addr; - uint32 relo_size = x_Exe->m_OptionalHeader.m_image_data_directory[5].m_size; - - uint32 dwBaseDiff = m_Header.dwPeBaseAddr - x_Exe->m_OptionalHeader.m_image_base; - - uint08 *reloc = GetAddr(relo_addr + m_Header.dwPeBaseAddr); - - // relocate, if necessary - if(reloc != 0) - { - uint32 v = 0; - - // relocate each relocation block - while(v < relo_size) - { - uint32 block_addr = *(uint32 *)&reloc[v+0]; - uint32 block_stop = *(uint32 *)&reloc[v+4] + v; - - v += 8; - - // relocate each rva - while(v < block_stop && v < relo_size) - { - uint16 data = *(uint16 *)&reloc[v]; - - uint32 type = (data & 0xF000) >> 12; - - if(type == 0) - { - v+=2; - break; - } - - // 32-bit field relocation - if(type == IMAGE_REL_BASED_HIGHLOW) - { - fixCount++; - - uint32 dwFixAddr = block_addr + (data & 0x0FFF) + m_Header.dwPeBaseAddr; - - uint08 *bzModRVA = GetAddr(dwFixAddr); - - if(bzModRVA != 0) - *(uint32*)bzModRVA += dwBaseDiff; - } - else - { - SetError("Unsupported relocation type", true); - goto cleanup; - } - - v+=2; - } - } - } - - printf("OK (%d Fixups)\n", fixCount); - } - - // locate kernel thunk table - { - // unfortunately, GCC doesn't populate the IAT entry in the data directory - // so if the value is 0, then it could mean there are no imports, or it - // could mean the EXE was compiled by GCC - uint32 ktRVA = x_Exe->m_OptionalHeader.m_image_data_directory[12].m_virtual_addr; - - if(ktRVA == 0) - { - // lets check to see if there is an import section. if so, look at offset 16 - // for the RVA of the Import Address Table - uint32 importRVA = x_Exe->m_OptionalHeader.m_image_data_directory[1].m_virtual_addr; - - if(importRVA != 0) - { - uint08 *importSection = GetAddr(importRVA + m_Header.dwPeBaseAddr); - - ktRVA = *(uint32 *)&importSection[16]; - } - } - - uint32 kt = ktRVA + m_Header.dwPeBaseAddr; - - kt ^= (x_bRetail ? XOR_KT_RETAIL : XOR_KT_DEBUG ); - - m_Header.dwKernelImageThunkAddr = kt; - } - } - -cleanup: - - if(GetError() != 0) - { - printf("FAILED!\n"); - printf("Xbe::Xbe: ERROR -> %s\n", GetError()); - } - - return; -} - // deconstructor Xbe::~Xbe() { diff --git a/src/Common/Xbe.h b/src/Common/Xbe.h index 8f84804b5..1f24cb25f 100644 --- a/src/Common/Xbe.h +++ b/src/Common/Xbe.h @@ -49,10 +49,7 @@ class Xbe : public Error public: // construct via Xbe file Xbe(const char *x_szFilename); - - // construct via Exe file object - Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail); - + // deconstructor ~Xbe(); diff --git a/src/Cxbx/EmuExe.cpp b/src/Cxbx/EmuExe.cpp deleted file mode 100644 index 3d0d5f292..000000000 --- a/src/Cxbx/EmuExe.cpp +++ /dev/null @@ -1,702 +0,0 @@ -// ****************************************************************** -// * -// * .,-::::: .,:: .::::::::. .,:: .: -// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; -// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' -// * $$$ Y$$$P $$""""Y$$ Y$$$P -// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, -// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, -// * -// * Cxbx->Win32->Cxbx->EmuExe.cpp -// * -// * This file is part of the Cxbx project. -// * -// * Cxbx and Cxbe are free software; you can redistribute them -// * and/or modify them under the terms of the GNU General Public -// * License as published by the Free Software Foundation; either -// * version 2 of the license, or (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have recieved a copy of the GNU General Public License -// * along with this program; see the file COPYING. -// * If not, write to the Free Software Foundation, Inc., -// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. -// * -// * (c) 2002-2003 Aaron Robinson -// * -// * All rights reserved -// * -// ****************************************************************** - -#include "EmuExe.h" -#include "Prolog.h" -#include "CxbxUtil.h" -#include "CxbxKrnl/CxbxKrnl.h" - -#include - -// ****************************************************************** -// * constructor -// ****************************************************************** -EmuExe::EmuExe(Xbe *x_Xbe, DebugMode x_debug_mode, char *x_debug_filename, HWND hwndParent) : Exe() -{ - ConstructorInit(); - - printf("EmuExe::EmuExe: Generating Exe file...\n"); - - // ****************************************************************** - // * generate pe header - // ****************************************************************** - { - printf("EmuExe::EmuExe: Generating PE header..."); - - m_Header.m_magic = *(uint32 *)"PE\0\0"; // magic number : "PE\0\0" - m_Header.m_machine = IMAGE_FILE_MACHINE_I386; // machine type : i386 - m_Header.m_sections = (uint16)(x_Xbe->m_Header.dwSections + 2); // xbe sections + .cxbximp + .cxbxplg - m_Header.m_timedate = x_Xbe->m_Header.dwTimeDate; // time/date stamp - m_Header.m_symbol_table_addr = 0; // unused - m_Header.m_symbols = 0; // unused - m_Header.m_sizeof_optional_header = sizeof(OptionalHeader); // size of optional header - m_Header.m_characteristics = 0x012F; // should be fine.. - - printf("OK\n"); - } - - // ****************************************************************** - // * generate optional header - // ****************************************************************** - { - printf("EmuExe::EmuExe: Generating Optional Header..."); - - m_OptionalHeader.m_magic = 0x010B; // magic number : 0x010B - - // ****************************************************************** - // * abitrary linker version : 6.0 - // ****************************************************************** - m_OptionalHeader.m_linker_version_major = 0x06; - m_OptionalHeader.m_linker_version_minor = 0x00; - - // ****************************************************************** - // * size of headers - // ****************************************************************** - m_OptionalHeader.m_sizeof_headers = sizeof(bzDOSStub) + sizeof(m_Header); - m_OptionalHeader.m_sizeof_headers += sizeof(m_OptionalHeader) + sizeof(*m_SectionHeader)*m_Header.m_sections; - m_OptionalHeader.m_sizeof_headers = RoundUp(m_OptionalHeader.m_sizeof_headers, PE_FILE_ALIGN); - - m_OptionalHeader.m_image_base = x_Xbe->m_Header.dwBaseAddr; - - m_OptionalHeader.m_section_alignment = PE_SEGM_ALIGN; - m_OptionalHeader.m_file_alignment = PE_FILE_ALIGN; - - // ****************************************************************** - // * OS version : 4.0 - // ****************************************************************** - m_OptionalHeader.m_os_version_major = 0x0004; - m_OptionalHeader.m_os_version_minor = 0x0000; - - // ****************************************************************** - // * image version : 0.0 - // ****************************************************************** - m_OptionalHeader.m_image_version_major = 0x0000; - m_OptionalHeader.m_image_version_minor = 0x0000; - - // ****************************************************************** - // * subsystem version : 4.0 - // ****************************************************************** - m_OptionalHeader.m_subsystem_version_major = 0x0004; - m_OptionalHeader.m_subsystem_version_minor = 0x0000; - - m_OptionalHeader.m_win32_version = 0x00000000; - m_OptionalHeader.m_checksum = 0x00000000; - m_OptionalHeader.m_subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI; - - // ****************************************************************** - // * no special dll characteristics are necessary - // ****************************************************************** - m_OptionalHeader.m_dll_characteristics = 0x0000; - - // ****************************************************************** - // * TODO: for each of these, check for bad values and correct them - // ****************************************************************** - m_OptionalHeader.m_sizeof_stack_reserve = 0x00100000; - m_OptionalHeader.m_sizeof_stack_commit = x_Xbe->m_Header.dwPeStackCommit; - m_OptionalHeader.m_sizeof_heap_reserve = x_Xbe->m_Header.dwPeHeapReserve; - m_OptionalHeader.m_sizeof_heap_commit = x_Xbe->m_Header.dwPeHeapCommit; - - // ****************************************************************** - // * this member is obsolete, so we'll just set it to zero - // ****************************************************************** - m_OptionalHeader.m_loader_flags = 0x00000000; - - // ****************************************************************** - // * we'll set this to the typical 0x10 (16) - // ****************************************************************** - m_OptionalHeader.m_data_directories = 0x10; - - // ****************************************************************** - // * clear all data directories (we'll setup some later) - // ****************************************************************** - for(uint32 d=0;dm_SectionHeader[0].dwRawAddr; - - // ****************************************************************** - // * generate xbe section headers - // ****************************************************************** - { - for(uint32 v=0;vm_Header.dwSections;v++) - { - printf("EmuExe::EmuExe: Generating Section Header 0x%.04X...", v); - - // ****************************************************************** - // * generate xbe section name - // ****************************************************************** - { - memset(m_SectionHeader[v].m_name, 0, 8); - - for(int c=0;c<8;c++) - { - m_SectionHeader[v].m_name[c] = x_Xbe->m_szSectionName[v][c]; - - if(m_SectionHeader[v].m_name[c] == '\0') - break; - } - } - - // ****************************************************************** - // * generate xbe section virtual size / addr - // ****************************************************************** - { - uint32 VirtSize = x_Xbe->m_SectionHeader[v].dwVirtualSize; - uint32 VirtAddr = x_Xbe->m_SectionHeader[v].dwVirtualAddr - x_Xbe->m_Header.dwBaseAddr; - - m_SectionHeader[v].m_virtual_size = VirtSize; - m_SectionHeader[v].m_virtual_addr = VirtAddr; - } - - // ****************************************************************** - // * generate xbe section raw size / addr - // ****************************************************************** - { - // TODO: get this working such that m_sizeof_raw can be the actual raw size, not virtual size - uint32 RawSize = RoundUp(x_Xbe->m_SectionHeader[v].dwVirtualSize, PE_FILE_ALIGN); - uint32 RawAddr = dwSectionCursor; - - m_SectionHeader[v].m_sizeof_raw = RawSize; - m_SectionHeader[v].m_raw_addr = RawAddr; - - dwSectionCursor += RawSize; - } - - // ****************************************************************** - // * relocation / line numbers will not exist - // ****************************************************************** - { - m_SectionHeader[v].m_relocations_addr = 0; - m_SectionHeader[v].m_linenumbers_addr = 0; - - m_SectionHeader[v].m_relocations = 0; - m_SectionHeader[v].m_linenumbers = 0; - } - - // ****************************************************************** - // * generate flags for this xbe section - // ****************************************************************** - { - uint32 flags = IMAGE_SCN_MEM_READ; - - if(x_Xbe->m_SectionHeader[v].dwFlags.bExecutable) - { - flags |= IMAGE_SCN_MEM_EXECUTE; - flags |= IMAGE_SCN_CNT_CODE; - } - else - { - flags |= IMAGE_SCN_CNT_INITIALIZED_DATA; - } - - if(x_Xbe->m_SectionHeader[v].dwFlags.bWritable) - flags |= IMAGE_SCN_MEM_WRITE; - - m_SectionHeader[v].m_characteristics = flags; - } - - printf("OK\n"); - } - } - - // ****************************************************************** - // * generate .cxbximp section header - // ****************************************************************** - { - uint32 i = m_Header.m_sections - 2; - - printf("EmuExe::EmuExe: Generating Section Header 0x%.04X (.cxbximp)...", i); - - memcpy(m_SectionHeader[i].m_name, ".cxbximp", 8); - - // ****************************************************************** - // * generate .cxbximp section virtual size / addr - // ****************************************************************** - { - uint32 virt_size = RoundUp(0x6E, PE_SEGM_ALIGN); - uint32 virt_addr = RoundUp(m_SectionHeader[i-1].m_virtual_addr + m_SectionHeader[i-1].m_virtual_size, PE_SEGM_ALIGN); - - m_SectionHeader[i].m_virtual_size = virt_size; - m_SectionHeader[i].m_virtual_addr = virt_addr; - } - - // ****************************************************************** - // * generate .cxbximp section raw size / addr - // ****************************************************************** - { - uint32 raw_size = RoundUp(m_SectionHeader[i].m_virtual_size, PE_FILE_ALIGN); - - m_SectionHeader[i].m_sizeof_raw = raw_size; - m_SectionHeader[i].m_raw_addr = dwSectionCursor; - - dwSectionCursor += raw_size; - } - - // ****************************************************************** - // * relocation / line numbers will not exist - // ****************************************************************** - { - m_SectionHeader[i].m_relocations_addr = 0; - m_SectionHeader[i].m_linenumbers_addr = 0; - - m_SectionHeader[i].m_relocations = 0; - m_SectionHeader[i].m_linenumbers = 0; - } - - // ****************************************************************** - // * make this section readable initialized data - // ****************************************************************** - m_SectionHeader[i].m_characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA; - - // ****************************************************************** - // * update import table directory entry - // ****************************************************************** - m_OptionalHeader.m_image_data_directory[IMAGE_DIRECTORY_ENTRY_IMPORT].m_virtual_addr = m_SectionHeader[i].m_virtual_addr + 0x08; - m_OptionalHeader.m_image_data_directory[IMAGE_DIRECTORY_ENTRY_IMPORT].m_size = 0x28; - - // ****************************************************************** - // * update import address table directory entry - // ****************************************************************** - m_OptionalHeader.m_image_data_directory[IMAGE_DIRECTORY_ENTRY_IAT].m_virtual_addr = m_SectionHeader[i].m_virtual_addr; - m_OptionalHeader.m_image_data_directory[IMAGE_DIRECTORY_ENTRY_IAT].m_size = 0x08; - - printf("OK\n"); - } - - // ****************************************************************** - // * generate .cxbxplg section header - // ****************************************************************** - { - uint32 i = m_Header.m_sections - 1; - - printf("EmuExe::EmuExe: Generating Section Header 0x%.04X (.cxbxplg)...", i); - - memcpy(m_SectionHeader[i].m_name, ".cxbxplg", 8); - - // ****************************************************************** - // * generate .cxbxplg section virtual size / addr - // ****************************************************************** - { - uint32 virt_size = RoundUp(m_OptionalHeader.m_image_base + 0x100 + x_Xbe->m_Header.dwSizeofHeaders + 260 - + sizeof(Xbe::LibraryVersion) * x_Xbe->m_Header.dwLibraryVersions + sizeof(Xbe::TLS) - + (x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr), 0x1000); - uint32 virt_addr = RoundUp(m_SectionHeader[i-1].m_virtual_addr + m_SectionHeader[i-1].m_virtual_size, PE_SEGM_ALIGN); - - m_SectionHeader[i].m_virtual_size = virt_size; - m_SectionHeader[i].m_virtual_addr = virt_addr; - - // our entry point should be the first bytes in this section - m_OptionalHeader.m_entry = virt_addr; - } - - // ****************************************************************** - // * generate .cxbxplg section raw size / addr - // ****************************************************************** - { - uint32 raw_size = RoundUp(m_SectionHeader[i].m_virtual_size, PE_FILE_ALIGN); - - m_SectionHeader[i].m_sizeof_raw = raw_size; - m_SectionHeader[i].m_raw_addr = dwSectionCursor; - - dwSectionCursor += raw_size; - } - - // ****************************************************************** - // * relocation / line numbers will not exist - // ****************************************************************** - { - m_SectionHeader[i].m_relocations_addr = 0; - m_SectionHeader[i].m_linenumbers_addr = 0; - - m_SectionHeader[i].m_relocations = 0; - m_SectionHeader[i].m_linenumbers = 0; - } - - // ****************************************************************** - // * make this section readable and executable - // ****************************************************************** - m_SectionHeader[i].m_characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE; - - printf("OK\n"); - } - } - - // ****************************************************************** - // * generate sections - // ****************************************************************** - { - printf("EmuExe::EmuExe: Generating Sections...\n"); - - m_bzSection = new uint08*[m_Header.m_sections]; - - // ****************************************************************** - // * generate xbe sections - // ****************************************************************** - { - uint32 kt = x_Xbe->m_Header.dwKernelImageThunkAddr; - - // ****************************************************************** - // * decode kernel thunk address - // ****************************************************************** - { - if((kt ^ XOR_KT_DEBUG) > 0x01000000) - kt ^= XOR_KT_RETAIL; - else - kt ^= XOR_KT_DEBUG; - } - - // ****************************************************************** - // * generate xbe sections - // ****************************************************************** - for(uint32 v=0;vm_Header.dwSections;v++) - { - printf("EmuExe::EmuExe: Generating Section 0x%.04X...", v); - - uint32 SectionSize = m_SectionHeader[v].m_sizeof_raw; - - m_bzSection[v] = new uint08[SectionSize]; - - memset(m_bzSection[v], 0, SectionSize); - - memcpy(m_bzSection[v], x_Xbe->m_bzSection[v], x_Xbe->m_SectionHeader[v].dwSizeofRaw); - - printf("OK\n"); - } - - } - - // ****************************************************************** - // * generate .cxbximp section - // ****************************************************************** - { - uint32 i = m_Header.m_sections - 2; - - printf("EmuExe::EmuExe: Generating Section 0x%.04X (.cxbximp)...", i); - - uint32 dwVirtAddr = m_SectionHeader[i].m_virtual_addr; - - uint32 dwRawSize = m_SectionHeader[i].m_sizeof_raw; - - m_bzSection[i] = new uint08[dwRawSize]; - - memset(m_bzSection[i], 0, dwRawSize); - - *(uint32*)&m_bzSection[i][0x00] = dwVirtAddr + 0x38; - *(uint32*)&m_bzSection[i][0x04] = 0; - *(uint32*)&m_bzSection[i][0x08] = dwVirtAddr + 0x30; - *(uint32*)&m_bzSection[i][0x0C] = 0; - - *(uint32*)&m_bzSection[i][0x10] = 0; - *(uint32*)&m_bzSection[i][0x14] = dwVirtAddr + 0x4A; - *(uint32*)&m_bzSection[i][0x18] = dwVirtAddr + 0x00; - *(uint32*)&m_bzSection[i][0x1C] = 0; - - *(uint32*)&m_bzSection[i][0x20] = 0; - *(uint32*)&m_bzSection[i][0x24] = 0; - *(uint32*)&m_bzSection[i][0x28] = 0; - *(uint32*)&m_bzSection[i][0x2C] = 0; - - *(uint32*)&m_bzSection[i][0x30] = dwVirtAddr + 0x38; - *(uint32*)&m_bzSection[i][0x34] = 0; - *(uint16*)&m_bzSection[i][0x38] = 0x0001; - - memcpy(&m_bzSection[i][0x3A], "CxbxKrnlNoFunc\0\0CxbxKrnl.dll\0\0", 30); - - printf("OK\n"); - } - - // ****************************************************************** - // * generate .cxbxplg section - // ****************************************************************** - { - uint32 ep = x_Xbe->m_Header.dwEntryAddr; - uint32 i = m_Header.m_sections - 1; - - printf("EmuExe::EmuExe: Generating Section 0x%.04X (.cxbxplg)...", i); - - // ****************************************************************** - // * decode entry point - // ****************************************************************** - if( (ep ^ XOR_EP_RETAIL) > 0x01000000) - ep ^= XOR_EP_DEBUG; - else - ep ^= XOR_EP_RETAIL; - - m_bzSection[i] = new uint08[m_SectionHeader[i].m_sizeof_raw]; - - uint08 *pWriteCursor = m_bzSection[i]; - - // ****************************************************************** - // * append prolog section - // ****************************************************************** - memcpy(pWriteCursor, Prolog, 0x1000); - pWriteCursor += 0x100; - - // ****************************************************************** - // * append xbe header - // ****************************************************************** - memcpy(pWriteCursor, &x_Xbe->m_Header, sizeof(Xbe::Header)); - pWriteCursor += sizeof(Xbe::Header); - - // ****************************************************************** - // * append xbe extra header bytes - // ****************************************************************** - memcpy(pWriteCursor, x_Xbe->m_HeaderEx, x_Xbe->m_Header.dwSizeofHeaders - sizeof(Xbe::Header)); - pWriteCursor -= sizeof(Xbe::Header); - pWriteCursor += x_Xbe->m_Header.dwSizeofHeaders; - - // ****************************************************************** - // * append x_debug_filename - // ****************************************************************** - memcpy(pWriteCursor, x_debug_filename, 260); - pWriteCursor += 260; - - // ****************************************************************** - // * append library versions - // ****************************************************************** - if(x_Xbe->m_LibraryVersion != 0) - { - memcpy(pWriteCursor, x_Xbe->m_LibraryVersion, sizeof(Xbe::LibraryVersion) * x_Xbe->m_Header.dwLibraryVersions); - pWriteCursor += sizeof(Xbe::LibraryVersion) * x_Xbe->m_Header.dwLibraryVersions; - } - - // ****************************************************************** - // * append TLS data - // ****************************************************************** - if(x_Xbe->m_TLS != 0) - { - memcpy(pWriteCursor, x_Xbe->m_TLS, sizeof(Xbe::TLS)); - pWriteCursor += sizeof(Xbe::TLS); - memcpy(pWriteCursor, x_Xbe->GetTLSData(), x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr); - pWriteCursor += x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr; - } - - // ****************************************************************** - // * patch prolog function parameters - // ****************************************************************** - uint32 WriteCursor = m_SectionHeader[i].m_virtual_addr + m_OptionalHeader.m_image_base + 0x100; - - // Function Pointer - *(uint32 *)((uint32)m_bzSection[i] + 1) = (uint32)CxbxKrnlInit; - - // Param 8 : Entry - *(uint32 *)((uint32)m_bzSection[i] + 6) = (uint32)ep; - - // Param 7 : dwXbeHeaderSize - *(uint32 *)((uint32)m_bzSection[i] + 11) = (uint32)x_Xbe->m_Header.dwSizeofHeaders; - - // Param 6 : pXbeHeader - *(uint32 *)((uint32)m_bzSection[i] + 16) = WriteCursor; - WriteCursor += x_Xbe->m_Header.dwSizeofHeaders; - - // Param 5 : szDebugFilename - *(uint32 *)((uint32)m_bzSection[i] + 21) = WriteCursor; - WriteCursor += 260; - - // Param 4 : DbgMode - *(uint32 *)((uint32)m_bzSection[i] + 26) = x_debug_mode; - - // Param 3 : pLibraryVersion - if(x_Xbe->m_LibraryVersion != 0) - { - *(uint32 *)((uint32)m_bzSection[i] + 31) = WriteCursor; - WriteCursor += sizeof(Xbe::LibraryVersion) * x_Xbe->m_Header.dwLibraryVersions; - } - else - { - *(uint32 *)((uint32)m_bzSection[i] + 31) = 0; - } - - // Param 2 : pTLS - if(x_Xbe->m_TLS != 0) - { - *(uint32 *)((uint32)m_bzSection[i] + 36) = WriteCursor; - WriteCursor += sizeof(Xbe::TLS); - } - else - { - *(uint32 *)((uint32)m_bzSection[i] + 36) = 0; - } - - // Param 1 : pTLSData - if(x_Xbe->m_TLS != 0) - { - *(uint32 *)((uint32)m_bzSection[i] + 41) = WriteCursor; - WriteCursor += x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr; - } - else - { - *(uint32 *)((uint32)m_bzSection[i] + 41) = 0; - } - - // Param 0 : hwndParent - *(uint32 *)((uint32)m_bzSection[i] + 46) = (uint32)hwndParent; - - printf("OK\n"); - } - } - - // ****************************************************************** - // * patch kernel thunk table - // ****************************************************************** - { - printf("EmuExe::EmuExe: Hijacking Kernel Imports...\n"); - - uint32 kt = x_Xbe->m_Header.dwKernelImageThunkAddr; - - // ****************************************************************** - // * decode kernel thunk address - // ****************************************************************** - { - if( (kt ^ XOR_KT_DEBUG) > 0x01000000) - kt ^= XOR_KT_RETAIL; - else - kt ^= XOR_KT_DEBUG; - } - - // ****************************************************************** - // * locate section containing kernel thunk table - // ****************************************************************** - for(uint32 v=0;vm_Header.dwSections;v++) - { - uint32 imag_base = m_OptionalHeader.m_image_base; - - uint32 virt_addr = m_SectionHeader[v].m_virtual_addr; - uint32 virt_size = m_SectionHeader[v].m_virtual_size; - - // ****************************************************************** - // * modify kernel thunk table, if found - // ****************************************************************** - if(kt >= virt_addr + imag_base && kt < virt_addr + virt_size + imag_base) - { - printf("EmuExe::EmuExe: Located Thunk Table in Section 0x%.04X (0x%.08X)...\n", v, kt); - - uint32 *kt_tbl = (uint32*)&m_bzSection[v][kt - virt_addr - imag_base]; - - for(int k=0;kt_tbl[k] != 0;k++) - { - int t = kt_tbl[k] & 0x7FFFFFFF; - - kt_tbl[k] = CxbxKrnl_KernelThunkTable[t]; - - if(t != -1) - printf("EmuExe::EmuExe: Thunk %.03d : *0x%.08X := 0x%.08X\n", t, kt + k*4, kt_tbl[k]); - } - - break; - } - } - } - - // ****************************************************************** - // * update imcomplete header fields - // ****************************************************************** - { - printf("EmuExe::EmuExe: Finalizing Exe file..."); - - // ****************************************************************** - // * calculate size of code / data / image - // ****************************************************************** - { - uint32 sizeof_code = 0; - uint32 sizeof_data = 0; - uint32 sizeof_undata = 0; - uint32 sizeof_image = 0; - - for(uint32 v=0;vWin32->Cxbx->EmuExe.h -// * -// * This file is part of the Cxbx project. -// * -// * Cxbx and Cxbe are free software; you can redistribute them -// * and/or modify them under the terms of the GNU General Public -// * License as published by the Free Software Foundation; either -// * version 2 of the license, or (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have recieved a copy of the GNU General Public License -// * along with this program; see the file COPYING. -// * If not, write to the Free Software Foundation, Inc., -// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. -// * -// * (c) 2002-2003 Aaron Robinson -// * -// * All rights reserved -// * -// ****************************************************************** -#ifndef EMUEXE_H -#define EMUEXE_H - -#include "Common/Exe.h" -#include - -// ****************************************************************** -// * class : EmuExe -// ****************************************************************** -class EmuExe : public Exe -{ - public: - // ****************************************************************** - // * Construct via Xbe file object - // ****************************************************************** - EmuExe(class Xbe *x_Xbe, DebugMode x_debug_mode, char *x_debug_filename, HWND hwndParent = NULL); -}; - -#endif diff --git a/src/Cxbx/ResCxbx.h b/src/Cxbx/ResCxbx.h index 22e453ee9..98b038ce6 100644 --- a/src/Cxbx/ResCxbx.h +++ b/src/Cxbx/ResCxbx.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by C:\Users\Brandon\Desktop\Cxbx\dstien\wip\resource\Cxbx.rc +// Used by S:\GitHub\Cxbx-Reloaded\resource\Cxbx.rc // #define IDI_CXBX 101 #define IDB_SPLASH 102 @@ -52,7 +52,6 @@ #define ID_FILE_EXIT 40005 #define ID_HELP_ABOUT 40008 #define ID_EMULATION_START 40009 -#define ID_FILE_EXPORTTOEXE 40011 #define ID_FILE_OPEN_XBE 40013 #define ID_FILE_CLOSE_XBE 40014 #define ID_HELP_HOMEPAGE 40019 @@ -62,7 +61,6 @@ #define ID_EDIT_LOGOBITMAP_IMPORT 40026 #define ID_EDIT_PATCH_ALLOW64MB 40027 #define ID_EDIT_PATCH_DEBUGMODE 40031 -#define ID_FILE_IMPORTFROMEXE 40032 #define ID_EMULATION_DEBUGOUTPUTGUI_CONSOLE 40035 #define ID_EMULATION_DEBUGOUTPUTGUI_FILE 40036 #define ID_EMULATION_DEBUGOUTPUTKERNEL_CONSOLE 40037 @@ -80,22 +78,10 @@ #define ID_FILE_RXBE_7 40057 #define ID_FILE_RXBE_8 40058 #define ID_FILE_RXBE_9 40059 -#define ID_FILE_REXE_0 40060 -#define ID_FILE_REXE_1 40061 -#define ID_FILE_REXE_2 40062 -#define ID_FILE_REXE_3 40063 -#define ID_FILE_REXE_4 40064 -#define ID_FILE_REXE_5 40065 -#define ID_FILE_REXE_6 40066 -#define ID_FILE_REXE_7 40067 -#define ID_FILE_REXE_8 40068 -#define ID_FILE_REXE_9 40069 #define ID_EDIT_DUMPXBEINFOTO_FILE 40071 #define ID_EDIT_DUMPXBEINFOTO_DEBUGCONSOLE 40072 -#define ID_SETTINGS_GENXP 40078 -#define ID_SETTINGS_GENWT 40079 -#define ID_SETTINGS_GENMA 40080 #define ID_EMULATION_STOP 40082 +#define IDC_STATIC -1 // Next default values for new objects // diff --git a/src/Cxbx/WinMain.cpp b/src/Cxbx/WinMain.cpp index a43bfb671..5afd251c0 100644 --- a/src/Cxbx/WinMain.cpp +++ b/src/Cxbx/WinMain.cpp @@ -34,8 +34,6 @@ #include "WndMain.h" -#include "Cxbx/EmuExe.h" - #include "CxbxKrnl/CxbxKrnl.h" #include "CxbxKrnl/Emu.h" #include "CxbxKrnl/EmuShared.h" @@ -73,7 +71,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine { MainWindow->OpenXbe(__argv[1]); - MainWindow->StartEmulation(AUTO_CONVERT_WINDOWS_TEMP, MainWindow->GetHwnd()); + MainWindow->StartEmulation(MainWindow->GetHwnd()); } /*! wait for window to be closed, or failure */ diff --git a/src/Cxbx/WndMain.cpp b/src/Cxbx/WndMain.cpp index b80b636fe..446d629fd 100644 --- a/src/Cxbx/WndMain.cpp +++ b/src/Cxbx/WndMain.cpp @@ -37,7 +37,6 @@ #include "DlgVideoConfig.h" #include "CxbxKrnl/EmuShared.h" #include "ResCxbx.h" -#include "EmuExe.h" #include "jpegdec/jpegdec.h" #include @@ -48,7 +47,7 @@ FILE _iob[] = { *stdin, *stdout, *stderr }; extern "C" FILE * __cdecl __iob_func(void) { return _iob; } -WndMain::WndMain(HINSTANCE x_hInstance) : Wnd(x_hInstance), m_bCreated(false), m_Xbe(0), m_Exe(0), m_bExeChanged(false), m_bXbeChanged(false), m_bCanStart(true), m_hwndChild(NULL), m_AutoConvertToExe(AUTO_CONVERT_WINDOWS_TEMP), m_KrnlDebug(DM_NONE), m_CxbxDebug(DM_NONE), m_dwRecentXbe(0), m_dwRecentExe(0) +WndMain::WndMain(HINSTANCE x_hInstance) : Wnd(x_hInstance), m_bCreated(false), m_Xbe(0), m_bXbeChanged(false), m_bCanStart(true), m_hwndChild(NULL), m_KrnlDebug(DM_NONE), m_CxbxDebug(DM_NONE), m_dwRecentXbe(0) { // initialize members { @@ -58,19 +57,13 @@ WndMain::WndMain(HINSTANCE x_hInstance) : Wnd(x_hInstance), m_bCreated(false), m m_w = 640; m_h = 480; - m_ExeFilename = (char*)calloc(1, MAX_PATH); m_XbeFilename = (char*)calloc(1, MAX_PATH); m_CxbxDebugFilename = (char*)calloc(1, MAX_PATH); m_KrnlDebugFilename = (char*)calloc(1, MAX_PATH); - int v=0; - - for(v=0;vm_Header.dwInitFlags.bLimit64MB = !m_Xbe->m_Header.dwInitFlags.bLimit64MB; @@ -826,7 +711,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP case ID_EDIT_PATCH_DEBUGMODE: { - m_bExeChanged = true; m_bXbeChanged = true; // patch to/from debug mode @@ -957,8 +841,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP MessageBox(m_hwnd, "This will not take effect until the next time emulation is started.\n", "Cxbx-Reloaded", MB_OK); - m_bExeChanged = true; - RefreshMenus(); UpdateDebugConsoles(); @@ -999,8 +881,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP strncpy(m_KrnlDebugFilename, ofn.lpstrFile, MAX_PATH-1); - m_bExeChanged = true; - m_KrnlDebug = DM_FILE; RefreshMenus(); @@ -1068,37 +948,13 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP break; case ID_EMULATION_START: - StartEmulation(m_AutoConvertToExe, hwnd); + StartEmulation(hwnd); break; case ID_EMULATION_STOP: StopEmulation(); break; - case ID_SETTINGS_GENWT: - { - m_AutoConvertToExe = AUTO_CONVERT_WINDOWS_TEMP; - - RefreshMenus(); - } - break; - - case ID_SETTINGS_GENXP: - { - m_AutoConvertToExe = AUTO_CONVERT_XBE_PATH; - - RefreshMenus(); - } - break; - - case ID_SETTINGS_GENMA: - { - m_AutoConvertToExe = AUTO_CONVERT_MANUAL; - - RefreshMenus(); - } - break; - case ID_HELP_ABOUT: { WndAbout *AboutWnd = new WndAbout(m_hInstance, m_hwnd); @@ -1239,27 +1095,15 @@ void WndMain::RefreshMenus() // enable/disable save .xbe file as EnableMenuItem(file_menu, ID_FILE_SAVEXBEFILEAS, MF_BYCOMMAND | ((m_Xbe == 0) ? MF_GRAYED : MF_ENABLED)); - - // enable/disable export to .exe - EnableMenuItem(file_menu, ID_FILE_EXPORTTOEXE, MF_BYCOMMAND | ((m_Xbe == 0) ? MF_GRAYED : MF_ENABLED)); - + // recent xbe files menu { - HMENU rxbe_menu = GetSubMenu(file_menu, 9); + HMENU rxbe_menu = GetSubMenu(file_menu, 6); int max = m_dwRecentXbe; for(int v=0;vGetError() != 0) - { - MessageBox(m_hwnd, i_exe->GetError(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); - - delete i_exe; - - return; - } - - m_Xbe = new Xbe(i_exe, "Untitled", true); - - if(m_Xbe->GetError() != 0) - { - MessageBox(m_hwnd, m_Xbe->GetError(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); - - delete m_Xbe; m_Xbe = 0; - - return; - } - - // save this exe to the list of recent exe files - if(m_ExeFilename[0] != '\0') - { - bool found = false; - - // if this filename already exists, temporarily remove it - for(int c=0, r=0;c m_dwRecentExe - 1) - m_szRecentExe[c] = 0; - else - strncpy(m_szRecentExe[c], m_szRecentExe[r], MAX_PATH-1); - } - } - - if(found) - m_dwRecentExe--; - - // move all items down one, removing the last one if necessary - for(int v=RECENT_EXE_SIZE-1;v>0;v--) - { - if(m_szRecentExe[v-1] == 0) - m_szRecentExe[v] = 0; - else - { - if(m_szRecentExe[v] == 0) - m_szRecentExe[v] = (char*)calloc(1, MAX_PATH); - strncpy(m_szRecentExe[v], m_szRecentExe[v-1], MAX_PATH-1); - } - } - - // add new item as first index - { - if(m_szRecentExe[0] == 0) - m_szRecentExe[0] = (char*)calloc(1, MAX_PATH); - - strcpy(m_szRecentExe[0], m_ExeFilename); - } - - if(m_dwRecentExe < RECENT_EXE_SIZE) - m_dwRecentExe++; - } - - UpdateRecentFiles(); - - XbeLoaded(); - - m_bExeChanged = true; -} - -// convert to exe file -bool WndMain::ConvertToExe(const char *x_filename, bool x_bVerifyIfExists, HWND hwndParent) -{ - char filename[MAX_PATH] = "default.exe"; - - if(x_filename == NULL) - { - OPENFILENAME ofn = {0}; - - SuggestFilename(m_XbeFilename, filename, ".exe"); - - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = m_hwnd; - ofn.lpstrFilter = "Windows Executables (*.exe)\0*.exe\0"; - ofn.lpstrFile = filename; - ofn.nMaxFile = MAX_PATH; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.lpstrDefExt = "exe"; - ofn.Flags = OFN_PATHMUSTEXIST; - - if(GetSaveFileName(&ofn) == FALSE) - return false; - - strcpy(filename, ofn.lpstrFile); - } - else - { - strcpy(filename, x_filename); - } - - // ask permission to overwrite if this file already exists - if(x_bVerifyIfExists) - { - if(_access(filename, 0) != -1) - { - if(MessageBox(m_hwnd, "Overwrite existing file?", "Cxbx-Reloaded", MB_ICONQUESTION | MB_YESNO) != IDYES) - return false; - } - } - - // convert file - { - EmuExe i_EmuExe(m_Xbe, m_KrnlDebug, m_KrnlDebugFilename, hwndParent); - - i_EmuExe.Export(filename); - - if(i_EmuExe.GetError() != 0) - { - MessageBox(m_hwnd, i_EmuExe.GetError(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK); - return false; - } - else - { - strcpy(m_ExeFilename, filename); - - printf("WndMain: %s was converted to .exe.\n", m_Xbe->m_szAsciiTitle); - - m_bExeChanged = false; - } - } - - return true; -} - // start emulation -void WndMain::StartEmulation(EnumAutoConvert x_AutoConvert, HWND hwndParent) +void WndMain::StartEmulation(HWND hwndParent) { char szBuffer[MAX_PATH]; diff --git a/src/Cxbx/WndMain.h b/src/Cxbx/WndMain.h index cdc776a7d..2eb3a8e30 100644 --- a/src/Cxbx/WndMain.h +++ b/src/Cxbx/WndMain.h @@ -35,24 +35,12 @@ #define WNDMAIN_H #include "Wnd.h" -#include "Common/Exe.h" #include "Common/Xbe.h" // ****************************************************************** // * constants // ****************************************************************** #define RECENT_XBE_SIZE 10 -#define RECENT_EXE_SIZE 10 - -// ****************************************************************** -// * AutoConvert methods -// ****************************************************************** -enum EnumAutoConvert -{ - AUTO_CONVERT_MANUAL = 0, - AUTO_CONVERT_XBE_PATH = 1, - AUTO_CONVERT_WINDOWS_TEMP = 2 -}; // ****************************************************************** // * class : WndMain @@ -77,15 +65,9 @@ class WndMain : public Wnd void SaveXbeAs(); // ****************************************************************** - // * Exe operations + // * start emulation // ****************************************************************** - void ImportExe(const char *x_filename); - bool ConvertToExe(const char *x_filename, bool x_bVerifyIfExists, HWND hwndParent); - - // ****************************************************************** - // * start emulation (converting to .exe if not done already) - // ****************************************************************** - void StartEmulation(EnumAutoConvert x_bAutoConvert, HWND hwndParent); + void StartEmulation(HWND hwndParent); // ****************************************************************** // * stop emulation (close existing child window) @@ -139,46 +121,32 @@ class WndMain : public Wnd HBITMAP m_LogoBmp; // ****************************************************************** - // * Xbe/Exe objects + // * Xbe objects // ****************************************************************** Xbe *m_Xbe; - Exe *m_Exe; // ****************************************************************** // * changes remembered for internal purposes // ****************************************************************** bool m_bXbeChanged; - bool m_bExeChanged; bool m_bCanStart; // ****************************************************************** // * cached filenames // ****************************************************************** char *m_XbeFilename; - char *m_ExeFilename; // ****************************************************************** // * cached child window handle // ****************************************************************** HWND m_hwndChild; - // ****************************************************************** - // * should emulation always auto-create the .exe? - // ****************************************************************** - EnumAutoConvert m_AutoConvertToExe; - // ****************************************************************** // * Recent Xbe files // ****************************************************************** int m_dwRecentXbe; char *m_szRecentXbe[RECENT_XBE_SIZE]; - // ****************************************************************** - // * Recent Exe files - // ****************************************************************** - int m_dwRecentExe; - char *m_szRecentExe[RECENT_EXE_SIZE]; - // ****************************************************************** // * is this window fully initialized? // ****************************************************************** diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index f99076360..36dd02e3e 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -444,9 +444,6 @@ extern "C" CXBXKRNL_API void CxbxKrnlInit IMAGE_SECTION_HEADER SectionHeader; } *PDUMMY_KERNEL; -#define XBOX_KERNEL_BASE 0x80010000 -#define XBOX_NV2A_INIT_VECTOR 0xFF000008 - PDUMMY_KERNEL DummyKernel = (PDUMMY_KERNEL)VirtualAlloc( (PVOID)XBOX_KERNEL_BASE, sizeof(DUMMY_KERNEL), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE @@ -491,7 +488,7 @@ extern "C" CXBXKRNL_API void CxbxKrnlInit CxbxRegisterDeviceNativePath(DeviceCdrom0, xbeDirectory); // Partition 0 contains configuration data, and is accessed as a native file, instead as a folder : - CxbxRegisterDeviceNativePath(DeviceHarddisk0Partition0, CxbxBasePath + "Partition0", true); /*IsFile=*/ + CxbxRegisterDeviceNativePath(DeviceHarddisk0Partition0, CxbxBasePath + "Partition0", /*IsFile=*/true); // The first two partitions are for Data and Shell files, respectively : CxbxRegisterDeviceNativePath(DeviceHarddisk0Partition1, CxbxBasePath + "Partition1"); CxbxRegisterDeviceNativePath(DeviceHarddisk0Partition2, CxbxBasePath + "Partition2"); @@ -514,10 +511,19 @@ extern "C" CXBXKRNL_API void CxbxKrnlInit // Determine Xbox path to XBE and place it in XeImageFileName std::string fileName(xbePath); + + // Strip out the path, leaving only the XBE file name + // NOTE: we assume that the XBE is always on the root of the C: drive + if (fileName.rfind('\\') >= 0) + fileName = fileName.substr(fileName.rfind('\\') + 1); + + if (xboxkrnl::XeImageFileName.Buffer != NULL) + free(xboxkrnl::XeImageFileName.Buffer); + + xboxkrnl::XeImageFileName.MaximumLength = MAX_PATH; xboxkrnl::XeImageFileName.Buffer = (PCHAR)malloc(MAX_PATH); sprintf(xboxkrnl::XeImageFileName.Buffer, "%c:\\%s", CxbxDefaultXbeVolumeLetter, fileName.c_str()); xboxkrnl::XeImageFileName.Length = (USHORT)strlen(xboxkrnl::XeImageFileName.Buffer); - xboxkrnl::XeImageFileName.MaximumLength = MAX_PATH; DbgPrintf("EmuMain : XeImageFileName = %s\n", xboxkrnl::XeImageFileName.Buffer); @@ -531,7 +537,7 @@ extern "C" CXBXKRNL_API void CxbxKrnlInit // Mount the Utility drive (Z:) conditionally : if (CxbxKrnl_XbeHeader->dwInitFlags.bMountUtilityDrive) - CxbxMountUtilityDrive(CxbxKrnl_XbeHeader->dwInitFlags.bFormatUtilityDrive);/*fFormatClean=*/ + CxbxMountUtilityDrive(/*formatClean=*/CxbxKrnl_XbeHeader->dwInitFlags.bFormatUtilityDrive); } // @@ -587,9 +593,9 @@ extern "C" CXBXKRNL_API void CxbxKrnlInit g_CPUOthers = g_CPUXbox; } - // Make sure Xbox1 code runs on one core : - SetThreadAffinityMask(GetCurrentThread(), g_CPUXbox); -} + // Make sure Xbox1 code runs on one core : + SetThreadAffinityMask(GetCurrentThread(), g_CPUXbox); + } DbgPrintf("EmuMain (0x%X): Initial thread starting.\n", GetCurrentThreadId()); diff --git a/src/CxbxKrnl/CxbxKrnl.h b/src/CxbxKrnl/CxbxKrnl.h index 89cbfe579..cedf156e7 100644 --- a/src/CxbxKrnl/CxbxKrnl.h +++ b/src/CxbxKrnl/CxbxKrnl.h @@ -48,6 +48,10 @@ extern "C" { #define XBOX_MEMORY_SIZE 128 * 1024 * 1024 +#define XBOX_KERNEL_BASE 0x80010000 +#define XBOX_NV2A_INIT_VECTOR 0xFF000008 + + /*! validate version string match */ CXBXKRNL_API bool CxbxKrnlVerifyVersion(const char *szVersion); diff --git a/src/CxbxKrnl/EmuFile.cpp b/src/CxbxKrnl/EmuFile.cpp index 7715ff7fe..c46ae1dbf 100644 --- a/src/CxbxKrnl/EmuFile.cpp +++ b/src/CxbxKrnl/EmuFile.cpp @@ -37,54 +37,60 @@ #include "EmuFile.h" #include #include +#include #include #include #pragma warning(disable:4005) // Ignore redefined status values #include #pragma warning(default:4005) #include "CxbxKrnl.h" +#include "EmuAlloc.h" //#include "Logging.h" // For hex4() -std::string DriveSerial = "\\??\\serial:"; -std::string DriveCdRom0 = "\\??\\CdRom0:"; // CD-ROM device -std::string DriveMbfs = "\\??\\mbfs:"; // media board's file system area device -std::string DriveMbcom = "\\??\\mbcom:"; // media board's communication area device -std::string DriveMbrom = "\\??\\mbrom:"; // media board's boot ROM device -std::string DriveC = "\\??\\C:"; // C: is HDD0 -std::string DriveD = "\\??\\D:"; // D: is DVD Player -std::string DriveE = "\\??\\E:"; -std::string DriveF = "\\??\\F:"; -std::string DriveT = "\\??\\T:"; // T: is Title persistent data region -std::string DriveU = "\\??\\U:"; // U: is User persistent data region -std::string DriveV = "\\??\\V:"; -std::string DriveW = "\\??\\W:"; -std::string DriveX = "\\??\\X:"; -std::string DriveY = "\\??\\Y:"; // Y: is Dashboard volume (contains "xboxdash.xbe" and "XDASH" folder + contents) -std::string DriveZ = "\\??\\Z:"; // Z: is Title utility data region -std::string DeviceCdrom0 = "\\Device\\CdRom0"; -std::string DeviceHarddisk0 = "\\Device\\Harddisk0"; -std::string DeviceHarddisk0Partition0 = "\\Device\\Harddisk0\\partition0"; // Contains raw config sectors (like XBOX_REFURB_INFO) + entire hard disk -std::string DeviceHarddisk0Partition1 = "\\Device\\Harddisk0\\partition1"; // Data partition. Contains TDATA and UDATA folders. -std::string DeviceHarddisk0Partition2 = "\\Device\\Harddisk0\\partition2"; // Shell partition. Contains Dashboard (cpxdash.xbe, evoxdash.xbe or xboxdash.xbe) -std::string DeviceHarddisk0Partition3 = "\\Device\\Harddisk0\\partition3"; // First cache partition. Contains cache data (from here up to largest number) -std::string DeviceHarddisk0Partition4 = "\\Device\\Harddisk0\\partition4"; -std::string DeviceHarddisk0Partition5 = "\\Device\\Harddisk0\\partition5"; -std::string DeviceHarddisk0Partition6 = "\\Device\\Harddisk0\\partition6"; -std::string DeviceHarddisk0Partition7 = "\\Device\\Harddisk0\\partition7"; -std::string DeviceHarddisk0Partition8 = "\\Device\\Harddisk0\\partition8"; -std::string DeviceHarddisk0Partition9 = "\\Device\\Harddisk0\\partition9"; -std::string DeviceHarddisk0Partition10 = "\\Device\\Harddisk0\\partition10"; -std::string DeviceHarddisk0Partition11 = "\\Device\\Harddisk0\\partition11"; -std::string DeviceHarddisk0Partition12 = "\\Device\\Harddisk0\\partition12"; -std::string DeviceHarddisk0Partition13 = "\\Device\\Harddisk0\\partition13"; -std::string DeviceHarddisk0Partition14 = "\\Device\\Harddisk0\\partition14"; -std::string DeviceHarddisk0Partition15 = "\\Device\\Harddisk0\\partition15"; -std::string DeviceHarddisk0Partition16 = "\\Device\\Harddisk0\\partition16"; -std::string DeviceHarddisk0Partition17 = "\\Device\\Harddisk0\\partition17"; -std::string DeviceHarddisk0Partition18 = "\\Device\\Harddisk0\\partition18"; -std::string DeviceHarddisk0Partition19 = "\\Device\\Harddisk0\\partition19"; -std::string DeviceHarddisk0Partition20 = "\\Device\\Harddisk0\\partition20"; // 20 = Largest possible partition number -char CxbxDefaultXbeVolumeLetter = 'C'; + +const std::string DrivePrefix = "\\??\\"; +const std::string DriveSerial = DrivePrefix + "serial:"; +const std::string DriveCdRom0 = DrivePrefix + "CdRom0:"; // CD-ROM device +const std::string DriveMbfs = DrivePrefix + "mbfs:"; // media board's file system area device +const std::string DriveMbcom = DrivePrefix + "mbcom:"; // media board's communication area device +const std::string DriveMbrom = DrivePrefix + "mbrom:"; // media board's boot ROM device +const std::string DriveC = DrivePrefix + "C:"; // C: is HDD0 +const std::string DriveD = DrivePrefix + "D:"; // D: is DVD Player +const std::string DriveE = DrivePrefix + "E:"; +const std::string DriveF = DrivePrefix + "F:"; +const std::string DriveT = DrivePrefix + "T:"; // T: is Title persistent data region +const std::string DriveU = DrivePrefix + "U:"; // U: is User persistent data region +const std::string DriveV = DrivePrefix + "V:"; +const std::string DriveW = DrivePrefix + "W:"; +const std::string DriveX = DrivePrefix + "X:"; +const std::string DriveY = DrivePrefix + "Y:"; // Y: is Dashboard volume (contains "xboxdash.xbe" and "XDASH" folder + contents) +const std::string DriveZ = DrivePrefix + "Z:"; // Z: is Title utility data region +const std::string DevicePrefix = "\\Device"; +const std::string DeviceCdrom0 = DevicePrefix + "\\CdRom0"; +const std::string DeviceHarddisk0 = DevicePrefix + "\\Harddisk0"; +const std::string DeviceHarddisk0PartitionPrefix = DevicePrefix + "\\Harddisk0\\partition"; +const std::string DeviceHarddisk0Partition0 = DeviceHarddisk0PartitionPrefix + "0"; // Contains raw config sectors (like XBOX_REFURB_INFO) + entire hard disk +const std::string DeviceHarddisk0Partition1 = DeviceHarddisk0PartitionPrefix + "1"; // Data partition. Contains TDATA and UDATA folders. +const std::string DeviceHarddisk0Partition2 = DeviceHarddisk0PartitionPrefix + "2"; // Shell partition. Contains Dashboard (cpxdash.xbe, evoxdash.xbe or xboxdash.xbe) +const std::string DeviceHarddisk0Partition3 = DeviceHarddisk0PartitionPrefix + "3"; // First cache partition. Contains cache data (from here up to largest number) +const std::string DeviceHarddisk0Partition4 = DeviceHarddisk0PartitionPrefix + "4"; +const std::string DeviceHarddisk0Partition5 = DeviceHarddisk0PartitionPrefix + "5"; +const std::string DeviceHarddisk0Partition6 = DeviceHarddisk0PartitionPrefix + "6"; +const std::string DeviceHarddisk0Partition7 = DeviceHarddisk0PartitionPrefix + "7"; +const std::string DeviceHarddisk0Partition8 = DeviceHarddisk0PartitionPrefix + "8"; +const std::string DeviceHarddisk0Partition9 = DeviceHarddisk0PartitionPrefix + "9"; +const std::string DeviceHarddisk0Partition10 = DeviceHarddisk0PartitionPrefix + "10"; +const std::string DeviceHarddisk0Partition11 = DeviceHarddisk0PartitionPrefix + "11"; +const std::string DeviceHarddisk0Partition12 = DeviceHarddisk0PartitionPrefix + "12"; +const std::string DeviceHarddisk0Partition13 = DeviceHarddisk0PartitionPrefix + "13"; +const std::string DeviceHarddisk0Partition14 = DeviceHarddisk0PartitionPrefix + "14"; +const std::string DeviceHarddisk0Partition15 = DeviceHarddisk0PartitionPrefix + "15"; +const std::string DeviceHarddisk0Partition16 = DeviceHarddisk0PartitionPrefix + "16"; +const std::string DeviceHarddisk0Partition17 = DeviceHarddisk0PartitionPrefix + "17"; +const std::string DeviceHarddisk0Partition18 = DeviceHarddisk0PartitionPrefix + "18"; +const std::string DeviceHarddisk0Partition19 = DeviceHarddisk0PartitionPrefix + "19"; +const std::string DeviceHarddisk0Partition20 = DeviceHarddisk0PartitionPrefix + "20"; // 20 = Largest possible partition number +const char CxbxDefaultXbeVolumeLetter = 'C'; EmuNtSymbolicLinkObject* NtSymbolicLinkObjects[26]; struct XboxDevice { @@ -123,9 +129,7 @@ HANDLE EmuNtObject::NewHandle() NTSTATUS EmuNtObject::NtClose() { - RefCount--; - - if (RefCount <= 0) { + if (--RefCount <= 0) { delete this; } @@ -153,36 +157,52 @@ HANDLE EmuHandleToHandle(EmuHandle* emuHandle) return (HANDLE)((uint32_t)emuHandle | 0x80000000); } -NTSTATUS CxbxObjectAttributesToNT(xboxkrnl::POBJECT_ATTRIBUTES ObjectAttributes, NativeObjectAttributes& nativeObjectAttributes, std::string aFileAPIName) +bool CxbxIsUtilityDrive(NtDll::HANDLE RootDirectory) { - NTSTATUS result = 0; - std::string OriginalPath; - std::string RelativePath; + EmuNtSymbolicLinkObject* SymbolicLinkObject = FindNtSymbolicLinkObjectByName(DriveZ); + if (SymbolicLinkObject) + return (SymbolicLinkObject->RootDirectoryHandle == RootDirectory); + else + return false; +} + +std::wstring string_to_wstring(std::string const & src) +{ + std::wstring result = std::wstring(src.length(), L' '); + std::copy(src.begin(), src.end(), result.begin()); + return result; +} + +std::wstring PUNICODE_STRING_to_wstring(NtDll::PUNICODE_STRING const & src) +{ + return std::wstring(src->Buffer, src->Length / sizeof(NtDll::WCHAR)); +} + +std::string PSTRING_to_string(xboxkrnl::PSTRING const & src) +{ + return std::string(src->Buffer, src->Length); +} + +void copy_string_to_PSTRING_to(std::string const & src, const xboxkrnl::PSTRING & dest) +{ + memcpy(dest->Buffer, src.c_str(), dest->Length); +} + +NTSTATUS _CxbxConvertFilePath(std::string RelativeXboxPath, std::wstring &RelativeNativePath, NtDll::HANDLE *RootDirectory, std::string aFileAPIName) +{ + std::string OriginalPath = RelativeXboxPath; + std::string RelativePath = RelativeXboxPath; std::string XboxFullPath; std::string NativePath; EmuNtSymbolicLinkObject* NtSymbolicLinkObject = NULL; - result = STATUS_SUCCESS; - if (ObjectAttributes == NULL) - { - // When the pointer is nil, make sure we pass nil to Windows too : - nativeObjectAttributes.NtObjAttrPtr = NULL; - return result; - } - - // ObjectAttributes are given, so make sure the pointer we're going to pass to Windows is assigned : - nativeObjectAttributes.NtObjAttrPtr = &nativeObjectAttributes.NtObjAttr; - - RelativePath = std::string(ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length); - OriginalPath = RelativePath; - + // Always trim '\??\' off : - if ((RelativePath.length() >= 4) && (RelativePath[0] == '\\') && (RelativePath[1] == '?') && (RelativePath[2] == '?') && (RelativePath[3] == '\\')) + if (RelativePath.compare(0, DrivePrefix.length(), DrivePrefix.c_str()) == 0) RelativePath.erase(0, 4); // Check if we where called from a File-handling API : if (!aFileAPIName.empty()) { - NtSymbolicLinkObject = NULL; // Check if the path starts with a volume indicator : if ((RelativePath.length() >= 2) && (RelativePath[1] == ':')) { @@ -234,23 +254,22 @@ NTSTATUS CxbxObjectAttributesToNT(xboxkrnl::POBJECT_ATTRIBUTES ObjectAttributes, } XboxFullPath = NtSymbolicLinkObject->XboxFullPath; - ObjectAttributes->RootDirectory = NtSymbolicLinkObject->RootDirectoryHandle; + *RootDirectory = NtSymbolicLinkObject->RootDirectoryHandle; } else { // No symbolic link - as last resort, check if the path accesses a partition from Harddisk0 : - if (_strnicmp(RelativePath.c_str(), (DeviceHarddisk0 + "\\partition").c_str(), (DeviceHarddisk0 + "\\partition").length()) != 0) + if (_strnicmp(RelativePath.c_str(), DeviceHarddisk0PartitionPrefix.c_str(), DeviceHarddisk0PartitionPrefix.length()) != 0) { - result = STATUS_UNRECOGNIZED_VOLUME; // TODO : Is this the correct error? EmuWarning((("Path not available : ") + OriginalPath).c_str()); - return result; + return STATUS_UNRECOGNIZED_VOLUME; // TODO : Is this the correct error? } XboxFullPath = RelativePath; // Remove Harddisk0 prefix, in the hope that the remaining path might work : RelativePath.erase(0, DeviceHarddisk0.length() + 1); // And set Root to the folder containing the partition-folders : - ObjectAttributes->RootDirectory = CxbxBasePathHandle; + *RootDirectory = CxbxBasePathHandle; NativePath = CxbxBasePath; } @@ -277,16 +296,45 @@ NTSTATUS CxbxObjectAttributesToNT(xboxkrnl::POBJECT_ATTRIBUTES ObjectAttributes, else { // For non-file API calls, prefix with '\??\' again : - RelativePath = "\\??\\" + RelativePath; - ObjectAttributes->RootDirectory = 0; + RelativePath = DrivePrefix + RelativePath; + *RootDirectory = 0; } - // Convert Ansi to Unicode : - mbstowcs(nativeObjectAttributes.wszObjectName, RelativePath.c_str(), 160); + // Convert the relative path to unicode + RelativeNativePath = string_to_wstring(RelativePath); + + return STATUS_SUCCESS; +} + +NTSTATUS CxbxObjectAttributesToNT( + xboxkrnl::POBJECT_ATTRIBUTES ObjectAttributes, + NativeObjectAttributes& nativeObjectAttributes, + const std::string aFileAPIName) +{ + NTSTATUS result = STATUS_SUCCESS; + std::string RelativeXboxPath; + std::wstring RelativeNativePath; + NtDll::HANDLE RootDirectory; + + if (ObjectAttributes == NULL) + { + // When the pointer is nil, make sure we pass nil to Windows too : + nativeObjectAttributes.NtObjAttrPtr = NULL; + return result; + } + + // ObjectAttributes are given, so make sure the pointer we're going to pass to Windows is assigned : + nativeObjectAttributes.NtObjAttrPtr = &nativeObjectAttributes.NtObjAttr; + + RelativeXboxPath = PSTRING_to_string(ObjectAttributes->ObjectName); + result = _CxbxConvertFilePath(RelativeXboxPath, RelativeNativePath, &RootDirectory, aFileAPIName); + + // Copy relative path string to the unicode string + wcscpy_s(nativeObjectAttributes.wszObjectName, RelativeNativePath.c_str()); NtDll::RtlInitUnicodeString(&nativeObjectAttributes.NtUnicodeString, nativeObjectAttributes.wszObjectName); - // Initialize the NT ObjectAttributes : - InitializeObjectAttributes(&nativeObjectAttributes.NtObjAttr, &nativeObjectAttributes.NtUnicodeString, ObjectAttributes->Attributes, ObjectAttributes->RootDirectory, NULL); + // Initialize the NT ObjectAttributes + InitializeObjectAttributes(&nativeObjectAttributes.NtObjAttr, &nativeObjectAttributes.NtUnicodeString, ObjectAttributes->Attributes, RootDirectory, NULL); return result; } @@ -294,9 +342,11 @@ NTSTATUS CxbxObjectAttributesToNT(xboxkrnl::POBJECT_ATTRIBUTES ObjectAttributes, bool CxbxRegisterDeviceNativePath(std::string XboxFullPath, std::string NativePath, bool IsFile) { bool result; + if (IsFile) { if (!PathFileExists(NativePath.c_str())) { HANDLE hf = CreateFile(NativePath.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); + SetFilePointer(hf, 512 * 1024, 0, FILE_BEGIN); SetEndOfFile(hf); CloseHandle(hf); @@ -313,6 +363,7 @@ bool CxbxRegisterDeviceNativePath(std::string XboxFullPath, std::string NativePa if (result) { XboxDevice newDevice; + newDevice.XboxFullPath = XboxFullPath; newDevice.NativePath = NativePath; Devices.push_back(newDevice); @@ -345,12 +396,12 @@ NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPa NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::string aFullPath) { - NTSTATUS result = 0; + NTSTATUS result = STATUS_OBJECT_NAME_INVALID; bool IsNativePath = false; int i = 0; std::string ExtraPath; int DeviceIndex = 0; - result = STATUS_OBJECT_NAME_INVALID; + DriveLetter = SymbolicLinkToDriveLetter(aSymbolicLinkName); if (DriveLetter >= 'A' && DriveLetter <= 'Z') { @@ -360,9 +411,8 @@ NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::strin // Look up the partition in the list of pre-registered devices : result = STATUS_DEVICE_DOES_NOT_EXIST; // TODO : Is this the correct error? - // Make a distinction between Xbox paths (starting with '\Device'...) and Native paths : - std::string deviceString = "\\Device"; - IsNativePath = _strnicmp(aFullPath.c_str(), deviceString.c_str(), deviceString.length()) != 0; + // Make a distinction between Xbox paths (starting with '\Device'...) and Native paths : + IsNativePath = _strnicmp(aFullPath.c_str(), DevicePrefix.c_str(), DevicePrefix.length()) != 0; if (IsNativePath) DeviceIndex = 0; else @@ -376,6 +426,7 @@ NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::strin } } } + if (DeviceIndex >= 0) { result = STATUS_SUCCESS; @@ -392,11 +443,11 @@ NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::strin // Handle the case where a sub folder of the partition is mounted (instead of it's root) : ExtraPath = aFullPath.substr(Devices[DeviceIndex].XboxFullPath.length(), std::string::npos); } + if (!ExtraPath.empty()) NativePath = NativePath + ExtraPath; SHCreateDirectoryEx(NULL, NativePath.c_str(), NULL); - RootDirectoryHandle = CreateFile(NativePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (RootDirectoryHandle == INVALID_HANDLE_VALUE) { @@ -411,6 +462,7 @@ NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::strin } } } + return result; } @@ -455,7 +507,6 @@ char SymbolicLinkToDriveLetter(std::string SymbolicLinkName) EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByVolumeLetter(const char VolumeLetter) { - EmuNtSymbolicLinkObject* result = NULL; if (VolumeLetter >= 'A' && VolumeLetter <= 'Z') return NtSymbolicLinkObjects[VolumeLetter - 'A']; @@ -480,7 +531,6 @@ EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDevice(std::string DeviceName return result; } - return NULL; } @@ -490,7 +540,6 @@ EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(const HANDLE Handl for (char VolumeLetter = 'A'; VolumeLetter <= 'Z'; VolumeLetter++) { EmuNtSymbolicLinkObject* result = NtSymbolicLinkObjects[VolumeLetter - 'A']; - result = NtSymbolicLinkObjects[VolumeLetter - 'A']; if ((result != NULL) && (Handle == result->RootDirectoryHandle)) return result; } @@ -498,6 +547,291 @@ EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(const HANDLE Handl return NULL; } + +void _CxbxPVOIDDeleter(PVOID *ptr) +{ + if (*ptr) + CxbxFree(*ptr); +} + +// ---------------------------------------------------------------------------- +// Xbox to NT converters +// ---------------------------------------------------------------------------- + +NtDll::FILE_LINK_INFORMATION * _XboxToNTLinkInfo(xboxkrnl::FILE_LINK_INFORMATION *xboxLinkInfo, ULONG *Length) +{ + // Convert the path from Xbox to native + std::string originalFileName(xboxLinkInfo->FileName, xboxLinkInfo->FileNameLength); + std::wstring convertedFileName; + NtDll::HANDLE RootDirectory; + _CxbxConvertFilePath(originalFileName, convertedFileName, &RootDirectory, "NtSetInformationFile"); + + // Build the native FILE_LINK_INFORMATION struct + *Length = sizeof(NtDll::FILE_LINK_INFORMATION) + convertedFileName.size() * sizeof(wchar_t); + NtDll::FILE_LINK_INFORMATION *ntLinkInfo = (NtDll::FILE_LINK_INFORMATION *) CxbxMalloc(*Length); + ZeroMemory(ntLinkInfo, *Length); + ntLinkInfo->ReplaceIfExists = xboxLinkInfo->ReplaceIfExists; + ntLinkInfo->RootDirectory = RootDirectory; + ntLinkInfo->FileNameLength = convertedFileName.size() * sizeof(wchar_t); + wmemcpy_s(ntLinkInfo->FileName, convertedFileName.size(), convertedFileName.c_str(), convertedFileName.size()); + + return ntLinkInfo; +} + +NtDll::FILE_RENAME_INFORMATION * _XboxToNTRenameInfo(xboxkrnl::FILE_RENAME_INFORMATION *xboxRenameInfo, ULONG *Length) +{ + // Convert the path from Xbox to native + std::string originalFileName(xboxRenameInfo->FileName.Buffer, xboxRenameInfo->FileName.Length); + std::wstring convertedFileName; + NtDll::HANDLE RootDirectory; + _CxbxConvertFilePath(originalFileName, convertedFileName, &RootDirectory, "NtSetInformationFile"); + + // Build the native FILE_RENAME_INFORMATION struct + *Length = sizeof(NtDll::FILE_RENAME_INFORMATION) + convertedFileName.size() * sizeof(wchar_t); + NtDll::FILE_RENAME_INFORMATION *ntRenameInfo = (NtDll::FILE_RENAME_INFORMATION *) CxbxMalloc(*Length); + ZeroMemory(ntRenameInfo, *Length); + ntRenameInfo->ReplaceIfExists = xboxRenameInfo->ReplaceIfExists; + ntRenameInfo->RootDirectory = RootDirectory; + ntRenameInfo->FileNameLength = convertedFileName.size() * sizeof(wchar_t); + wmemcpy_s(ntRenameInfo->FileName, convertedFileName.size(), convertedFileName.c_str(), convertedFileName.size()); + + return ntRenameInfo; +} + +// ---------------------------------------------------------------------------- +// NT to Xbox converters - common functions +// ---------------------------------------------------------------------------- + +void _ConvertXboxBasicInfo(xboxkrnl::FILE_BASIC_INFORMATION *xboxBasicInfo) +{ + // Fix up attributes + xboxBasicInfo->FileAttributes &= FILE_ATTRIBUTE_VALID_FLAGS; +} + +NTSTATUS _ConvertXboxNameInfo(NtDll::FILE_NAME_INFORMATION *ntNameInfo, xboxkrnl::FILE_NAME_INFORMATION *xboxNameInfo, int convertedFileNameLength, ULONG Length) +{ + // Convert the file name to ANSI in-place + xboxNameInfo->FileNameLength = convertedFileNameLength; + + // Check if the new file name fits within the given struct size and copy as many chars as possible if not + int maxFileNameLength = Length - sizeof(xboxkrnl::FILE_NAME_INFORMATION); + size_t convertedChars; + wcstombs_s(&convertedChars, xboxNameInfo->FileName, maxFileNameLength, ntNameInfo->FileName, ntNameInfo->FileNameLength); + + // Return the appropriate result depending on whether the string was fully copied + return convertedChars == ntNameInfo->FileNameLength / sizeof(NtDll::WCHAR) + ? STATUS_SUCCESS + : STATUS_BUFFER_OVERFLOW; +} + +// ---------------------------------------------------------------------------- +// NT to Xbox converters +// ---------------------------------------------------------------------------- + +NTSTATUS _NTToXboxNetOpenInfo(NtDll::FILE_NETWORK_OPEN_INFORMATION *ntNetOpenInfo, xboxkrnl::FILE_NETWORK_OPEN_INFORMATION *xboxNetOpenInfo, ULONG Length) +{ + // Copy everything from the NT struct + memcpy_s(xboxNetOpenInfo, Length, ntNetOpenInfo, sizeof(NtDll::FILE_NETWORK_OPEN_INFORMATION)); + + // Fix up attributes + xboxNetOpenInfo->FileAttributes &= FILE_ATTRIBUTE_VALID_FLAGS; + + return STATUS_SUCCESS; +} + +NTSTATUS _NTToXboxBasicInfo(NtDll::FILE_BASIC_INFORMATION *ntBasicInfo, xboxkrnl::FILE_BASIC_INFORMATION *xboxBasicInfo, ULONG Length) +{ + // Copy everything from the NT struct + memcpy_s(xboxBasicInfo, sizeof(xboxkrnl::FILE_BASIC_INFORMATION), ntBasicInfo, sizeof(NtDll::FILE_BASIC_INFORMATION)); + + _ConvertXboxBasicInfo(xboxBasicInfo); + + return STATUS_SUCCESS; +} + +NTSTATUS _NTToXboxNameInfo(NtDll::FILE_NAME_INFORMATION *ntNameInfo, xboxkrnl::FILE_NAME_INFORMATION *xboxNameInfo, ULONG Length) +{ + // TODO: the FileName probably needs to be converted back to an Xbox path in some cases + // Determine new file name length + size_t convertedFileNameLength = ntNameInfo->FileNameLength / sizeof(NtDll::WCHAR); + + // Clean up the Xbox FILE_NAME_INFORMATION struct + ZeroMemory(xboxNameInfo, Length); + + // Convert file name and return the result + return _ConvertXboxNameInfo(ntNameInfo, xboxNameInfo, convertedFileNameLength, Length); +} + +NTSTATUS _NTToXboxAllInfo(NtDll::FILE_ALL_INFORMATION *ntAllInfo, xboxkrnl::FILE_ALL_INFORMATION *xboxAllInfo, ULONG Length) +{ + // TODO: the FileName probably needs to be converted back to an Xbox path in some cases + // Determine new file name length + size_t convertedFileNameLength = ntAllInfo->NameInformation.FileNameLength / sizeof(NtDll::WCHAR); + + // Copy everything from the NT struct + memcpy_s(xboxAllInfo, Length, ntAllInfo, sizeof(NtDll::FILE_ALL_INFORMATION)); + + // Convert NT structs to Xbox where needed and return the result + _ConvertXboxBasicInfo(&xboxAllInfo->BasicInformation); + return _ConvertXboxNameInfo(&ntAllInfo->NameInformation, &xboxAllInfo->NameInformation, convertedFileNameLength, Length); +} + +// ---------------------------------------------------------------------------- +// File information struct converters +// ---------------------------------------------------------------------------- + +PVOID _XboxToNTFileInformation +( + IN PVOID xboxFileInformation, + IN ULONG FileInformationClass, + OUT ULONG *Length +) +{ + // The following classes of file information structs are identical between platforms: + // FileBasicInformation + // FileDispositionInformation + // FileEndOfFileInformation + // FileLinkInformation + // FilePositionInformation + + PVOID result = NULL; + + switch (FileInformationClass) + { + case xboxkrnl::FileLinkInformation: + { + xboxkrnl::FILE_LINK_INFORMATION *xboxLinkInfo = reinterpret_cast(xboxFileInformation); + result = _XboxToNTLinkInfo(xboxLinkInfo, Length); + break; + } + case xboxkrnl::FileRenameInformation: + { + xboxkrnl::FILE_RENAME_INFORMATION *xboxRenameInfo = reinterpret_cast(xboxFileInformation); + result = _XboxToNTRenameInfo(xboxRenameInfo, Length); + break; + } + default: + { + result = NULL; + break; + } + } + + return result; +} + +NTSTATUS NTToXboxFileInformation +( + IN PVOID nativeFileInformation, + OUT PVOID xboxFileInformation, + IN ULONG FileInformationClass, + IN ULONG Length +) +{ + // The following classes of file information structs are identical between platforms: + // FileAccessInformation + // FileAlignmentInformation + // FileEaInformation + // FileInternalInformation + // FileModeInformation + // FilePositionInformation + // FileStandardInformation + // FileReparsePointInformation + + NTSTATUS result = STATUS_SUCCESS; + + switch (FileInformationClass) + { + case NtDll::FileAllInformation: + { + NtDll::FILE_ALL_INFORMATION *ntAllInfo = reinterpret_cast(nativeFileInformation); + xboxkrnl::FILE_ALL_INFORMATION *xboxAllInfo = reinterpret_cast(xboxFileInformation); + result = _NTToXboxAllInfo(ntAllInfo, xboxAllInfo, Length); + break; + } + case NtDll::FileBasicInformation: + { + NtDll::FILE_BASIC_INFORMATION *ntBasicInfo = reinterpret_cast(nativeFileInformation); + xboxkrnl::FILE_BASIC_INFORMATION *xboxBasicInfo = reinterpret_cast(xboxFileInformation); + result = _NTToXboxBasicInfo(ntBasicInfo, xboxBasicInfo, Length); + break; + } + case NtDll::FileNameInformation: + { + NtDll::FILE_NAME_INFORMATION *ntNameInfo = reinterpret_cast(nativeFileInformation); + xboxkrnl::FILE_NAME_INFORMATION *xboxNameInfo = reinterpret_cast(xboxFileInformation); + result = _NTToXboxNameInfo(ntNameInfo, xboxNameInfo, Length); + break; + } + case NtDll::FileNetworkOpenInformation: + { + NtDll::FILE_NETWORK_OPEN_INFORMATION *ntNetOpenInfo = reinterpret_cast(nativeFileInformation); + xboxkrnl::FILE_NETWORK_OPEN_INFORMATION *xboxNetOpenInfo = reinterpret_cast(xboxFileInformation); + result = _NTToXboxNetOpenInfo(ntNetOpenInfo, xboxNetOpenInfo, Length); + break; + } + case NtDll::FileBothDirectoryInformation: + { + // TODO: handle differences + // - Xbox reuses the FILE_DIRECTORY_INFORMATION struct, which is mostly identical to FILE_BOTH_DIR_INFORMATION + // - NextEntryOffset might be a problem + // - NT has extra fields before FileName: + // - ULONG EaSize + // - CCHAR ShortNameLength + // - WCHAR ShortName[12] + // - FileName on Xbox uses single-byte chars, NT uses wide chars + + //break; + } + case NtDll::FileDirectoryInformation: + { + // TODO: handle differences + // - NextEntryOffset might be a problem + // - FileName on Xbox uses single-byte chars, NT uses wide chars + + //break; + } + case NtDll::FileFullDirectoryInformation: + { + // TODO: handle differences + // - Xbox reuses the FILE_DIRECTORY_INFORMATION struct, which is mostly identical to FILE_FULL_DIR_INFORMATION + // - NextEntryOffset might be a problem + // - NT has one extra field before FileName: + // - ULONG EaSize + // - FileName on Xbox uses single-byte chars, NT uses wide chars + + //break; + } + case NtDll::FileNamesInformation: + { + // TODO: handle differences + // - NextEntryOffset might be a problem + // - FileName on Xbox uses single-byte chars, NT uses wide chars + + //break; + } + case NtDll::FileObjectIdInformation: + { + // TODO: handle differences + // - The LONGLONG FileReference field from NT can be ignored + // - ExtendedInfo is an union on NT, but is otherwise identical + + //break; + } + default: + { + // No differences between structs; a simple copy should suffice + memcpy_s(xboxFileInformation, Length, nativeFileInformation, Length); + result = STATUS_SUCCESS; + break; + } + } + + return result; +} + +// TODO: FS_INFORMATION_CLASS and its related structs most likely need to be converted too + // TODO : Move to a better suited file /* TODO : Also, fix C2593: "'operator <<' is ambiguous" for this std::ostream& operator<<(std::ostream& os, const NtDll::NTSTATUS& value) diff --git a/src/CxbxKrnl/EmuFile.h b/src/CxbxKrnl/EmuFile.h index cf33b65f8..5403373c4 100644 --- a/src/CxbxKrnl/EmuFile.h +++ b/src/CxbxKrnl/EmuFile.h @@ -44,6 +44,7 @@ namespace xboxkrnl #include #include +#include // ****************************************************************** // * prevent name collisions @@ -58,50 +59,98 @@ namespace NtDll // TODO : Move to a better suited file //std::ostream& operator<<(std::ostream& os, const NtDll::NTSTATUS& value); -extern std::string DriveSerial; -extern std::string DriveCdRom0; -extern std::string DriveMbfs; -extern std::string DriveMbcom; -extern std::string DriveMbrom; -extern std::string DriveC; -extern std::string DriveD; -extern std::string DriveE; -extern std::string DriveF; -extern std::string DriveT; -extern std::string DriveU; -extern std::string DriveV; -extern std::string DriveW; -extern std::string DriveX; -extern std::string DriveY; -extern std::string DriveZ; -extern std::string DeviceCdrom0; -extern std::string DeviceHarddisk0; -extern std::string DeviceHarddisk0Partition0; -extern std::string DeviceHarddisk0Partition1; -extern std::string DeviceHarddisk0Partition2; -extern std::string DeviceHarddisk0Partition3; -extern std::string DeviceHarddisk0Partition4; -extern std::string DeviceHarddisk0Partition5; -extern std::string DeviceHarddisk0Partition6; -extern std::string DeviceHarddisk0Partition7; -extern std::string DeviceHarddisk0Partition8; -extern std::string DeviceHarddisk0Partition9; -extern std::string DeviceHarddisk0Partition10; -extern std::string DeviceHarddisk0Partition11; -extern std::string DeviceHarddisk0Partition12; -extern std::string DeviceHarddisk0Partition13; -extern std::string DeviceHarddisk0Partition14; -extern std::string DeviceHarddisk0Partition15; -extern std::string DeviceHarddisk0Partition16; -extern std::string DeviceHarddisk0Partition17; -extern std::string DeviceHarddisk0Partition18; -extern std::string DeviceHarddisk0Partition19; -extern std::string DeviceHarddisk0Partition20; -extern char CxbxDefaultXbeVolumeLetter; +extern const std::string DrivePrefix; +extern const std::string DriveSerial; +extern const std::string DriveCdRom0; +extern const std::string DriveMbfs; +extern const std::string DriveMbcom; +extern const std::string DriveMbrom; +extern const std::string DriveC; +extern const std::string DriveD; +extern const std::string DriveE; +extern const std::string DriveF; +extern const std::string DriveT; +extern const std::string DriveU; +extern const std::string DriveV; +extern const std::string DriveW; +extern const std::string DriveX; +extern const std::string DriveY; +extern const std::string DriveZ; +extern const std::string DevicePrefix; +extern const std::string DeviceCdrom0; +extern const std::string DeviceHarddisk0; +extern const std::string DeviceHarddisk0PartitionPrefix; +extern const std::string DeviceHarddisk0Partition0; +extern const std::string DeviceHarddisk0Partition1; +extern const std::string DeviceHarddisk0Partition2; +extern const std::string DeviceHarddisk0Partition3; +extern const std::string DeviceHarddisk0Partition4; +extern const std::string DeviceHarddisk0Partition5; +extern const std::string DeviceHarddisk0Partition6; +extern const std::string DeviceHarddisk0Partition7; +extern const std::string DeviceHarddisk0Partition8; +extern const std::string DeviceHarddisk0Partition9; +extern const std::string DeviceHarddisk0Partition10; +extern const std::string DeviceHarddisk0Partition11; +extern const std::string DeviceHarddisk0Partition12; +extern const std::string DeviceHarddisk0Partition13; +extern const std::string DeviceHarddisk0Partition14; +extern const std::string DeviceHarddisk0Partition15; +extern const std::string DeviceHarddisk0Partition16; +extern const std::string DeviceHarddisk0Partition17; +extern const std::string DeviceHarddisk0Partition18; +extern const std::string DeviceHarddisk0Partition19; +extern const std::string DeviceHarddisk0Partition20; +extern const char CxbxDefaultXbeVolumeLetter; extern std::string CxbxBasePath; extern HANDLE CxbxBasePathHandle; +const size_t XboxFileInfoStructSizes[xboxkrnl::FileMaximumInformation] = { + 0, // (index 0) + sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileDirectoryInformation + sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileFullDirectoryInformation + sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileBothDirectoryInformation + sizeof(xboxkrnl::FILE_BASIC_INFORMATION), // FileBasicInformation + sizeof(xboxkrnl::FILE_STANDARD_INFORMATION), // FileStandardInformation + sizeof(xboxkrnl::FILE_INTERNAL_INFORMATION), // FileInternalInformation + sizeof(xboxkrnl::FILE_EA_INFORMATION), // FileEaInformation + sizeof(xboxkrnl::FILE_ACCESS_INFORMATION), // FileAccessInformation + sizeof(xboxkrnl::FILE_NAME_INFORMATION), // FileNameInformation + sizeof(xboxkrnl::FILE_RENAME_INFORMATION), // FileRenameInformation + sizeof(xboxkrnl::FILE_LINK_INFORMATION), // FileLinkInformation + sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileNamesInformation + sizeof(xboxkrnl::FILE_DISPOSITION_INFORMATION), // FileDispositionInformation + sizeof(xboxkrnl::FILE_POSITION_INFORMATION), // FilePositionInformation + sizeof(xboxkrnl::FILE_FULL_EA_INFORMATION), // FileFullEaInformation + sizeof(xboxkrnl::FILE_MODE_INFORMATION), // FileModeInformation + sizeof(xboxkrnl::FILE_ALIGNMENT_INFORMATION), // FileAlignmentInformation + sizeof(xboxkrnl::FILE_ALL_INFORMATION), // FileAllInformation + sizeof(xboxkrnl::FILE_ALLOCATION_INFORMATION), // FileAllocationInformation + sizeof(xboxkrnl::FILE_END_OF_FILE_INFORMATION), // FileEndOfFileInformation + sizeof(xboxkrnl::FILE_NAME_INFORMATION), // FileAlternateNameInformation + sizeof(xboxkrnl::FILE_STREAM_INFORMATION), // FileStreamInformation + sizeof(xboxkrnl::FILE_PIPE_INFORMATION), // FilePipeInformation + sizeof(xboxkrnl::FILE_PIPE_LOCAL_INFORMATION), // FilePipeLocalInformation + sizeof(xboxkrnl::FILE_PIPE_REMOTE_INFORMATION), // FilePipeRemoteInformation + sizeof(xboxkrnl::FILE_MAILSLOT_QUERY_INFORMATION), // FileMailslotQueryInformation + sizeof(xboxkrnl::FILE_MAILSLOT_SET_INFORMATION), // FileMailslotSetInformation + sizeof(xboxkrnl::FILE_COMPRESSION_INFORMATION), // FileCompressionInformation + 0, // FileCopyOnWriteInformation + sizeof(xboxkrnl::FILE_COMPLETION_INFORMATION), // FileCompletionInformation + sizeof(xboxkrnl::FILE_MOVE_CLUSTER_INFORMATION), // FileMoveClusterInformation + 0, // FileQuotaInformation + sizeof(xboxkrnl::FILE_REPARSE_POINT_INFORMATION), // FileReparsePointInformation + sizeof(xboxkrnl::FILE_NETWORK_OPEN_INFORMATION), // FileNetworkOpenInformation + sizeof(xboxkrnl::FILE_DIRECTORY_INFORMATION), // FileObjectIdInformation + sizeof(xboxkrnl::FILE_TRACKING_INFORMATION), // FileTrackingInformation + 0, // FileOleDirectoryInformation + 0, // FileContentIndexInformation + 0, // FileInheritContentIndexInformation + 0 // FileOleInformation +}; + + class EmuNtObject; struct NativeObjectAttributes { @@ -177,5 +226,49 @@ bool CxbxRegisterDeviceNativePath(std::string XboxFullPath, std::string NativePa HANDLE CxbxGetDeviceNativeRootHandle(std::string XboxFullPath); NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPath); bool CxbxMountUtilityDrive(bool formatClean); +bool CxbxIsUtilityDrive(NtDll::HANDLE RootDirectory); +std::wstring string_to_wstring(std::string const & src); +std::wstring PUNICODE_STRING_to_wstring(NtDll::PUNICODE_STRING const & src); +std::string PSTRING_to_string(xboxkrnl::PSTRING const & src); +void copy_string_to_PSTRING_to(std::string const & src, const xboxkrnl::PSTRING & dest); + +static int NtFileDirectoryInformationSize = sizeof(NtDll::FILE_DIRECTORY_INFORMATION) - 1; +static int NtPathBufferSize = MAX_PATH * sizeof(wchar_t); + +// Deletes structs created by the converters +void _CxbxPVOIDDeleter(PVOID *ptr); + +// Creates a PVOID variable named var which takes the given value +// and is automatically deleted when it goes out of scope +#define SMART_PVOID(var, value, orig) \ + PVOID var = value; \ + std::shared_ptr __var_shared_ptr; \ + if (NULL == var) \ + { \ + __var_shared_ptr = NULL; \ + var = orig; \ + } \ + else \ + __var_shared_ptr = std::shared_ptr(&var, _CxbxPVOIDDeleter); + +// Converts an Xbox FileInformation struct to the NT equivalent. +// Used by NtSetInformationFile. +#define XboxToNTFileInformation(var, i, c, l) SMART_PVOID(var, _XboxToNTFileInformation(i, c, l), i) +PVOID _XboxToNTFileInformation +( + IN PVOID xboxFileInformation, + IN ULONG FileInformationClass, + OUT ULONG *Length +); + +// Converts an NT FileInformation struct to the Xbox equivalent. +// Used by NtQueryInformationFile and NtQueryDirectoryFile +NTSTATUS NTToXboxFileInformation +( + IN PVOID nativeFileInformation, + OUT PVOID xboxFileInformation, + IN ULONG FileInformationClass, + IN ULONG Length +); #endif diff --git a/src/CxbxKrnl/EmuKrnlIo.cpp b/src/CxbxKrnl/EmuKrnlIo.cpp index 9e5ea3b8b..9816270ff 100644 --- a/src/CxbxKrnl/EmuKrnlIo.cpp +++ b/src/CxbxKrnl/EmuKrnlIo.cpp @@ -164,7 +164,7 @@ XBSYSAPI EXPORTNUM(67) xboxkrnl::NTSTATUS NTAPI xboxkrnl::IoCreateSymbolicLink LOG_FUNC_ARG(DeviceName) LOG_FUNC_END; - NTSTATUS ret = CxbxCreateSymbolicLink(std::string(SymbolicLinkName->Buffer, SymbolicLinkName->Length), std::string(DeviceName->Buffer, DeviceName->Length)); + NTSTATUS ret = CxbxCreateSymbolicLink(PSTRING_to_string(SymbolicLinkName), PSTRING_to_string(DeviceName)); RETURN(ret); } @@ -179,11 +179,11 @@ XBSYSAPI EXPORTNUM(69) xboxkrnl::NTSTATUS NTAPI xboxkrnl::IoDeleteSymbolicLink { LOG_FUNC_ONE_ARG(SymbolicLinkName); - EmuNtSymbolicLinkObject* symbolicLink = FindNtSymbolicLinkObjectByName(std::string(SymbolicLinkName->Buffer, SymbolicLinkName->Length)); + EmuNtSymbolicLinkObject* symbolicLink = FindNtSymbolicLinkObjectByName(PSTRING_to_string(SymbolicLinkName)); NTSTATUS ret = STATUS_OBJECT_NAME_NOT_FOUND; - if ((symbolicLink != NULL)) + if (symbolicLink != NULL) ret = symbolicLink->NtClose(); RETURN(ret); diff --git a/src/CxbxKrnl/EmuKrnlLogging.h b/src/CxbxKrnl/EmuKrnlLogging.h index 39663bb50..477705a8a 100644 --- a/src/CxbxKrnl/EmuKrnlLogging.h +++ b/src/CxbxKrnl/EmuKrnlLogging.h @@ -51,6 +51,7 @@ enum CREATE_OPTION; #include // for std::ostream //?#include "Logging.h" + // Headers for rendering non-Xbox types : std::ostream& operator<<(std::ostream& os, const PULONG& value); diff --git a/src/CxbxKrnl/EmuKrnlNt.cpp b/src/CxbxKrnl/EmuKrnlNt.cpp index 6a9e4be5b..15c2f8374 100644 --- a/src/CxbxKrnl/EmuKrnlNt.cpp +++ b/src/CxbxKrnl/EmuKrnlNt.cpp @@ -305,21 +305,21 @@ XBSYSAPI EXPORTNUM(192) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateMutant LOG_FUNC_ARG(InitialOwner) LOG_FUNC_END; - char *szBuffer = (ObjectAttributes != 0) ? ObjectAttributes->ObjectName->Buffer : 0; - wchar_t wszObjectName[160]; + char *szBuffer = (ObjectAttributes != NULL) ? ObjectAttributes->ObjectName->Buffer : nullptr; + wchar_t wszObjectName[MAX_PATH]; NtDll::UNICODE_STRING NtUnicodeString; NtDll::OBJECT_ATTRIBUTES NtObjAttr; // initialize object attributes - if (szBuffer != 0) + if (szBuffer != nullptr) { - mbstowcs(wszObjectName, "\\??\\", 4); - mbstowcs(wszObjectName + 4, szBuffer, 160); + mbstowcs(/*Dest=*/wszObjectName, /*Source=*/DrivePrefix.c_str(), /*MaxCount=*/DrivePrefix.length()); + mbstowcs(/*Dest=*/wszObjectName + DrivePrefix.length(), /*Source=*/szBuffer, /*MaxCount=*/MAX_PATH); NtDll::RtlInitUnicodeString(&NtUnicodeString, wszObjectName); - InitializeObjectAttributes(&NtObjAttr, &NtUnicodeString, ObjectAttributes->Attributes, ObjectAttributes->RootDirectory, NULL); + InitializeObjectAttributes(&NtObjAttr, &NtUnicodeString, ObjectAttributes->Attributes, ObjectAttributes->RootDirectory, nullptr); } NtObjAttr.RootDirectory = 0; @@ -448,37 +448,22 @@ XBSYSAPI EXPORTNUM(196) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtDeviceIoControlFile NTSTATUS ret = STATUS_SUCCESS; - if (IsEmuHandle(FileHandle)) + switch (IoControlCode) { - switch (IoControlCode) - { - case 0x4D014: // IOCTL_SCSI_PASS_THROUGH_DIRECT - { - PSCSI_PASS_THROUGH_DIRECT PassThrough = (PSCSI_PASS_THROUGH_DIRECT)InputBuffer; - PDVDX2_AUTHENTICATION Authentication = (PDVDX2_AUTHENTICATION)PassThrough->DataBuffer; + case 0x4D014: // IOCTL_SCSI_PASS_THROUGH_DIRECT + { + PSCSI_PASS_THROUGH_DIRECT PassThrough = (PSCSI_PASS_THROUGH_DIRECT)InputBuffer; + PDVDX2_AUTHENTICATION Authentication = (PDVDX2_AUTHENTICATION)PassThrough->DataBuffer; - // Should be just enough info to pass XapiVerifyMediaInDrive - Authentication->AuthenticationPage.CDFValid = 1; - Authentication->AuthenticationPage.PartitionArea = 1; - Authentication->AuthenticationPage.Authentication = 1; - break; - } - default: - LOG_UNIMPLEMENTED(); - } + // Should be just enough info to pass XapiVerifyMediaInDrive + Authentication->AuthenticationPage.CDFValid = 1; + Authentication->AuthenticationPage.PartitionArea = 1; + Authentication->AuthenticationPage.Authentication = 1; + break; + } + default: + LOG_UNIMPLEMENTED(); } - else - ret = NtDll::NtDeviceIoControlFile( - FileHandle, - Event, - (NtDll::PIO_APC_ROUTINE)ApcRoutine, - ApcContext, - (NtDll::IO_STATUS_BLOCK*)IoStatusBlock, - IoControlCode, - InputBuffer, - InputBufferLength, - OutputBuffer, - OutputBufferLength); RETURN(ret); } @@ -686,21 +671,21 @@ XBSYSAPI EXPORTNUM(203) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtOpenSymbolicLinkObj LOG_FUNC_ARG(ObjectAttributes) LOG_FUNC_END; - NTSTATUS ret = 0; - EmuNtSymbolicLinkObject* symbolicLinkObject = NULL; + NTSTATUS ret = STATUS_OBJECT_PATH_NOT_FOUND; + EmuNtSymbolicLinkObject* symbolicLinkObject = + FindNtSymbolicLinkObjectByName(PSTRING_to_string(ObjectAttributes->ObjectName)); - symbolicLinkObject = FindNtSymbolicLinkObjectByName(std::string(ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length)); if (symbolicLinkObject != NULL) { - // Return a new handle (which is an EmuHandle, actually) : + // Return a new handle (which is an EmuHandle, actually) : *LinkHandle = symbolicLinkObject->NewHandle(); ret = STATUS_SUCCESS; } + + if (ret != STATUS_SUCCESS) + EmuWarning("NtOpenSymbolicLinkObject failed! (%s)", NtStatusToString(ret)); else - if (ret != STATUS_SUCCESS) - EmuWarning("NtOpenSymbolicLinkObject failed! (%s)", NtStatusToString(ret)); - else - DbgPrintf("EmuKrnl : NtOpenSymbolicLinkObject LinkHandle^ = 0x%.08X", *LinkHandle); + DbgPrintf("EmuKrnl : NtOpenSymbolicLinkObject LinkHandle^ = 0x%.08X", *LinkHandle); RETURN(ret); } @@ -821,46 +806,48 @@ XBSYSAPI EXPORTNUM(207) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryDirectoryFile NTSTATUS ret; - if (FileInformationClass != 1) // Due to unicode->string conversion + if (FileInformationClass != FileDirectoryInformation) // Due to unicode->string conversion CxbxKrnlCleanup("Unsupported FileInformationClass"); NtDll::UNICODE_STRING NtFileMask; - wchar_t wszObjectName[160]; + wchar_t wszObjectName[MAX_PATH]; // initialize FileMask { if (FileMask != 0) - mbstowcs(wszObjectName, FileMask->Buffer, 160); + mbstowcs(/*Dest=*/wszObjectName, /*Source=*/FileMask->Buffer, /*MaxCount=*/MAX_PATH); else - mbstowcs(wszObjectName, "", 160); + mbstowcs(/*Dest=*/wszObjectName, /*Source=*/"", /*MaxCount=*/MAX_PATH); NtDll::RtlInitUnicodeString(&NtFileMask, wszObjectName); } NtDll::FILE_DIRECTORY_INFORMATION *NtFileDirInfo = - (NtDll::FILE_DIRECTORY_INFORMATION*)CxbxMalloc(0x40 + 160 * 2); + (NtDll::FILE_DIRECTORY_INFORMATION *) CxbxMalloc(NtFileDirectoryInformationSize + NtPathBufferSize); // Short-hand pointer to Nt filename : wchar_t *wcstr = NtFileDirInfo->FileName; + char *mbstr = FileInformation->FileName; // Go, query that directory : do { - ZeroMemory(wcstr, 160 * 2); + ZeroMemory(wcstr, MAX_PATH * sizeof(wchar_t)); ret = NtDll::NtQueryDirectoryFile( - FileHandle, - Event, - (NtDll::PIO_APC_ROUTINE)ApcRoutine, - ApcContext, - (NtDll::IO_STATUS_BLOCK*)IoStatusBlock, - NtFileDirInfo, - /*Length=*/0x40 + 160 * 2, - (NtDll::FILE_INFORMATION_CLASS)FileInformationClass, + FileHandle, + Event, + (NtDll::PIO_APC_ROUTINE)ApcRoutine, + ApcContext, + (NtDll::IO_STATUS_BLOCK*)IoStatusBlock, + /*FileInformation=*/NtFileDirInfo, + NtFileDirectoryInformationSize + NtPathBufferSize, + (NtDll::FILE_INFORMATION_CLASS)FileInformationClass, /*ReturnSingleEntry=*/TRUE, &NtFileMask, - RestartScan); + RestartScan + ); RestartScan = FALSE; } @@ -869,9 +856,10 @@ XBSYSAPI EXPORTNUM(207) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryDirectoryFile // convert from PC to Xbox { - memcpy(FileInformation, NtFileDirInfo, 0x40); - wcstombs(/*Dest=*/FileInformation->FileName, /*Source=*/wcstr, /*MaxCount=*/160); - FileInformation->FileNameLength /= 2; + // TODO : assert that NtDll::FILE_DIRECTORY_INFORMATION has same members and size as xboxkrnl::FILE_DIRECTORY_INFORMATION + memcpy(/*Dst=*/FileInformation, /*Src=*/NtFileDirInfo, /*Size=*/NtFileDirectoryInformationSize); + wcstombs(/*Dest=*/mbstr, /*Source=*/wcstr, MAX_PATH); + FileInformation->FileNameLength /= sizeof(wchar_t); } // TODO: Cache the last search result for quicker access with CreateFile (xbox does this internally!) @@ -886,7 +874,7 @@ XBSYSAPI EXPORTNUM(207) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryDirectoryFile XBSYSAPI EXPORTNUM(210) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryFullAttributesFile ( IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PVOID Attributes + OUT xboxkrnl::PFILE_NETWORK_OPEN_INFORMATION Attributes ) { LOG_FUNC_BEGIN @@ -896,6 +884,8 @@ XBSYSAPI EXPORTNUM(210) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryFullAttributes // __asm int 3; NativeObjectAttributes nativeObjectAttributes; + NtDll::FILE_NETWORK_OPEN_INFORMATION nativeNetOpenInfo; + NTSTATUS ret = CxbxObjectAttributesToNT( ObjectAttributes, /*var*/nativeObjectAttributes, @@ -904,7 +894,10 @@ XBSYSAPI EXPORTNUM(210) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryFullAttributes if (ret == STATUS_SUCCESS) ret = NtDll::NtQueryFullAttributesFile( nativeObjectAttributes.NtObjAttrPtr, - Attributes); + &nativeNetOpenInfo); + + // Convert Attributes to Xbox + NTToXboxFileInformation(&nativeNetOpenInfo, Attributes, FileNetworkOpenInformation, sizeof(xboxkrnl::FILE_NETWORK_OPEN_INFORMATION)); if (FAILED(ret)) EmuWarning("NtQueryFullAttributesFile failed! (0x%.08X)\n", ret); @@ -921,7 +914,7 @@ XBSYSAPI EXPORTNUM(211) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryInformationFil OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, - IN FILE_INFORMATION_CLASS FileInfo + IN FILE_INFORMATION_CLASS FileInformationClass ) { LOG_FUNC_BEGIN @@ -929,46 +922,55 @@ XBSYSAPI EXPORTNUM(211) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryInformationFil LOG_FUNC_ARG_OUT(IoStatusBlock) LOG_FUNC_ARG_OUT(FileInformation) LOG_FUNC_ARG(Length) - LOG_FUNC_ARG(FileInfo) + LOG_FUNC_ARG(FileInformationClass) LOG_FUNC_END; - // TODO: IIRC, this function is deprecated. Maybe we should just use - // ZwQueryInformationFile instead? + NTSTATUS ret; + PVOID ntFileInfo; - // if(FileInfo != FilePositionInformation && FileInfo != FileNetworkOpenInformation) - // CxbxKrnlCleanup("Unknown FILE_INFORMATION_CLASS 0x%.08X", FileInfo); + // Start with sizeof(corresponding struct) + size_t bufferSize = XboxFileInfoStructSizes[FileInformationClass]; - NTSTATUS ret = NtDll::NtQueryInformationFile( - FileHandle, - (NtDll::PIO_STATUS_BLOCK)IoStatusBlock, - (NtDll::PFILE_FS_SIZE_INFORMATION)FileInformation, - Length, - (NtDll::FILE_INFORMATION_CLASS)FileInfo); - - // - // DEBUGGING! - // + // We need to retry the operation in case the buffer is too small to fit the data + do { - /* - _asm int 3; - NtDll::FILE_NETWORK_OPEN_INFORMATION *pInfo = (NtDll::FILE_NETWORK_OPEN_INFORMATION*)FileInformation; + ntFileInfo = CxbxMalloc(bufferSize); - if(FileInfo == FileNetworkOpenInformation && (pInfo->AllocationSize.LowPart == 57344)) + ret = NtDll::NtQueryInformationFile( + FileHandle, + (NtDll::PIO_STATUS_BLOCK)IoStatusBlock, + ntFileInfo, + bufferSize, + (NtDll::FILE_INFORMATION_CLASS)FileInformationClass); + + // Buffer is too small; make a larger one + if (ret == STATUS_BUFFER_OVERFLOW) { - DbgPrintf("pInfo->AllocationSize : %d\n", pInfo->AllocationSize.LowPart); - DbgPrintf("pInfo->EndOfFile : %d\n", pInfo->EndOfFile.LowPart); + CxbxFree(ntFileInfo); - pInfo->EndOfFile.LowPart = 0x1000; - pInfo->AllocationSize.LowPart = 0x1000; - - fflush(stdout); + bufferSize *= 2; + // Bail out if the buffer gets too big + if (bufferSize > 65536) + return STATUS_INVALID_PARAMETER; // TODO: what's the appropriate error code to return here? + + ntFileInfo = CxbxMalloc(bufferSize); } - */ - } + } while (ret == STATUS_BUFFER_OVERFLOW); + + // Convert and copy NT data to the given Xbox struct + NTSTATUS convRet = NTToXboxFileInformation(ntFileInfo, FileInformation, FileInformationClass, Length); + + // Make sure to free the memory first + CxbxFree(ntFileInfo); if (FAILED(ret)) EmuWarning("NtQueryInformationFile failed! (0x%.08X)", ret); + // Prioritize the buffer overflow over real return code, + // in case the Xbox program decides to follow the same procedure above + if (convRet == STATUS_BUFFER_OVERFLOW) + return convRet; + RETURN(ret); } @@ -1006,7 +1008,7 @@ XBSYSAPI EXPORTNUM(215) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQuerySymbolicLinkOb LinkTarget->Length = LinkTarget->MaximumLength; } - memcpy(LinkTarget->Buffer, symbolicLinkObject->XboxFullPath.c_str(), LinkTarget->Length); + copy_string_to_PSTRING_to(symbolicLinkObject->XboxFullPath, LinkTarget); } if (ReturnedLength != NULL) @@ -1295,10 +1297,10 @@ XBSYSAPI EXPORTNUM(225) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtSetEvent // ****************************************************************** XBSYSAPI EXPORTNUM(226) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtSetInformationFile ( - IN HANDLE FileHandle, // TODO: correct paramters - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PVOID FileInformation, - IN ULONG Length, + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID FileInformation, + IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass ) { @@ -1309,11 +1311,13 @@ XBSYSAPI EXPORTNUM(226) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtSetInformationFile LOG_FUNC_ARG(Length) LOG_FUNC_ARG(FileInformationClass) LOG_FUNC_END; + + XboxToNTFileInformation(convertedFileInfo, FileInformation, FileInformationClass, &Length); NTSTATUS ret = NtDll::NtSetInformationFile( FileHandle, IoStatusBlock, - FileInformation, + convertedFileInfo, Length, FileInformationClass); diff --git a/src/CxbxKrnl/EmuKrnlOb.cpp b/src/CxbxKrnl/EmuKrnlOb.cpp index 137d6cbac..1fee68a91 100644 --- a/src/CxbxKrnl/EmuKrnlOb.cpp +++ b/src/CxbxKrnl/EmuKrnlOb.cpp @@ -50,8 +50,14 @@ namespace NtDll #include "EmuNtDll.h" }; +#include "CxbxKrnl.h" // For CxbxKrnlCleanup +#include "EmuFile.h" // For EmuNtSymbolicLinkObject, NtStatusToString(), etc. #include "Emu.h" // For EmuWarning() +#pragma warning(disable:4005) // Ignore redefined status values +#include +#pragma warning(default:4005) + // ****************************************************************** // * 0x00F0 - ObDirectoryObjectType // ****************************************************************** @@ -86,9 +92,32 @@ XBSYSAPI EXPORTNUM(243) xboxkrnl::NTSTATUS NTAPI xboxkrnl::ObOpenObjectByName LOG_FUNC_ARG_OUT(Handle) LOG_FUNC_END; - LOG_UNIMPLEMENTED(); + NTSTATUS ret = STATUS_OBJECT_PATH_NOT_FOUND; - RETURN(STATUS_SUCCESS); + if (ObjectType == &xboxkrnl::ObSymbolicLinkObjectType) + { + EmuNtSymbolicLinkObject* symbolicLinkObject = + FindNtSymbolicLinkObjectByName(PSTRING_to_string(ObjectAttributes->ObjectName)); + + if (symbolicLinkObject != NULL) + { + // Return a new handle (which is an EmuHandle, actually) : + *Handle = symbolicLinkObject->NewHandle(); + ret = STATUS_SUCCESS; + } + } + else + if (ObjectType == &xboxkrnl::ObDirectoryObjectType) + LOG_UNIMPLEMENTED(); + else + LOG_UNIMPLEMENTED(); + + if (ret == STATUS_SUCCESS) + DbgPrintf("EmuKrnl : ObOpenObjectByName Handle^ = 0x%.08X", *Handle); + else + EmuWarning("ObOpenObjectByName failed! (%s)", NtStatusToString(ret)); + + RETURN(ret); } // ****************************************************************** diff --git a/src/CxbxKrnl/EmuNtDll.h b/src/CxbxKrnl/EmuNtDll.h index 8a16fb611..1c869afb1 100644 --- a/src/CxbxKrnl/EmuNtDll.h +++ b/src/CxbxKrnl/EmuNtDll.h @@ -506,47 +506,47 @@ FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; // ****************************************************************** typedef enum _FILE_INFORMATION_CLASS { - FileDirectoryInformation=1, - FileFullDirectoryInformation, - FileBothDirectoryInformation, - FileBasicInformation, - FileStandardInformation, - FileInternalInformation, - FileEaInformation, - FileAccessInformation, - FileNameInformation, - FileRenameInformation, - FileLinkInformation, - FileNamesInformation, - FileDispositionInformation, - FilePositionInformation, - FileFullEaInformation, - FileModeInformation, - FileAlignmentInformation, - FileAllInformation, - FileAllocationInformation, - FileEndOfFileInformation, - FileAlternateNameInformation, - FileStreamInformation, - FilePipeInformation, - FilePipeLocalInformation, - FilePipeRemoteInformation, - FileMailslotQueryInformation, - FileMailslotSetInformation, - FileCompressionInformation, - FileCopyOnWriteInformation, - FileCompletionInformation, - FileMoveClusterInformation, - FileQuotaInformation, - FileReparsePointInformation, - FileNetworkOpenInformation, - FileObjectIdInformation, - FileTrackingInformation, - FileOleDirectoryInformation, - FileContentIndexInformation, - FileInheritContentIndexInformation, - FileOleInformation, - FileMaximumInformation + FileDirectoryInformation=1, + FileFullDirectoryInformation, + FileBothDirectoryInformation, + FileBasicInformation, + FileStandardInformation, + FileInternalInformation, + FileEaInformation, + FileAccessInformation, + FileNameInformation, + FileRenameInformation, + FileLinkInformation, + FileNamesInformation, + FileDispositionInformation, + FilePositionInformation, + FileFullEaInformation, + FileModeInformation, + FileAlignmentInformation, + FileAllInformation, + FileAllocationInformation, + FileEndOfFileInformation, + FileAlternateNameInformation, + FileStreamInformation, + FilePipeInformation, + FilePipeLocalInformation, + FilePipeRemoteInformation, + FileMailslotQueryInformation, + FileMailslotSetInformation, + FileCompressionInformation, + FileCopyOnWriteInformation, + FileCompletionInformation, + FileMoveClusterInformation, + FileQuotaInformation, + FileReparsePointInformation, + FileNetworkOpenInformation, + FileObjectIdInformation, + FileTrackingInformation, + FileOleDirectoryInformation, + FileContentIndexInformation, + FileInheritContentIndexInformation, + FileOleInformation, + FileMaximumInformation } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; @@ -572,34 +572,142 @@ FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; // ****************************************************************** typedef struct _FILE_DIRECTORY_INFORMATION { - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - WCHAR FileName[1]; // Offset: 0x40 + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + WCHAR FileName[1]; // Offset: 0x40 } FILE_DIRECTORY_INFORMATION; +// ****************************************************************** +// * FILE_RENAME_INFORMATION +// ****************************************************************** +typedef struct _FILE_RENAME_INFORMATION +{ + BOOLEAN ReplaceIfExists; + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} +FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION; + +// ****************************************************************** +// * FILE_LINK_INFORMATION +// ****************************************************************** +typedef struct _FILE_LINK_INFORMATION { + BOOLEAN ReplaceIfExists; + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION; + // ****************************************************************** // * FILE_NETWORK_OPEN_INFORMATION // ****************************************************************** -typedef struct _FILE_NETWORK_OPEN_INFORMATION -{ - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG FileAttributes; -} -FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; +typedef struct _FILE_NETWORK_OPEN_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; + ULONG Reserved; +} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION; + +// ****************************************************************** +// * FILE_BASIC_INFORMATION +// ****************************************************************** +typedef struct _FILE_BASIC_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + ULONG FileAttributes; +} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; + +// ****************************************************************** +// * FILE_STANDARD_INFORMATION +// ****************************************************************** +typedef struct _FILE_STANDARD_INFORMATION { + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; +} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; + +// ****************************************************************** +// * FILE_INTERNAL_INFORMATION +// ****************************************************************** +typedef struct _FILE_INTERNAL_INFORMATION { + LARGE_INTEGER IndexNumber; +} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION; + +// ****************************************************************** +// * FILE_EA_INFORMATION +// ****************************************************************** +typedef struct _FILE_EA_INFORMATION { + ULONG EaSize; +} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION; + +// ****************************************************************** +// * FILE_ACCESS_INFORMATION +// ****************************************************************** +typedef struct _FILE_ACCESS_INFORMATION { + ACCESS_MASK AccessFlags; +} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION; + +// ****************************************************************** +// * FILE_POSITION_INFORMATION +// ****************************************************************** +typedef struct _FILE_POSITION_INFORMATION { + LARGE_INTEGER CurrentByteOffset; +} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; + +// ****************************************************************** +// * FILE_MODE_INFORMATION +// ****************************************************************** +typedef struct _FILE_MODE_INFORMATION { + ULONG Mode; +} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; + +// ****************************************************************** +// * FILE_ALIGNMENT_INFORMATION +// ****************************************************************** +typedef struct _FILE_ALIGNMENT_INFORMATION { + ULONG AlignmentRequirement; +} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; + +// ****************************************************************** +// * FILE_NAME_INFORMATION +// ****************************************************************** +typedef struct _FILE_NAME_INFORMATION { + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; + +// ****************************************************************** +// * FILE_ALL_INFORMATION +// ****************************************************************** +typedef struct _FILE_ALL_INFORMATION { + FILE_BASIC_INFORMATION BasicInformation; + FILE_STANDARD_INFORMATION StandardInformation; + FILE_INTERNAL_INFORMATION InternalInformation; + FILE_EA_INFORMATION EaInformation; + FILE_ACCESS_INFORMATION AccessInformation; + FILE_POSITION_INFORMATION PositionInformation; + FILE_MODE_INFORMATION ModeInformation; + FILE_ALIGNMENT_INFORMATION AlignmentInformation; + FILE_NAME_INFORMATION NameInformation; +} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; // ****************************************************************** // * TIME_FIELDS @@ -1242,7 +1350,7 @@ typedef NTSTATUS (NTAPI *FPTR_NtQueryDirectoryFile) typedef NTSTATUS (NTAPI *FPTR_NtQueryFullAttributesFile) ( IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PVOID Attributes + OUT PFILE_NETWORK_OPEN_INFORMATION Attributes ); // ****************************************************************** @@ -1252,7 +1360,7 @@ typedef NTSTATUS (NTAPI *FPTR_NtQueryInformationFile) ( IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PFILE_FS_SIZE_INFORMATION FileInformation, + OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInfo ); diff --git a/src/Standard/Cxbe/Main.cpp b/src/Standard/Cxbe/Main.cpp deleted file mode 100644 index d78c7f388..000000000 --- a/src/Standard/Cxbe/Main.cpp +++ /dev/null @@ -1,277 +0,0 @@ -// ****************************************************************** -// * -// * .,-::::: .,:: .::::::::. .,:: .: -// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; -// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' -// * $$$ Y$$$P $$""""Y$$ Y$$$P -// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, -// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, -// * -// * Cxbx->Standard->Cxbe->Main.cpp -// * -// * This file is part of the Cxbx project. -// * -// * Cxbx and Cxbe are free software; you can redistribute them -// * and/or modify them under the terms of the GNU General Public -// * License as published by the Free Software Foundation; either -// * version 2 of the license, or (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have recieved a copy of the GNU General Public License -// * along with this program; see the file COPYING. -// * If not, write to the Free Software Foundation, Inc., -// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. -// * -// * (c) 2002-2003 Aaron Robinson -// * -// * All rights reserved -// * -// ****************************************************************** -#include "Exe.h" -#include "Xbe.h" - -#include - -// static global(s) -static void ShowUsage(); -static void MakeUpper(char *str); - -// program entry point -int main(int argc, char *argv[]) -{ - char szErrorMessage[266] = {0}; - char szExeFilename[266] = {0}; - char szXbeFilename[266] = {0}; - char szDumpFilename[266] = {0}; - char szXbeTitle[256] = "Untitled"; - bool bRetail = true; - - // parse command line - for(int v=1;v 256) - printf("WARNING: Title too long, using default title\n"); - else - strcpy(szXbeTitle, szParam); - } - else if(strcmp(szOptionU, "MODE") == 0) - { - if(strcmp(szParamU, "RETAIL") == 0) - bRetail = true; - else if(strcmp(szParamU, "DEBUG") == 0) - bRetail = false; - else - { - strcpy(szErrorMessage, "invalid MODE"); - goto cleanup; - } - } - else - { - char szBuffer[255]; - sprintf(szBuffer, "Unrecognized command : %s", szOption); - strcpy(szErrorMessage, szBuffer); - goto cleanup; - } - } - } - - // verify we recieved the required parameters - if(szExeFilename[0] == '\0') - { - ShowUsage(); - return 1; - } - - // if we don't have an Xbe filename, generate one from szExeFilename - if(szXbeFilename[0] == '\0') - { - strcpy(szXbeFilename, szExeFilename); - - char *szFilename = &szXbeFilename[0]; - - // locate last \ or / (if there are any) - { - for(int c=0;szXbeFilename[c] != 0;c++) - if(szXbeFilename[c] == '\\' || szXbeFilename[c] == '/') - szFilename = &szXbeFilename[c+1]; - } - - // locate and remove last . (if there are any) - { - char szWorkingU[266]; - - char *szWorking = szFilename; - - strncpy(szWorkingU, szWorking, 265); - - for(int c=0;szFilename[c] != 0;c++) - if(szFilename[c] == '.') - szWorking = &szFilename[c]; - - MakeUpper(szWorking); - - if(strcmp(szWorkingU, ".exe") == 0) - strcpy(szWorking, ".xbe"); - else - strcat(szXbeFilename, ".xbe"); - } - } - - // open and convert Exe file - { - Exe *ExeFile = new Exe(szExeFilename); - - if(ExeFile->GetError() != 0) - { - strcpy(szErrorMessage, ExeFile->GetError()); - goto cleanup; - } - - Xbe *XbeFile = new Xbe(ExeFile, szXbeTitle, bRetail); - - if(XbeFile->GetError() != 0) - { - strcpy(szErrorMessage, XbeFile->GetError()); - goto cleanup; - } - - if(szDumpFilename[0] != 0) - { - FILE *outfile = fopen(szDumpFilename, "wt"); - XbeFile->DumpInformation(outfile); - fclose(outfile); - - if(XbeFile->GetError() != 0) - { - if(XbeFile->IsFatal()) - { - strcpy(szErrorMessage, XbeFile->GetError()); - goto cleanup; - } - else - { - printf("DUMPINFO -> Warning: %s\n", XbeFile->GetError()); - XbeFile->ClearError(); - } - } - } - - XbeFile->Export(szXbeFilename); - - if(XbeFile->GetError() != 0) - { - strcpy(szErrorMessage, XbeFile->GetError()); - goto cleanup; - } - } - -cleanup: - - if(szErrorMessage[0] != 0) - { - ShowUsage(); - - printf("\n"); - printf(" * Error : %s\n", szErrorMessage); - - return 1; - } - - return 0; -} - -// show program usage -static void ShowUsage() -{ - printf - ( - "CXBE XBE->EXE (XBox->Win32) Relinker (CXBX Core Version " _CXBX_VERSION ")\n" - "Copyright (C) Aaron Robinson 2002-2003. All rights reserved.\n" - "\n" - "Usage : cxbe [options] [exefile]\n" - "\n" - "Options :\n" - "\n" - " -OUT:filename\n" - " -DUMPINFO:filename\n" - " -TITLE:title\n" - " -MODE:{debug|retail}\n" - ); -} - -// convert string to upper case -static void MakeUpper(char *str) -{ - while(*str != '\0') - { - if(*str >= 'a' && *str <= 'z') - *str = *str - ('a' - 'A'); - - str++; - } -}