aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/internal/filepathlite/path_windows.go19
-rw-r--r--src/internal/syscall/windows/syscall_windows.go1
-rw-r--r--src/internal/syscall/windows/zsyscall_windows.go7
-rw-r--r--src/path/filepath/path_test.go15
4 files changed, 31 insertions, 11 deletions
diff --git a/src/internal/filepathlite/path_windows.go b/src/internal/filepathlite/path_windows.go
index 8f34838a98..011baa96f0 100644
--- a/src/internal/filepathlite/path_windows.go
+++ b/src/internal/filepathlite/path_windows.go
@@ -7,6 +7,7 @@ package filepathlite
import (
"internal/bytealg"
"internal/stringslite"
+ "internal/syscall/windows"
"syscall"
)
@@ -114,13 +115,14 @@ func isReservedName(name string) bool {
return true
}
// The path element is a reserved name with an extension.
- // Some Windows versions consider this a reserved name,
- // while others do not. Use FullPath to see if the name is
- // reserved.
- if p, _ := syscall.FullPath(name); len(p) >= 4 && p[:4] == `\\.\` {
- return true
+ // Since Windows 11, reserved names with extensions are no
+ // longer reserved. For example, "CON.txt" is a valid file
+ // name. Use RtlIsDosDeviceName_U to see if the name is reserved.
+ p, err := syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return false
}
- return false
+ return windows.RtlIsDosDeviceName_U(p) > 0
}
func isReservedBaseName(name string) bool {
@@ -297,11 +299,6 @@ func cutPath(path string) (before, after string, found bool) {
return path, "", false
}
-// isUNC reports whether path is a UNC path.
-func isUNC(path string) bool {
- return len(path) > 1 && IsPathSeparator(path[0]) && IsPathSeparator(path[1])
-}
-
// postClean adjusts the results of Clean to avoid turning a relative path
// into an absolute or rooted one.
func postClean(out *lazybuf) {
diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go
index c848f92d1f..e4d42f3dae 100644
--- a/src/internal/syscall/windows/syscall_windows.go
+++ b/src/internal/syscall/windows/syscall_windows.go
@@ -535,3 +535,4 @@ const (
//sys NtOpenFile(handle *syscall.Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, share uint32, options uint32) (ntstatus error) = ntdll.NtOpenFile
//sys rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) = ntdll.RtlNtStatusToDosErrorNoTeb
//sys NtSetInformationFile(handle syscall.Handle, iosb *IO_STATUS_BLOCK, inBuffer uintptr, inBufferLen uint32, class uint32) (ntstatus error) = ntdll.NtSetInformationFile
+//sys RtlIsDosDeviceName_U(name *uint16) (ret uint32) = ntdll.RtlIsDosDeviceName_U
diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go
index 6a6ea7bdc0..f7b89e9ca3 100644
--- a/src/internal/syscall/windows/zsyscall_windows.go
+++ b/src/internal/syscall/windows/zsyscall_windows.go
@@ -96,6 +96,7 @@ var (
procNtOpenFile = modntdll.NewProc("NtOpenFile")
procNtSetInformationFile = modntdll.NewProc("NtSetInformationFile")
procRtlGetVersion = modntdll.NewProc("RtlGetVersion")
+ procRtlIsDosDeviceName_U = modntdll.NewProc("RtlIsDosDeviceName_U")
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
@@ -500,6 +501,12 @@ func rtlGetVersion(info *_OSVERSIONINFOW) {
return
}
+func RtlIsDosDeviceName_U(name *uint16) (ret uint32) {
+ r0, _, _ := syscall.Syscall(procRtlIsDosDeviceName_U.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+ ret = uint32(r0)
+ return
+}
+
func rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) {
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(ntstatus), 0, 0)
ret = syscall.Errno(r0)
diff --git a/src/path/filepath/path_test.go b/src/path/filepath/path_test.go
index e9cd82d6c5..7ea02a7c28 100644
--- a/src/path/filepath/path_test.go
+++ b/src/path/filepath/path_test.go
@@ -1889,3 +1889,18 @@ func TestEvalSymlinksTooManyLinks(t *testing.T) {
t.Fatal("expected error, got nil")
}
}
+
+func BenchmarkIsLocal(b *testing.B) {
+ tests := islocaltests
+ if runtime.GOOS == "windows" {
+ tests = append(tests, winislocaltests...)
+ }
+ if runtime.GOOS == "plan9" {
+ tests = append(tests, plan9islocaltests...)
+ }
+ for b.Loop() {
+ for _, test := range tests {
+ filepath.IsLocal(test.path)
+ }
+ }
+}