Function ntToWin32Namespace [src]

Similar to RtlNtPathNameToDosPathName but does not do any heap allocation. The possible transformations are: ??\C:\Some\Path -> C:\Some\Path ??\UNC\server\share\foo -> \server\share\foo If the path does not have the NT namespace prefix, then error.NotNtPath is returned. Functionality is based on the ReactOS test cases found here: https://github.com/reactos/reactos/blob/master/modules/rostests/apitests/ntdll/RtlNtPathNameToDosPathName.c path should be encoded as WTF-16LE.

Prototype

pub fn ntToWin32Namespace(path: []const u16) !PathSpace

Parameters

path: []const u16

Example

test ntToWin32Namespace { const L = std.unicode.utf8ToUtf16LeStringLiteral; try testNtToWin32Namespace(L("UNC"), L("\\??\\UNC")); try testNtToWin32Namespace(L("\\\\"), L("\\??\\UNC\\")); try testNtToWin32Namespace(L("\\\\path1"), L("\\??\\UNC\\path1")); try testNtToWin32Namespace(L("\\\\path1\\path2"), L("\\??\\UNC\\path1\\path2")); try testNtToWin32Namespace(L(""), L("\\??\\")); try testNtToWin32Namespace(L("C:"), L("\\??\\C:")); try testNtToWin32Namespace(L("C:\\"), L("\\??\\C:\\")); try testNtToWin32Namespace(L("C:\\test"), L("\\??\\C:\\test")); try testNtToWin32Namespace(L("C:\\test\\"), L("\\??\\C:\\test\\")); try std.testing.expectError(error.NotNtPath, ntToWin32Namespace(L("foo"))); try std.testing.expectError(error.NotNtPath, ntToWin32Namespace(L("C:\\test"))); try std.testing.expectError(error.NotNtPath, ntToWin32Namespace(L("\\\\.\\test"))); }

Source

pub fn ntToWin32Namespace(path: []const u16) !PathSpace { if (path.len > PATH_MAX_WIDE) return error.NameTooLong; var path_space: PathSpace = undefined; const namespace_prefix = getNamespacePrefix(u16, path); switch (namespace_prefix) { .nt => { var dest_index: usize = 0; var after_prefix = path[4..]; // after the `\??\` // The prefix \??\UNC\ means this is a UNC path, in which case the // `\??\UNC\` should be replaced by `\\` (two backslashes) // TODO: the "UNC" should technically be matched case-insensitively, but // it's unlikely to matter since most/all paths passed into this // function will have come from the OS meaning it should have // the 'canonical' uppercase UNC. const is_unc = after_prefix.len >= 4 and std.mem.eql(u16, after_prefix[0..3], std.unicode.utf8ToUtf16LeStringLiteral("UNC")) and std.fs.path.PathType.windows.isSep(u16, std.mem.littleToNative(u16, after_prefix[3])); if (is_unc) { path_space.data[0] = comptime std.mem.nativeToLittle(u16, '\\'); dest_index += 1; // We want to include the last `\` of `\??\UNC\` after_prefix = path[7..]; } @memcpy(path_space.data[dest_index..][0..after_prefix.len], after_prefix); path_space.len = dest_index + after_prefix.len; path_space.data[path_space.len] = 0; return path_space; }, else => return error.NotNtPath, } }