diff --git a/Include/Aurora/IO/FS/IFileStream.hpp b/Include/Aurora/IO/FS/IFileStream.hpp index 26aea960..b7248d42 100644 --- a/Include/Aurora/IO/FS/IFileStream.hpp +++ b/Include/Aurora/IO/FS/IFileStream.hpp @@ -64,5 +64,9 @@ namespace Aurora::IO::FS */ virtual void MakeTemporary() = 0; + /** + * @brief Returns the IO handle backing the file stream, if available. + */ + virtual AuSPtr GetHandle() = 0; }; } \ No newline at end of file diff --git a/Source/IO/FS/FileStream.NT.cpp b/Source/IO/FS/FileStream.NT.cpp index 1fdcda95..7611a560 100644 --- a/Source/IO/FS/FileStream.NT.cpp +++ b/Source/IO/FS/FileStream.NT.cpp @@ -31,7 +31,7 @@ namespace Aurora::IO::FS LARGE_INTEGER distance {}; LARGE_INTEGER pos {}; - auto hHandle = this->GetHandle(); + auto hHandle = this->GetWin32Handle(); if (hHandle == INVALID_HANDLE_VALUE) { @@ -56,7 +56,7 @@ namespace Aurora::IO::FS LARGE_INTEGER distance {}; LARGE_INTEGER pos {}; - auto hHandle = this->GetHandle(); + auto hHandle = this->GetWin32Handle(); if (hHandle == INVALID_HANDLE_VALUE) { @@ -79,7 +79,7 @@ namespace Aurora::IO::FS { LARGE_INTEGER length; - auto hHandle = this->GetHandle(); + auto hHandle = this->GetWin32Handle(); if (hHandle == INVALID_HANDLE_VALUE) { @@ -98,7 +98,7 @@ namespace Aurora::IO::FS bool WinFileStream::Read(const Memory::MemoryViewStreamWrite ¶meters) { - auto hHandle = this->GetHandle(); + auto hHandle = this->GetWin32Handle(); HANDLE hEventHandle { INVALID_HANDLE_VALUE }; if (hHandle == INVALID_HANDLE_VALUE) @@ -184,7 +184,7 @@ namespace Aurora::IO::FS bool WinFileStream::Write(const Memory::MemoryViewStreamRead ¶meters) { - auto hHandle = this->GetHandle(); + auto hHandle = this->GetWin32Handle(); HANDLE hEventHandle { INVALID_HANDLE_VALUE }; if (hHandle == INVALID_HANDLE_VALUE) @@ -275,7 +275,7 @@ namespace Aurora::IO::FS void WinFileStream::WriteEoS() { - auto hHandle = this->GetHandle(); + auto hHandle = this->GetWin32Handle(); if (hHandle == INVALID_HANDLE_VALUE) { @@ -288,7 +288,9 @@ namespace Aurora::IO::FS void WinFileStream::Close() { - auto hHandle = this->GetHandle(); + auto hHandle = this->GetWin32Handle(); + bool bDeleteFailed {}; + AuString path; if ((hHandle != INVALID_HANDLE_VALUE) && (this->bShouldDelete)) @@ -298,16 +300,29 @@ namespace Aurora::IO::FS if (!(pSetFileInformationByHandle && pSetFileInformationByHandle(hHandle, _FILE_INFO_BY_HANDLE_CLASS::FileDispositionInfo, &rm, sizeof(rm)))) { - SysPushErrorIO("Couldn't delete temporary file {}", this->pHandle_ ? this->pHandle_->GetPath() : ""); + path = this->pHandle_ ? this->pHandle_->GetPath() : ""; + + SysPushErrorIO("Couldn't delete temporary file {}", path); + + if (path.length()) + { + bDeleteFailed = true; + } } } AuResetMember(this->pHandle_); + + // a bit of a hack for problematic NT-like platforms and Windows XP + if (bDeleteFailed) + { + AuFS::Remove(path); + } } void WinFileStream::Flush() { - auto hHandle = this->GetHandle(); + auto hHandle = this->GetWin32Handle(); ::FlushFileBuffers(hHandle); } @@ -317,7 +332,12 @@ namespace Aurora::IO::FS this->bShouldDelete = true; } - HANDLE WinFileStream::GetHandle() + AuSPtr WinFileStream::GetHandle() + { + return this->pHandle_; + } + + HANDLE WinFileStream::GetWin32Handle() { return this->pHandle_ ? (HANDLE)this->pHandle_->GetOSWriteHandleSafe().ValueOr(this->pHandle_->GetOSReadHandleSafe().ValueOr((AuUInt)INVALID_HANDLE_VALUE)) : diff --git a/Source/IO/FS/FileStream.NT.hpp b/Source/IO/FS/FileStream.NT.hpp index f7c461bc..20b9fdcd 100644 --- a/Source/IO/FS/FileStream.NT.hpp +++ b/Source/IO/FS/FileStream.NT.hpp @@ -26,8 +26,9 @@ namespace Aurora::IO::FS void Flush() override; void WriteEoS() override; void MakeTemporary() override; + AuSPtr GetHandle() override; - HANDLE GetHandle(); + HANDLE GetWin32Handle(); private: AuSPtr pHandle_;