Merge remote-tracking branch 'refs/remotes/Cxbx-Reloaded/master' into OOVPA_Refactoring
This commit is contained in:
commit
4971b951a6
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -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.
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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?
|
||||
// ******************************************************************
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue