Merge pull request #2055 from CookiePLMonster/fix-completion-callback

Preserve original IO status block and context for ApcRoutine
This commit is contained in:
Luke Usher 2020-11-29 14:07:22 +00:00 committed by GitHub
commit 764304c0ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 4 deletions

View File

@ -1648,10 +1648,17 @@ XBSYSAPI EXPORTNUM(219) xbox::ntstatus_xt NTAPI xbox::NtReadFile
CxbxDebugger::ReportFileRead(FileHandle, Length, Offset);
}
if (ApcRoutine != nullptr) {
// Pack the original parameters to a wrapped context for a custom APC routine
CxbxIoDispatcherContext* cxbxContext = new CxbxIoDispatcherContext(IoStatusBlock, ApcRoutine, ApcContext);
ApcRoutine = CxbxIoApcDispatcher;
ApcContext = cxbxContext;
}
NTSTATUS ret = NtDll::NtReadFile(
FileHandle,
Event,
(PVOID)ApcRoutine,
ApcRoutine,
ApcContext,
IoStatusBlock,
Buffer,
@ -2043,8 +2050,8 @@ XBSYSAPI EXPORTNUM(232) xbox::void_xt NTAPI xbox::NtUserIoApcDispatcher
dwErrorCode = RtlNtStatusToDosError(IoStatusBlock->Status);
}
LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine = (LPOVERLAPPED_COMPLETION_ROUTINE)ApcContext;
LPOVERLAPPED lpOverlapped = (LPOVERLAPPED)CONTAINING_RECORD(IoStatusBlock, OVERLAPPED, Internal);
LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine = reinterpret_cast<LPOVERLAPPED_COMPLETION_ROUTINE>(ApcContext);
LPOVERLAPPED lpOverlapped = reinterpret_cast<LPOVERLAPPED>(IoStatusBlock);
(CompletionRoutine)(dwErrorCode, dwTransferred, lpOverlapped);
@ -2168,10 +2175,17 @@ XBSYSAPI EXPORTNUM(236) xbox::ntstatus_xt NTAPI xbox::NtWriteFile
CxbxDebugger::ReportFileWrite(FileHandle, Length, Offset);
}
if (ApcRoutine != nullptr) {
// Pack the original parameters to a wrapped context for a custom APC routine
CxbxIoDispatcherContext* cxbxContext = new CxbxIoDispatcherContext(IoStatusBlock, ApcRoutine, ApcContext);
ApcRoutine = CxbxIoApcDispatcher;
ApcContext = cxbxContext;
}
NTSTATUS ret = NtDll::NtWriteFile(
FileHandle,
Event,
(PVOID)ApcRoutine,
ApcRoutine,
ApcContext,
IoStatusBlock,
Buffer,

View File

@ -191,6 +191,14 @@ void CxbxFormatPartitionByHandle(HANDLE hFile)
printf("Formatted EmuDisk Partition%d\n", CxbxGetPartitionNumberFromHandle(hFile));
}
void NTAPI CxbxIoApcDispatcher(PVOID ApcContext, xbox::PIO_STATUS_BLOCK /*IoStatusBlock*/, xbox::ulong_xt Reserved)
{
CxbxIoDispatcherContext* cxbxContext = reinterpret_cast<CxbxIoDispatcherContext*>(ApcContext);
std::get<xbox::PIO_APC_ROUTINE>(*cxbxContext)(
std::get<LPVOID>(*cxbxContext),std::get<xbox::PIO_STATUS_BLOCK>(*cxbxContext), Reserved);
delete cxbxContext;
}
const std::string MediaBoardRomFile = "Chihiro\\fpr21042_m29w160et.bin";
const std::string DrivePrefix = "\\??\\";
const std::string DriveSerial = DrivePrefix + "serial:";

View File

@ -304,4 +304,15 @@ int CxbxGetPartitionNumberFromHandle(HANDLE hFile);
std::string CxbxGetPartitionDataPathFromHandle(HANDLE hFile);
void CxbxFormatPartitionByHandle(HANDLE hFile);
// Ensures that an original IoStatusBlock gets passed to the completion callback
// Used by NtReadFile and NtWriteFile
using CxbxIoDispatcherContext = std::tuple<xbox::PIO_STATUS_BLOCK, xbox::PIO_APC_ROUTINE, PVOID>;
void NTAPI CxbxIoApcDispatcher
(
PVOID ApcContext,
xbox::PIO_STATUS_BLOCK IoStatusBlock,
xbox::ulong_xt Reserved
);
#endif