github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/path/filepath/symlink_windows.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package filepath
     6  
     7  import (
     8  	"syscall"
     9  )
    10  
    11  func toShort(path string) (string, error) {
    12  	p, err := syscall.UTF16FromString(path)
    13  	if err != nil {
    14  		return "", err
    15  	}
    16  	b := p // GetShortPathName says we can reuse buffer
    17  	n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
    18  	if err != nil {
    19  		return "", err
    20  	}
    21  	if n > uint32(len(b)) {
    22  		b = make([]uint16, n)
    23  		n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
    24  		if err != nil {
    25  			return "", err
    26  		}
    27  	}
    28  	return syscall.UTF16ToString(b), nil
    29  }
    30  
    31  func toLong(path string) (string, error) {
    32  	p, err := syscall.UTF16FromString(path)
    33  	if err != nil {
    34  		return "", err
    35  	}
    36  	b := p // GetLongPathName says we can reuse buffer
    37  	n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
    38  	if err != nil {
    39  		return "", err
    40  	}
    41  	if n > uint32(len(b)) {
    42  		b = make([]uint16, n)
    43  		n, err = syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
    44  		if err != nil {
    45  			return "", err
    46  		}
    47  	}
    48  	b = b[:n]
    49  	return syscall.UTF16ToString(b), nil
    50  }
    51  
    52  func evalSymlinks(path string) (string, error) {
    53  	path, err := walkSymlinks(path)
    54  	if err != nil {
    55  		return "", err
    56  	}
    57  
    58  	p, err := toShort(path)
    59  	if err != nil {
    60  		return "", err
    61  	}
    62  	p, err = toLong(p)
    63  	if err != nil {
    64  		return "", err
    65  	}
    66  	// syscall.GetLongPathName does not change the case of the drive letter,
    67  	// but the result of EvalSymlinks must be unique, so we have
    68  	// EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
    69  	// Make drive letter upper case.
    70  	if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' {
    71  		p = string(p[0]+'A'-'a') + p[1:]
    72  	}
    73  	return Clean(p), nil
    74  }