]> Cypherpunks.ru repositories - gostls13.git/commitdiff
path/filepath: use windows GetShortPathName api to force GetLongPathName to do its...
authorAlex Brainman <alex.brainman@gmail.com>
Tue, 27 Mar 2012 04:53:08 +0000 (15:53 +1100)
committerAlex Brainman <alex.brainman@gmail.com>
Tue, 27 Mar 2012 04:53:08 +0000 (15:53 +1100)
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5928043

api/go1.txt
src/pkg/path/filepath/symlink_windows.go
src/pkg/syscall/syscall_windows.go
src/pkg/syscall/zsyscall_windows_386.go
src/pkg/syscall/zsyscall_windows_amd64.go

index d6372314aff6af5e6539b6b3eee5911d8e725bcb..e6bdd173e92edaac621b2f54621634742d8e7139 100644 (file)
@@ -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 GetQueuedCompletionStatus(Handle, *uint32, *uint32, **Overlapped, uint32) 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 GetStdHandle(int) (Handle, error)
 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 GetQueuedCompletionStatus(Handle, *uint32, *uint32, **Overlapped, uint32) 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 GetStdHandle(int) (Handle, error)
 pkg syscall (windows-amd64), func GetSystemTimeAsFileTime(*Filetime)
index 2d4257720e000989d2bb6292c059b4aeafe454e0..2b5d1fc681b767caa71d1d85d40d35d6136d60a1 100644 (file)
@@ -8,7 +8,24 @@ import (
        "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)
        b := p // GetLongPathName says we can reuse buffer
        n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
@@ -23,13 +40,24 @@ func evalSymlinks(path string) (string, error) {
                }
        }
        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,
        // but the result of EvalSymlinks must be unique, so we have
        // EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
        // Make drive letter upper case. This matches what os.Getwd returns.
-       if len(s) >= 2 && s[1] == ':' && 'a' <= s[0] && s[0] <= 'z' {
-               s = string(s[0]+'A'-'a') + s[1:]
+       if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' {
+               p = string(p[0]+'A'-'a') + p[1:]
        }
-       return Clean(s), nil
+       return Clean(p), nil
 }
index b0c24cca698cf9ef687bc7ab0a84f98a6ca6e93e..47209da8fecd7a436306c1153108d5906910124a 100644 (file)
@@ -175,6 +175,7 @@ func NewCallback(fn interface{}) uintptr
 //sys  FlushFileBuffers(handle Handle) (err error)
 //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  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  MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
 //sys  UnmapViewOfFile(addr uintptr) (err error)
index 093c4768f2f0795ed9906aaba526b32942b7db4a..8e6afcf0a859c2ce2092c1f0fac45e6adc26624d 100644 (file)
@@ -79,6 +79,7 @@ var (
        procFlushFileBuffers                 = modkernel32.NewProc("FlushFileBuffers")
        procGetFullPathNameW                 = modkernel32.NewProc("GetFullPathNameW")
        procGetLongPathNameW                 = modkernel32.NewProc("GetLongPathNameW")
+       procGetShortPathNameW                = modkernel32.NewProc("GetShortPathNameW")
        procCreateFileMappingW               = modkernel32.NewProc("CreateFileMappingW")
        procMapViewOfFile                    = modkernel32.NewProc("MapViewOfFile")
        procUnmapViewOfFile                  = modkernel32.NewProc("UnmapViewOfFile")
@@ -904,6 +905,19 @@ func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err er
        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) {
        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)
index d298b7451fd5629f2041c1749998a5f4bf48ca7c..c6ff6fe02e228c7d651b97a3713f52b616ef593e 100644 (file)
@@ -79,6 +79,7 @@ var (
        procFlushFileBuffers                 = modkernel32.NewProc("FlushFileBuffers")
        procGetFullPathNameW                 = modkernel32.NewProc("GetFullPathNameW")
        procGetLongPathNameW                 = modkernel32.NewProc("GetLongPathNameW")
+       procGetShortPathNameW                = modkernel32.NewProc("GetShortPathNameW")
        procCreateFileMappingW               = modkernel32.NewProc("CreateFileMappingW")
        procMapViewOfFile                    = modkernel32.NewProc("MapViewOfFile")
        procUnmapViewOfFile                  = modkernel32.NewProc("UnmapViewOfFile")
@@ -904,6 +905,19 @@ func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err er
        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) {
        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)