DoxigAlpha

GetFinalPathNameByHandle

Returns canonical (normalized) path of handle. Use GetFinalPathNameByHandleFormat to specify whether the path is meant to include NT or DOS volume name (e.g., \Device\HarddiskVolume0\foo.txt versus C:\foo.txt). If DOS volume name format is selected, note that this function does not prepend \\?\ prefix to the resultant path.

Function parameters

Parameters

#
out_buffer:[]u16

Type definitions in this namespace

Types

#
GetFinalPathNameByHandleFormat
Specifies how to format volume path in the result of `GetFinalPathNameByHandle`.
TransferType
https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/buffer-descriptions-for-i-o-control-codes
PEB
Process Environment Block
PEB_LDR_DATA
The `PEB_LDR_DATA` structure is the main record of what modules are loaded in a process.
LDR_DATA_TABLE_ENTRY
Microsoft documentation of this is incomplete, the fields here are taken from various resources including:
PF
Processor feature enumeration.
KUSER_SHARED_DATA
Shared Kernel User Data

Functions in this namespace

Functions

#
CreatePipe
A Zig wrapper around `NtCreateNamedPipeFile` and `NtCreateFile` syscalls.
DeviceIoControl
A Zig wrapper around `NtDeviceIoControlFile` and `NtFsControlFile` syscalls.
RtlGenRandom
Call RtlGenRandom() instead of CryptGetRandom() on Windows
ReadFile
If buffer's length exceeds what a Windows DWORD integer can hold, it will be broken into
GetCurrentDirectory
The result is a slice of `buffer`, indexed from 0.
CreateSymbolicLink
Needs either:
SetFilePointerEx_BEGIN
The SetFilePointerEx function with the `dwMoveMethod` parameter set to `FILE_BEGIN`.
SetFilePointerEx_CURRENT
The SetFilePointerEx function with the `dwMoveMethod` parameter set to `FILE_CURRENT`.
SetFilePointerEx_END
The SetFilePointerEx function with the `dwMoveMethod` parameter set to `FILE_END`.
SetFilePointerEx_CURRENT_get
The SetFilePointerEx function with parameters to get the current offset.
GetFinalPathNameByHandle
Returns canonical (normalized) path of handle.
WSASocketW
Microsoft requires WSAStartup to be called to initialize, or else
fromSysTime
A file time is a 64-bit value that represents the number of 100-nanosecond
nanoSecondsToFileTime
Converts a number of nanoseconds since the POSIX epoch to a Windows FILETIME.
eqlIgnoreCaseWTF16
Compares two WTF16 strings using the equivalent functionality of
eqlIgnoreCaseWtf8
Compares two WTF-8 strings using the equivalent functionality of
removeDotDirsSanitized
Removes '.' and '..' path components from a "sanitized relative path".
normalizePath
Normalizes a Windows path with the following steps:
cStrToPrefixedFileW
Same as `sliceToPrefixedFileW` but accepts a pointer
sliceToPrefixedFileW
Same as `wToPrefixedFileW` but accepts a WTF-8 encoded path.
wToPrefixedFileW
Converts the `path` to WTF16, null-terminated.
getNamespacePrefix
If `T` is `u16`, then `path` should be encoded as WTF-16LE.
getUnprefixedPathType
Get the path type of a path that is known to not have any namespace prefixes
ntToWin32Namespace
Similar to `RtlNtPathNameToDosPathName` but does not do any heap allocation.
loadWinsockExtensionFunction
Loads a Winsock extension function in runtime specified by a GUID.
unexpectedError
Call this when you made a windows DLL call or something that does SetLastError
unexpectedStatus
Call this when you made a windows NtDll call
CTL_CODE
https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes
FileInformationIterator
Helper for iterating a byte buffer of FILE_*_INFORMATION structures (from
ProcessBaseAddress
Returns the base address of the process loaded into memory.

Error sets in this namespace

Error Sets

#
RemoveDotDirsError
The error type for `removeDotDirsSanitized`

= @as(HANDLE, @ptrFromInt(maxInt(usize)))

Values

#
self_process_handle
= @as(HANDLE, @ptrFromInt(maxInt(usize)))
STD_INPUT_HANDLE
The standard input device.
STD_OUTPUT_HANDLE
The standard output device.
STD_ERROR_HANDLE
The standard error device.
TCHAR
= @compileError("Deprecated: choose between `CHAR` or `WCHAR` directly instead.")
LPTSTR
= @compileError("Deprecated: choose between `LPSTR` or `LPWSTR` directly instead.")
LPCTSTR
= @compileError("Deprecated: choose between `LPCSTR` or `LPCWSTR` directly instead.")
PTSTR
= @compileError("Deprecated: choose between `PSTR` or `PWSTR` directly instead.")
PCTSTR
= @compileError("Deprecated: choose between `PCSTR` or `PCWSTR` directly instead.")
TRUE
= 1
INVALID_HANDLE_VALUE
= @as(HANDLE, @ptrFromInt(maxInt(usize)))
INVALID_FILE_ATTRIBUTES
= @as(DWORD, maxInt(DWORD))
reparse_tag_name_surrogate_bit
"If this bit is set, the file or directory represents another named entity in the system."
FILE_NAME_NORMALIZED
Return the normalized drive name.
FILE_NAME_OPENED
Return the opened file name (not normalized).
VOLUME_NAME_DOS
Return the path with the drive letter.
VOLUME_NAME_GUID
Return the path with a volume GUID path instead of the drive name.
VOLUME_NAME_NONE
Return the path with no drive information.
VOLUME_NAME_NT
Return the path with the volume device path.
PIPE_ACCESS_DUPLEX
= 0x00000003
PIPE_TYPE_BYTE
= 0x00000000
PIPE_TYPE_MESSAGE
= 0x00000004
PIPE_READMODE_BYTE
= 0x00000000
PIPE_WAIT
= 0x00000000
PIPE_NOWAIT
= 0x00000001
GENERIC_READ
= 0x80000000
GENERIC_WRITE
= 0x40000000
GENERIC_EXECUTE
= 0x20000000
GENERIC_ALL
= 0x10000000
FILE_SHARE_DELETE
= 0x00000004
FILE_SHARE_READ
= 0x00000001
FILE_SHARE_WRITE
= 0x00000002
DELETE
= 0x00010000
READ_CONTROL
= 0x00020000
WRITE_DAC
= 0x00040000
WRITE_OWNER
= 0x00080000
SYNCHRONIZE
= 0x00100000
STANDARD_RIGHTS_READ
= READ_CONTROL
STANDARD_RIGHTS_WRITE
= READ_CONTROL
STANDARD_RIGHTS_REQUIRED
= DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER
MAXIMUM_ALLOWED
= 0x02000000
FILE_READ_DATA
= 0x00000001
FILE_WRITE_DATA
= 0x00000002
FILE_ADD_FILE
= 0x00000002
FILE_APPEND_DATA
= 0x00000004
FILE_READ_EA
= 0x00000008
FILE_WRITE_EA
= 0x00000010
FILE_EXECUTE
= 0x00000020
FILE_TRAVERSE
= 0x00000020
FILE_DELETE_CHILD
= 0x00000040
FILE_WRITE_THROUGH
= 0x00000002
FILE_RANDOM_ACCESS
= 0x00000800
FILE_ALL_ACCESS
= STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1ff
FILE_GENERIC_READ
= STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE
FILE_GENERIC_WRITE
= STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE
FILE_GENERIC_EXECUTE
= STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE
MEM_IMAGE
= 0x1000000
MEM_MAPPED
= 0x40000
MEM_PRIVATE
= 0x20000
STARTF_USEHOTKEY
= 0x00000200
STARTF_USEPOSITION
= 0x00000004
STARTF_USESIZE
= 0x00000002
INFINITE
= 4294967295
WAIT_ABANDONED
= 0x00000080
WAIT_ABANDONED_0
= WAIT_ABANDONED + 0
WAIT_OBJECT_0
= 0x00000000
WAIT_TIMEOUT
= 0x00000102
WAIT_FAILED
= 0xFFFFFFFF
HEAP_NO_SERIALIZE
= 0x00000001
MEM_COMMIT
= 0x1000
MEM_RESERVE
= 0x2000
MEM_FREE
= 0x10000
MEM_RESET
= 0x80000
MEM_RESET_UNDO
= 0x1000000
MEM_LARGE_PAGES
= 0x20000000
MEM_PHYSICAL
= 0x400000
MEM_TOP_DOWN
= 0x100000
MEM_WRITE_WATCH
= 0x200000
PAGE_GUARD
= 0x100
MEM_DECOMMIT
= 0x4000
MEM_RELEASE
= 0x8000
FOLDERID_LocalAppData
= GUID.parse("{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}")
KF_FLAG_ALIAS_ONLY
= -2147483648
S_OK
= 0
S_FALSE
= 0x00000001
E_NOTIMPL
= @as(c_long, @bitCast(@as(c_ulong, 0x80004001)))
E_NOINTERFACE
= @as(c_long, @bitCast(@as(c_ulong, 0x80004002)))
E_POINTER
= @as(c_long, @bitCast(@as(c_ulong, 0x80004003)))
E_ABORT
= @as(c_long, @bitCast(@as(c_ulong, 0x80004004)))
E_FAIL
= @as(c_long, @bitCast(@as(c_ulong, 0x80004005)))
E_UNEXPECTED
= @as(c_long, @bitCast(@as(c_ulong, 0x8000FFFF)))
E_ACCESSDENIED
= @as(c_long, @bitCast(@as(c_ulong, 0x80070005)))
E_HANDLE
= @as(c_long, @bitCast(@as(c_ulong, 0x80070006)))
E_OUTOFMEMORY
= @as(c_long, @bitCast(@as(c_ulong, 0x8007000E)))
E_INVALIDARG
= @as(c_long, @bitCast(@as(c_ulong, 0x80070057)))
TLS_OUT_OF_INDEXES
= 4294967295
SECTION_ALL_ACCESS
= STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_EXTEND_SIZE
SEC_64K_PAGES
= 0x80000
SEC_FILE
= 0x800000
SEC_IMAGE
= 0x1000000
SEC_RESERVE
= 0x4000000
SEC_COMMIT
= 0x8000000
SEC_IMAGE_NO_EXECUTE
= SEC_IMAGE | SEC_NOCACHE
SEC_NOCACHE
= 0x10000000
SEC_WRITECOMBINE
= 0x40000000
SEC_LARGE_PAGES
= 0x80000000
HKEY_CLASSES_ROOT
= @ptrFromInt(0x80000000)
HKEY_CURRENT_USER
= @ptrFromInt(0x80000001)
HKEY_LOCAL_MACHINE
= @ptrFromInt(0x80000002)
HKEY_USERS
= @ptrFromInt(0x80000003)
HKEY_PERFORMANCE_DATA
= @ptrFromInt(0x80000004)
HKEY_PERFORMANCE_TEXT
= @ptrFromInt(0x80000050)
HKEY_PERFORMANCE_NLSTEXT
= @ptrFromInt(0x80000060)
HKEY_CURRENT_CONFIG
= @ptrFromInt(0x80000005)
HKEY_DYN_DATA
= @ptrFromInt(0x80000006)
HKEY_CURRENT_USER_LOCAL_SETTINGS
= @ptrFromInt(0x80000007)
KEY_ALL_ACCESS
Combines the STANDARD_RIGHTS_REQUIRED, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY,
KEY_CREATE_LINK
Reserved for system use.
KEY_CREATE_SUB_KEY
Required to create a subkey of a registry key.
KEY_ENUMERATE_SUB_KEYS
Required to enumerate the subkeys of a registry key.
KEY_EXECUTE
Equivalent to KEY_READ.
KEY_NOTIFY
Required to request change notifications for a registry key or for subkeys of a registry key.
KEY_QUERY_VALUE
Required to query the values of a registry key.
KEY_READ
Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
KEY_SET_VALUE
Required to create, delete, or set a registry value.
KEY_WOW64_32KEY
Indicates that an application on 64-bit Windows should operate on the 32-bit registry view.
KEY_WOW64_64KEY
Indicates that an application on 64-bit Windows should operate on the 64-bit registry view.
KEY_WRITE
Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights.
REG_OPTION_OPEN_LINK
Open symbolic link.
RTL_REGISTRY_ABSOLUTE
Path is a full path
RTL_REGISTRY_SERVICES
\Registry\Machine\System\CurrentControlSet\Services
RTL_REGISTRY_CONTROL
\Registry\Machine\System\CurrentControlSet\Control
RTL_REGISTRY_WINDOWS_NT
\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion
RTL_REGISTRY_DEVICEMAP
\Registry\Machine\Hardware\DeviceMap
RTL_REGISTRY_USER
\Registry\User\CurrentUser
RTL_REGISTRY_HANDLE
Low order bits are registry handle
RTL_REGISTRY_OPTIONAL
Indicates the key node is optional
RTL_QUERY_REGISTRY_SUBKEY
Name is a subkey and remainder of table or until next subkey are value
RTL_QUERY_REGISTRY_TOPKEY
Reset current key to original key for this and all following table entries.
RTL_QUERY_REGISTRY_REQUIRED
Fail if no match found for this table entry.
RTL_QUERY_REGISTRY_NOVALUE
Used to mark a table entry that has no value name, just wants a call out, not
RTL_QUERY_REGISTRY_NOEXPAND
Used to suppress the expansion of REG_MULTI_SZ into multiple callouts or
RTL_QUERY_REGISTRY_DIRECT
QueryRoutine field ignored.
RTL_QUERY_REGISTRY_DELETE
Used to delete value keys after they are queried.
RTL_QUERY_REGISTRY_TYPECHECK
Use this flag with the RTL_QUERY_REGISTRY_DIRECT flag to verify that the REG_XXX type
FILE_ACTION_ADDED
= 0x00000001
INIT_ONCE_STATIC_INIT
= RTL_RUN_ONCE_INIT
RTL_RUN_ONCE_INIT
= RTL_RUN_ONCE{ .Ptr = null }
PATH_MAX_WIDE
> The maximum path of 32,767 characters is approximate, because the "\\?\"
NAME_MAX
> [Each file name component can be] up to the value returned in the
OBJ_INHERIT
= 0x00000002
OBJ_PERMANENT
= 0x00000010
OBJ_EXCLUSIVE
= 0x00000020
OBJ_OPENIF
= 0x00000080
OBJ_OPENLINK
= 0x00000100
OBJ_KERNEL_HANDLE
= 0x00000200
IOCTL_MOUNTMGR_QUERY_POINTS
= CTL_CODE(MOUNTMGRCONTROLTYPE, 2, .METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH
= CTL_CODE(MOUNTMGRCONTROLTYPE, 12, .METHOD_BUFFERED, FILE_ANY_ACCESS)
SRWLOCK_INIT
= SRWLOCK{}
CONDITION_VARIABLE_INIT
= CONDITION_VARIABLE{}
SharedUserData
Read-only user-mode address for the shared data.
TH32CS_SNAPPROCESS
= 0x00000002
TH32CS_SNAPTHREAD
= 0x00000004
TH32CS_SNAPMODULE
= 0x00000008
TH32CS_SNAPALL
= TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE
TH32CS_INHERIT
= 0x80000000

Source

Implementation

#
pub fn GetFinalPathNameByHandle(
    hFile: HANDLE,
    fmt: GetFinalPathNameByHandleFormat,
    out_buffer: []u16,
) GetFinalPathNameByHandleError![]u16 {
    const final_path = QueryObjectName(hFile, out_buffer) catch |err| switch (err) {
        // we assume InvalidHandle is close enough to FileNotFound in semantics
        // to not further complicate the error set
        error.InvalidHandle => return error.FileNotFound,
        else => |e| return e,
    };

    switch (fmt.volume_name) {
        .Nt => {
            // the returned path is already in .Nt format
            return final_path;
        },
        .Dos => {
            // parse the string to separate volume path from file path
            const expected_prefix = std.unicode.utf8ToUtf16LeStringLiteral("\\Device\\");

            // TODO find out if a path can start with something besides `\Device\<volume name>`,
            // and if we need to handle it differently
            // (i.e. how to determine the start and end of the volume name in that case)
            if (!mem.eql(u16, expected_prefix, final_path[0..expected_prefix.len])) return error.Unexpected;

            const file_path_begin_index = mem.indexOfPos(u16, final_path, expected_prefix.len, &[_]u16{'\\'}) orelse unreachable;
            const volume_name_u16 = final_path[0..file_path_begin_index];
            const device_name_u16 = volume_name_u16[expected_prefix.len..];
            const file_name_u16 = final_path[file_path_begin_index..];

            // MUP is Multiple UNC Provider, and indicates that the path is a UNC
            // path. In this case, the canonical UNC path can be gotten by just
            // dropping the \Device\Mup\ and making sure the path begins with \\
            if (mem.eql(u16, device_name_u16, std.unicode.utf8ToUtf16LeStringLiteral("Mup"))) {
                out_buffer[0] = '\\';
                @memmove(out_buffer[1..][0..file_name_u16.len], file_name_u16);
                return out_buffer[0 .. 1 + file_name_u16.len];
            }

            // Get DOS volume name. DOS volume names are actually symbolic link objects to the
            // actual NT volume. For example:
            // (NT) \Device\HarddiskVolume4 => (DOS) \DosDevices\C: == (DOS) C:
            const MIN_SIZE = @sizeOf(MOUNTMGR_MOUNT_POINT) + MAX_PATH;
            // We initialize the input buffer to all zeros for convenience since
            // `DeviceIoControl` with `IOCTL_MOUNTMGR_QUERY_POINTS` expects this.
            var input_buf: [MIN_SIZE]u8 align(@alignOf(MOUNTMGR_MOUNT_POINT)) = [_]u8{0} ** MIN_SIZE;
            var output_buf: [MIN_SIZE * 4]u8 align(@alignOf(MOUNTMGR_MOUNT_POINTS)) = undefined;

            // This surprising path is a filesystem path to the mount manager on Windows.
            // Source: https://stackoverflow.com/questions/3012828/using-ioctl-mountmgr-query-points
            // This is the NT namespaced version of \\.\MountPointManager
            const mgmt_path_u16 = std.unicode.utf8ToUtf16LeStringLiteral("\\??\\MountPointManager");
            const mgmt_handle = OpenFile(mgmt_path_u16, .{
                .access_mask = SYNCHRONIZE,
                .share_access = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                .creation = FILE_OPEN,
            }) catch |err| switch (err) {
                error.IsDir => return error.Unexpected,
                error.NotDir => return error.Unexpected,
                error.NoDevice => return error.Unexpected,
                error.AccessDenied => return error.Unexpected,
                error.PipeBusy => return error.Unexpected,
                error.PathAlreadyExists => return error.Unexpected,
                error.WouldBlock => return error.Unexpected,
                error.NetworkNotFound => return error.Unexpected,
                error.AntivirusInterference => return error.Unexpected,
                else => |e| return e,
            };
            defer CloseHandle(mgmt_handle);

            var input_struct: *MOUNTMGR_MOUNT_POINT = @ptrCast(&input_buf[0]);
            input_struct.DeviceNameOffset = @sizeOf(MOUNTMGR_MOUNT_POINT);
            input_struct.DeviceNameLength = @intCast(volume_name_u16.len * 2);
            @memcpy(input_buf[@sizeOf(MOUNTMGR_MOUNT_POINT)..][0 .. volume_name_u16.len * 2], @as([*]const u8, @ptrCast(volume_name_u16.ptr)));

            DeviceIoControl(mgmt_handle, IOCTL_MOUNTMGR_QUERY_POINTS, &input_buf, &output_buf) catch |err| switch (err) {
                error.AccessDenied => return error.Unexpected,
                else => |e| return e,
            };
            const mount_points_struct: *const MOUNTMGR_MOUNT_POINTS = @ptrCast(&output_buf[0]);

            const mount_points = @as(
                [*]const MOUNTMGR_MOUNT_POINT,
                @ptrCast(&mount_points_struct.MountPoints[0]),
            )[0..mount_points_struct.NumberOfMountPoints];

            for (mount_points) |mount_point| {
                const symlink = @as(
                    [*]const u16,
                    @ptrCast(@alignCast(&output_buf[mount_point.SymbolicLinkNameOffset])),
                )[0 .. mount_point.SymbolicLinkNameLength / 2];

                // Look for `\DosDevices\` prefix. We don't really care if there are more than one symlinks
                // with traditional DOS drive letters, so pick the first one available.
                var prefix_buf = std.unicode.utf8ToUtf16LeStringLiteral("\\DosDevices\\");
                const prefix = prefix_buf[0..prefix_buf.len];

                if (mem.startsWith(u16, symlink, prefix)) {
                    const drive_letter = symlink[prefix.len..];

                    if (out_buffer.len < drive_letter.len + file_name_u16.len) return error.NameTooLong;

                    @memcpy(out_buffer[0..drive_letter.len], drive_letter);
                    @memmove(out_buffer[drive_letter.len..][0..file_name_u16.len], file_name_u16);
                    const total_len = drive_letter.len + file_name_u16.len;

                    // Validate that DOS does not contain any spurious nul bytes.
                    if (mem.indexOfScalar(u16, out_buffer[0..total_len], 0)) |_| {
                        return error.BadPathName;
                    }

                    return out_buffer[0..total_len];
                } else if (mountmgrIsVolumeName(symlink)) {
                    // If the symlink is a volume GUID like \??\Volume{383da0b0-717f-41b6-8c36-00500992b58d},
                    // then it is a volume mounted as a path rather than a drive letter. We need to
                    // query the mount manager again to get the DOS path for the volume.

                    // 49 is the maximum length accepted by mountmgrIsVolumeName
                    const vol_input_size = @sizeOf(MOUNTMGR_TARGET_NAME) + (49 * 2);
                    var vol_input_buf: [vol_input_size]u8 align(@alignOf(MOUNTMGR_TARGET_NAME)) = [_]u8{0} ** vol_input_size;
                    // Note: If the path exceeds MAX_PATH, the Disk Management GUI doesn't accept the full path,
                    // and instead if must be specified using a shortened form (e.g. C:\FOO~1\BAR~1\<...>).
                    // However, just to be sure we can handle any path length, we use PATH_MAX_WIDE here.
                    const min_output_size = @sizeOf(MOUNTMGR_VOLUME_PATHS) + (PATH_MAX_WIDE * 2);
                    var vol_output_buf: [min_output_size]u8 align(@alignOf(MOUNTMGR_VOLUME_PATHS)) = undefined;

                    var vol_input_struct: *MOUNTMGR_TARGET_NAME = @ptrCast(&vol_input_buf[0]);
                    vol_input_struct.DeviceNameLength = @intCast(symlink.len * 2);
                    @memcpy(@as([*]WCHAR, &vol_input_struct.DeviceName)[0..symlink.len], symlink);

                    DeviceIoControl(mgmt_handle, IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH, &vol_input_buf, &vol_output_buf) catch |err| switch (err) {
                        error.AccessDenied => return error.Unexpected,
                        else => |e| return e,
                    };
                    const volume_paths_struct: *const MOUNTMGR_VOLUME_PATHS = @ptrCast(&vol_output_buf[0]);
                    const volume_path = std.mem.sliceTo(@as(
                        [*]const u16,
                        &volume_paths_struct.MultiSz,
                    )[0 .. volume_paths_struct.MultiSzLength / 2], 0);

                    if (out_buffer.len < volume_path.len + file_name_u16.len) return error.NameTooLong;

                    // `out_buffer` currently contains the memory of `file_name_u16`, so it can overlap with where
                    // we want to place the filename before returning. Here are the possible overlapping cases:
                    //
                    // out_buffer:       [filename]
                    //       dest: [___(a)___] [___(b)___]
                    //
                    // In the case of (a), we need to copy forwards, and in the case of (b) we need
                    // to copy backwards. We also need to do this before copying the volume path because
                    // it could overwrite the file_name_u16 memory.
                    const file_name_dest = out_buffer[volume_path.len..][0..file_name_u16.len];
                    @memmove(file_name_dest, file_name_u16);
                    @memcpy(out_buffer[0..volume_path.len], volume_path);
                    const total_len = volume_path.len + file_name_u16.len;

                    // Validate that DOS does not contain any spurious nul bytes.
                    if (mem.indexOfScalar(u16, out_buffer[0..total_len], 0)) |_| {
                        return error.BadPathName;
                    }

                    return out_buffer[0..total_len];
                }
            }

            // If we've ended up here, then something went wrong/is corrupted in the OS,
            // so error out!
            return error.FileNotFound;
        },
    }
}