[*] Pin overlapped structure until async IO completion

This commit is contained in:
Reece Wilson 2021-09-14 15:20:31 +01:00
parent 2382f75759
commit 03368d262f

View File

@ -36,7 +36,7 @@ namespace Aurora::IO::FS
AuSPtr<FileHandle> handle_;
};
class NtAsyncFileTransaction : public IAsyncTransaction
class NtAsyncFileTransaction : public IAsyncTransaction, std::enable_shared_from_this<NtAsyncFileTransaction>
{
public:
~NtAsyncFileTransaction();
@ -57,10 +57,13 @@ namespace Aurora::IO::FS
HANDLE GetHandle();
AuSPtr<FileHandle> GetFileHandle();
// Required for a very evil hack
OVERLAPPED overlap_ {};
private:
AuSPtr<NtAsyncFileTransaction> pin_;
AuSPtr<FileHandle> handle_;
HANDLE event_ = INVALID_HANDLE_VALUE;
OVERLAPPED overlap_ {};
AuUInt32 lastAbstractStat_ {}, lastAbstractOffset_ {};
bool latch_ {};
AuSPtr<IAsyncFinishedSubscriber> sub_;
@ -170,6 +173,16 @@ namespace Aurora::IO::FS
}
}
VOID WINAPI GenericCompletionRoutine(
_In_ DWORD dwErrorCode,
_In_ DWORD dwNumberOfBytesTransfered,
_Inout_ LPOVERLAPPED lpOverlapped
)
{
auto transaction = reinterpret_cast<NtAsyncFileTransaction *>(reinterpret_cast<AuUInt8*>(lpOverlapped) - offsetof(NtAsyncFileTransaction, overlap_));
transaction->Complete();
}
bool NtAsyncFileTransaction::StartRead(AuUInt64 offset, void *buffer, AuUInt32 length)
{
this->latch_ = {};
@ -177,7 +190,8 @@ namespace Aurora::IO::FS
this->lastAbstractOffset_ = offset;
this->overlap_.Offset = offset & 0xFFFFFFFF;
this->overlap_.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
auto ret = ::ReadFile(this->handle_->handle, buffer, length, NULL, &overlap_);
this->pin_ = AU_SHARED_FROM_THIS;
auto ret = ::ReadFileEx(this->handle_->handle, buffer, length, &overlap_, GenericCompletionRoutine);
return TranslateNtStatus(this, ret);
}
@ -188,7 +202,8 @@ namespace Aurora::IO::FS
this->lastAbstractOffset_ = offset;
this->overlap_.Offset = offset & 0xFFFFFFFF;
this->overlap_.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
auto ret = ::WriteFile(this->handle_->handle, buffer, length, NULL, &overlap_);
this->pin_ = AU_SHARED_FROM_THIS;
auto ret = ::WriteFileEx(this->handle_->handle, buffer, length, &overlap_, GenericCompletionRoutine);
return TranslateNtStatus(this, ret);
}
@ -198,6 +213,8 @@ namespace Aurora::IO::FS
{
return;
}
this->pin_ = {};
if (this->sub_)
{