Merge remote-tracking branch 'refs/remotes/Cxbx-Reloaded/master' into OOVPA_Refactoring

This commit is contained in:
PatrickvL 2016-12-23 11:34:13 +01:00
commit 4971b951a6
23 changed files with 1197 additions and 2319 deletions

View File

@ -163,7 +163,6 @@
<ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8Types.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuDInput.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuDSound.h" />
<ClInclude Include="..\..\src\Cxbx\EmuExe.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuShared.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuXapi.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuXG.h" />
@ -177,6 +176,7 @@
<ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8\State.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8\VertexBuffer.h" />
<ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8\VertexShader.h" />
<ClInclude Include="..\..\src\Cxbx\ResCxbx.h" />
<ClInclude Include="..\..\src\Cxbx\Wnd.h" />
<ClInclude Include="..\..\src\Cxbx\WndAbout.h" />
<ClInclude Include="..\..\src\Cxbx\WndMain.h" />
@ -215,12 +215,6 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\..\src\Cxbx\EmuExe.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\..\src\Common\Error.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>

View File

@ -271,7 +271,7 @@ XBSYSAPI VOID *NtQueryEvent;
XBSYSAPI EXPORTNUM(210) NTSTATUS NTAPI NtQueryFullAttributesFile
(
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PVOID Attributes
OUT PFILE_NETWORK_OPEN_INFORMATION Attributes
);
// ******************************************************************

View File

@ -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
// ******************************************************************
@ -611,6 +635,267 @@ typedef struct _FILE_DIRECTORY_INFORMATION
}
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
// ******************************************************************

Binary file not shown.

View File

@ -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
@ -77,10 +70,7 @@ 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
@ -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

View File

@ -32,7 +32,6 @@
// *
// ******************************************************************
#include "Xbe.h"
#include "Exe.h"
#include "CxbxUtil.h"
#include <memory.h>
@ -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;v<m_Header.dwSections;v++)
{
uint32 s = 0;
while(s < 8 && x_Exe->m_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;v<m_Header.dwSections;v++)
{
printf("Xbe::Xbe: Generating Section Header %.04X...", v);
uint32 characteristics = x_Exe->m_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;v<m_Header.dwSections;v++)
{
printf("Xbe::Xbe: Generating Section %.04X...", v);
uint32 RawSize = m_SectionHeader[v].dwSizeofRaw;
m_bzSection[v] = new uint08[RawSize];
memcpy(m_bzSection[v], x_Exe->m_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()
{

View File

@ -50,9 +50,6 @@ class Xbe : public Error
// 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();

View File

@ -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 <caustik@caustik.com>
// *
// * All rights reserved
// *
// ******************************************************************
#include "EmuExe.h"
#include "Prolog.h"
#include "CxbxUtil.h"
#include "CxbxKrnl/CxbxKrnl.h"
#include <cstdio>
// ******************************************************************
// * 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;d<m_OptionalHeader.m_data_directories;d++)
{
m_OptionalHeader.m_image_data_directory[d].m_virtual_addr = 0;
m_OptionalHeader.m_image_data_directory[d].m_size = 0;
}
printf("OK\n");
}
// ******************************************************************
// * generate section headers
// ******************************************************************
{
printf("EmuExe::EmuExe: Generating Section Headers...\n");
m_SectionHeader = new SectionHeader[m_Header.m_sections];
// ******************************************************************
// * start appending section headers at this point
// ******************************************************************
uint32 dwSectionCursor = x_Xbe->m_SectionHeader[0].dwRawAddr;
// ******************************************************************
// * generate xbe section headers
// ******************************************************************
{
for(uint32 v=0;v<x_Xbe->m_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;v<x_Xbe->m_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;v<x_Xbe->m_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;v<m_Header.m_sections;v++)
{
uint32 characteristics = m_SectionHeader[v].m_characteristics;
if( (characteristics & IMAGE_SCN_MEM_EXECUTE) || (characteristics & IMAGE_SCN_CNT_CODE) )
sizeof_code += m_SectionHeader[v].m_sizeof_raw;
if( (characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) )
sizeof_data += m_SectionHeader[v].m_sizeof_raw;
}
// ******************************************************************
// * calculate size of image
// ******************************************************************
sizeof_image = sizeof_undata + sizeof_data + sizeof_code + m_OptionalHeader.m_sizeof_headers;
sizeof_image = RoundUp(sizeof_image, PE_SEGM_ALIGN);
// ******************************************************************
// * update optional header as necessary
// ******************************************************************
m_OptionalHeader.m_sizeof_code = sizeof_code;
m_OptionalHeader.m_sizeof_initialized_data = sizeof_data;
m_OptionalHeader.m_sizeof_uninitialized_data = sizeof_undata;
m_OptionalHeader.m_sizeof_image = sizeof_image;
}
// ******************************************************************
// * we'll set code base as the virtual address of the first section
// ******************************************************************
m_OptionalHeader.m_code_base = m_SectionHeader[0].m_virtual_addr;
// ******************************************************************
// * we'll set data base as the virtual address of the first section
// * that is not marked as containing code or being executable
// ******************************************************************
for(uint32 v=0;v<m_Header.m_sections;v++)
{
uint32 characteristics = m_SectionHeader[v].m_characteristics;
if( !(characteristics & IMAGE_SCN_MEM_EXECUTE) || !(characteristics & IMAGE_SCN_CNT_CODE) )
{
m_OptionalHeader.m_data_base = m_SectionHeader[v].m_virtual_addr;
break;
}
}
printf("OK\n");
}
}

View File

@ -1,52 +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.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 <caustik@caustik.com>
// *
// * All rights reserved
// *
// ******************************************************************
#ifndef EMUEXE_H
#define EMUEXE_H
#include "Common/Exe.h"
#include <windows.h>
// ******************************************************************
// * 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

View File

@ -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
//

View File

@ -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 */

View File

@ -37,7 +37,6 @@
#include "DlgVideoConfig.h"
#include "CxbxKrnl/EmuShared.h"
#include "ResCxbx.h"
#include "EmuExe.h"
#include "jpegdec/jpegdec.h"
#include <io.h>
@ -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;v<RECENT_XBE_SIZE;v++)
for(int v=0;v<RECENT_XBE_SIZE;v++)
m_szRecentXbe[v] = 0;
for(v=0;v<RECENT_EXE_SIZE;v++)
m_szRecentExe[v] = 0;
}
// center to desktop
@ -99,12 +92,6 @@ WndMain::WndMain(HINSTANCE x_hInstance) : Wnd(x_hInstance), m_bCreated(false), m
dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegQueryValueEx(hKey, "RecentXbe", NULL, &dwType, (PBYTE)&m_dwRecentXbe, &dwSize);
dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegQueryValueEx(hKey, "RecentExe", NULL, &dwType, (PBYTE)&m_dwRecentExe, &dwSize);
dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegQueryValueEx(hKey, "AutoConvertToExe", NULL, &dwType, (PBYTE)&m_AutoConvertToExe, &dwSize);
dwType = REG_SZ; dwSize = MAX_PATH;
RegQueryValueEx(hKey, "CxbxDebugFilename", NULL, &dwType, (PBYTE)m_CxbxDebugFilename, &dwSize);
@ -125,18 +112,6 @@ WndMain::WndMain(HINSTANCE x_hInstance) : Wnd(x_hInstance), m_bCreated(false), m
RegQueryValueEx(hKey, buffer, NULL, &dwType, (PBYTE)m_szRecentXbe[v], &dwSize);
}
for(v=0;v<m_dwRecentExe;v++)
{
char buffer[32];
sprintf(buffer, "RecentExe%d", v);
m_szRecentExe[v] = (char*)calloc(1, MAX_PATH);
dwType = REG_SZ; dwSize = MAX_PATH;
RegQueryValueEx(hKey, buffer, NULL, &dwType, (PBYTE)m_szRecentExe[v], &dwSize);
}
RegCloseKey(hKey);
}
}
@ -168,19 +143,6 @@ WndMain::~WndMain()
free(m_szRecentXbe[v]);
}
for(v=0;v<m_dwRecentExe;v++)
{
char buffer[32];
sprintf(buffer, "RecentExe%d", v);
dwType = REG_SZ; dwSize = MAX_PATH;
RegSetValueEx(hKey, buffer, 0, dwType, (PBYTE)m_szRecentExe[v], dwSize);
free(m_szRecentExe[v]);
}
dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegSetValueEx(hKey, "CxbxDebug", 0, dwType, (PBYTE)&m_CxbxDebug, dwSize);
@ -190,12 +152,6 @@ WndMain::~WndMain()
dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegSetValueEx(hKey, "RecentXbe", 0, dwType, (PBYTE)&m_dwRecentXbe, dwSize);
dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegSetValueEx(hKey, "RecentExe", 0, dwType, (PBYTE)&m_dwRecentExe, dwSize);
dwType = REG_DWORD; dwSize = sizeof(DWORD);
RegSetValueEx(hKey, "AutoConvertToExe", 0, dwType, (PBYTE)&m_AutoConvertToExe, dwSize);
dwType = REG_SZ; dwSize = MAX_PATH;
RegSetValueEx(hKey, "CxbxDebugFilename", 0, dwType, (PBYTE)m_CxbxDebugFilename, dwSize);
@ -207,10 +163,8 @@ WndMain::~WndMain()
// cleanup allocations
{
delete m_Xbe;
delete m_Exe;
free(m_XbeFilename);
free(m_ExeFilename);
free(m_CxbxDebugFilename);
free(m_KrnlDebugFilename);
@ -413,7 +367,7 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
if(m_Xbe != 0 && (m_hwndChild == NULL) && m_bCanStart)
{
m_bCanStart = false;
StartEmulation(m_AutoConvertToExe, hwnd);
StartEmulation(hwnd);
}
}
break;
@ -489,42 +443,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
SaveXbeAs();
break;
case ID_FILE_IMPORTFROMEXE:
{
m_ExeFilename[0] = '\0';
OPENFILENAME ofn = {0};
char filename[MAX_PATH] = {0};
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.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if(GetOpenFileName(&ofn) == TRUE)
{
if(m_Xbe != 0)
CloseXbe();
if(m_Xbe != 0)
break;
ImportExe(ofn.lpstrFile);
}
}
break;
case ID_FILE_EXPORTTOEXE:
ConvertToExe(NULL, true, hwnd);
break;
case ID_FILE_RXBE_0:
case ID_FILE_RXBE_1:
case ID_FILE_RXBE_2:
@ -544,7 +462,7 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
HMENU menu = GetMenu(m_hwnd);
HMENU file_menu = GetSubMenu(menu, 0);
HMENU rxbe_menu = GetSubMenu(file_menu, 9);
HMENU rxbe_menu = GetSubMenu(file_menu, 6);
char szBuffer[270];
@ -556,37 +474,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
}
break;
case ID_FILE_REXE_0:
case ID_FILE_REXE_1:
case ID_FILE_REXE_2:
case ID_FILE_REXE_3:
case ID_FILE_REXE_4:
case ID_FILE_REXE_5:
case ID_FILE_REXE_6:
case ID_FILE_REXE_7:
case ID_FILE_REXE_8:
case ID_FILE_REXE_9:
{
if(m_Xbe != 0)
CloseXbe();
if(m_Xbe != 0)
break;
HMENU menu = GetMenu(m_hwnd);
HMENU file_menu = GetSubMenu(menu, 0);
HMENU rexe_menu = GetSubMenu(file_menu, 10);
char szBuffer[270];
GetMenuString(rexe_menu, LOWORD(wParam), szBuffer, 269, MF_BYCOMMAND);
char *szFilename = (char*)((uint32)szBuffer + 5);
ImportExe(szFilename);
}
break;
case ID_FILE_EXIT:
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
@ -790,7 +677,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
}
else
{
m_bExeChanged = true;
m_bXbeChanged = true;
LoadLogo();
@ -810,7 +696,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
case ID_EDIT_PATCH_ALLOW64MB:
{
m_bExeChanged = true;
m_bXbeChanged = true;
m_Xbe->m_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);
@ -1240,26 +1096,14 @@ 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;v<max;v++)
EnableMenuItem(rxbe_menu, ID_FILE_RXBE_0 + v, MF_BYCOMMAND | MF_ENABLED);
}
// recent exe files menu
{
HMENU rexe_menu = GetSubMenu(file_menu, 10);
int max = m_dwRecentExe;
for(int v=0;v<max;v++)
EnableMenuItem(rexe_menu, ID_FILE_REXE_0 + v, MF_BYCOMMAND | MF_ENABLED);
}
}
// edit menu
@ -1337,32 +1181,6 @@ void WndMain::RefreshMenus()
}
}
// settings menu
{
HMENU sett_menu = GetSubMenu(menu, 3);
HMENU auto_menu = GetSubMenu(sett_menu, 4);
// check appropriate choice
if(m_AutoConvertToExe == AUTO_CONVERT_WINDOWS_TEMP)
{
CheckMenuItem(auto_menu, ID_SETTINGS_GENWT, MF_BYCOMMAND | MF_CHECKED);
CheckMenuItem(auto_menu, ID_SETTINGS_GENXP, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(auto_menu, ID_SETTINGS_GENMA, MF_BYCOMMAND | MF_UNCHECKED);
}
else if(m_AutoConvertToExe == AUTO_CONVERT_XBE_PATH)
{
CheckMenuItem(auto_menu, ID_SETTINGS_GENWT, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(auto_menu, ID_SETTINGS_GENXP, MF_BYCOMMAND | MF_CHECKED);
CheckMenuItem(auto_menu, ID_SETTINGS_GENMA, MF_BYCOMMAND | MF_UNCHECKED);
}
else
{
CheckMenuItem(auto_menu, ID_SETTINGS_GENWT, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(auto_menu, ID_SETTINGS_GENXP, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(auto_menu, ID_SETTINGS_GENMA, MF_BYCOMMAND | MF_CHECKED);
}
}
// emulation menu
{
HMENU emul_menu = GetSubMenu(menu, 4);
@ -1417,8 +1235,7 @@ void WndMain::UpdateDebugConsoles()
void WndMain::UpdateRecentFiles()
{
HMENU FileMenu = GetSubMenu(GetMenu(m_hwnd), 0);
HMENU RXbeMenu = GetSubMenu(FileMenu, 9);
HMENU RExeMenu = GetSubMenu(FileMenu, 10);
HMENU RXbeMenu = GetSubMenu(FileMenu, 6);
// clear existing menu items
{
@ -1427,10 +1244,6 @@ void WndMain::UpdateRecentFiles()
max = GetMenuItemCount(RXbeMenu);
for(v=0;v<max;v++)
RemoveMenu(RXbeMenu, 0, MF_BYPOSITION);
max = GetMenuItemCount(RExeMenu);
for(v=0;v<max;v++)
RemoveMenu(RExeMenu, 0, MF_BYPOSITION);
}
// insert recent xbe files
@ -1453,27 +1266,6 @@ void WndMain::UpdateRecentFiles()
AppendMenu(RXbeMenu, MF_STRING, ID_FILE_RXBE_0 + v, szBuffer);
}
}
// insert recent exe files
{
char szBuffer[270];
int max = m_dwRecentExe;
// if there are no recent files, throw in a disabled "(none)"
if(max == 0)
{
AppendMenu(RExeMenu, MF_STRING, ID_FILE_REXE_0, "(none)");
EnableMenuItem(RExeMenu, ID_FILE_REXE_0, MF_BYCOMMAND | MF_GRAYED);
}
// NOTE: Resource defines ID_FILE_REXE_0 through ID_FILE_REXE_9 must be in order
for(int v=0;v<max;v++)
{
sprintf(szBuffer, "&%d : %s", v, m_szRecentExe[v]);
AppendMenu(RExeMenu, MF_STRING, ID_FILE_REXE_0 + v, szBuffer);
}
}
}
// open an xbe file
@ -1482,8 +1274,6 @@ void WndMain::OpenXbe(const char *x_filename)
if(m_Xbe != 0)
return;
m_ExeFilename[0] = '\0';
strcpy(m_XbeFilename, x_filename);
m_Xbe = new Xbe(m_XbeFilename);
@ -1656,160 +1446,8 @@ void WndMain::SaveXbeAs()
SaveXbe(ofn.lpstrFile);
}
// import an exe file
void WndMain::ImportExe(const char *x_filename)
{
m_XbeFilename[0] = '\0';
Exe *i_exe = new Exe(x_filename);
if(i_exe->GetError() != 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;c++, r++)
{
if(strcmp(m_szRecentExe[c], m_ExeFilename) == 0)
{
found = true;
r++;
}
if(r != c)
{
if(m_szRecentExe[r] == 0 || r > 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];

View File

@ -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?
// ******************************************************************

View File

@ -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);
}
//
@ -589,7 +595,7 @@ extern "C" CXBXKRNL_API void CxbxKrnlInit
// Make sure Xbox1 code runs on one core :
SetThreadAffinityMask(GetCurrentThread(), g_CPUXbox);
}
}
DbgPrintf("EmuMain (0x%X): Initial thread starting.\n", GetCurrentThreadId());

View File

@ -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);

View File

@ -37,54 +37,60 @@
#include "EmuFile.h"
#include <vector>
#include <string>
#include <cassert>
#include <Shlobj.h>
#include <Shlwapi.h>
#pragma warning(disable:4005) // Ignore redefined status values
#include <ntstatus.h>
#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')
{
@ -361,8 +412,7 @@ NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::strin
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;
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<xboxkrnl::FILE_LINK_INFORMATION *>(xboxFileInformation);
result = _XboxToNTLinkInfo(xboxLinkInfo, Length);
break;
}
case xboxkrnl::FileRenameInformation:
{
xboxkrnl::FILE_RENAME_INFORMATION *xboxRenameInfo = reinterpret_cast<xboxkrnl::FILE_RENAME_INFORMATION *>(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<NtDll::FILE_ALL_INFORMATION *>(nativeFileInformation);
xboxkrnl::FILE_ALL_INFORMATION *xboxAllInfo = reinterpret_cast<xboxkrnl::FILE_ALL_INFORMATION *>(xboxFileInformation);
result = _NTToXboxAllInfo(ntAllInfo, xboxAllInfo, Length);
break;
}
case NtDll::FileBasicInformation:
{
NtDll::FILE_BASIC_INFORMATION *ntBasicInfo = reinterpret_cast<NtDll::FILE_BASIC_INFORMATION *>(nativeFileInformation);
xboxkrnl::FILE_BASIC_INFORMATION *xboxBasicInfo = reinterpret_cast<xboxkrnl::FILE_BASIC_INFORMATION *>(xboxFileInformation);
result = _NTToXboxBasicInfo(ntBasicInfo, xboxBasicInfo, Length);
break;
}
case NtDll::FileNameInformation:
{
NtDll::FILE_NAME_INFORMATION *ntNameInfo = reinterpret_cast<NtDll::FILE_NAME_INFORMATION *>(nativeFileInformation);
xboxkrnl::FILE_NAME_INFORMATION *xboxNameInfo = reinterpret_cast<xboxkrnl::FILE_NAME_INFORMATION *>(xboxFileInformation);
result = _NTToXboxNameInfo(ntNameInfo, xboxNameInfo, Length);
break;
}
case NtDll::FileNetworkOpenInformation:
{
NtDll::FILE_NETWORK_OPEN_INFORMATION *ntNetOpenInfo = reinterpret_cast<NtDll::FILE_NETWORK_OPEN_INFORMATION *>(nativeFileInformation);
xboxkrnl::FILE_NETWORK_OPEN_INFORMATION *xboxNetOpenInfo = reinterpret_cast<xboxkrnl::FILE_NETWORK_OPEN_INFORMATION *>(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)

View File

@ -44,6 +44,7 @@ namespace xboxkrnl
#include <cstdio>
#include <string>
#include <memory>
// ******************************************************************
// * 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<PVOID> __var_shared_ptr; \
if (NULL == var) \
{ \
__var_shared_ptr = NULL; \
var = orig; \
} \
else \
__var_shared_ptr = std::shared_ptr<PVOID>(&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

View File

@ -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);

View File

@ -51,6 +51,7 @@ enum CREATE_OPTION;
#include <sstream> // for std::ostream
//?#include "Logging.h"
// Headers for rendering non-Xbox types :
std::ostream& operator<<(std::ostream& os, const PULONG& value);

View File

@ -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,8 +448,6 @@ XBSYSAPI EXPORTNUM(196) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtDeviceIoControlFile
NTSTATUS ret = STATUS_SUCCESS;
if (IsEmuHandle(FileHandle))
{
switch (IoControlCode)
{
case 0x4D014: // IOCTL_SCSI_PASS_THROUGH_DIRECT
@ -466,19 +464,6 @@ XBSYSAPI EXPORTNUM(196) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtDeviceIoControlFile
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,17 +671,17 @@ 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) :
*LinkHandle = symbolicLinkObject->NewHandle();
ret = STATUS_SUCCESS;
}
else
if (ret != STATUS_SUCCESS)
EmuWarning("NtOpenSymbolicLinkObject failed! (%s)", NtStatusToString(ret));
else
@ -821,33 +806,34 @@ 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,
@ -855,12 +841,13 @@ XBSYSAPI EXPORTNUM(207) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryDirectoryFile
(NtDll::PIO_APC_ROUTINE)ApcRoutine,
ApcContext,
(NtDll::IO_STATUS_BLOCK*)IoStatusBlock,
NtFileDirInfo,
/*Length=*/0x40 + 160 * 2,
/*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(
// We need to retry the operation in case the buffer is too small to fit the data
do
{
ntFileInfo = CxbxMalloc(bufferSize);
ret = NtDll::NtQueryInformationFile(
FileHandle,
(NtDll::PIO_STATUS_BLOCK)IoStatusBlock,
(NtDll::PFILE_FS_SIZE_INFORMATION)FileInformation,
Length,
(NtDll::FILE_INFORMATION_CLASS)FileInfo);
ntFileInfo,
bufferSize,
(NtDll::FILE_INFORMATION_CLASS)FileInformationClass);
//
// DEBUGGING!
//
// Buffer is too small; make a larger one
if (ret == STATUS_BUFFER_OVERFLOW)
{
/*
_asm int 3;
NtDll::FILE_NETWORK_OPEN_INFORMATION *pInfo = (NtDll::FILE_NETWORK_OPEN_INFORMATION*)FileInformation;
CxbxFree(ntFileInfo);
if(FileInfo == FileNetworkOpenInformation && (pInfo->AllocationSize.LowPart == 57344))
{
DbgPrintf("pInfo->AllocationSize : %d\n", pInfo->AllocationSize.LowPart);
DbgPrintf("pInfo->EndOfFile : %d\n", pInfo->EndOfFile.LowPart);
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?
pInfo->EndOfFile.LowPart = 0x1000;
pInfo->AllocationSize.LowPart = 0x1000;
fflush(stdout);
}
*/
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,7 +1297,7 @@ XBSYSAPI EXPORTNUM(225) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtSetEvent
// ******************************************************************
XBSYSAPI EXPORTNUM(226) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtSetInformationFile
(
IN HANDLE FileHandle, // TODO: correct paramters
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
@ -1310,10 +1312,12 @@ XBSYSAPI EXPORTNUM(226) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtSetInformationFile
LOG_FUNC_ARG(FileInformationClass)
LOG_FUNC_END;
XboxToNTFileInformation(convertedFileInfo, FileInformation, FileInformationClass, &Length);
NTSTATUS ret = NtDll::NtSetInformationFile(
FileHandle,
IoStatusBlock,
FileInformation,
convertedFileInfo,
Length,
FileInformationClass);

View File

@ -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 <ntstatus.h>
#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;
NTSTATUS ret = STATUS_OBJECT_PATH_NOT_FOUND;
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();
RETURN(STATUS_SUCCESS);
if (ret == STATUS_SUCCESS)
DbgPrintf("EmuKrnl : ObOpenObjectByName Handle^ = 0x%.08X", *Handle);
else
EmuWarning("ObOpenObjectByName failed! (%s)", NtStatusToString(ret));
RETURN(ret);
}
// ******************************************************************

View File

@ -586,11 +586,32 @@ typedef struct _FILE_DIRECTORY_INFORMATION
}
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
{
typedef struct _FILE_NETWORK_OPEN_INFORMATION {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
@ -598,8 +619,95 @@ typedef struct _FILE_NETWORK_OPEN_INFORMATION
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG FileAttributes;
}
FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
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
);

View File

@ -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 <caustik@caustik.com>
// *
// * All rights reserved
// *
// ******************************************************************
#include "Exe.h"
#include "Xbe.h"
#include <string.h>
// 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<argc;v++)
{
char *szOption = 0;
char *szParam = 0;
uint dwParamSize = 0;
// if this isn't an option, it must be the Exe file
if(argv[v][0] != '-')
{
strncpy(szExeFilename, argv[v], 265);
continue;
}
// locate the colon and seperate option / parameters
{
uint dwColon = (uint)-1;
for(uint c=1;argv[v][c] != 0;c++)
{
if(argv[v][c] == ':')
{
dwColon = c;
break;
}
}
if(dwColon == (uint)-1)
{
strcpy(szErrorMessage, "Command line format error");
goto cleanup;
}
argv[v][dwColon] = '\0';
szOption = &argv[v][1];
szParam = &argv[v][dwColon + 1];
while(szParam[dwParamSize] != 0)
dwParamSize++;
}
// interpret the current switch
{
char szOptionU[266] = {0};
char szParamU[266] = {0};
strncpy(szOptionU, szOption, 265);
strncpy(szParamU, szParam, 265);
MakeUpper(szOptionU);
MakeUpper(szParamU);
if(strcmp(szOptionU, "OUT") == 0)
{
strcpy(szXbeFilename, szParam);
}
else if(strcmp(szOptionU, "DUMPINFO") == 0)
{
strcpy(szDumpFilename, szParam);
}
else if(strcmp(szOptionU, "TITLE") == 0)
{
if(dwParamSize > 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++;
}
}