Finally solved the Symbolic Link corruption bug using the Dxbx implementation of EmuFile
This commit is contained in:
parent
0a51fdf535
commit
0aae6c5f67
|
@ -81,19 +81,6 @@ 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';
|
||||
|
||||
// Array of EmuHandles in the system
|
||||
EmuHandle EmuHandle::Handles[EMU_MAX_HANDLES];
|
||||
|
||||
// Pointer to first free handle in array, or NULL if none
|
||||
volatile EmuHandle *EmuHandle::FirstFree;
|
||||
|
||||
// Pointer to last free handle in array, or NULL if none
|
||||
volatile EmuHandle *EmuHandle::LastFree;
|
||||
|
||||
// Lock on the handle system
|
||||
CRITICAL_SECTION EmuHandle::HandleLock;
|
||||
|
||||
EmuNtSymbolicLinkObject* NtSymbolicLinkObjects[26];
|
||||
|
||||
struct XboxDevice {
|
||||
|
@ -103,6 +90,60 @@ struct XboxDevice {
|
|||
};
|
||||
std::vector<XboxDevice> Devices;
|
||||
|
||||
EmuHandle::EmuHandle(EmuNtObject* ntObject)
|
||||
{
|
||||
NtObject = ntObject;
|
||||
}
|
||||
|
||||
NTSTATUS EmuHandle::NtClose()
|
||||
{
|
||||
return NtObject->NtClose();
|
||||
}
|
||||
|
||||
NTSTATUS EmuHandle::NtDuplicateObject(PHANDLE TargetHandle, DWORD Options)
|
||||
{
|
||||
*TargetHandle = NtObject->NtDuplicateObject(Options)->NewHandle();
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
EmuNtObject::EmuNtObject()
|
||||
{
|
||||
RefCount = 1;
|
||||
}
|
||||
|
||||
HANDLE EmuNtObject::NewHandle()
|
||||
{
|
||||
RefCount++;
|
||||
return EmuHandleToHandle(new EmuHandle(this));
|
||||
}
|
||||
|
||||
NTSTATUS EmuNtObject::NtClose()
|
||||
{
|
||||
RefCount--;
|
||||
|
||||
if (RefCount <= 0) {
|
||||
delete this;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
EmuNtObject* EmuNtObject::NtDuplicateObject(DWORD Options)
|
||||
{
|
||||
RefCount++;
|
||||
return this;
|
||||
}
|
||||
|
||||
bool IsEmuHandle(HANDLE Handle)
|
||||
{
|
||||
return (uint32_t)Handle > 0x80000000;
|
||||
}
|
||||
|
||||
EmuHandle* HandleToEmuHandle(HANDLE Handle)
{
return (EmuHandle*)((uint32_t)Handle & 0x7FFFFFFF);
}
HANDLE EmuHandleToHandle(EmuHandle* emuHandle)
|
||||
{
|
||||
return (HANDLE)((uint32_t)emuHandle | 0x80000000);
|
||||
}
|
||||
|
||||
bool CxbxRegisterDeviceNativePath(std::string XboxFullPath, std::string NativePath, bool IsFile)
|
||||
{
|
||||
bool result;
|
||||
|
@ -147,82 +188,6 @@ NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPa
|
|||
return result;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * Initialize the handle database
|
||||
// ******************************************************************
|
||||
bool EmuHandle::Initialize()
|
||||
{
|
||||
size_t x;
|
||||
|
||||
// Initialize the critical section
|
||||
InitializeCriticalSection(&HandleLock);
|
||||
|
||||
// Mark all handles as free. We also set up the linked list of
|
||||
// free handles here.
|
||||
for (x = 0; x < EMU_MAX_HANDLES; x++)
|
||||
{
|
||||
Handles[x].m_Type = EMUHANDLE_TYPE_EMPTY;
|
||||
Handles[x].m_NextFree = &Handles[x + 1];
|
||||
}
|
||||
|
||||
// The last entry should have a NULL next entry
|
||||
Handles[EMU_MAX_HANDLES - 1].m_NextFree = NULL;
|
||||
|
||||
// Set up the head and tail pointers
|
||||
FirstFree = &Handles[0];
|
||||
LastFree = &Handles[EMU_MAX_HANDLES];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * func: EmuHandle::Lock
|
||||
// * Locks the handle database
|
||||
// ******************************************************************
|
||||
inline void EmuHandle::Lock(void)
|
||||
{
|
||||
EnterCriticalSection(&HandleLock);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * func: EmuHandle::Unlock
|
||||
// * Unlocks the handle database
|
||||
// ******************************************************************
|
||||
inline void EmuHandle::Unlock(void)
|
||||
{
|
||||
LeaveCriticalSection(&HandleLock);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * func: EmuHandle::Allocate
|
||||
// * Allocates a new handle
|
||||
// ******************************************************************
|
||||
EmuHandle volatile *EmuHandle::Allocate(void)
|
||||
{
|
||||
volatile EmuHandle *Handle;
|
||||
|
||||
// Lock the database
|
||||
Lock();
|
||||
|
||||
// Get the first free entry
|
||||
Handle = FirstFree;
|
||||
|
||||
// Remove it from the list
|
||||
FirstFree = Handle->m_NextFree;
|
||||
|
||||
// If it was the last handle, clear LastFree
|
||||
if (!Handle->m_NextFree)
|
||||
LastFree = NULL;
|
||||
|
||||
// Initialize the handle's fields
|
||||
Handle->m_Type = EMUHANDLE_TYPE_ALLOCATED;
|
||||
Handle->m_Object = NULL;
|
||||
|
||||
// Unlock the database
|
||||
Unlock();
|
||||
|
||||
return Handle;
|
||||
}
|
||||
|
||||
NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::string aFullPath)
|
||||
{
|
||||
|
@ -295,7 +260,7 @@ NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::strin
|
|||
return result;
|
||||
}
|
||||
|
||||
void EmuNtSymbolicLinkObject::Free()
|
||||
EmuNtSymbolicLinkObject::~EmuNtSymbolicLinkObject()
|
||||
{
|
||||
if (DriveLetter >= 'A' && DriveLetter <= 'Z') {
|
||||
NtSymbolicLinkObjects[DriveLetter - 'A'] = NULL;
|
||||
|
@ -388,21 +353,3 @@ EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(const HANDLE Handl
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS EmuNtObject::NtClose()
|
||||
{
|
||||
NTSTATUS result = 0;
|
||||
RefCount--;
|
||||
if (RefCount <= 0)
|
||||
Free();
|
||||
result = STATUS_SUCCESS;
|
||||
return result;
|
||||
}
|
||||
|
||||
EmuNtObject* EmuNtObject::NtDuplicateObject(DWORD Options)
|
||||
{
|
||||
EmuNtObject* result = NULL;
|
||||
RefCount++;
|
||||
result = this;
|
||||
return result;
|
||||
}
|
|
@ -1,274 +1,165 @@
|
|||
// ******************************************************************
|
||||
// *
|
||||
// * .,-::::: .,:: .::::::::. .,:: .:
|
||||
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
|
||||
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
|
||||
// * $$$ Y$$$P $$""""Y$$ Y$$$P
|
||||
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
|
||||
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
|
||||
// *
|
||||
// * Cxbx->Win32->CxbxKrnl->EmuFile.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 EMUFILE_H
|
||||
#define EMUFILE_H
|
||||
|
||||
// ******************************************************************
|
||||
// * prevent name collisions
|
||||
// ******************************************************************
|
||||
namespace xboxkrnl
|
||||
{
|
||||
#include <xboxkrnl/xboxkrnl.h>
|
||||
};
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
// ******************************************************************
|
||||
// * prevent name collisions
|
||||
// ******************************************************************
|
||||
namespace NtDll
|
||||
{
|
||||
#include "EmuNtDll.h"
|
||||
};
|
||||
|
||||
#include "Emu.h"
|
||||
|
||||
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 std::string CxbxBasePath;
|
||||
extern HANDLE CxbxBasePathHandle;
|
||||
|
||||
// ******************************************************************
|
||||
// * Maximum number of open handles in the system
|
||||
// ******************************************************************
|
||||
#define EMU_MAX_HANDLES 1024
|
||||
|
||||
|
||||
// ******************************************************************
|
||||
// * Wrapper of a handle object
|
||||
// ******************************************************************
|
||||
class EmuHandle
|
||||
{
|
||||
public:
|
||||
// Type of handle
|
||||
volatile enum _EmuHandleType m_Type;
|
||||
|
||||
// To keep the size 8 bytes, these 2 items are in a union
|
||||
union
|
||||
{
|
||||
// Pointer to actual object (when handle is valid)
|
||||
volatile class EmuNtObject *m_Object;
|
||||
|
||||
// Pointer to next free handle
|
||||
volatile EmuHandle *m_NextFree;
|
||||
};
|
||||
|
||||
// Close this handle
|
||||
NtDll::NTSTATUS Close(void);
|
||||
|
||||
// Initialize the EmuHandle system
|
||||
static bool Initialize();
|
||||
|
||||
// Close all open handles
|
||||
static void CloseAll(void);
|
||||
|
||||
// Allocate an empty handle
|
||||
static volatile EmuHandle *Allocate(void);
|
||||
|
||||
private:
|
||||
// Array of EmuHandles in the system
|
||||
static EmuHandle Handles[EMU_MAX_HANDLES];
|
||||
|
||||
// Pointer to first free handle in array, or NULL if none
|
||||
volatile static EmuHandle *FirstFree;
|
||||
|
||||
// Pointer to last free handle in array, or NULL if none
|
||||
volatile static EmuHandle *LastFree;
|
||||
|
||||
// Lock on the handle system
|
||||
static CRITICAL_SECTION HandleLock;
|
||||
|
||||
// Quick functions to lock/unlock
|
||||
inline static void Lock(void);
|
||||
inline static void Unlock(void);
|
||||
};
|
||||
|
||||
// ******************************************************************
|
||||
// * Various "special" handle types
|
||||
// ******************************************************************
|
||||
typedef enum _EmuHandleType
|
||||
{
|
||||
// Unallocated handle
|
||||
EMUHANDLE_TYPE_EMPTY = 0,
|
||||
|
||||
// Allocated but so far unused handle
|
||||
EMUHANDLE_TYPE_ALLOCATED,
|
||||
|
||||
// File handle with no really special features
|
||||
EMUHANDLE_TYPE_FILE,
|
||||
|
||||
// Fake file/directory/directory object/partition handle
|
||||
EMUHANDLE_TYPE_OBJECT
|
||||
}
|
||||
EmuHandleType;
|
||||
|
||||
// ******************************************************************
|
||||
// * An NT fake object
|
||||
// ******************************************************************
|
||||
class EmuNtObject
|
||||
{
|
||||
public:
|
||||
// Decrements the reference count of this object (never override)
|
||||
NTSTATUS NtClose(void);
|
||||
|
||||
// These functions mimic the Nt* calls
|
||||
|
||||
// Increments the reference count of this object
|
||||
// For file handles, a whole new EmuFile structure is returned.
|
||||
// For other objects (the default implementation), "this" is returned.
|
||||
EmuNtObject *NtDuplicateObject(DWORD options);
|
||||
|
||||
protected:
|
||||
// Object name (Unicode, because we handle after-conversion strings)
|
||||
const WCHAR *Name;
|
||||
ULONG NameLength;
|
||||
// Permanent status
|
||||
bool PermanentFlag;
|
||||
|
||||
// Called by close() when the reference count reaches zero
|
||||
virtual void Free(void) = 0;
|
||||
|
||||
|
||||
private:
|
||||
// Reference count
|
||||
LONG RefCount;
|
||||
};
|
||||
|
||||
// ******************************************************************
|
||||
// * Emulated file handle
|
||||
// ******************************************************************
|
||||
class EmuNtFile : public EmuNtObject
|
||||
{
|
||||
public:
|
||||
// We need to override NtDuplicateObject in this case
|
||||
|
||||
private:
|
||||
// The Windows file handle
|
||||
HANDLE File;
|
||||
// Pointer to the volume from which this came
|
||||
//EmuNtVolume *Volume;
|
||||
};
|
||||
|
||||
// ******************************************************************
|
||||
// * Emulated symbolic link handle
|
||||
// ******************************************************************
|
||||
class EmuNtSymbolicLinkObject : public EmuNtObject {
|
||||
public:
|
||||
char DriveLetter;
|
||||
std::string SymbolicLinkName;
|
||||
std::string XboxFullPath;
|
||||
std::string NativePath;
|
||||
HANDLE RootDirectoryHandle;
|
||||
NTSTATUS Init(std::string aSymbolicLinkName, std::string aFullPath);
|
||||
void Free();
|
||||
};
|
||||
|
||||
// ******************************************************************
|
||||
// * is hFile a 'special' emulated handle?
|
||||
// ******************************************************************
|
||||
static inline bool IsEmuHandle(xboxkrnl::HANDLE hFile)
|
||||
{
|
||||
bool ret = ((uint32)hFile > 0x80000000) && ((uint32)hFile != -1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * convert from 'special' emulated handle to a pointer
|
||||
// ******************************************************************
|
||||
static inline EmuHandle *EmuHandleToPtr(xboxkrnl::HANDLE hFile)
|
||||
{
|
||||
return (EmuHandle*)((uint32)hFile - 0x80000000);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * convert from 'special' emulated handle to a pointer
|
||||
// ******************************************************************
|
||||
static inline HANDLE PtrToEmuHandle(EmuHandle *pEmuHandle)
|
||||
{
|
||||
return (HANDLE)((uint32)pEmuHandle + 0x80000000);
|
||||
}
|
||||
|
||||
char SymbolicLinkToDriveLetter(std::string aSymbolicLinkName);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByVolumeLetter(const char VolumeLetter);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByName(std::string SymbolicLinkName);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDevice(std::string DeviceName);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(HANDLE Handle);
|
||||
void CleanupSymbolicLinks();
|
||||
bool CxbxRegisterDeviceNativePath(std::string XboxFullPath, std::string NativePath, bool IsFile = false);
|
||||
HANDLE CxbxGetDeviceNativeRootHandle(std::string XboxFullPath);
|
||||
NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPath);
|
||||
bool CxbxMountUtilityDrive(bool formatClean);
|
||||
|
||||
#endif
|
||||
// ******************************************************************
|
||||
// *
|
||||
// * .,-::::: .,:: .::::::::. .,:: .:
|
||||
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
|
||||
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
|
||||
// * $$$ Y$$$P $$""""Y$$ Y$$$P
|
||||
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
|
||||
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
|
||||
// *
|
||||
// * Cxbx->Win32->CxbxKrnl->EmuFile.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 EMUFILE_H
|
||||
#define EMUFILE_H
|
||||
|
||||
// ******************************************************************
|
||||
// * prevent name collisions
|
||||
// ******************************************************************
|
||||
namespace xboxkrnl
|
||||
{
|
||||
#include <xboxkrnl/xboxkrnl.h>
|
||||
};
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
// ******************************************************************
|
||||
// * prevent name collisions
|
||||
// ******************************************************************
|
||||
namespace NtDll
|
||||
{
|
||||
#include "EmuNtDll.h"
|
||||
};
|
||||
|
||||
#include "Emu.h"
|
||||
|
||||
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 std::string CxbxBasePath;
|
||||
extern HANDLE CxbxBasePathHandle;
|
||||
|
||||
class EmuNtObject;
|
||||
|
||||
// ******************************************************************
|
||||
// * Wrapper of a handle object
|
||||
// ******************************************************************
|
||||
class EmuHandle
|
||||
{
|
||||
public:
|
||||
EmuHandle(EmuNtObject* ntObject);
|
||||
NTSTATUS NtClose();
|
||||
NTSTATUS NtDuplicateObject(PHANDLE TargetHandle, DWORD Options);
|
||||
EmuNtObject* NtObject;
|
||||
};
|
||||
|
||||
// ******************************************************************
|
||||
// * An NT fake object
|
||||
// ******************************************************************
|
||||
class EmuNtObject
|
||||
{
|
||||
public:
|
||||
EmuNtObject();
|
||||
HANDLE NewHandle();
|
||||
NTSTATUS NtClose();
|
||||
EmuNtObject* NtDuplicateObject(DWORD Options);
|
||||
protected:
|
||||
virtual ~EmuNtObject() {};
|
||||
private:
|
||||
ULONG RefCount;
|
||||
|
||||
};
|
||||
|
||||
// ******************************************************************
|
||||
// * Emulated symbolic link handle
|
||||
// ******************************************************************
|
||||
class EmuNtSymbolicLinkObject : public EmuNtObject {
|
||||
public:
|
||||
char DriveLetter;
|
||||
std::string SymbolicLinkName;
|
||||
std::string XboxFullPath;
|
||||
std::string NativePath;
|
||||
HANDLE RootDirectoryHandle;
|
||||
NTSTATUS Init(std::string aSymbolicLinkName, std::string aFullPath);
|
||||
~EmuNtSymbolicLinkObject();
|
||||
};
|
||||
|
||||
// ******************************************************************
|
||||
// * is hFile a 'special' emulated handle?
|
||||
// ******************************************************************
|
||||
bool IsEmuHandle(HANDLE Handle);
|
||||
EmuHandle* HandleToEmuHandle(HANDLE Handle);
HANDLE EmuHandleToHandle(EmuHandle* emuHandle);
|
||||
|
||||
|
||||
char SymbolicLinkToDriveLetter(std::string aSymbolicLinkName);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByVolumeLetter(const char VolumeLetter);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByName(std::string SymbolicLinkName);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDevice(std::string DeviceName);
|
||||
EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(HANDLE Handle);
|
||||
void CleanupSymbolicLinks();
|
||||
bool CxbxRegisterDeviceNativePath(std::string XboxFullPath, std::string NativePath, bool IsFile = false);
|
||||
HANDLE CxbxGetDeviceNativeRootHandle(std::string XboxFullPath);
|
||||
NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPath);
|
||||
bool CxbxMountUtilityDrive(bool formatClean);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2975,15 +2975,8 @@ XBSYSAPI EXPORTNUM(187) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtClose
|
|||
// delete 'special' handles
|
||||
if(IsEmuHandle(Handle))
|
||||
{
|
||||
EmuHandle *iEmuHandle = EmuHandleToPtr(Handle);
|
||||
|
||||
// HACK: Do not delete emuhandle
|
||||
// There is an issue with EmuHandle/EmuNtObject causing referencing counting to not function
|
||||
// Consider translating the entirity of EmuFile & EmuKrnl from Dxbx
|
||||
//delete iEmuHandle;
|
||||
EmuWarning("EmuKrnl::NtClose : EmuHandle not deleted");
|
||||
|
||||
ret = STATUS_SUCCESS;
|
||||
EmuHandle *iEmuHandle = HandleToEmuHandle(Handle);
|
||||
ret = iEmuHandle->NtClose();
|
||||
}
|
||||
// close normal handles
|
||||
else
|
||||
|
@ -3260,15 +3253,24 @@ XBSYSAPI EXPORTNUM(197) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtDuplicateObject
|
|||
");\n",
|
||||
GetCurrentThreadId(), SourceHandle, TargetHandle, Options);
|
||||
|
||||
// redirect to Win2k/XP
|
||||
NTSTATUS ret = NtDll::NtDuplicateObject
|
||||
(
|
||||
GetCurrentProcess(),
|
||||
SourceHandle,
|
||||
GetCurrentProcess(),
|
||||
TargetHandle,
|
||||
0, 0, Options
|
||||
);
|
||||
NTSTATUS ret;
|
||||
|
||||
if (IsEmuHandle(SourceHandle)) {
|
||||
EmuHandle* iEmuHandle = HandleToEmuHandle(SourceHandle);
|
||||
ret = iEmuHandle->NtDuplicateObject(TargetHandle, Options);
|
||||
}
|
||||
else {
|
||||
// redirect to Win2k/XP
|
||||
ret = NtDll::NtDuplicateObject
|
||||
(
|
||||
GetCurrentProcess(),
|
||||
SourceHandle,
|
||||
GetCurrentProcess(),
|
||||
TargetHandle,
|
||||
0, 0, Options
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if(ret != STATUS_SUCCESS)
|
||||
EmuWarning("Object was not duplicated!");
|
||||
|
@ -3393,7 +3395,7 @@ XBSYSAPI EXPORTNUM(203) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtOpenSymbolicLinkObj
|
|||
if ((symbolicLinkObject != NULL))
|
||||
{
|
||||
// Return a new handle
|
||||
*LinkHandle = EmuHandleToPtr(symbolicLinkObject);
|
||||
*LinkHandle = symbolicLinkObject->NewHandle();
|
||||
ret = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
|
@ -3664,9 +3666,10 @@ XBSYSAPI EXPORTNUM(215) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQuerySymbolicLinkOb
|
|||
// Check that we actually got an EmuHandle :
|
||||
result = STATUS_INVALID_HANDLE;
|
||||
|
||||
EmuHandle* iEmuHandle = HandleToEmuHandle(LinkHandle);
|
||||
// Retrieve the NtSymbolicLinkObject and populate the output arguments :
|
||||
result = STATUS_SUCCESS;
|
||||
symbolicLinkObject = ((EmuNtSymbolicLinkObject*)PtrToEmuHandle((EmuHandle*)LinkHandle));
|
||||
symbolicLinkObject = (EmuNtSymbolicLinkObject*)iEmuHandle->NtObject;
|
||||
if ((LinkTarget != NULL)) {
|
||||
if (LinkTarget->Length > LinkTarget->MaximumLength) {
|
||||
result = STATUS_BUFFER_TOO_SMALL;
|
||||
|
@ -4157,9 +4160,21 @@ XBSYSAPI EXPORTNUM(234) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtWaitForSingleObject
|
|||
");\n",
|
||||
GetCurrentThreadId(), Handle, WaitMode, Alertable, Timeout, Timeout == 0 ? 0 : Timeout->QuadPart);
|
||||
|
||||
NTSTATUS ret = NtDll::NtWaitForSingleObject(Handle, Alertable, (NtDll::PLARGE_INTEGER)Timeout);
|
||||
NTSTATUS ret;
|
||||
|
||||
DbgPrintf("Finished waiting for 0x%.08X\n", Handle);
|
||||
if (IsEmuHandle(Handle))
|
||||
{
|
||||
ret = WAIT_FAILED;
|
||||
EmuWarning("WaitFor EmuHandle not supported!");
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NtDll::NtWaitForSingleObject(Handle, Alertable, (NtDll::PLARGE_INTEGER)Timeout);
|
||||
DbgPrintf("Finished waiting for 0x%.08X\n", Handle);
|
||||
}
|
||||
|
||||
if (ret == WAIT_FAILED)
|
||||
EmuWarning("NtWaitForSingleObjectEx failed! (%s)", NtStatusToString(ret));
|
||||
|
||||
EmuSwapFS(); // Xbox FS
|
||||
|
||||
|
@ -4193,6 +4208,7 @@ XBSYSAPI EXPORTNUM(235) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtWaitForMultipleObje
|
|||
GetCurrentThreadId(), Count, Handles, WaitType, WaitMode, Alertable,
|
||||
Timeout, Timeout == 0 ? 0 : Timeout->QuadPart);
|
||||
|
||||
// TODO: Process EmuHandle
|
||||
NTSTATUS ret = NtDll::NtWaitForMultipleObjects(Count, Handles, (NtDll::OBJECT_WAIT_TYPE)WaitType, Alertable, (NtDll::PLARGE_INTEGER)Timeout);
|
||||
|
||||
EmuSwapFS(); // Xbox FS
|
||||
|
|
Loading…
Reference in New Issue