1// +build windows
2
3/*
4Copyright 2019 The Kubernetes Authors.
5
6Licensed under the Apache License, Version 2.0 (the "License");
7you may not use this file except in compliance with the License.
8You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing, software
13distributed under the License is distributed on an "AS IS" BASIS,
14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15See the License for the specific language governing permissions and
16limitations under the License.
17*/
18
19package mount
20
21import (
22	"fmt"
23	"os"
24	"strconv"
25	"strings"
26	"syscall"
27
28	"k8s.io/klog/v2"
29)
30
31// following failure codes are from https://docs.microsoft.com/en-us/windows/desktop/debug/system-error-codes--1300-1699-
32// ERROR_BAD_NETPATH                 = 53
33// ERROR_NETWORK_BUSY                = 54
34// ERROR_UNEXP_NET_ERR               = 59
35// ERROR_NETNAME_DELETED             = 64
36// ERROR_NETWORK_ACCESS_DENIED       = 65
37// ERROR_BAD_DEV_TYPE                = 66
38// ERROR_BAD_NET_NAME                = 67
39// ERROR_SESSION_CREDENTIAL_CONFLICT = 1219
40// ERROR_LOGON_FAILURE               = 1326
41var errorNoList = [...]int{53, 54, 59, 64, 65, 66, 67, 1219, 1326}
42
43// IsCorruptedMnt return true if err is about corrupted mount point
44func IsCorruptedMnt(err error) bool {
45	if err == nil {
46		return false
47	}
48
49	var underlyingError error
50	switch pe := err.(type) {
51	case nil:
52		return false
53	case *os.PathError:
54		underlyingError = pe.Err
55	case *os.LinkError:
56		underlyingError = pe.Err
57	case *os.SyscallError:
58		underlyingError = pe.Err
59	}
60
61	if ee, ok := underlyingError.(syscall.Errno); ok {
62		for _, errno := range errorNoList {
63			if int(ee) == errno {
64				klog.Warningf("IsCorruptedMnt failed with error: %v, error code: %v", err, errno)
65				return true
66			}
67		}
68	}
69
70	return false
71}
72
73// NormalizeWindowsPath makes sure the given path is a valid path on Windows
74// systems by making sure all instances of `/` are replaced with `\\`, and the
75// path beings with `c:`
76func NormalizeWindowsPath(path string) string {
77	normalizedPath := strings.Replace(path, "/", "\\", -1)
78	if strings.HasPrefix(normalizedPath, "\\") {
79		normalizedPath = "c:" + normalizedPath
80	}
81	return normalizedPath
82}
83
84// ValidateDiskNumber : disk number should be a number in [0, 99]
85func ValidateDiskNumber(disk string) error {
86	diskNum, err := strconv.Atoi(disk)
87	if err != nil {
88		return fmt.Errorf("wrong disk number format: %q, err:%v", disk, err)
89	}
90
91	if diskNum < 0 || diskNum > 99 {
92		return fmt.Errorf("disk number out of range: %q", disk)
93	}
94
95	return nil
96}
97
98// isMountPointMatch determines if the mountpoint matches the dir
99func isMountPointMatch(mp MountPoint, dir string) bool {
100	return mp.Path == dir
101}
102