github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/pkg/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  	p, err := toShort(path)
    54  	if err != nil {
    55  		return "", err
    56  	}
    57  	p, err = toLong(p)
    58  	if err != nil {
    59  		return "", err
    60  	}
    61  	// syscall.GetLongPathName does not change the case of the drive letter,
    62  	// but the result of EvalSymlinks must be unique, so we have
    63  	// EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
    64  	// Make drive letter upper case.
    65  	if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' {
    66  		p = string(p[0]+'A'-'a') + p[1:]
    67  	}
    68  	return Clean(p), nil
    69  }