path_windows.cpp #1

  • //
  • guest/
  • ShadauxCat/
  • Sprawl/
  • Mainline/
  • filesystem/
  • path_windows.cpp
  • View
  • Commits
  • Open Download .zip Download (3 KB)
#include "path.hpp"
#include <limits.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <windows.h>

char sprawl::path::Separator()
{
	return '\\';
}

char sprawl::path::AltSeparator()
{
	return '/';
}

char sprawl::path::ExtSeparator()
{
	return '.';
}

char sprawl::path::PathSeparator()
{
	return ';';
}

char sprawl::path::DriveSeparator()
{
	return ':';
}

bool sprawl::path::LinkExists(String const& path)
{
	return GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES;
}

sprawl::String sprawl::path::ExpandPath(String const& path)
{
	char out[MAX_PATH];
	ExpandEnvironmentStringsA(path.c_str(), out, MAX_PATH);
	return sprawl::String(out);
}

sprawl::String sprawl::path::RealPath(String const& path)
{
	HANDLE fileHandle = CreateFileA(
		path.c_str(),
		GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		nullptr,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		nullptr
	);
	if (fileHandle == INVALID_HANDLE_VALUE)
	{
		return "";
	}
	char buf[MAX_PATH];
	GetFinalPathNameByHandleA(fileHandle, buf, MAX_PATH, FILE_NAME_NORMALIZED);
	CloseHandle(fileHandle);
}

int64_t sprawl::path::GetAccessTime(String const& path)
{
	HANDLE fileHandle = CreateFileA(
		path.c_str(),
		GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		nullptr,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		nullptr
		);
	if (fileHandle == INVALID_HANDLE_VALUE)
	{
		return 0;
	}
	FILETIME out;
	GetFileTime(fileHandle, nullptr, &out, nullptr);
	CloseHandle(fileHandle);

	uint64_t tt = out.dwHighDateTime;
	tt <<= 32;
	tt |= out.dwLowDateTime;
	tt -= 116444736000000000ULL;
	tt *= 100;
	return int64_t(tt);
}

int64_t sprawl::path::GetModificationTime(String const& path)
{
	HANDLE fileHandle = CreateFileA(
		path.c_str(),
		GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		nullptr,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		nullptr
		);
	if (fileHandle == INVALID_HANDLE_VALUE)
	{
		return 0;
	}
	FILETIME out;
	GetFileTime(fileHandle, nullptr, nullptr, &out);
	CloseHandle(fileHandle);

	uint64_t tt = out.dwHighDateTime;
	tt <<= 32;
	tt |= out.dwLowDateTime;
	tt -= 116444736000000000ULL;
	tt *= 100;
	return int64_t(tt);
}

int64_t sprawl::path::GetSize(String const& path)
{
	struct _stat attrib;
	_stat(path.c_str(), &attrib);
	return attrib.st_size;
}

bool sprawl::path::IsFile(String const& path)
{
	return (GetFileAttributesA(path.c_str()) & FILE_ATTRIBUTE_NORMAL) != 0;
}

bool sprawl::path::IsDirectory(String const& path)
{
	return (GetFileAttributesA(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY) != 0;
}

bool sprawl::path::IsLink(String const& path)
{
	return (GetFileAttributesA(path.c_str()) & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
}

bool sprawl::path::IsMountPoint(String const& path)
{
	if((GetFileAttributesA(path.c_str()) & FILE_ATTRIBUTE_REPARSE_POINT) != 0)
	{
		return false;
	}

	struct _stat attrib;
	if(_stat(path.c_str(), &attrib) != 0)
	{
		return false;
	}

	struct _stat attrib2;
	if(_stat(Join(path, "..").c_str(), &attrib2) != 0)
	{
		return false;
	}

	if(attrib.st_dev != attrib2.st_dev)
	{
		return true;
	}

	if(attrib.st_ino == attrib2.st_ino)
	{
		return true;
	}

	return false;
}

bool sprawl::path::SameFile(String const& path1, String const& path2)
{
	struct _stat attrib;
	_stat(path1.c_str(), &attrib);

	struct _stat attrib2;
	_stat(path2.c_str(), &attrib2);

	return attrib.st_ino == attrib2.st_ino && attrib.st_dev == attrib2.st_dev;
}
# Change User Description Committed
#3 14822 ShadauxCat Last batch of filesystem code for now, added MakeSymlink and GetPid, removed other todo functions for the time being.
Also fixed some bugs:

-Linux IsLink() implementation not using lstat = broken
-File::IsClosed() would crash if file were created via default constructor or null handle
-Remove() and RmDir() on Windows were inconsistent with Linux - in Linux all symlinks are removed with Remove() even if they point to directories. Forced windows to work the same way.
-Asked RmTree to please not descend into symbolic links to directories, but just to remove them, thanks.
-Removed starting \\?\ from result of RealPath() on Windows
-Fixed IsFile() on Windows just not working - assuming anything that's not a directory is a file now.
-Fixed StringBuilder only printing the first character if you passed it type char* instead of type char const*

#review-14823
#2 14816 ShadauxCat Filled in some more filesystem functions, added appropriate unit tests.
Only a few remain.

#review-14817
#1 14761 ShadauxCat First drop of code for sprawl::filesystem and sprawl::path.
Library will continue to grow.

Also fixed a warning on linux.

#review-14762