[*] 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_; AuSPtr<FileHandle> handle_;
}; };
class NtAsyncFileTransaction : public IAsyncTransaction class NtAsyncFileTransaction : public IAsyncTransaction, std::enable_shared_from_this<NtAsyncFileTransaction>
{ {
public: public:
~NtAsyncFileTransaction(); ~NtAsyncFileTransaction();
@ -57,10 +57,13 @@ namespace Aurora::IO::FS
HANDLE GetHandle(); HANDLE GetHandle();
AuSPtr<FileHandle> GetFileHandle(); AuSPtr<FileHandle> GetFileHandle();
// Required for a very evil hack
OVERLAPPED overlap_ {};
private: private:
AuSPtr<NtAsyncFileTransaction> pin_;
AuSPtr<FileHandle> handle_; AuSPtr<FileHandle> handle_;
HANDLE event_ = INVALID_HANDLE_VALUE; HANDLE event_ = INVALID_HANDLE_VALUE;
OVERLAPPED overlap_ {};
AuUInt32 lastAbstractStat_ {}, lastAbstractOffset_ {}; AuUInt32 lastAbstractStat_ {}, lastAbstractOffset_ {};
bool latch_ {}; bool latch_ {};
AuSPtr<IAsyncFinishedSubscriber> sub_; 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) bool NtAsyncFileTransaction::StartRead(AuUInt64 offset, void *buffer, AuUInt32 length)
{ {
this->latch_ = {}; this->latch_ = {};
@ -177,7 +190,8 @@ namespace Aurora::IO::FS
this->lastAbstractOffset_ = offset; this->lastAbstractOffset_ = offset;
this->overlap_.Offset = offset & 0xFFFFFFFF; this->overlap_.Offset = offset & 0xFFFFFFFF;
this->overlap_.OffsetHigh = (offset >> 32) & 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); return TranslateNtStatus(this, ret);
} }
@ -188,7 +202,8 @@ namespace Aurora::IO::FS
this->lastAbstractOffset_ = offset; this->lastAbstractOffset_ = offset;
this->overlap_.Offset = offset & 0xFFFFFFFF; this->overlap_.Offset = offset & 0xFFFFFFFF;
this->overlap_.OffsetHigh = (offset >> 32) & 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); return TranslateNtStatus(this, ret);
} }
@ -198,6 +213,8 @@ namespace Aurora::IO::FS
{ {
return; return;
} }
this->pin_ = {};
if (this->sub_) if (this->sub_)
{ {