From a04a079f197563d49f10b140cf4e84683f713d88 Mon Sep 17 00:00:00 2001 From: jackchentwkh Date: Sun, 16 May 2021 15:42:44 +0800 Subject: [PATCH 1/5] Adding code to allocate memory for ImageDesc and copy ImageDesc from DSP ImageBuffer. Tested with Otogi, success. --- .../hle/DSOUND/DirectSound/DirectSound.cpp | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.cpp b/src/core/hle/DSOUND/DirectSound/DirectSound.cpp index 59dc389a5..5ecaa7fc6 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.cpp @@ -518,13 +518,13 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_SetEffectData) // ****************************************************************** xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_DownloadEffectsImage) ( - LPDIRECTSOUND8 pThis, - LPCVOID pvImageBuffer, - dword_xt dwImageSize, - PVOID pImageLoc, // TODO: Use this param - PVOID* ppImageDesc) // TODO: Use this param + LPDIRECTSOUND8 pThis, + LPCVOID pvImageBuffer, + dword_xt dwImageSize, + PVOID pImageLoc, // TODO: Use this param + PVOID* ppImageDesc) // TODO: Use this param { - DSoundMutexGuardLock; + DSoundMutexGuardLock; LOG_FUNC_BEGIN LOG_FUNC_ARG(pThis) @@ -534,11 +534,29 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_DownloadEffectsImage) LOG_FUNC_ARG(ppImageDesc) LOG_FUNC_END; - // This function is relative to DSP for Interactive 3-D Audio Level 2 (I3DL2) + // This function is relative to DSP for Interactive 3-D Audio Level 2 (I3DL2) - LOG_NOT_SUPPORTED(); - - return S_OK; + LOG_NOT_SUPPORTED(); + if(ppImageDesc)//If the guest code request a pointer to ImageDesc structure to be returned, then we should allocate a memory and create ImageDesc. + { + // Code block below is reversed from Otogi. + // ImageBuffer header starts from offset ox800 and ends in offset 0x817. actual DSP code segment starts from offset 0x818. + // DWORD at offset 0x804 and offset 0x80C should be the code segment sizes in dwords. + // ImageDesc is appended after code segments. There are additional two DWORDs data for each effect appended after ImageDesc which I have no idea what they are for. + DWORD N1 = *(DWORD *)((BYTE *)pvImageBuffer + 0x804); //first code segment size in dwords + DWORD N2 = *(DWORD *)((BYTE *)pvImageBuffer + 0x80C); //2nd code segment size in dwords + BYTE * pImageDesc = ((BYTE *)pvImageBuffer + 0x818 + 4 * (N1 + N2)); //calculate the starting address of ImageDesc inside the imagebuffer + DWORD EffectCount = *(DWORD *)pImageDesc; //the first DWORD in ImageDesc is EffectCount. + DWORD ImageDescSize = 8 + 32 * EffectCount; //The size of ImageDesc is two Dwords (8 bytes) + 8 DWORS (32 bytes) for each effects. + if (*ppImageDesc = malloc(ImageDescSize)) //allocate a new memory to keep the ImageDesc for guest code since the imagebuffer should be freed after the image were downloaded. + { + memcpy(*ppImageDesc, pImageDesc, ImageDescSize); //copy the ImageDesc from ImageBuffer. + } + // with the code above, we could easily retrieve the address and size of ImageDesc within the image buffer. + // then we can allocate a new memory, copy the imageDesc from the image buffer to the newly allocated memory, + // then assign the newly allocated memory to the ppImageDesc. that's all. + } + return S_OK; } // ****************************************************************** From d49762d27ee7308caeb4d11ec4870eb44b713403 Mon Sep 17 00:00:00 2001 From: jackchentwkh Date: Wed, 19 May 2021 19:20:39 +0800 Subject: [PATCH 2/5] Rebase Code and State Segments in EffectMaps. fix PGR2 --- .../hle/DSOUND/DirectSound/DirectSound.cpp | 68 ++++++++++++++++--- .../hle/DSOUND/DirectSound/DirectSound.hpp | 48 ++++++++++++- .../DSOUND/DirectSound/XFileMediaObject.cpp | 33 ++++++++- src/core/hle/Patches.cpp | 3 +- 4 files changed, 136 insertions(+), 16 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.cpp b/src/core/hle/DSOUND/DirectSound/DirectSound.cpp index 5ecaa7fc6..8ec17b6e9 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.cpp @@ -514,9 +514,9 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_SetEffectData) } // ****************************************************************** -// * patch: IDirectSound_DownloadEffectsImage +// * patch: CDirectSound_DownloadEffectsImage // ****************************************************************** -xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_DownloadEffectsImage) +xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSound_DownloadEffectsImage) ( LPDIRECTSOUND8 pThis, LPCVOID pvImageBuffer, @@ -536,22 +536,68 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_DownloadEffectsImage) // This function is relative to DSP for Interactive 3-D Audio Level 2 (I3DL2) - LOG_NOT_SUPPORTED(); + LOG_INCOMPLETE(); if(ppImageDesc)//If the guest code request a pointer to ImageDesc structure to be returned, then we should allocate a memory and create ImageDesc. { // Code block below is reversed from Otogi. // ImageBuffer header starts from offset ox800 and ends in offset 0x817. actual DSP code segment starts from offset 0x818. // DWORD at offset 0x804 and offset 0x80C should be the code segment sizes in dwords. // ImageDesc is appended after code segments. There are additional two DWORDs data for each effect appended after ImageDesc which I have no idea what they are for. - DWORD N1 = *(DWORD *)((BYTE *)pvImageBuffer + 0x804); //first code segment size in dwords - DWORD N2 = *(DWORD *)((BYTE *)pvImageBuffer + 0x80C); //2nd code segment size in dwords - BYTE * pImageDesc = ((BYTE *)pvImageBuffer + 0x818 + 4 * (N1 + N2)); //calculate the starting address of ImageDesc inside the imagebuffer - DWORD EffectCount = *(DWORD *)pImageDesc; //the first DWORD in ImageDesc is EffectCount. - DWORD ImageDescSize = 8 + 32 * EffectCount; //The size of ImageDesc is two Dwords (8 bytes) + 8 DWORS (32 bytes) for each effects. - if (*ppImageDesc = malloc(ImageDescSize)) //allocate a new memory to keep the ImageDesc for guest code since the imagebuffer should be freed after the image were downloaded. - { - memcpy(*ppImageDesc, pImageDesc, ImageDescSize); //copy the ImageDesc from ImageBuffer. + + // Image buffer must be copied to internal and backed up 1st. the data might be referenced by the guest code later. + // The Code Segment Address and State address in DSEFFECTMAP aEffectMaps[1] must be rebased to the internal buffer. + + + // NOTE: this buffer should also be freed in IDirectSound_Release when the ref counter drops to zero, but that function is currently not implemented. + static PBYTE ImageBufferBackup = zeroptr; //The image buffer must be backed up since some game might reference ths data. ex. PGR2. + if (ImageBufferBackup != zeroptr) { + ExFreePool(ImageBufferBackup); } + + ImageBufferBackup = static_cast(ExAllocatePool(dwImageSize)); + if (ImageBufferBackup == zeroptr) { + return E_OUTOFMEMORY; + } + + std::memcpy(ImageBufferBackup, pvImageBuffer, dwImageSize); //Copy the ImageBuffer to internal backup Buffer. + + //from here, all process should base on internal image buffer. + + dword_xt N1 = *(PDWORD)(ImageBufferBackup + 0x804); //Total code segment size in dwords + dword_xt N2 = *(PDWORD)(ImageBufferBackup + 0x80C); //Total state segment size in dwords + PBYTE pImageDesc = ImageBufferBackup + 0x818 + 4 * (N1 + N2); //calculate the starting address of ImageDesc in image buffer + DWORD EffectCount = ((LPDSEFFECTIMAGEDESC)pImageDesc)->dwEffectCount; //the first DWORD in ImageDesc is EffectCount. + dword_xt ImageDescSize = 8 + 32 * EffectCount; //The size of ImageDesc is two Dwords (8 bytes) + 8 DWORS (32 bytes) for each effects. + + //Process the DSEFFECTMAP in internal image buffer, rebase code segmemt address and state segment address of each effect. + PBYTE pEffectMaps = (pImageDesc + 8); //EffectMaps array start from here. + for (int effect_loop = 0; effect_loop < EffectCount; effect_loop++) + { + + PBYTE pCodeSeg = pEffectMaps + effect_loop * 32; + *(PDWORD)pCodeSeg += (DWORD)ImageBufferBackup; + + PBYTE pStateSeg = pEffectMaps + effect_loop * 32+8; + *(PDWORD)pStateSeg += (DWORD)ImageBufferBackup; + + } + + + // NOTE: this buffer should also be freed in IDirectSound_Release when the ref counter drops to zero, but that function is currently not implemented. + static PBYTE ImageDescBuffer = zeroptr; + if (ImageDescBuffer != zeroptr) { + ExFreePool(ImageDescBuffer); + } + + ImageDescBuffer = static_cast(ExAllocatePool(ImageDescSize)); + if (ImageDescBuffer == zeroptr) { + return E_OUTOFMEMORY; + } + + // NOTE: this is very wrong. The dsp image is encrypted, and thus simply copying the original encrypted image won't do any good. + *ppImageDesc = ImageDescBuffer; + std::memcpy(*ppImageDesc, pImageDesc, ImageDescSize); + // with the code above, we could easily retrieve the address and size of ImageDesc within the image buffer. // then we can allocate a new memory, copy the imageDesc from the image buffer to the newly allocated memory, // then assign the newly allocated memory to the ppImageDesc. that's all. diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp index e87167707..cefdaf186 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.hpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.hpp @@ -127,6 +127,50 @@ struct SharedDSBuffer : DSBUFFER_S { } }; +typedef struct _DSEFFECTMAP { + LPVOID lpvCodeSegment; + DWORD dwCodeSize; + LPVOID lpvStateSegment; + DWORD dwStateSize; + LPVOID lpvYMemorySegment; + DWORD dwYMemorySize; + LPVOID lpvScratchSegment; + DWORD dwScratchSize; +} DSEFFECTMAP, *LPDSEFFECTMAP; +/*Members +lpvCodeSegment +Starting address of the DSP code segment for this effect. +dwCodeSize +Value that contains the code segment size, in DWORDs. +lpvStateSegment +Starting address of the effect state segment. +dwStateSize +Value that contains the size of the effect state segment, in DWORDs. +lpvYMemorySegment +Starting address of the DSP Y-memory segment. +dwYMemorySize +Value that contains the Y-memory segment size, in DWORDs. +lpvScratchSegment +Starting address of the scratch memory segment. +dwScratchSize +Value that contains the size of the scratch segment, in DWORDs. +*/ + +typedef struct _DSEFFECTIMAGEDESC { + DWORD dwEffectCount; + DWORD dwTotalScratchSize; + DSEFFECTMAP aEffectMaps[1]; +} DSEFFECTIMAGEDESC, *LPDSEFFECTIMAGEDESC; + +/*Members +dwEffectCount +Value that contains the number of effects in the image. +dwTotalScratchSize +Value that contains the total amount of space required by effects that use scratch space for delay lines. +aEffectMaps +Variable-length array that contains the effect descriptions. +*/ + //Custom flags (4 bytes support up to 31 shifts,starting from 0) #define DSE_FLAG_PCM (1 << 0) #define DSE_FLAG_XADPCM (1 << 1) @@ -414,9 +458,9 @@ xbox::hresult_xt WINAPI EMUPATCH(IDirectSound_SynchPlayback) ); // ****************************************************************** -// * patch: IDirectSound_DownloadEffectsImage +// * patch: CDirectSound_DownloadEffectsImage // ****************************************************************** -xbox::hresult_xt WINAPI EMUPATCH(IDirectSound_DownloadEffectsImage) +xbox::hresult_xt WINAPI EMUPATCH(CDirectSound_DownloadEffectsImage) ( LPDIRECTSOUND8 pThis, LPCVOID pvImageBuffer, diff --git a/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp b/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp index fb85b8a66..bae6f286a 100644 --- a/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp +++ b/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp @@ -38,6 +38,8 @@ #include "DirectSoundInline.hpp" +#include + // TODO: Tasks need to do for DirectSound HLE // * Need create patches // * Ac97CreateMediaObject (Need OOVPA) @@ -115,9 +117,36 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage) LOG_FUNC_ARG(ppImageDesc) LOG_FUNC_END; - LOG_NOT_SUPPORTED(); + LOG_INCOMPLETE(); + LPDIRECTSOUND8 pThis_tmp= zeroptr; + PBYTE pvImageBuffer; + dword_xt dwImageSize; - return S_OK; + HANDLE hFile; + DWORD dwBytesRead; + LPSTR pszScratchFile; + + //convert_pszImageName_to_pszScratchFile(); + std::string hostpath = CxbxConvertXboxToHostPath(std::string_view (pszImageName)); + + hFile = CreateFile(hostpath.c_str(),GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); + + dwImageSize = GetFileSize(hFile, NULL); + + pvImageBuffer = new BYTE[dwImageSize]; + + BOOL bResult = ReadFile(hFile,pvImageBuffer,dwImageSize,&dwBytesRead,0); + + xbox::hresult_xt result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(pThis_tmp, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc); + + delete[] pvImageBuffer; + + if (hFile != INVALID_HANDLE_VALUE) + { + CloseHandle(hFile); + } + + return result;// result; } // ****************************************************************** diff --git a/src/core/hle/Patches.cpp b/src/core/hle/Patches.cpp index e27f43424..7fa2bb3f3 100644 --- a/src/core/hle/Patches.cpp +++ b/src/core/hle/Patches.cpp @@ -312,7 +312,8 @@ std::map g_PatchTable = { PATCH_ENTRY("IDirectSound_CommitEffectData", xbox::EMUPATCH(IDirectSound_CommitEffectData), PATCH_HLE_DSOUND), PATCH_ENTRY("IDirectSound_CreateSoundBuffer", xbox::EMUPATCH(IDirectSound_CreateSoundBuffer), PATCH_HLE_DSOUND), PATCH_ENTRY("IDirectSound_CreateSoundStream", xbox::EMUPATCH(IDirectSound_CreateSoundStream), PATCH_HLE_DSOUND), - PATCH_ENTRY("IDirectSound_DownloadEffectsImage", xbox::EMUPATCH(IDirectSound_DownloadEffectsImage), PATCH_HLE_DSOUND), +// PATCH_ENTRY("IDirectSound_DownloadEffectsImage", xbox::EMUPATCH(IDirectSound_DownloadEffectsImage), PATCH_HLE_DSOUND), + PATCH_ENTRY("CDirectSound_DownloadEffectsImage", xbox::EMUPATCH(CDirectSound_DownloadEffectsImage), PATCH_HLE_DSOUND), PATCH_ENTRY("IDirectSound_EnableHeadphones", xbox::EMUPATCH(IDirectSound_EnableHeadphones), PATCH_HLE_DSOUND), PATCH_ENTRY("IDirectSound_GetCaps", xbox::EMUPATCH(IDirectSound_GetCaps), PATCH_HLE_DSOUND), PATCH_ENTRY("IDirectSound_GetEffectData", xbox::EMUPATCH(IDirectSound_GetEffectData), PATCH_HLE_DSOUND), From a665cf1f8ee24ee49c78fdc0750b3540cc5136a7 Mon Sep 17 00:00:00 2001 From: jackchentwkh Date: Fri, 21 May 2021 13:28:13 +0800 Subject: [PATCH 3/5] Replace host CreateFile/GetFileSize/ReadFile/Close with xbox::NtCreateFile/NtQueryFile/NtReadFile/NtClose. Add necessary error check logic, Add logic for loading image file from xbe section in case we encounter such guest code, alghough highly unlikely. Basicaly reversed from PGR2's code. --- .../DSOUND/DirectSound/XFileMediaObject.cpp | 163 ++++++++++++++++-- src/core/kernel/common/ob.h | 2 + 2 files changed, 146 insertions(+), 19 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp b/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp index bae6f286a..4745a722b 100644 --- a/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp +++ b/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp @@ -118,35 +118,160 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage) LOG_FUNC_END; LOG_INCOMPLETE(); - LPDIRECTSOUND8 pThis_tmp= zeroptr; - PBYTE pvImageBuffer; - dword_xt dwImageSize; - HANDLE hFile; - DWORD dwBytesRead; - LPSTR pszScratchFile; + xbox::hresult_xt result = S_OK; + if(ppImageDesc){ //only process image section/file which the guest code asks for ImageDesc. - //convert_pszImageName_to_pszScratchFile(); - std::string hostpath = CxbxConvertXboxToHostPath(std::string_view (pszImageName)); + PBYTE pvImageBuffer; + dword_xt dwImageSize; + + if (dwFlags & 1) { // dwFlags == XAUDIO_DOWNLOADFX_XBESECTION, The DSP effects image is located in a section of the XBE. + /* + //future code for loading imgae from XBE section. these codes are reversd from PGR2. + + PXBEIMAGE_SECTION pImageSectionHandle=XGetSectionHandle(pszImageName); //get section handle by section name, not implemented yet. + // perhaps use pImageSectionHandle = CxbxKrnl_Xbe->FindSection(pszImageName); will be easier. + + + if(XeLoadSection(pImageSectionHandle)>0{ //load section handle and get the loaded address. + pvImageBuffer= pImageSectionHandle->VirtualAddress; //note this sction must be freed after the internal image bacup and ImageDesc was created. + //EmuKnrlXe.cpp implements XeLoadSection(). could reference that code. + dwImageSize=pImageSectionHandle->VirtualSize; //get section size by section handle. + + result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(pThis_tmp, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc); + + if(pImageSectionHandle<>0 && pImageSectionHandle!=-1) + XeUnloadSection(pImageSectionHandle); + + */ + + result = S_OK;//this line should be removed once the section loading code was implemented. + } + else { // load from file - hFile = CreateFile(hostpath.c_str(),GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL); + + LPDIRECTSOUND8 pThis_tmp= zeroptr; - dwImageSize = GetFileSize(hFile, NULL); + HANDLE hFile; + DWORD dwBytesRead; + + // using xbox::NtCreateFile() directly instead of Host CreateFile(); + OBJECT_ATTRIBUTES obj; + ANSI_STRING file_name; + IO_STATUS_BLOCK io_status_block; + RtlInitAnsiString(&file_name, pszImageName); + + XB_InitializeObjectAttributes(&obj, &file_name, OBJ_CASE_INSENSITIVE, ObDosDevicesDirectory()); + ntstatus_xt NtStatusCreateFile; + //LARGE_INTEGER tmp_LargeInt; + //tmp_LargeInt.QuadPart= dwImageSize; + NtStatusCreateFile=NtCreateFile( + &hFile,//OUT PHANDLE &hFile, + FILE_GENERIC_READ,//FILE_READ_DATA,//GENERIC_READ,//IN access_mask_xt DesiredAccess, + &obj,//IN POBJECT_ATTRIBUTES ObjectAttributes, + &io_status_block,//OUT PIO_STATUS_BLOCK IoStatusBlock, + zeroptr,//IN PLARGE_INTEGER AllocationSize OPTIONAL, must be none zero, no effect for read acceess. + FILE_ATTRIBUTE_NORMAL,//IN ulong_xt FileAttributes, + FILE_SHARE_READ,//IN ulong_xt ShareAccess, + FILE_OPEN,//IN ulong_xt CreateDisposition, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);//IN ulong_xt CreateOptions); CreateFileA Convert dwCreationDisposition== 3 OPEN_EXISTING to CreateOptions = 1 FILE_DIRECTORY_FILE!!?? but with 1, this will fail. + //process possible error with NtCreateFile() + if (NtStatusCreateFile < 0)//something wrong + { + //ULONG DOSERRORNtCreateFile=RtlNtStatusToDosError(NtStatusCreateFile); + EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file NtCreateFile() error"); + if (NtStatusCreateFile == 0xC0000035)//STATUS_OBJECT_NAME_COLLISION + { + EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file name collision"); + } + else if (NtStatusCreateFile == 0xC00000BA)//STATUS_FILE_IS_A_DIRECTORY + { + EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file name is a directory or invalid"); + } + hFile= INVALID_HANDLE_VALUE; + } - pvImageBuffer = new BYTE[dwImageSize]; + if(hFile!=INVALID_HANDLE_VALUE){ - BOOL bResult = ReadFile(hFile,pvImageBuffer,dwImageSize,&dwBytesRead,0); + FILE_STANDARD_INFORMATION FileStdInfo; - xbox::hresult_xt result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(pThis_tmp, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc); + NTSTATUS NtStatusQueryInfoFile = NtQueryInformationFile( + hFile,//IN HANDLE FileHandle, + &io_status_block,//OUT PIO_STATUS_BLOCK IoStatusBlock, + &FileStdInfo,//OUT PVOID FileInformation, //File_Information Class Structure address. + sizeof(FILE_STANDARD_INFORMATION),//IN ulong_xt Length, //Length of the file information class structure buffer. + FileStandardInformation);//34);//IN FILE_INFORMATION_CLASS FileInformationClass // Enumation of the file information class. + if (NtStatusQueryInfoFile >= 0) + { + dwImageSize = FileStdInfo.EndOfFile.u.LowPart; + } + else + { + EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file NtQueryInformationFile() error."); + dwImageSize = 0; + } - delete[] pvImageBuffer; + if(dwImageSize>0)//proceed the process only if the file size > 0 + { + pvImageBuffer = new BYTE[dwImageSize]; //allocate buffer to read in to image file. - if (hFile != INVALID_HANDLE_VALUE) - { - CloseHandle(hFile); + //use NtReadFile() to replace host CreatFile(); + ntstatus_xt NtStatusReadFile =NtReadFile( + hFile,//IN HANDLE FileHandle + 0,//IN HANDLE Event OPTIONAL + 0, //IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + 0,//IN PVOID ApcContext, + &io_status_block,//OUT PIO_STATUS_BLOCK IoStatusBlock, + pvImageBuffer,//OUT PVOID Buffer, + dwImageSize,//IN ulong_xt Length, + zeroptr); //IN PLARGE_INTEGER ByteOffset OPTIONAL + + DWORD dwBytesRead = 0; + if (NtStatusReadFile == 0x103)//STATUS_PENDING + { + NtStatusReadFile = NtWaitForSingleObject(hFile, 0, 0); + if (NtStatusReadFile < 0){//something wrong + EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file NtReadFile error"); + if (NtStatusReadFile != 0xC0000011)//STATUS_END_OF_FILE + { + if ((NtStatusReadFile & 0xC0000000) == 0x80000000)//Error happened during file reading + { + dwBytesRead = io_status_block.Information; + EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: NtReadFile read file end"); + //ULONG DOSErrorNtReadFile = RtlNtStatusToDosError(NtStatusReadFile);// this is supposed to be the error code of xbox::CreateFile() + } + }else{ + dwBytesRead = 0; + } + } + NtStatusReadFile = io_status_block.Status; + } + if (NtStatusReadFile >= 0) + { + dwBytesRead = io_status_block.Information; + } + + + if(dwBytesRead == dwImageSize){//only process the image if the whole image was read successfully. + result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(pThis_tmp, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc); + } + else { + EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file NtReadFile read in lenth not enough"); + } + + if(pvImageBuffer) + { + delete[] pvImageBuffer; + } + if (hFile != INVALID_HANDLE_VALUE) + { + NtClose(hFile); + } + } + } + } } - - return result;// result; + return result; } // ****************************************************************** diff --git a/src/core/kernel/common/ob.h b/src/core/kernel/common/ob.h index 5df648399..d55bf4cc7 100644 --- a/src/core/kernel/common/ob.h +++ b/src/core/kernel/common/ob.h @@ -35,6 +35,8 @@ typedef struct _OBJECT_HEADER_NAME_INFO { OBJECT_STRING Name; } OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO; +#define OBJ_CASE_INSENSITIVE 0x40 + #define ObDosDevicesDirectory() ((HANDLE)-3) #define ObWin32NamedObjectsDirectory() ((HANDLE)-4) From 2e1ed31aaafd648acf1d9cb4968828e58c47a15f Mon Sep 17 00:00:00 2001 From: ergo720 <45463469+ergo720@users.noreply.github.com> Date: Fri, 21 May 2021 13:08:57 +0200 Subject: [PATCH 4/5] Untabfied code and update code style --- .../hle/DSOUND/DirectSound/DirectSound.cpp | 131 ++++----- .../DSOUND/DirectSound/XFileMediaObject.cpp | 274 +++++++++--------- src/core/kernel/common/types.h | 2 + 3 files changed, 194 insertions(+), 213 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.cpp b/src/core/hle/DSOUND/DirectSound/DirectSound.cpp index 8ec17b6e9..bf1198767 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.cpp @@ -518,91 +518,86 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_SetEffectData) // ****************************************************************** xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSound_DownloadEffectsImage) ( - LPDIRECTSOUND8 pThis, - LPCVOID pvImageBuffer, - dword_xt dwImageSize, - PVOID pImageLoc, // TODO: Use this param - PVOID* ppImageDesc) // TODO: Use this param + LPDIRECTSOUND8 pThis, + LPCVOID pvImageBuffer, + dword_xt dwImageSize, + PVOID pImageLoc, // TODO: Use this param + PVOID* ppImageDesc) // TODO: Use this param { - DSoundMutexGuardLock; + DSoundMutexGuardLock; - LOG_FUNC_BEGIN - LOG_FUNC_ARG(pThis) - LOG_FUNC_ARG(pvImageBuffer) - LOG_FUNC_ARG(dwImageSize) - LOG_FUNC_ARG(pImageLoc) - LOG_FUNC_ARG(ppImageDesc) - LOG_FUNC_END; + LOG_FUNC_BEGIN + LOG_FUNC_ARG(pThis) + LOG_FUNC_ARG(pvImageBuffer) + LOG_FUNC_ARG(dwImageSize) + LOG_FUNC_ARG(pImageLoc) + LOG_FUNC_ARG(ppImageDesc) + LOG_FUNC_END; - // This function is relative to DSP for Interactive 3-D Audio Level 2 (I3DL2) + // This function is relative to DSP for Interactive 3-D Audio Level 2 (I3DL2) - LOG_INCOMPLETE(); - if(ppImageDesc)//If the guest code request a pointer to ImageDesc structure to be returned, then we should allocate a memory and create ImageDesc. - { - // Code block below is reversed from Otogi. - // ImageBuffer header starts from offset ox800 and ends in offset 0x817. actual DSP code segment starts from offset 0x818. - // DWORD at offset 0x804 and offset 0x80C should be the code segment sizes in dwords. - // ImageDesc is appended after code segments. There are additional two DWORDs data for each effect appended after ImageDesc which I have no idea what they are for. + LOG_INCOMPLETE(); - // Image buffer must be copied to internal and backed up 1st. the data might be referenced by the guest code later. - // The Code Segment Address and State address in DSEFFECTMAP aEffectMaps[1] must be rebased to the internal buffer. + if (ppImageDesc) { // If the guest code request a pointer to ImageDesc structure to be returned, then we should allocate a memory and create ImageDesc. + // Code block below is reversed from Otogi. + // ImageBuffer header starts from offset ox800 and ends in offset 0x817. actual DSP code segment starts from offset 0x818. + // DWORD at offset 0x804 and offset 0x80C should be the code segment sizes in dwords. + // ImageDesc is appended after code segments. There are additional two DWORDs data for each effect appended after ImageDesc which I have no idea what they are for. + // Image buffer must be copied to internal and backed up 1st. the data might be referenced by the guest code later. + // The Code Segment Address and State address in DSEFFECTMAP aEffectMaps[1] must be rebased to the internal buffer. - // NOTE: this buffer should also be freed in IDirectSound_Release when the ref counter drops to zero, but that function is currently not implemented. - static PBYTE ImageBufferBackup = zeroptr; //The image buffer must be backed up since some game might reference ths data. ex. PGR2. - if (ImageBufferBackup != zeroptr) { - ExFreePool(ImageBufferBackup); - } + // NOTE: this buffer should also be freed in IDirectSound_Release when the ref counter drops to zero, but that function is currently not implemented. + static PBYTE ImageBufferBackup = zeroptr; //The image buffer must be backed up since some game might reference ths data. ex. PGR2. + if (ImageBufferBackup != zeroptr) { + ExFreePool(ImageBufferBackup); + } - ImageBufferBackup = static_cast(ExAllocatePool(dwImageSize)); - if (ImageBufferBackup == zeroptr) { - return E_OUTOFMEMORY; - } + ImageBufferBackup = static_cast(ExAllocatePool(dwImageSize)); + if (ImageBufferBackup == zeroptr) { + return E_OUTOFMEMORY; + } - std::memcpy(ImageBufferBackup, pvImageBuffer, dwImageSize); //Copy the ImageBuffer to internal backup Buffer. + std::memcpy(ImageBufferBackup, pvImageBuffer, dwImageSize); // Copy the ImageBuffer to internal backup Buffer. - //from here, all process should base on internal image buffer. - - dword_xt N1 = *(PDWORD)(ImageBufferBackup + 0x804); //Total code segment size in dwords - dword_xt N2 = *(PDWORD)(ImageBufferBackup + 0x80C); //Total state segment size in dwords - PBYTE pImageDesc = ImageBufferBackup + 0x818 + 4 * (N1 + N2); //calculate the starting address of ImageDesc in image buffer - DWORD EffectCount = ((LPDSEFFECTIMAGEDESC)pImageDesc)->dwEffectCount; //the first DWORD in ImageDesc is EffectCount. - dword_xt ImageDescSize = 8 + 32 * EffectCount; //The size of ImageDesc is two Dwords (8 bytes) + 8 DWORS (32 bytes) for each effects. + // from here, all process should base on internal image buffer. + dword_xt N1 = *(PDWORD)(ImageBufferBackup + 0x804); //Total code segment size in dwords + dword_xt N2 = *(PDWORD)(ImageBufferBackup + 0x80C); //Total state segment size in dwords + PBYTE pImageDesc = ImageBufferBackup + 0x818 + 4 * (N1 + N2); //calculate the starting address of ImageDesc in image buffer + DWORD EffectCount = ((LPDSEFFECTIMAGEDESC)pImageDesc)->dwEffectCount; //the first DWORD in ImageDesc is EffectCount. + dword_xt ImageDescSize = 8 + 32 * EffectCount; //The size of ImageDesc is two Dwords (8 bytes) + 8 DWORS (32 bytes) for each effects. - //Process the DSEFFECTMAP in internal image buffer, rebase code segmemt address and state segment address of each effect. - PBYTE pEffectMaps = (pImageDesc + 8); //EffectMaps array start from here. - for (int effect_loop = 0; effect_loop < EffectCount; effect_loop++) - { + // Process the DSEFFECTMAP in internal image buffer, rebase code segmemt address and state segment address of each effect. + PBYTE pEffectMaps = (pImageDesc + 8); //EffectMaps array start from here. + for (int effect_loop = 0; effect_loop < EffectCount; effect_loop++) { + PBYTE pCodeSeg = pEffectMaps + effect_loop * 32; + *(PDWORD)pCodeSeg += (DWORD)ImageBufferBackup; - PBYTE pCodeSeg = pEffectMaps + effect_loop * 32; - *(PDWORD)pCodeSeg += (DWORD)ImageBufferBackup; + PBYTE pStateSeg = pEffectMaps + effect_loop * 32+8; + *(PDWORD)pStateSeg += (DWORD)ImageBufferBackup; + } - PBYTE pStateSeg = pEffectMaps + effect_loop * 32+8; - *(PDWORD)pStateSeg += (DWORD)ImageBufferBackup; + // NOTE: this buffer should also be freed in IDirectSound_Release when the ref counter drops to zero, but that function is currently not implemented. + static PBYTE ImageDescBuffer = zeroptr; + if (ImageDescBuffer != zeroptr) { + ExFreePool(ImageDescBuffer); + } - } + ImageDescBuffer = static_cast(ExAllocatePool(ImageDescSize)); + if (ImageDescBuffer == zeroptr) { + return E_OUTOFMEMORY; + } + // NOTE: this is very wrong. The dsp image is encrypted, and thus simply copying the original encrypted image won't do any good. + *ppImageDesc = ImageDescBuffer; + std::memcpy(*ppImageDesc, pImageDesc, ImageDescSize); - // NOTE: this buffer should also be freed in IDirectSound_Release when the ref counter drops to zero, but that function is currently not implemented. - static PBYTE ImageDescBuffer = zeroptr; - if (ImageDescBuffer != zeroptr) { - ExFreePool(ImageDescBuffer); - } + // with the code above, we could easily retrieve the address and size of ImageDesc within the image buffer. + // then we can allocate a new memory, copy the imageDesc from the image buffer to the newly allocated memory, + // then assign the newly allocated memory to the ppImageDesc. that's all. + } - ImageDescBuffer = static_cast(ExAllocatePool(ImageDescSize)); - if (ImageDescBuffer == zeroptr) { - return E_OUTOFMEMORY; - } - - // NOTE: this is very wrong. The dsp image is encrypted, and thus simply copying the original encrypted image won't do any good. - *ppImageDesc = ImageDescBuffer; - std::memcpy(*ppImageDesc, pImageDesc, ImageDescSize); - - // with the code above, we could easily retrieve the address and size of ImageDesc within the image buffer. - // then we can allocate a new memory, copy the imageDesc from the image buffer to the newly allocated memory, - // then assign the newly allocated memory to the ppImageDesc. that's all. - } - return S_OK; + return S_OK; } // ****************************************************************** diff --git a/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp b/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp index 4745a722b..70e721564 100644 --- a/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp +++ b/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp @@ -38,8 +38,6 @@ #include "DirectSoundInline.hpp" -#include - // TODO: Tasks need to do for DirectSound HLE // * Need create patches // * Ac97CreateMediaObject (Need OOVPA) @@ -110,168 +108,154 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage) { DSoundMutexGuardLock; - LOG_FUNC_BEGIN - LOG_FUNC_ARG(pszImageName) - LOG_FUNC_ARG(pImageLoc) - LOG_FUNC_ARG(dwFlags) - LOG_FUNC_ARG(ppImageDesc) - LOG_FUNC_END; + LOG_FUNC_BEGIN + LOG_FUNC_ARG(pszImageName) + LOG_FUNC_ARG(pImageLoc) + LOG_FUNC_ARG(dwFlags) + LOG_FUNC_ARG(ppImageDesc) + LOG_FUNC_END; - LOG_INCOMPLETE(); + LOG_INCOMPLETE(); - xbox::hresult_xt result = S_OK; - if(ppImageDesc){ //only process image section/file which the guest code asks for ImageDesc. + xbox::hresult_xt result = S_OK; + if (ppImageDesc) { //only process image section/file which the guest code asks for ImageDesc. - PBYTE pvImageBuffer; - dword_xt dwImageSize; + PBYTE pvImageBuffer; + dword_xt dwImageSize; - if (dwFlags & 1) { // dwFlags == XAUDIO_DOWNLOADFX_XBESECTION, The DSP effects image is located in a section of the XBE. - /* - //future code for loading imgae from XBE section. these codes are reversd from PGR2. + if (dwFlags & 1) { // dwFlags == XAUDIO_DOWNLOADFX_XBESECTION, The DSP effects image is located in a section of the XBE. + /* + //future code for loading imgae from XBE section. these codes are reversd from PGR2. - PXBEIMAGE_SECTION pImageSectionHandle=XGetSectionHandle(pszImageName); //get section handle by section name, not implemented yet. - // perhaps use pImageSectionHandle = CxbxKrnl_Xbe->FindSection(pszImageName); will be easier. + PXBEIMAGE_SECTION pImageSectionHandle=XGetSectionHandle(pszImageName); //get section handle by section name, not implemented yet. + // perhaps use pImageSectionHandle = CxbxKrnl_Xbe->FindSection(pszImageName); will be easier. - - if(XeLoadSection(pImageSectionHandle)>0{ //load section handle and get the loaded address. - pvImageBuffer= pImageSectionHandle->VirtualAddress; //note this sction must be freed after the internal image bacup and ImageDesc was created. - //EmuKnrlXe.cpp implements XeLoadSection(). could reference that code. - dwImageSize=pImageSectionHandle->VirtualSize; //get section size by section handle. + if (XeLoadSection(pImageSectionHandle) > 0) { //load section handle and get the loaded address. + //note this sction must be freed after the internal image bacup and ImageDesc was created. + //EmuKnrlXe.cpp implements XeLoadSection(). could reference that code. + pvImageBuffer = pImageSectionHandle->VirtualAddress; + } - result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(pThis_tmp, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc); + dwImageSize=pImageSectionHandle->VirtualSize; //get section size by section handle. - if(pImageSectionHandle<>0 && pImageSectionHandle!=-1) - XeUnloadSection(pImageSectionHandle); + result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(pThis_tmp, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc); - */ + if(pImageSectionHandle<>0 && pImageSectionHandle!=-1) + XeUnloadSection(pImageSectionHandle); - result = S_OK;//this line should be removed once the section loading code was implemented. - } - else { // load from file - - - LPDIRECTSOUND8 pThis_tmp= zeroptr; + */ - HANDLE hFile; - DWORD dwBytesRead; - - // using xbox::NtCreateFile() directly instead of Host CreateFile(); - OBJECT_ATTRIBUTES obj; - ANSI_STRING file_name; - IO_STATUS_BLOCK io_status_block; - RtlInitAnsiString(&file_name, pszImageName); - - XB_InitializeObjectAttributes(&obj, &file_name, OBJ_CASE_INSENSITIVE, ObDosDevicesDirectory()); - ntstatus_xt NtStatusCreateFile; - //LARGE_INTEGER tmp_LargeInt; - //tmp_LargeInt.QuadPart= dwImageSize; - NtStatusCreateFile=NtCreateFile( - &hFile,//OUT PHANDLE &hFile, - FILE_GENERIC_READ,//FILE_READ_DATA,//GENERIC_READ,//IN access_mask_xt DesiredAccess, - &obj,//IN POBJECT_ATTRIBUTES ObjectAttributes, - &io_status_block,//OUT PIO_STATUS_BLOCK IoStatusBlock, - zeroptr,//IN PLARGE_INTEGER AllocationSize OPTIONAL, must be none zero, no effect for read acceess. - FILE_ATTRIBUTE_NORMAL,//IN ulong_xt FileAttributes, - FILE_SHARE_READ,//IN ulong_xt ShareAccess, - FILE_OPEN,//IN ulong_xt CreateDisposition, - FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);//IN ulong_xt CreateOptions); CreateFileA Convert dwCreationDisposition== 3 OPEN_EXISTING to CreateOptions = 1 FILE_DIRECTORY_FILE!!?? but with 1, this will fail. - //process possible error with NtCreateFile() - if (NtStatusCreateFile < 0)//something wrong - { - //ULONG DOSERRORNtCreateFile=RtlNtStatusToDosError(NtStatusCreateFile); - EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file NtCreateFile() error"); - if (NtStatusCreateFile == 0xC0000035)//STATUS_OBJECT_NAME_COLLISION - { - EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file name collision"); - } - else if (NtStatusCreateFile == 0xC00000BA)//STATUS_FILE_IS_A_DIRECTORY - { - EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file name is a directory or invalid"); - } - hFile= INVALID_HANDLE_VALUE; - } + result = S_OK;//this line should be removed once the section loading code was implemented. + } + else { // load from file + LPDIRECTSOUND8 pThis_tmp = zeroptr; + HANDLE hFile; + DWORD dwBytesRead; - if(hFile!=INVALID_HANDLE_VALUE){ + // using xbox::NtCreateFile() directly instead of Host CreateFile(); + OBJECT_ATTRIBUTES obj; + ANSI_STRING file_name; + IO_STATUS_BLOCK io_status_block; + RtlInitAnsiString(&file_name, pszImageName); + XB_InitializeObjectAttributes(&obj, &file_name, OBJ_CASE_INSENSITIVE, ObDosDevicesDirectory()); + ntstatus_xt NtStatusCreateFile; + //LARGE_INTEGER tmp_LargeInt; + //tmp_LargeInt.QuadPart= dwImageSize; + NtStatusCreateFile = NtCreateFile( + &hFile, + FILE_GENERIC_READ, // FILE_READ_DATA, GENERIC_READ, DesiredAccess, + &obj, + &io_status_block, + zeroptr, // AllocationSize OPTIONAL, must be none zero, no effect for read acceess. + FILE_ATTRIBUTE_NORMAL, // FileAttributes, + FILE_SHARE_READ, // ShareAccess, + FILE_OPEN, // CreateDisposition, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); // CreateOptions; CreateFileA Convert dwCreationDisposition== 3 OPEN_EXISTING to CreateOptions = 1 FILE_DIRECTORY_FILE!!?? but with 1, this will fail. - FILE_STANDARD_INFORMATION FileStdInfo; + //process possible error with NtCreateFile() + if (NtStatusCreateFile < 0) { + //ULONG DOSERRORNtCreateFile=RtlNtStatusToDosError(NtStatusCreateFile); + EmuLog(LOG_LEVEL::WARNING, "%s: Image file NtCreateFile() error", __func__); + if (NtStatusCreateFile == status_object_name_collision) { + EmuLog(LOG_LEVEL::WARNING, "%s: Image file name collision", __func__); + } + else if (NtStatusCreateFile == status_file_is_a_directory) { + EmuLog(LOG_LEVEL::WARNING, "%s: Image file name is a directory or invalid", __func__); + } + hFile= INVALID_HANDLE_VALUE; + } - NTSTATUS NtStatusQueryInfoFile = NtQueryInformationFile( - hFile,//IN HANDLE FileHandle, - &io_status_block,//OUT PIO_STATUS_BLOCK IoStatusBlock, - &FileStdInfo,//OUT PVOID FileInformation, //File_Information Class Structure address. - sizeof(FILE_STANDARD_INFORMATION),//IN ulong_xt Length, //Length of the file information class structure buffer. - FileStandardInformation);//34);//IN FILE_INFORMATION_CLASS FileInformationClass // Enumation of the file information class. - if (NtStatusQueryInfoFile >= 0) - { - dwImageSize = FileStdInfo.EndOfFile.u.LowPart; - } - else - { - EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file NtQueryInformationFile() error."); - dwImageSize = 0; - } + if (hFile != INVALID_HANDLE_VALUE) { + FILE_STANDARD_INFORMATION FileStdInfo; + NTSTATUS NtStatusQueryInfoFile = NtQueryInformationFile( + hFile, + &io_status_block, + &FileStdInfo, // FileInformation + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation); // FileInformationClass; Enumation of the file information class. + if (NtStatusQueryInfoFile >= 0) { + dwImageSize = FileStdInfo.EndOfFile.u.LowPart; + } + else { + EmuLog(LOG_LEVEL::WARNING, "%s: Image file NtQueryInformationFile() error.", __func__); + dwImageSize = 0; + } - if(dwImageSize>0)//proceed the process only if the file size > 0 - { - pvImageBuffer = new BYTE[dwImageSize]; //allocate buffer to read in to image file. + if (dwImageSize > 0) { //proceed the process only if the file size > 0 + pvImageBuffer = new BYTE[dwImageSize]; //allocate buffer to read in to image file. - //use NtReadFile() to replace host CreatFile(); - ntstatus_xt NtStatusReadFile =NtReadFile( - hFile,//IN HANDLE FileHandle - 0,//IN HANDLE Event OPTIONAL - 0, //IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - 0,//IN PVOID ApcContext, - &io_status_block,//OUT PIO_STATUS_BLOCK IoStatusBlock, - pvImageBuffer,//OUT PVOID Buffer, - dwImageSize,//IN ulong_xt Length, - zeroptr); //IN PLARGE_INTEGER ByteOffset OPTIONAL + //use NtReadFile() to replace host CreatFile(); + ntstatus_xt NtStatusReadFile = NtReadFile( + hFile, + 0, // Event OPTIONAL + 0, // ApcRoutine OPTIONAL + 0, // ApcContext + &io_status_block, + pvImageBuffer, + dwImageSize, + zeroptr); // ByteOffset OPTIONAL - DWORD dwBytesRead = 0; - if (NtStatusReadFile == 0x103)//STATUS_PENDING - { - NtStatusReadFile = NtWaitForSingleObject(hFile, 0, 0); - if (NtStatusReadFile < 0){//something wrong - EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file NtReadFile error"); - if (NtStatusReadFile != 0xC0000011)//STATUS_END_OF_FILE - { - if ((NtStatusReadFile & 0xC0000000) == 0x80000000)//Error happened during file reading - { - dwBytesRead = io_status_block.Information; - EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: NtReadFile read file end"); - //ULONG DOSErrorNtReadFile = RtlNtStatusToDosError(NtStatusReadFile);// this is supposed to be the error code of xbox::CreateFile() - } - }else{ - dwBytesRead = 0; - } - } - NtStatusReadFile = io_status_block.Status; - } - if (NtStatusReadFile >= 0) - { - dwBytesRead = io_status_block.Information; - } - + DWORD dwBytesRead = 0; + if (NtStatusReadFile == status_pending) { + NtStatusReadFile = NtWaitForSingleObject(hFile, 0, 0); + if (NtStatusReadFile < 0){ //something wrong + EmuLog(LOG_LEVEL::WARNING, "%s: Image file NtReadFile error", __func__); + if (NtStatusReadFile != status_end_of_file) { + if ((NtStatusReadFile & 0xC0000000) == 0x80000000) { //Error happened during file reading + dwBytesRead = io_status_block.Information; + EmuLog(LOG_LEVEL::WARNING, "%s: NtReadFile read file end", __func__); + // ULONG DOSErrorNtReadFile = RtlNtStatusToDosError(NtStatusReadFile); this is supposed to be the error code of xbox::CreateFile() + } + } else { + dwBytesRead = 0; + } + } + NtStatusReadFile = io_status_block.Status; + } + if (NtStatusReadFile >= 0) { + dwBytesRead = io_status_block.Information; + } - if(dwBytesRead == dwImageSize){//only process the image if the whole image was read successfully. - result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(pThis_tmp, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc); - } - else { - EmuLog(LOG_LEVEL::WARNING, "EmuXAudioDownloadEffectsImage: Image file NtReadFile read in lenth not enough"); - } + if (dwBytesRead == dwImageSize) { // only process the image if the whole image was read successfully. + result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(pThis_tmp, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc); + } + else { + EmuLog(LOG_LEVEL::WARNING, "%s: Image file NtReadFile read in lenth not enough", __func__); + } - if(pvImageBuffer) - { - delete[] pvImageBuffer; - } - if (hFile != INVALID_HANDLE_VALUE) - { - NtClose(hFile); - } - } - } - } - } - return result; + if (pvImageBuffer) { + delete[] pvImageBuffer; + } + + if (hFile != INVALID_HANDLE_VALUE) { + NtClose(hFile); + } + } + } + } + } + + return result; } // ****************************************************************** diff --git a/src/core/kernel/common/types.h b/src/core/kernel/common/types.h index 759483b1e..d579da3a5 100644 --- a/src/core/kernel/common/types.h +++ b/src/core/kernel/common/types.h @@ -92,6 +92,8 @@ inline constexpr dword_xt status_xbe_media_mismatch = 0xC0050002L; inline constexpr dword_xt status_object_name_invalid = 0xC0000033L; inline constexpr dword_xt status_object_name_not_found = 0xC0000034L; inline constexpr dword_xt status_object_name_collision = 0xC0000035L; +inline constexpr dword_xt status_file_is_a_directory = 0xC00000BAL; +inline constexpr dword_xt status_end_of_file = 0xC0000011L; inline constexpr dword_xt status_invalid_page_protection = 0xC0000045L; inline constexpr dword_xt status_conflicting_addresses = 0xC0000018L; inline constexpr dword_xt status_unable_to_free_vm = 0xC000001AL; From 8cc4b10ce099a873ffedc3fe662d01b8983d6a86 Mon Sep 17 00:00:00 2001 From: ergo720 <45463469+ergo720@users.noreply.github.com> Date: Fri, 21 May 2021 19:25:22 +0200 Subject: [PATCH 5/5] Added test case + fixed a macro redefinition warning --- src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp | 4 +++- src/core/kernel/common/ob.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp b/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp index 70e721564..e4b0bc575 100644 --- a/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp +++ b/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp @@ -145,6 +145,8 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage) */ + LOG_TEST_CASE("Loading dsp images from xbe sections is currently not yet supported"); + result = S_OK;//this line should be removed once the section loading code was implemented. } else { // load from file @@ -157,7 +159,7 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage) ANSI_STRING file_name; IO_STATUS_BLOCK io_status_block; RtlInitAnsiString(&file_name, pszImageName); - XB_InitializeObjectAttributes(&obj, &file_name, OBJ_CASE_INSENSITIVE, ObDosDevicesDirectory()); + XB_InitializeObjectAttributes(&obj, &file_name, obj_case_insensitive, ObDosDevicesDirectory()); ntstatus_xt NtStatusCreateFile; //LARGE_INTEGER tmp_LargeInt; //tmp_LargeInt.QuadPart= dwImageSize; diff --git a/src/core/kernel/common/ob.h b/src/core/kernel/common/ob.h index d55bf4cc7..a63a1251e 100644 --- a/src/core/kernel/common/ob.h +++ b/src/core/kernel/common/ob.h @@ -35,7 +35,7 @@ typedef struct _OBJECT_HEADER_NAME_INFO { OBJECT_STRING Name; } OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO; -#define OBJ_CASE_INSENSITIVE 0x40 +inline constexpr dword_xt obj_case_insensitive = 0x40; #define ObDosDevicesDirectory() ((HANDLE)-3) #define ObWin32NamedObjectsDirectory() ((HANDLE)-4)