mirror of
https://github.com/golang/go
synced 2024-11-25 04:57:56 -07:00
path/filepath: use windows GetShortPathName api to force GetLongPathName to do its work
R=golang-dev, rsc CC=golang-dev https://golang.org/cl/5928043
This commit is contained in:
parent
d6c9af6a4e
commit
7a39654174
@ -22244,6 +22244,7 @@ pkg syscall (windows-386), func GetProcessTimes(Handle, *Filetime, *Filetime, *F
|
|||||||
pkg syscall (windows-386), func GetProtoByName(string) (*Protoent, error)
|
pkg syscall (windows-386), func GetProtoByName(string) (*Protoent, error)
|
||||||
pkg syscall (windows-386), func GetQueuedCompletionStatus(Handle, *uint32, *uint32, **Overlapped, uint32) error
|
pkg syscall (windows-386), func GetQueuedCompletionStatus(Handle, *uint32, *uint32, **Overlapped, uint32) error
|
||||||
pkg syscall (windows-386), func GetServByName(string, string) (*Servent, error)
|
pkg syscall (windows-386), func GetServByName(string, string) (*Servent, error)
|
||||||
|
pkg syscall (windows-386), func GetShortPathName(*uint16, *uint16, uint32) (uint32, error)
|
||||||
pkg syscall (windows-386), func GetStartupInfo(*StartupInfo) error
|
pkg syscall (windows-386), func GetStartupInfo(*StartupInfo) error
|
||||||
pkg syscall (windows-386), func GetStdHandle(int) (Handle, error)
|
pkg syscall (windows-386), func GetStdHandle(int) (Handle, error)
|
||||||
pkg syscall (windows-386), func GetSystemTimeAsFileTime(*Filetime)
|
pkg syscall (windows-386), func GetSystemTimeAsFileTime(*Filetime)
|
||||||
@ -23161,6 +23162,7 @@ pkg syscall (windows-amd64), func GetProcessTimes(Handle, *Filetime, *Filetime,
|
|||||||
pkg syscall (windows-amd64), func GetProtoByName(string) (*Protoent, error)
|
pkg syscall (windows-amd64), func GetProtoByName(string) (*Protoent, error)
|
||||||
pkg syscall (windows-amd64), func GetQueuedCompletionStatus(Handle, *uint32, *uint32, **Overlapped, uint32) error
|
pkg syscall (windows-amd64), func GetQueuedCompletionStatus(Handle, *uint32, *uint32, **Overlapped, uint32) error
|
||||||
pkg syscall (windows-amd64), func GetServByName(string, string) (*Servent, error)
|
pkg syscall (windows-amd64), func GetServByName(string, string) (*Servent, error)
|
||||||
|
pkg syscall (windows-amd64), func GetShortPathName(*uint16, *uint16, uint32) (uint32, error)
|
||||||
pkg syscall (windows-amd64), func GetStartupInfo(*StartupInfo) error
|
pkg syscall (windows-amd64), func GetStartupInfo(*StartupInfo) error
|
||||||
pkg syscall (windows-amd64), func GetStdHandle(int) (Handle, error)
|
pkg syscall (windows-amd64), func GetStdHandle(int) (Handle, error)
|
||||||
pkg syscall (windows-amd64), func GetSystemTimeAsFileTime(*Filetime)
|
pkg syscall (windows-amd64), func GetSystemTimeAsFileTime(*Filetime)
|
||||||
|
@ -8,7 +8,24 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
func evalSymlinks(path string) (string, error) {
|
func toShort(path string) (string, error) {
|
||||||
|
p := syscall.StringToUTF16(path)
|
||||||
|
b := p // GetShortPathName says we can reuse buffer
|
||||||
|
n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if n > uint32(len(b)) {
|
||||||
|
b = make([]uint16, n)
|
||||||
|
n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return syscall.UTF16ToString(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func toLong(path string) (string, error) {
|
||||||
p := syscall.StringToUTF16(path)
|
p := syscall.StringToUTF16(path)
|
||||||
b := p // GetLongPathName says we can reuse buffer
|
b := p // GetLongPathName says we can reuse buffer
|
||||||
n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
|
n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
|
||||||
@ -23,13 +40,24 @@ func evalSymlinks(path string) (string, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
b = b[:n]
|
b = b[:n]
|
||||||
s := syscall.UTF16ToString(b)
|
return syscall.UTF16ToString(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func evalSymlinks(path string) (string, error) {
|
||||||
|
p, err := toShort(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
p, err = toLong(p)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
// syscall.GetLongPathName does not change the case of the drive letter,
|
// syscall.GetLongPathName does not change the case of the drive letter,
|
||||||
// but the result of EvalSymlinks must be unique, so we have
|
// but the result of EvalSymlinks must be unique, so we have
|
||||||
// EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
|
// EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
|
||||||
// Make drive letter upper case. This matches what os.Getwd returns.
|
// Make drive letter upper case. This matches what os.Getwd returns.
|
||||||
if len(s) >= 2 && s[1] == ':' && 'a' <= s[0] && s[0] <= 'z' {
|
if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' {
|
||||||
s = string(s[0]+'A'-'a') + s[1:]
|
p = string(p[0]+'A'-'a') + p[1:]
|
||||||
}
|
}
|
||||||
return Clean(s), nil
|
return Clean(p), nil
|
||||||
}
|
}
|
||||||
|
@ -175,6 +175,7 @@ func NewCallback(fn interface{}) uintptr
|
|||||||
//sys FlushFileBuffers(handle Handle) (err error)
|
//sys FlushFileBuffers(handle Handle) (err error)
|
||||||
//sys GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW
|
//sys GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW
|
||||||
//sys GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW
|
//sys GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW
|
||||||
|
//sys GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW
|
||||||
//sys CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW
|
//sys CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW
|
||||||
//sys MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
|
//sys MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
|
||||||
//sys UnmapViewOfFile(addr uintptr) (err error)
|
//sys UnmapViewOfFile(addr uintptr) (err error)
|
||||||
|
@ -79,6 +79,7 @@ var (
|
|||||||
procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers")
|
procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers")
|
||||||
procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW")
|
procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW")
|
||||||
procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW")
|
procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW")
|
||||||
|
procGetShortPathNameW = modkernel32.NewProc("GetShortPathNameW")
|
||||||
procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW")
|
procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW")
|
||||||
procMapViewOfFile = modkernel32.NewProc("MapViewOfFile")
|
procMapViewOfFile = modkernel32.NewProc("MapViewOfFile")
|
||||||
procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile")
|
procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile")
|
||||||
@ -904,6 +905,19 @@ func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err er
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) {
|
||||||
|
r0, _, e1 := Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen))
|
||||||
|
n = uint32(r0)
|
||||||
|
if n == 0 {
|
||||||
|
if e1 != 0 {
|
||||||
|
err = error(e1)
|
||||||
|
} else {
|
||||||
|
err = EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
|
func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
|
||||||
r0, _, e1 := Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
|
r0, _, e1 := Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
|
||||||
handle = Handle(r0)
|
handle = Handle(r0)
|
||||||
|
@ -79,6 +79,7 @@ var (
|
|||||||
procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers")
|
procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers")
|
||||||
procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW")
|
procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW")
|
||||||
procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW")
|
procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW")
|
||||||
|
procGetShortPathNameW = modkernel32.NewProc("GetShortPathNameW")
|
||||||
procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW")
|
procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW")
|
||||||
procMapViewOfFile = modkernel32.NewProc("MapViewOfFile")
|
procMapViewOfFile = modkernel32.NewProc("MapViewOfFile")
|
||||||
procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile")
|
procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile")
|
||||||
@ -904,6 +905,19 @@ func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err er
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) {
|
||||||
|
r0, _, e1 := Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen))
|
||||||
|
n = uint32(r0)
|
||||||
|
if n == 0 {
|
||||||
|
if e1 != 0 {
|
||||||
|
err = error(e1)
|
||||||
|
} else {
|
||||||
|
err = EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
|
func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
|
||||||
r0, _, e1 := Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
|
r0, _, e1 := Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
|
||||||
handle = Handle(r0)
|
handle = Handle(r0)
|
||||||
|
Loading…
Reference in New Issue
Block a user