示例#1
0
文件: posix_w32.c 项目: gitpan/Git-XS
extern int p_rename(const char *from, const char *to)
{
	wchar_t *wfrom = gitwin_to_utf16(from);
	wchar_t *wto = gitwin_to_utf16(to);
	int ret;

	ret = MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? GIT_SUCCESS : GIT_EOSERR;

	git__free(wfrom);
	git__free(wto);

	return ret;
}
示例#2
0
文件: posix_w32.c 项目: gitpan/Git-XS
char *p_realpath(const char *orig_path, char *buffer)
{
	int ret;
	wchar_t* orig_path_w = gitwin_to_utf16(orig_path);
	wchar_t* buffer_w = (wchar_t*)git__malloc(GIT_PATH_MAX * sizeof(wchar_t));

	ret = GetFullPathNameW(orig_path_w, GIT_PATH_MAX, buffer_w, NULL);
	git__free(orig_path_w);

	if (!ret || ret > GIT_PATH_MAX) {
		buffer = NULL;
		goto done;
	}

	if (buffer == NULL) {
		int buffer_sz = WideCharToMultiByte(CP_UTF8, 0, buffer_w, -1, NULL, 0, NULL, NULL);

		if (!buffer_sz ||
			!(buffer = (char *)git__malloc(buffer_sz)) ||
			!WideCharToMultiByte(CP_UTF8, 0, buffer_w, -1, buffer, buffer_sz, NULL, NULL))
		{
			git__free(buffer);
			buffer = NULL;
		}
	} else {
		if (!WideCharToMultiByte(CP_UTF8, 0, buffer_w, -1, buffer, GIT_PATH_MAX, NULL, NULL))
			buffer = NULL;
	}

done:
	git__free(buffer_w);
	if (buffer)
		git_path_mkposix(buffer);
	return buffer;
}
示例#3
0
文件: posix_w32.c 项目: gitpan/Git-XS
int p_rmdir(const char* path)
{
	wchar_t* buf = gitwin_to_utf16(path);
	int ret = _wrmdir(buf);

	git__free(buf);
	return ret;
}
示例#4
0
文件: posix_w32.c 项目: gitpan/Git-XS
int p_chmod(const char* path, mode_t mode)
{
	wchar_t* buf = gitwin_to_utf16(path);
	int ret = _wchmod(buf, mode);

	git__free(buf);
	return ret;
}
示例#5
0
文件: posix_w32.c 项目: gitpan/Git-XS
int p_creat(const char *path, mode_t mode)
{
	int fd;
	wchar_t* buf = gitwin_to_utf16(path);
	fd = _wopen(buf, _O_WRONLY | _O_CREAT | _O_TRUNC | _O_BINARY, mode);

	git__free(buf);
	return fd;
}
示例#6
0
文件: posix_w32.c 项目: gitpan/Git-XS
int p_open(const char *path, int flags)
{
	int fd;
	wchar_t* buf = gitwin_to_utf16(path);
	fd = _wopen(buf, flags | _O_BINARY);

	git__free(buf);
	return fd;
}
示例#7
0
文件: posix_w32.c 项目: gitpan/Git-XS
int p_unlink(const char *path)
{
	int ret = 0;
	wchar_t* buf;

	buf = gitwin_to_utf16(path);
	_wchmod(buf, 0666);
	ret = _wunlink(buf);
	git__free(buf);

	return ret;
}
示例#8
0
文件: posix_w32.c 项目: gitpan/Git-XS
static int do_lstat(const char *file_name, struct stat *buf)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;
	wchar_t* fbuf = gitwin_to_utf16(file_name);

	if (GetFileAttributesExW(fbuf, GetFileExInfoStandard, &fdata)) {
		int fMode = S_IREAD;

		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			fMode |= S_IFDIR;
		else
			fMode |= S_IFREG;

		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
			fMode |= S_IWRITE;

		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
			fMode |= S_IFLNK;

		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = (mode_t)fMode;
		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
		buf->st_dev = buf->st_rdev = (_getdrive() - 1);
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));

		git__free(fbuf);
		return GIT_SUCCESS;
	}

	git__free(fbuf);

	switch (GetLastError()) {
		case ERROR_ACCESS_DENIED:
		case ERROR_SHARING_VIOLATION:
		case ERROR_LOCK_VIOLATION:
		case ERROR_SHARING_BUFFER_EXCEEDED:
			return GIT_EOSERR;

		case ERROR_BUFFER_OVERFLOW:
		case ERROR_NOT_ENOUGH_MEMORY:
			return GIT_ENOMEM;

		default:
			return GIT_EINVALIDPATH;
	}
}
示例#9
0
文件: posix_w32.c 项目: gitpan/Git-XS
int p_hide_directory__w32(const char *path)
{
	int error;
	wchar_t* buf = gitwin_to_utf16(path);

	error = SetFileAttributesW(buf, FILE_ATTRIBUTE_HIDDEN) != 0 ?
		GIT_SUCCESS : GIT_ERROR; /* MSDN states a "non zero" value indicates a success */

	git__free(buf);

	if (error < GIT_SUCCESS)
		error = git__throw(GIT_EOSERR, "Failed to hide directory '%s'", path);

	return error;
}
示例#10
0
static int do_lstat(const char *file_name, struct stat *buf)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;
	DWORD last_error;
	wchar_t* fbuf = gitwin_to_utf16(file_name);
	if (!fbuf)
		return -1;

	if (GetFileAttributesExW(fbuf, GetFileExInfoStandard, &fdata)) {
		int fMode = S_IREAD;

		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			fMode |= S_IFDIR;
		else
			fMode |= S_IFREG;

		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
			fMode |= S_IWRITE;

		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
			fMode |= S_IFLNK;

		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = (mode_t)fMode;
		buf->st_size = ((git_off_t)fdata.nFileSizeHigh << 32) + fdata.nFileSizeLow;
		buf->st_dev = buf->st_rdev = (_getdrive() - 1);
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));

		git__free(fbuf);
		return 0;
	}

	last_error = GetLastError();
	if (last_error == ERROR_FILE_NOT_FOUND)
		errno = ENOENT;
	else if (last_error == ERROR_PATH_NOT_FOUND)
		errno = ENOTDIR;

	git__free(fbuf);
	return -1;
}
示例#11
0
文件: fileops.c 项目: ileitch/meanie
int git_futils_creat_locked(const char *path, const mode_t mode)
{
	int fd;

#ifdef GIT_WIN32
	wchar_t* buf;

	buf = gitwin_to_utf16(path);
	fd = _wopen(buf, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_EXCL, mode);
	git__free(buf);
#else
	fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_EXCL, mode);
#endif

	if (fd < 0) {
		giterr_set(GITERR_OS, "Failed to create locked file '%s'", path);
		return -1;
	}

	return fd;
}
示例#12
0
int p_readlink(const char *link, char *target, size_t target_len)
{
	typedef DWORD (WINAPI *fpath_func)(HANDLE, LPWSTR, DWORD, DWORD);
	static fpath_func pGetFinalPath = NULL;
	HANDLE hFile;
	DWORD dwRet;
	wchar_t* link_w;
	wchar_t* target_w;
	int error = 0;

	assert(link && target && target_len > 0);

	/*
	 * Try to load the pointer to pGetFinalPath dynamically, because
	 * it is not available in platforms older than Vista
	 */
	if (pGetFinalPath == NULL) {
		HINSTANCE library = LoadLibrary("kernel32");

		if (library != NULL)
			pGetFinalPath = (fpath_func)GetProcAddress(library, "GetFinalPathNameByHandleW");

		if (pGetFinalPath == NULL) {
			giterr_set(GITERR_OS,
				"'GetFinalPathNameByHandleW' is not available in this platform");
			return -1;
		}
	}

	link_w = gitwin_to_utf16(link);
	GITERR_CHECK_ALLOC(link_w);

	hFile = CreateFileW(link_w,			// file to open
			GENERIC_READ,			// open for reading
			FILE_SHARE_READ,		// share for reading
			NULL,					// default security
			OPEN_EXISTING,			// existing file only
			FILE_FLAG_BACKUP_SEMANTICS, // normal file
			NULL);					// no attr. template

	git__free(link_w);

	if (hFile == INVALID_HANDLE_VALUE) {
		giterr_set(GITERR_OS, "Cannot open '%s' for reading", link);
		return -1;
	}

	target_w = (wchar_t*)git__malloc(target_len * sizeof(wchar_t));
	GITERR_CHECK_ALLOC(target_w);

	dwRet = pGetFinalPath(hFile, target_w, (DWORD)target_len, 0x0);
	if (dwRet == 0 ||
		dwRet >= target_len ||
		!WideCharToMultiByte(CP_UTF8, 0, target_w, -1, target,
			(int)(target_len * sizeof(char)), NULL, NULL))
		error = -1;

	git__free(target_w);
	CloseHandle(hFile);

	if (error)
		return error;

	/* Skip first 4 characters if they are "\\?\" */
	if (dwRet > 4 &&
		target[0] == '\\' && target[1] == '\\' &&
		target[2] == '?' && target[3] == '\\')
	{
		unsigned int offset = 4;
		dwRet -= 4;

		/* \??\UNC\ */
		if (dwRet > 7 &&
			target[4] == 'U' && target[5] == 'N' && target[6] == 'C')
		{
			offset += 2;
			dwRet -= 2;
			target[offset] = '\\';
		}

		memmove(target, target + offset, dwRet);
	}

	target[dwRet] = '\0';

	return dwRet;
}
示例#13
0
文件: posix_w32.c 项目: gitpan/Git-XS
int p_readlink(const char *link, char *target, size_t target_len)
{
	typedef DWORD (WINAPI *fpath_func)(HANDLE, LPWSTR, DWORD, DWORD);
	static fpath_func pGetFinalPath = NULL;
	HANDLE hFile;
	DWORD dwRet;
	wchar_t* link_w;
	wchar_t* target_w;

	/*
	 * Try to load the pointer to pGetFinalPath dynamically, because
	 * it is not available in platforms older than Vista
	 */
	if (pGetFinalPath == NULL) {
		HINSTANCE library = LoadLibrary("kernel32");

		if (library != NULL)
			pGetFinalPath = (fpath_func)GetProcAddress(library, "GetFinalPathNameByHandleW");

		if (pGetFinalPath == NULL)
			return git__throw(GIT_EOSERR,
				"'GetFinalPathNameByHandleW' is not available in this platform");
	}

	link_w = gitwin_to_utf16(link);

	hFile = CreateFileW(link_w,			// file to open
			GENERIC_READ,			// open for reading
			FILE_SHARE_READ,		// share for reading
			NULL,					// default security
			OPEN_EXISTING,			// existing file only
			FILE_FLAG_BACKUP_SEMANTICS, // normal file
			NULL);					// no attr. template

	git__free(link_w);

	if (hFile == INVALID_HANDLE_VALUE)
		return GIT_EOSERR;

	if (target_len <= 0) {
		return GIT_EINVALIDARGS;
	}

	target_w = (wchar_t*)git__malloc(target_len * sizeof(wchar_t));

	dwRet = pGetFinalPath(hFile, target_w, target_len, 0x0);
	if (dwRet >= target_len) {
		git__free(target_w);
		CloseHandle(hFile);
		return GIT_ENOMEM;
	}

	if (!WideCharToMultiByte(CP_UTF8, 0, target_w, -1, target, target_len * sizeof(char), NULL, NULL)) {
		git__free(target_w);
		return GIT_EOSERR;
	}

	git__free(target_w);
	CloseHandle(hFile);

	if (dwRet > 4) {
		/* Skip first 4 characters if they are "\\?\" */
		if (target[0] == '\\' && target[1] == '\\' && target[2] == '?' && target[3] == '\\') {
			char tmp[GIT_PATH_MAX];
			unsigned int offset = 4;
			dwRet -= 4;

			/* \??\UNC\ */
			if (dwRet > 7 && target[4] == 'U' && target[5] == 'N' && target[6] == 'C') {
				offset += 2;
				dwRet -= 2;
				target[offset] = '\\';
			}

			memcpy(tmp, target + offset, dwRet);
			memcpy(target, tmp, dwRet);
		}
	}

	target[dwRet] = '\0';
	return dwRet;
}