Repository :
https://github.com/FarGroup/FarManager
On branch : master
Link :
https://github.com/FarGroup/FarManager/commit/6be7b7a8f0ad5f8fa5c8c96efedfb1a1ce35dfa9
>---------------------------------------------------------------
commit 6be7b7a8f0ad5f8fa5c8c96efedfb1a1ce35dfa9
Author: Alex Alabuzhev <
alab...@gmail.com>
Date: Mon Jul 13 23:29:03 2026 +0100
Refactoring
>---------------------------------------------------------------
6be7b7a8f0ad5f8fa5c8c96efedfb1a1ce35dfa9
far/changelog | 5 ++
far/platform.cpp | 22 +++++++
far/platform.fs.cpp | 148 ++++++++++++++++++++++-------------------------
far/platform.hpp | 8 +++
far/platform.process.cpp | 37 ++++++------
far/platform.version.cpp | 2 +-
far/vbuild.m4 | 2 +-
7 files changed, 122 insertions(+), 102 deletions(-)
diff --git a/far/changelog b/far/changelog
index 3ffa01a36..e6d22ad4f 100644
--- a/far/changelog
+++ b/far/changelog
@@ -1,3 +1,8 @@
+--------------------------------------------------------------------------------
+drkns 2026-07-13 23:28:48+01:00 - build 6715
+
+1. Refactoring.
+
--------------------------------------------------------------------------------
MZK 2026-07-11 22:07:16-04:00 - build 6714
diff --git a/far/platform.cpp b/far/platform.cpp
index 8ac8024a1..35ec590f7 100644
--- a/far/platform.cpp
+++ b/far/platform.cpp
@@ -65,6 +65,28 @@ namespace os
{
namespace detail
{
+ UNICODE_STRING make_readonly_unicode_string(string_view const Str)
+ {
+ const auto Size = static_cast<USHORT>(Str.size() * sizeof(wchar_t));
+
+ return
+ {
+ Size,
+ Size,
+ const_cast<wchar_t*>(Str.data())
+ };
+ }
+
+ string_view make_string_view(UNICODE_STRING const Str)
+ {
+ return { Str.Buffer, Str.Length / sizeof(wchar_t) };
+ }
+
+ bool is_buffer_too_small(NTSTATUS const Status)
+ {
+ return any_of(Status, STATUS_INFO_LENGTH_MISMATCH, STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL);
+ }
+
static bool ApiDynamicStringReceiverImpl(
string& Destination,
function_ref<size_t(std::span<wchar_t> WritableBuffer)> const Callable,
diff --git a/far/platform.fs.cpp b/far/platform.fs.cpp
index d454dc8db..e4dcbc93d 100644
--- a/far/platform.fs.cpp
+++ b/far/platform.fs.cpp
@@ -57,7 +57,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Common:
#include "common.hpp"
#include "common/algorithm.hpp"
-#include "common/scope_exit.hpp"
#include "common/uuid.hpp"
// External:
@@ -616,24 +615,27 @@ namespace os::fs
if (!Handle->Object.Open(FileName, 0, file_share_all, nullptr, OPEN_EXISTING))
return nullptr;
- // for network paths buffer size must be <= 64k
- // we double it in a first loop, so starting value is 32k
- size_t BufferSize = 32768;
- auto Result = STATUS_UNSUCCESSFUL;
- do
+ const auto ReasonableSize = 1024;
+ Handle->BufferBase.reset(ReasonableSize);
+
+ for(;;)
{
- BufferSize *= 2;
- Handle->BufferBase.reset(BufferSize);
// sometimes for directories NtQueryInformationFile returns STATUS_SUCCESS but doesn't fill the buffer
- auto& StreamInfo = edit_as<FILE_STREAM_INFORMATION>(Handle->BufferBase.data());
- StreamInfo.StreamNameLength = 0;
- // BUGBUG check result
- (void)Handle->Object.NtQueryInformationFile(Handle->BufferBase.data(), Handle->BufferBase.size(), FileStreamInformation, &Result);
- }
- while (any_of(Result, STATUS_INFO_LENGTH_MISMATCH, STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL));
+ edit_as<FILE_STREAM_INFORMATION>(Handle->BufferBase.data()).StreamNameLength = 0;
- if (!NT_SUCCESS(Result))
- return nullptr;
+ NTSTATUS Result;
+ if (Handle->Object.NtQueryInformationFile(Handle->BufferBase.data(), Handle->BufferBase.size(), FileStreamInformation, &Result))
+ break;
+
+ if (!os::detail::is_buffer_too_small(Result))
+ {
+ LOGWARNING(L"NtQueryInformationFile(): {}"sv, format_ntstatus(Result));
+ Handle->BufferBase.reset();
+ return nullptr;
+ }
+
+ Handle->BufferBase.reset(grow_exp(Handle->BufferBase.size(), {}));
+ }
const auto& StreamInfo = view_as<FILE_STREAM_INFORMATION>(Handle->BufferBase.data());
Handle->NextOffset = StreamInfo.NextEntryOffset;
@@ -713,55 +715,43 @@ namespace os::fs
enum_devices::enum_devices(string_view const Object)
{
- m_Object.Buffer = const_cast<wchar_t*>(Object.data());
- m_Object.Length = m_Object.MaximumLength = static_cast<USHORT>(Object.size() * sizeof(wchar_t));
+ m_Object = os::detail::make_readonly_unicode_string(Object);
OBJECT_ATTRIBUTES Attributes;
InitializeObjectAttributes(&Attributes, &m_Object, 0, nullptr, nullptr)
- if (!NT_SUCCESS(imports.NtOpenDirectoryObject(&ptr_setter(m_Handle), GENERIC_READ, &Attributes)))
+ if (const auto Result = imports.NtOpenDirectoryObject(&ptr_setter(m_Handle), GENERIC_READ, &Attributes); !NT_SUCCESS(Result))
+ {
+ LOGWARNING(L"NtOpenDirectoryObject({}): {}"sv, Object, format_ntstatus(Result));
return;
+ }
m_Buffer.reset(32 * 1024);
}
- bool enum_devices::get(bool Reset, string_view& Value) const
+ bool enum_devices::get(bool const Reset, string_view& Value) const
{
if (!m_Handle)
return false;
- if (Reset)
- m_Index.reset();
-
- auto RestartScan = Reset;
+ const auto Entries = std::bit_cast<OBJECT_DIRECTORY_INFORMATION const*>(m_Buffer.data());
- const auto fill = [&]
+ if (Reset || !Entries[*m_Index].Name.Length)
{
- ULONG Size;
- if (!NT_SUCCESS(imports.NtQueryDirectoryObject(m_Handle.native_handle(), m_Buffer.data(), static_cast<ULONG>(m_Buffer.size()), false, RestartScan, &m_Context, &Size)))
- return false;
+ m_Index.reset();
- RestartScan = false;
- m_Index = 0;
- return true;
- };
+ if (const auto Result = imports.NtQueryDirectoryObject(m_Handle.native_handle(), m_Buffer.data(), static_cast<ULONG>(m_Buffer.size()), false, Reset, &m_Context, {}); !NT_SUCCESS(Result))
+ {
+ if (Result != STATUS_NO_MORE_ENTRIES)
+ LOGWARNING(L"NtQueryDirectoryObject(): {}"sv, format_ntstatus(Result));
- if (!m_Index)
- {
- if (!fill())
return false;
- }
-
- const auto Entries = std::bit_cast<OBJECT_DIRECTORY_INFORMATION const*>(m_Buffer.data());
+ }
- if (!Entries[*m_Index].Name.Length)
- {
- m_Index.reset();
- if (!fill())
- return false;
+ m_Index = 0;
}
- Value = { Entries[*m_Index].Name.Buffer, Entries[*m_Index].Name.Length / sizeof(wchar_t) };
+ Value = os::detail::make_string_view(Entries[*m_Index].Name);
++*m_Index;
return true;
@@ -1007,9 +997,7 @@ namespace os::fs
UNICODE_STRING NameString;
if (!FileName.empty())
{
- NameString.Buffer = const_cast<wchar_t*>(FileName.data());
- NameString.Length = static_cast<USHORT>(FileName.size() * sizeof(wchar_t));
- NameString.MaximumLength = NameString.Length;
+ NameString = os::detail::make_readonly_unicode_string(FileName.data());
pNameString = &NameString;
}
const auto di = static_cast<FILE_ID_BOTH_DIR_INFORMATION*>(FileInformation);
@@ -1033,9 +1021,8 @@ namespace os::fs
set_last_error_from_ntstatus(Result);
if (Status)
- {
*Status = Result;
- }
+
return NT_SUCCESS(Result);
}
@@ -1044,25 +1031,26 @@ namespace os::fs
//
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntifs/nf-ntifs-obquerynamestring
// A reasonable size for the buffer to accommodate most object names is 1024 bytes.
const auto ReasonableSize = 1024;
- block_ptr<OBJECT_NAME_INFORMATION, ReasonableSize> oni(ReasonableSize);
- ULONG ReturnLength;
+ block_ptr<OBJECT_NAME_INFORMATION, ReasonableSize> Buffer(ReasonableSize);
- const auto QueryObject = [&]
+ for (;;)
{
- return imports.NtQueryObject(hFile, ObjectNameInformation, oni.data(), static_cast<unsigned long>(oni.size()), &ReturnLength);
- };
+ ULONG ReturnSize{};
+ const auto Result = imports.NtQueryObject(hFile, ObjectNameInformation, Buffer.data(), static_cast<unsigned long>(Buffer.size()), &ReturnSize);
+ if (NT_SUCCESS(Result))
+ break;
- auto Result = QueryObject();
- if (any_of(Result, STATUS_INFO_LENGTH_MISMATCH, STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL))
- {
- oni.reset(ReturnLength);
- Result = QueryObject();
- }
+ if (!os::detail::is_buffer_too_small(Result))
+ {
+ LOGWARNING(L"NtQueryObject(): {}"sv, format_ntstatus(Result));
+ Buffer.reset();
+ return false;
+ }
- if (!NT_SUCCESS(Result))
- return false;
+ Buffer.reset(ReturnSize? ReturnSize : grow_exp(Buffer.size(), {}));
+ }
- ObjectName.assign(oni->Name.Buffer, oni->Name.Length / sizeof(wchar_t));
+ ObjectName = os::detail::make_string_view(Buffer->Name);
return true;
}
@@ -1587,9 +1575,7 @@ WARNING_POP()
const auto KernelDevicePath = kernel_path(DevicePath);
- UNICODE_STRING ObjName;
- ObjName.Length = ObjName.MaximumLength = static_cast<USHORT>(KernelDevicePath.size() * sizeof(wchar_t));
- ObjName.Buffer = const_cast<wchar_t*>(KernelDevicePath.data());
+ auto ObjName = os::detail::make_readonly_unicode_string(KernelDevicePath);
OBJECT_ATTRIBUTES ObjAttrs;
InitializeObjectAttributes(&ObjAttrs, &ObjName, 0, nullptr, nullptr)
@@ -1598,27 +1584,29 @@ WARNING_POP()
if (!NT_SUCCESS(imports.NtOpenSymbolicLinkObject(&ptr_setter(SymLink), GENERIC_READ, &ObjAttrs)))
return false;
- wchar_t_ptr Buffer(1024);
+ const auto ReasonableSize = 1024;
+ wchar_t_ptr Buffer(ReasonableSize);
UNICODE_STRING LinkTarget;
- ULONG ReturnLength;
- const auto QuerySymbolicLinkObject = [&]
+ for (;;)
{
LinkTarget = { 0, static_cast<USHORT>(Buffer.size() * sizeof(wchar_t)), Buffer.data() };
- return imports.NtQuerySymbolicLinkObject(SymLink.native_handle(), &LinkTarget, &ReturnLength);
- };
+ ULONG ReturnSize{};
+ const auto Result = imports.NtQuerySymbolicLinkObject(SymLink.native_handle(), &LinkTarget, &ReturnSize);
+ if (NT_SUCCESS(Result))
+ break;
- auto Result = QuerySymbolicLinkObject();
- if (any_of(Result, STATUS_INFO_LENGTH_MISMATCH, STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL))
- {
- Buffer.reset(ReturnLength / sizeof(wchar_t));
- Result = QuerySymbolicLinkObject();
- }
+ if (!os::detail::is_buffer_too_small(Result))
+ {
+ LOGWARNING(L"NtQuerySymbolicLinkObject(): {}"sv, format_ntstatus(Result));
+ Buffer.reset();
+ return false;
+ }
- if (!NT_SUCCESS(Result))
- return false;
+ Buffer.reset(ReturnSize? ReturnSize / sizeof(wchar_t) : grow_exp(Buffer.size(), {}));
+ }
- TargetDevicePath.assign(LinkTarget.Buffer, LinkTarget.Length / sizeof(wchar_t));
+ TargetDevicePath = os::detail::make_string_view(LinkTarget);
return true;
}
diff --git a/far/platform.hpp b/far/platform.hpp
index 263702848..3d14b3a7a 100644
--- a/far/platform.hpp
+++ b/far/platform.hpp
@@ -65,6 +65,14 @@ namespace os
namespace detail
{
+ [[nodiscard]]
+ UNICODE_STRING make_readonly_unicode_string(string_view Str);
+ [[nodiscard]]
+ string_view make_string_view(UNICODE_STRING Str);
+
+ [[nodiscard]]
+ bool is_buffer_too_small(NTSTATUS Status);
+
template<typename buffer_type>
[[nodiscard]]
bool ApiDynamicReceiver(
diff --git a/far/platform.process.cpp b/far/platform.process.cpp
index d047e2c1d..ecce5c746 100644
--- a/far/platform.process.cpp
+++ b/far/platform.process.cpp
@@ -407,20 +407,19 @@ namespace os::process
const auto ReasonableSize = 1024;
block_ptr<FILE_PROCESS_IDS_USING_FILE_INFORMATION, ReasonableSize> Info(ReasonableSize);
- auto Result = STATUS_UNSUCCESSFUL;
-
- while (
- !File.NtQueryInformationFile(Info.data(), Info.size(), FileProcessIdsUsingFileInformation, &Result) &&
- any_of(Result, STATUS_INFO_LENGTH_MISMATCH, STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL)
- )
+ for (;;)
{
- Info.reset(Info.size() * 2);
- }
+ NTSTATUS Result;
+ if (File.NtQueryInformationFile(Info.data(), Info.size(), FileProcessIdsUsingFileInformation, &Result))
+ break;
- if (!NT_SUCCESS(Result))
- {
- LOGWARNING(L"NtQueryInformationFile({}): {}"sv, Filename, format_ntstatus(Result));
- return 0;
+ if (!os::detail::is_buffer_too_small(Result))
+ {
+ LOGWARNING(L"NtQueryInformationFile({}): {}"sv, Filename, format_ntstatus(Result));
+ return 0;
+ }
+
+ Info.reset(grow_exp(Info.size(), {}));
}
for (const auto& i: std::span(Info->ProcessIdList, Info->NumberOfProcessIdsInList))
@@ -451,16 +450,14 @@ namespace os::process
if (NT_SUCCESS(Result))
break;
- if (any_of(Result, STATUS_INFO_LENGTH_MISMATCH, STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL))
+ if (!os::detail::is_buffer_too_small(Result))
{
- m_Info.reset(ReturnSize? ReturnSize : grow_exp(m_Info.size(), {}));
- continue;
+ LOGWARNING(L"NtQuerySystemInformation(): {}"sv, format_ntstatus(Result));
+ m_Info.reset();
+ return;
}
- LOGWARNING(L"NtQuerySystemInformation(): {}"sv, format_ntstatus(Result));
-
- m_Info.reset();
- return;
+ m_Info.reset(ReturnSize? ReturnSize : grow_exp(m_Info.size(), {}));
}
}
@@ -479,7 +476,7 @@ namespace os::process
const auto& Info = view_as<SYSTEM_PROCESS_INFORMATION>(m_Info.data(), m_Offset);
Value.Pid = static_cast<DWORD>(std::bit_cast<uintptr_t>(Info.UniqueProcessId));
- Value.Name = { Info.ImageName.Buffer, Info.ImageName.Length / sizeof(wchar_t) };
+ Value.Name = os::detail::make_string_view(Info.ImageName);
Value.Threads = { view_as<SYSTEM_THREAD_INFORMATION const*>(&Info, sizeof(Info)), Info.NumberOfThreads };
if (Info.NextEntryOffset)
diff --git a/far/platform.version.cpp b/far/platform.version.cpp
index fad310342..990ff0019 100644
--- a/far/platform.version.cpp
+++ b/far/platform.version.cpp
@@ -262,7 +262,7 @@ WARNING_POP()
return far::format(L" {} ({}.{})"sv, Info.szCSDVersion, Info.wServicePackMajor, Info.wServicePackMinor);
if (Info.wServicePackMajor)
- return far::format(L" Service Pack {}.{}"sv, Info.wServicePackMajor, Info.wServicePackMinor);
+ return far::format(L" Service Pack {0} ({0}.{1})"sv, Info.wServicePackMajor, Info.wServicePackMinor);
return L""s;
}
diff --git a/far/vbuild.m4 b/far/vbuild.m4
index 3379c3648..ea12fd224 100644
--- a/far/vbuild.m4
+++ b/far/vbuild.m4
@@ -1 +1 @@
-6714
+6715