Source file
src/path/filepath/symlink_windows.go
1
2
3
4
5 package filepath
6
7 import (
8 "strings"
9 "syscall"
10 )
11
12
13
14
15 func normVolumeName(path string) string {
16 volume := VolumeName(path)
17
18 if len(volume) > 2 {
19 return volume
20 }
21
22 return strings.ToUpper(volume)
23 }
24
25
26 func normBase(path string) (string, error) {
27 p, err := syscall.UTF16PtrFromString(path)
28 if err != nil {
29 return "", err
30 }
31
32 var data syscall.Win32finddata
33
34 h, err := syscall.FindFirstFile(p, &data)
35 if err != nil {
36 return "", err
37 }
38 syscall.FindClose(h)
39
40 return syscall.UTF16ToString(data.FileName[:]), nil
41 }
42
43
44
45 func baseIsDotDot(path string) bool {
46 i := strings.LastIndexByte(path, Separator)
47 return path[i+1:] == ".."
48 }
49
50
51
52
53
54
55
56
57
58
59
60
61 func toNorm(path string, normBase func(string) (string, error)) (string, error) {
62 if path == "" {
63 return path, nil
64 }
65
66 path = Clean(path)
67
68 volume := normVolumeName(path)
69 path = path[len(volume):]
70
71
72 if path == "" || path == "." || path == `\` {
73 return volume + path, nil
74 }
75
76 var normPath string
77
78 for {
79 if baseIsDotDot(path) {
80 normPath = path + `\` + normPath
81
82 break
83 }
84
85 name, err := normBase(volume + path)
86 if err != nil {
87 return "", err
88 }
89
90 normPath = name + `\` + normPath
91
92 i := strings.LastIndexByte(path, Separator)
93 if i == -1 {
94 break
95 }
96 if i == 0 {
97 normPath = `\` + normPath
98
99 break
100 }
101
102 path = path[:i]
103 }
104
105 normPath = normPath[:len(normPath)-1]
106
107 return volume + normPath, nil
108 }
109
110 func evalSymlinks(path string) (string, error) {
111 newpath, err := walkSymlinks(path)
112 if err != nil {
113 return "", err
114 }
115 newpath, err = toNorm(newpath, normBase)
116 if err != nil {
117 return "", err
118 }
119 return newpath, nil
120 }
121
View as plain text