Blame src/win32/w32_util.h

Packit Service 20376f
/*
Packit Service 20376f
 * Copyright (C) the libgit2 contributors. All rights reserved.
Packit Service 20376f
 *
Packit Service 20376f
 * This file is part of libgit2, distributed under the GNU GPL v2 with
Packit Service 20376f
 * a Linking Exception. For full terms see the included COPYING file.
Packit Service 20376f
 */
Packit Service 20376f
Packit Service 20376f
#ifndef INCLUDE_w32_util_h__
Packit Service 20376f
#define INCLUDE_w32_util_h__
Packit Service 20376f
Packit Service 20376f
#include "utf-conv.h"
Packit Service 20376f
#include "posix.h"
Packit Service 20376f
#include "path_w32.h"
Packit Service 20376f
Packit Service 20376f
/*
Packit Service 20376f
Packit Service 20376f
#include "common.h"
Packit Service 20376f
#include "path.h"
Packit Service 20376f
#include "path_w32.h"
Packit Service 20376f
#include "utf-conv.h"
Packit Service 20376f
#include "posix.h"
Packit Service 20376f
#include "reparse.h"
Packit Service 20376f
#include "dir.h"
Packit Service 20376f
*/
Packit Service 20376f
Packit Service 20376f
Packit Service 20376f
GIT_INLINE(bool) git_win32__isalpha(wchar_t c)
Packit Service 20376f
{
Packit Service 20376f
	return ((c >= L'A' && c <= L'Z') || (c >= L'a' && c <= L'z'));
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
/**
Packit Service 20376f
 * Creates a FindFirstFile(Ex) filter string from a UTF-8 path.
Packit Service 20376f
 * The filter string enumerates all items in the directory.
Packit Service 20376f
 *
Packit Service 20376f
 * @param dest The buffer to receive the filter string.
Packit Service 20376f
 * @param src The UTF-8 path of the directory to enumerate.
Packit Service 20376f
 * @return True if the filter string was created successfully; false otherwise
Packit Service 20376f
 */
Packit Service 20376f
bool git_win32__findfirstfile_filter(git_win32_path dest, const char *src);
Packit Service 20376f
Packit Service 20376f
/**
Packit Service 20376f
 * Ensures the given path (file or folder) has the +H (hidden) attribute set
Packit Service 20376f
 * or unset.
Packit Service 20376f
 *
Packit Service 20376f
 * @param path The path that should receive the +H bit.
Packit Service 20376f
 * @param hidden true to set +H, false to unset it
Packit Service 20376f
 * @return 0 on success; -1 on failure
Packit Service 20376f
 */
Packit Service 20376f
extern int git_win32__set_hidden(const char *path, bool hidden);
Packit Service 20376f
Packit Service 20376f
/**
Packit Service 20376f
 * Determines if the given file or folder has the hidden attribute set.
Packit Service 20376f
 * @param hidden pointer to store hidden value
Packit Service 20376f
 * @param path The path that should be queried for hiddenness.
Packit Service 20376f
 * @return 0 on success or an error code.
Packit Service 20376f
 */
Packit Service 20376f
extern int git_win32__hidden(bool *hidden, const char *path);
Packit Service 20376f
Packit Service 20376f
/**
Packit Service 20376f
 * Removes any trailing backslashes from a path, except in the case of a drive
Packit Service 20376f
 * letter path (C:\, D:\, etc.). This function cannot fail.
Packit Service 20376f
 *
Packit Service 20376f
 * @param path The path which should be trimmed.
Packit Service 20376f
 * @return The length of the modified string (<= the input length)
Packit Service 20376f
 */
Packit Service 20376f
size_t git_win32__path_trim_end(wchar_t *str, size_t len);
Packit Service 20376f
Packit Service 20376f
/**
Packit Service 20376f
 * Removes any of the following namespace prefixes from a path,
Packit Service 20376f
 * if found: "\??\", "\\?\", "\\?\UNC\". This function cannot fail.
Packit Service 20376f
 *
Packit Service 20376f
 * @param path The path which should be converted.
Packit Service 20376f
 * @return The length of the modified string (<= the input length)
Packit Service 20376f
 */
Packit Service 20376f
size_t git_win32__canonicalize_path(wchar_t *str, size_t len);
Packit Service 20376f
Packit Service 20376f
/**
Packit Service 20376f
 * Converts a FILETIME structure to a struct timespec.
Packit Service 20376f
 *
Packit Service 20376f
 * @param FILETIME A pointer to a FILETIME
Packit Service 20376f
 * @param ts A pointer to the timespec structure to fill in
Packit Service 20376f
 */
Packit Service 20376f
GIT_INLINE(void) git_win32__filetime_to_timespec(
Packit Service 20376f
	const FILETIME *ft,
Packit Service 20376f
	struct timespec *ts)
Packit Service 20376f
{
Packit Service 20376f
	long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
Packit Service 20376f
	winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
Packit Service 20376f
	ts->tv_sec = (time_t)(winTime / 10000000);
Packit Service 20376f
#ifdef GIT_USE_NSEC
Packit Service 20376f
	ts->tv_nsec = (winTime % 10000000) * 100;
Packit Service 20376f
#else
Packit Service 20376f
	ts->tv_nsec = 0;
Packit Service 20376f
#endif
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
GIT_INLINE(void) git_win32__timeval_to_filetime(
Packit Service 20376f
	FILETIME *ft, const struct p_timeval tv)
Packit Service 20376f
{
Packit Service 20376f
	long long ticks = (tv.tv_sec * 10000000LL) +
Packit Service 20376f
		(tv.tv_usec * 10LL) + 116444736000000000LL;
Packit Service 20376f
Packit Service 20376f
	ft->dwHighDateTime = ((ticks >> 32) & 0xffffffffLL);
Packit Service 20376f
	ft->dwLowDateTime = (ticks & 0xffffffffLL);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
GIT_INLINE(void) git_win32__stat_init(
Packit Service 20376f
	struct stat *st,
Packit Service 20376f
	DWORD dwFileAttributes,
Packit Service 20376f
	DWORD nFileSizeHigh,
Packit Service 20376f
	DWORD nFileSizeLow,
Packit Service 20376f
	FILETIME ftCreationTime,
Packit Service 20376f
	FILETIME ftLastAccessTime,
Packit Service 20376f
	FILETIME ftLastWriteTime)
Packit Service 20376f
{
Packit Service 20376f
	mode_t mode = S_IREAD;
Packit Service 20376f
Packit Service 20376f
	memset(st, 0, sizeof(struct stat));
Packit Service 20376f
Packit Service 20376f
	if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
Packit Service 20376f
		mode |= S_IFDIR;
Packit Service 20376f
	else
Packit Service 20376f
		mode |= S_IFREG;
Packit Service 20376f
Packit Service 20376f
	if ((dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
Packit Service 20376f
		mode |= S_IWRITE;
Packit Service 20376f
Packit Service 20376f
	st->st_ino = 0;
Packit Service 20376f
	st->st_gid = 0;
Packit Service 20376f
	st->st_uid = 0;
Packit Service 20376f
	st->st_nlink = 1;
Packit Service 20376f
	st->st_mode = mode;
Packit Service 20376f
	st->st_size = ((git_off_t)nFileSizeHigh << 32) + nFileSizeLow;
Packit Service 20376f
	st->st_dev = _getdrive() - 1;
Packit Service 20376f
	st->st_rdev = st->st_dev;
Packit Service 20376f
	git_win32__filetime_to_timespec(&ftLastAccessTime, &(st->st_atim));
Packit Service 20376f
	git_win32__filetime_to_timespec(&ftLastWriteTime, &(st->st_mtim));
Packit Service 20376f
	git_win32__filetime_to_timespec(&ftCreationTime, &(st->st_ctim));
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
GIT_INLINE(void) git_win32__file_information_to_stat(
Packit Service 20376f
	struct stat *st,
Packit Service 20376f
	const BY_HANDLE_FILE_INFORMATION *fileinfo)
Packit Service 20376f
{
Packit Service 20376f
	git_win32__stat_init(st,
Packit Service 20376f
		fileinfo->dwFileAttributes,
Packit Service 20376f
		fileinfo->nFileSizeHigh,
Packit Service 20376f
		fileinfo->nFileSizeLow,
Packit Service 20376f
		fileinfo->ftCreationTime,
Packit Service 20376f
		fileinfo->ftLastAccessTime,
Packit Service 20376f
		fileinfo->ftLastWriteTime);
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
GIT_INLINE(int) git_win32__file_attribute_to_stat(
Packit Service 20376f
	struct stat *st,
Packit Service 20376f
	const WIN32_FILE_ATTRIBUTE_DATA *attrdata,
Packit Service 20376f
	const wchar_t *path)
Packit Service 20376f
{
Packit Service 20376f
	git_win32__stat_init(st,
Packit Service 20376f
		attrdata->dwFileAttributes,
Packit Service 20376f
		attrdata->nFileSizeHigh,
Packit Service 20376f
		attrdata->nFileSizeLow,
Packit Service 20376f
		attrdata->ftCreationTime,
Packit Service 20376f
		attrdata->ftLastAccessTime,
Packit Service 20376f
		attrdata->ftLastWriteTime);
Packit Service 20376f
Packit Service 20376f
	if (attrdata->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && path) {
Packit Service 20376f
		git_win32_path target;
Packit Service 20376f
Packit Service 20376f
		if (git_win32_path_readlink_w(target, path) >= 0) {
Packit Service 20376f
			st->st_mode = (st->st_mode & ~S_IFMT) | S_IFLNK;
Packit Service 20376f
Packit Service 20376f
			/* st_size gets the UTF-8 length of the target name, in bytes,
Packit Service 20376f
			 * not counting the NULL terminator */
Packit Service 20376f
			if ((st->st_size = git__utf16_to_8(NULL, 0, target)) < 0) {
Packit Service 20376f
				giterr_set(GITERR_OS, "could not convert reparse point name for '%ls'", path);
Packit Service 20376f
				return -1;
Packit Service 20376f
			}
Packit Service 20376f
		}
Packit Service 20376f
	}
Packit Service 20376f
Packit Service 20376f
	return 0;
Packit Service 20376f
}
Packit Service 20376f
Packit Service 20376f
#endif