git

Форк
0
/
fsm-path-utils-win32.c 
148 строк · 3.4 Кб
1
#include "git-compat-util.h"
2
#include "fsmonitor-ll.h"
3
#include "fsmonitor-path-utils.h"
4
#include "gettext.h"
5
#include "trace.h"
6

7
/*
8
 * Check remote working directory protocol.
9
 *
10
 * Return -1 if client machine cannot get remote protocol information.
11
 */
12
static int check_remote_protocol(wchar_t *wpath)
13
{
14
	HANDLE h;
15
	FILE_REMOTE_PROTOCOL_INFO proto_info;
16

17
	h = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
18
			FILE_FLAG_BACKUP_SEMANTICS, NULL);
19

20
	if (h == INVALID_HANDLE_VALUE) {
21
		error(_("[GLE %ld] unable to open for read '%ls'"),
22
		      GetLastError(), wpath);
23
		return -1;
24
	}
25

26
	if (!GetFileInformationByHandleEx(h, FileRemoteProtocolInfo,
27
		&proto_info, sizeof(proto_info))) {
28
		error(_("[GLE %ld] unable to get protocol information for '%ls'"),
29
		      GetLastError(), wpath);
30
		CloseHandle(h);
31
		return -1;
32
	}
33

34
	CloseHandle(h);
35

36
	trace_printf_key(&trace_fsmonitor,
37
				"check_remote_protocol('%ls') remote protocol %#8.8lx",
38
				wpath, proto_info.Protocol);
39

40
	return 0;
41
}
42

43
/*
44
 * Notes for testing:
45
 *
46
 * (a) Windows allows a network share to be mapped to a drive letter.
47
 *     (This is the normal method to access it.)
48
 *
49
 *     $ NET USE Z: \\server\share
50
 *     $ git -C Z:/repo status
51
 *
52
 * (b) Windows allows a network share to be referenced WITHOUT mapping
53
 *     it to drive letter.
54
 *
55
 *     $ NET USE \\server\share\dir
56
 *     $ git -C //server/share/repo status
57
 *
58
 * (c) Windows allows "SUBST" to create a fake drive mapping to an
59
 *     arbitrary path (which may be remote)
60
 *
61
 *     $ SUBST Q: Z:\repo
62
 *     $ git -C Q:/ status
63
 *
64
 * (d) Windows allows a directory symlink to be created on a local
65
 *     file system that points to a remote repo.
66
 *
67
 *     $ mklink /d ./link //server/share/repo
68
 *     $ git -C ./link status
69
 */
70
int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info)
71
{
72
	wchar_t wpath[MAX_PATH];
73
	wchar_t wfullpath[MAX_PATH];
74
	size_t wlen;
75
	UINT driveType;
76

77
	/*
78
	 * Do everything in wide chars because the drive letter might be
79
	 * a multi-byte sequence.  See win32_has_dos_drive_prefix().
80
	 */
81
	if (xutftowcs_path(wpath, path) < 0) {
82
		return -1;
83
	}
84

85
	/*
86
	 * GetDriveTypeW() requires a final slash.  We assume that the
87
	 * worktree pathname points to an actual directory.
88
	 */
89
	wlen = wcslen(wpath);
90
	if (wpath[wlen - 1] != L'\\' && wpath[wlen - 1] != L'/') {
91
		wpath[wlen++] = L'\\';
92
		wpath[wlen] = 0;
93
	}
94

95
	/*
96
	 * Normalize the path.  If nothing else, this converts forward
97
	 * slashes to backslashes.  This is essential to get GetDriveTypeW()
98
	 * correctly handle some UNC "\\server\share\..." paths.
99
	 */
100
	if (!GetFullPathNameW(wpath, MAX_PATH, wfullpath, NULL)) {
101
		return -1;
102
	}
103

104
	driveType = GetDriveTypeW(wfullpath);
105
	trace_printf_key(&trace_fsmonitor,
106
			 "DriveType '%s' L'%ls' (%u)",
107
			 path, wfullpath, driveType);
108

109
	if (driveType == DRIVE_REMOTE) {
110
		fs_info->is_remote = 1;
111
		if (check_remote_protocol(wfullpath) < 0)
112
			return -1;
113
	} else {
114
		fs_info->is_remote = 0;
115
	}
116

117
	trace_printf_key(&trace_fsmonitor,
118
				"'%s' is_remote: %d",
119
				path, fs_info->is_remote);
120

121
	return 0;
122
}
123

124
int fsmonitor__is_fs_remote(const char *path)
125
{
126
	struct fs_info fs;
127
	if (fsmonitor__get_fs_info(path, &fs))
128
		return -1;
129
	return fs.is_remote;
130
}
131

132
/*
133
 * No-op for now.
134
 */
135
int fsmonitor__get_alias(const char *path UNUSED,
136
			 struct alias_info *info UNUSED)
137
{
138
	return 0;
139
}
140

141
/*
142
 * No-op for now.
143
 */
144
char *fsmonitor__resolve_alias(const char *path UNUSED,
145
			       const struct alias_info *info UNUSED)
146
{
147
	return NULL;
148
}
149

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.