d7a3a090df
From the 1.17 release notes (https://golang.org/doc/go1.17#gofmt): gofmt (and go fmt) now synchronizes //go:build lines with // +build lines. More info about this change can be found at https://golang.org/design/draft-gobuild
55 lines
1021 B
Go
55 lines
1021 B
Go
//go:build windows
|
|
// +build windows
|
|
|
|
package tools
|
|
|
|
import (
|
|
"golang.org/x/sys/windows"
|
|
)
|
|
|
|
func openSymlink(path string) (windows.Handle, error) {
|
|
p, err := windows.UTF16PtrFromString(path)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
attrs := uint32(windows.FILE_FLAG_BACKUP_SEMANTICS)
|
|
h, err := windows.CreateFile(p, 0, 0, nil, windows.OPEN_EXISTING, attrs, 0)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return h, nil
|
|
}
|
|
|
|
func CanonicalizeSystemPath(path string) (string, error) {
|
|
h, err := openSymlink(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer windows.CloseHandle(h)
|
|
|
|
buf := make([]uint16, 100)
|
|
for {
|
|
n, err := windows.GetFinalPathNameByHandle(h, &buf[0], uint32(len(buf)), 0)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if n < uint32(len(buf)) {
|
|
break
|
|
}
|
|
buf = make([]uint16, n)
|
|
}
|
|
|
|
s := windows.UTF16ToString(buf)
|
|
if len(s) > 4 && s[:4] == `\\?\` {
|
|
s = s[4:]
|
|
if len(s) > 3 && s[:3] == `UNC` {
|
|
// return path like \\server\share\...
|
|
return `\` + s[3:], nil
|
|
}
|
|
return s, nil
|
|
}
|
|
return s, nil
|
|
}
|