13cab2bb3Spatrick //===- FuzzerIOWindows.cpp - IO utils for Windows. ------------------------===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick // IO functions implementation for Windows.
93cab2bb3Spatrick //===----------------------------------------------------------------------===//
101f9cb04fSpatrick #include "FuzzerPlatform.h"
113cab2bb3Spatrick #if LIBFUZZER_WINDOWS
123cab2bb3Spatrick
133cab2bb3Spatrick #include "FuzzerExtFunctions.h"
143cab2bb3Spatrick #include "FuzzerIO.h"
153cab2bb3Spatrick #include <cstdarg>
163cab2bb3Spatrick #include <cstdio>
173cab2bb3Spatrick #include <fstream>
183cab2bb3Spatrick #include <io.h>
193cab2bb3Spatrick #include <iterator>
203cab2bb3Spatrick #include <sys/stat.h>
213cab2bb3Spatrick #include <sys/types.h>
223cab2bb3Spatrick #include <windows.h>
233cab2bb3Spatrick
243cab2bb3Spatrick namespace fuzzer {
253cab2bb3Spatrick
IsFile(const std::string & Path,const DWORD & FileAttributes)263cab2bb3Spatrick static bool IsFile(const std::string &Path, const DWORD &FileAttributes) {
273cab2bb3Spatrick
283cab2bb3Spatrick if (FileAttributes & FILE_ATTRIBUTE_NORMAL)
293cab2bb3Spatrick return true;
303cab2bb3Spatrick
313cab2bb3Spatrick if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
323cab2bb3Spatrick return false;
333cab2bb3Spatrick
343cab2bb3Spatrick HANDLE FileHandle(
353cab2bb3Spatrick CreateFileA(Path.c_str(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
363cab2bb3Spatrick FILE_FLAG_BACKUP_SEMANTICS, 0));
373cab2bb3Spatrick
383cab2bb3Spatrick if (FileHandle == INVALID_HANDLE_VALUE) {
393cab2bb3Spatrick Printf("CreateFileA() failed for \"%s\" (Error code: %lu).\n", Path.c_str(),
403cab2bb3Spatrick GetLastError());
413cab2bb3Spatrick return false;
423cab2bb3Spatrick }
433cab2bb3Spatrick
443cab2bb3Spatrick DWORD FileType = GetFileType(FileHandle);
453cab2bb3Spatrick
463cab2bb3Spatrick if (FileType == FILE_TYPE_UNKNOWN) {
473cab2bb3Spatrick Printf("GetFileType() failed for \"%s\" (Error code: %lu).\n", Path.c_str(),
483cab2bb3Spatrick GetLastError());
493cab2bb3Spatrick CloseHandle(FileHandle);
503cab2bb3Spatrick return false;
513cab2bb3Spatrick }
523cab2bb3Spatrick
533cab2bb3Spatrick if (FileType != FILE_TYPE_DISK) {
543cab2bb3Spatrick CloseHandle(FileHandle);
553cab2bb3Spatrick return false;
563cab2bb3Spatrick }
573cab2bb3Spatrick
583cab2bb3Spatrick CloseHandle(FileHandle);
593cab2bb3Spatrick return true;
603cab2bb3Spatrick }
613cab2bb3Spatrick
IsFile(const std::string & Path)623cab2bb3Spatrick bool IsFile(const std::string &Path) {
633cab2bb3Spatrick DWORD Att = GetFileAttributesA(Path.c_str());
643cab2bb3Spatrick
653cab2bb3Spatrick if (Att == INVALID_FILE_ATTRIBUTES) {
663cab2bb3Spatrick Printf("GetFileAttributesA() failed for \"%s\" (Error code: %lu).\n",
673cab2bb3Spatrick Path.c_str(), GetLastError());
683cab2bb3Spatrick return false;
693cab2bb3Spatrick }
703cab2bb3Spatrick
713cab2bb3Spatrick return IsFile(Path, Att);
723cab2bb3Spatrick }
733cab2bb3Spatrick
IsDir(DWORD FileAttrs)743cab2bb3Spatrick static bool IsDir(DWORD FileAttrs) {
753cab2bb3Spatrick if (FileAttrs == INVALID_FILE_ATTRIBUTES) return false;
763cab2bb3Spatrick return FileAttrs & FILE_ATTRIBUTE_DIRECTORY;
773cab2bb3Spatrick }
783cab2bb3Spatrick
IsDirectory(const std::string & Path)79d89ec533Spatrick bool IsDirectory(const std::string &Path) {
80d89ec533Spatrick DWORD Att = GetFileAttributesA(Path.c_str());
81d89ec533Spatrick
82d89ec533Spatrick if (Att == INVALID_FILE_ATTRIBUTES) {
83d89ec533Spatrick Printf("GetFileAttributesA() failed for \"%s\" (Error code: %lu).\n",
84d89ec533Spatrick Path.c_str(), GetLastError());
85d89ec533Spatrick return false;
86d89ec533Spatrick }
87d89ec533Spatrick
88d89ec533Spatrick return IsDir(Att);
89d89ec533Spatrick }
90d89ec533Spatrick
Basename(const std::string & Path)913cab2bb3Spatrick std::string Basename(const std::string &Path) {
923cab2bb3Spatrick size_t Pos = Path.find_last_of("/\\");
933cab2bb3Spatrick if (Pos == std::string::npos) return Path;
943cab2bb3Spatrick assert(Pos < Path.size());
953cab2bb3Spatrick return Path.substr(Pos + 1);
963cab2bb3Spatrick }
973cab2bb3Spatrick
FileSize(const std::string & Path)983cab2bb3Spatrick size_t FileSize(const std::string &Path) {
993cab2bb3Spatrick WIN32_FILE_ATTRIBUTE_DATA attr;
1003cab2bb3Spatrick if (!GetFileAttributesExA(Path.c_str(), GetFileExInfoStandard, &attr)) {
1013cab2bb3Spatrick DWORD LastError = GetLastError();
1023cab2bb3Spatrick if (LastError != ERROR_FILE_NOT_FOUND)
1033cab2bb3Spatrick Printf("GetFileAttributesExA() failed for \"%s\" (Error code: %lu).\n",
1043cab2bb3Spatrick Path.c_str(), LastError);
1053cab2bb3Spatrick return 0;
1063cab2bb3Spatrick }
1073cab2bb3Spatrick ULARGE_INTEGER size;
1083cab2bb3Spatrick size.HighPart = attr.nFileSizeHigh;
1093cab2bb3Spatrick size.LowPart = attr.nFileSizeLow;
1103cab2bb3Spatrick return size.QuadPart;
1113cab2bb3Spatrick }
1123cab2bb3Spatrick
ListFilesInDirRecursive(const std::string & Dir,long * Epoch,std::vector<std::string> * V,bool TopDir)1133cab2bb3Spatrick void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
114*810390e3Srobert std::vector<std::string> *V, bool TopDir) {
1153cab2bb3Spatrick auto E = GetEpoch(Dir);
1163cab2bb3Spatrick if (Epoch)
1173cab2bb3Spatrick if (E && *Epoch >= E) return;
1183cab2bb3Spatrick
1193cab2bb3Spatrick std::string Path(Dir);
1203cab2bb3Spatrick assert(!Path.empty());
1213cab2bb3Spatrick if (Path.back() != '\\')
1223cab2bb3Spatrick Path.push_back('\\');
1233cab2bb3Spatrick Path.push_back('*');
1243cab2bb3Spatrick
1253cab2bb3Spatrick // Get the first directory entry.
1263cab2bb3Spatrick WIN32_FIND_DATAA FindInfo;
1273cab2bb3Spatrick HANDLE FindHandle(FindFirstFileA(Path.c_str(), &FindInfo));
1283cab2bb3Spatrick if (FindHandle == INVALID_HANDLE_VALUE)
1293cab2bb3Spatrick {
1303cab2bb3Spatrick if (GetLastError() == ERROR_FILE_NOT_FOUND)
1313cab2bb3Spatrick return;
1323cab2bb3Spatrick Printf("No such file or directory: %s; exiting\n", Dir.c_str());
1333cab2bb3Spatrick exit(1);
1343cab2bb3Spatrick }
1353cab2bb3Spatrick
1363cab2bb3Spatrick do {
1373cab2bb3Spatrick std::string FileName = DirPlusFile(Dir, FindInfo.cFileName);
1383cab2bb3Spatrick
1393cab2bb3Spatrick if (FindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1403cab2bb3Spatrick size_t FilenameLen = strlen(FindInfo.cFileName);
1413cab2bb3Spatrick if ((FilenameLen == 1 && FindInfo.cFileName[0] == '.') ||
1423cab2bb3Spatrick (FilenameLen == 2 && FindInfo.cFileName[0] == '.' &&
1433cab2bb3Spatrick FindInfo.cFileName[1] == '.'))
1443cab2bb3Spatrick continue;
1453cab2bb3Spatrick
1463cab2bb3Spatrick ListFilesInDirRecursive(FileName, Epoch, V, false);
1473cab2bb3Spatrick }
1483cab2bb3Spatrick else if (IsFile(FileName, FindInfo.dwFileAttributes))
1493cab2bb3Spatrick V->push_back(FileName);
1503cab2bb3Spatrick } while (FindNextFileA(FindHandle, &FindInfo));
1513cab2bb3Spatrick
1523cab2bb3Spatrick DWORD LastError = GetLastError();
1533cab2bb3Spatrick if (LastError != ERROR_NO_MORE_FILES)
1543cab2bb3Spatrick Printf("FindNextFileA failed (Error code: %lu).\n", LastError);
1553cab2bb3Spatrick
1563cab2bb3Spatrick FindClose(FindHandle);
1573cab2bb3Spatrick
1583cab2bb3Spatrick if (Epoch && TopDir)
1593cab2bb3Spatrick *Epoch = E;
1603cab2bb3Spatrick }
1613cab2bb3Spatrick
IterateDirRecursive(const std::string & Dir,void (* DirPreCallback)(const std::string & Dir),void (* DirPostCallback)(const std::string & Dir),void (* FileCallback)(const std::string & Dir))1623cab2bb3Spatrick void IterateDirRecursive(const std::string &Dir,
1633cab2bb3Spatrick void (*DirPreCallback)(const std::string &Dir),
1643cab2bb3Spatrick void (*DirPostCallback)(const std::string &Dir),
1653cab2bb3Spatrick void (*FileCallback)(const std::string &Dir)) {
1663cab2bb3Spatrick // TODO(metzman): Implement ListFilesInDirRecursive via this function.
1673cab2bb3Spatrick DirPreCallback(Dir);
1683cab2bb3Spatrick
1693cab2bb3Spatrick DWORD DirAttrs = GetFileAttributesA(Dir.c_str());
1703cab2bb3Spatrick if (!IsDir(DirAttrs)) return;
1713cab2bb3Spatrick
1723cab2bb3Spatrick std::string TargetDir(Dir);
1733cab2bb3Spatrick assert(!TargetDir.empty());
1743cab2bb3Spatrick if (TargetDir.back() != '\\') TargetDir.push_back('\\');
1753cab2bb3Spatrick TargetDir.push_back('*');
1763cab2bb3Spatrick
1773cab2bb3Spatrick WIN32_FIND_DATAA FindInfo;
1783cab2bb3Spatrick // Find the directory's first file.
1793cab2bb3Spatrick HANDLE FindHandle = FindFirstFileA(TargetDir.c_str(), &FindInfo);
1803cab2bb3Spatrick if (FindHandle == INVALID_HANDLE_VALUE) {
1813cab2bb3Spatrick DWORD LastError = GetLastError();
1823cab2bb3Spatrick if (LastError != ERROR_FILE_NOT_FOUND) {
1833cab2bb3Spatrick // If the directory isn't empty, then something abnormal is going on.
1843cab2bb3Spatrick Printf("FindFirstFileA failed for %s (Error code: %lu).\n", Dir.c_str(),
1853cab2bb3Spatrick LastError);
1863cab2bb3Spatrick }
1873cab2bb3Spatrick return;
1883cab2bb3Spatrick }
1893cab2bb3Spatrick
1903cab2bb3Spatrick do {
1913cab2bb3Spatrick std::string Path = DirPlusFile(Dir, FindInfo.cFileName);
1923cab2bb3Spatrick DWORD PathAttrs = FindInfo.dwFileAttributes;
1933cab2bb3Spatrick if (IsDir(PathAttrs)) {
1943cab2bb3Spatrick // Is Path the current directory (".") or the parent ("..")?
1953cab2bb3Spatrick if (strcmp(FindInfo.cFileName, ".") == 0 ||
1963cab2bb3Spatrick strcmp(FindInfo.cFileName, "..") == 0)
1973cab2bb3Spatrick continue;
1983cab2bb3Spatrick IterateDirRecursive(Path, DirPreCallback, DirPostCallback, FileCallback);
1993cab2bb3Spatrick } else if (PathAttrs != INVALID_FILE_ATTRIBUTES) {
2003cab2bb3Spatrick FileCallback(Path);
2013cab2bb3Spatrick }
2023cab2bb3Spatrick } while (FindNextFileA(FindHandle, &FindInfo));
2033cab2bb3Spatrick
2043cab2bb3Spatrick DWORD LastError = GetLastError();
2053cab2bb3Spatrick if (LastError != ERROR_NO_MORE_FILES)
2063cab2bb3Spatrick Printf("FindNextFileA failed for %s (Error code: %lu).\n", Dir.c_str(),
2073cab2bb3Spatrick LastError);
2083cab2bb3Spatrick
2093cab2bb3Spatrick FindClose(FindHandle);
2103cab2bb3Spatrick DirPostCallback(Dir);
2113cab2bb3Spatrick }
2123cab2bb3Spatrick
GetSeparator()2133cab2bb3Spatrick char GetSeparator() {
2143cab2bb3Spatrick return '\\';
2153cab2bb3Spatrick }
2163cab2bb3Spatrick
OpenFile(int Fd,const char * Mode)2173cab2bb3Spatrick FILE* OpenFile(int Fd, const char* Mode) {
2183cab2bb3Spatrick return _fdopen(Fd, Mode);
2193cab2bb3Spatrick }
2203cab2bb3Spatrick
CloseFile(int Fd)2213cab2bb3Spatrick int CloseFile(int Fd) {
2223cab2bb3Spatrick return _close(Fd);
2233cab2bb3Spatrick }
2243cab2bb3Spatrick
DuplicateFile(int Fd)2253cab2bb3Spatrick int DuplicateFile(int Fd) {
2263cab2bb3Spatrick return _dup(Fd);
2273cab2bb3Spatrick }
2283cab2bb3Spatrick
RemoveFile(const std::string & Path)2293cab2bb3Spatrick void RemoveFile(const std::string &Path) {
2303cab2bb3Spatrick _unlink(Path.c_str());
2313cab2bb3Spatrick }
2323cab2bb3Spatrick
RenameFile(const std::string & OldPath,const std::string & NewPath)2333cab2bb3Spatrick void RenameFile(const std::string &OldPath, const std::string &NewPath) {
2343cab2bb3Spatrick rename(OldPath.c_str(), NewPath.c_str());
2353cab2bb3Spatrick }
2363cab2bb3Spatrick
GetHandleFromFd(int fd)2373cab2bb3Spatrick intptr_t GetHandleFromFd(int fd) {
2383cab2bb3Spatrick return _get_osfhandle(fd);
2393cab2bb3Spatrick }
2403cab2bb3Spatrick
IsSeparator(char C)241d89ec533Spatrick bool IsSeparator(char C) {
2423cab2bb3Spatrick return C == '\\' || C == '/';
2433cab2bb3Spatrick }
2443cab2bb3Spatrick
2453cab2bb3Spatrick // Parse disk designators, like "C:\". If Relative == true, also accepts: "C:".
2463cab2bb3Spatrick // Returns number of characters considered if successful.
ParseDrive(const std::string & FileName,const size_t Offset,bool Relative=true)2473cab2bb3Spatrick static size_t ParseDrive(const std::string &FileName, const size_t Offset,
2483cab2bb3Spatrick bool Relative = true) {
2493cab2bb3Spatrick if (Offset + 1 >= FileName.size() || FileName[Offset + 1] != ':')
2503cab2bb3Spatrick return 0;
2513cab2bb3Spatrick if (Offset + 2 >= FileName.size() || !IsSeparator(FileName[Offset + 2])) {
2523cab2bb3Spatrick if (!Relative) // Accept relative path?
2533cab2bb3Spatrick return 0;
2543cab2bb3Spatrick else
2553cab2bb3Spatrick return 2;
2563cab2bb3Spatrick }
2573cab2bb3Spatrick return 3;
2583cab2bb3Spatrick }
2593cab2bb3Spatrick
2603cab2bb3Spatrick // Parse a file name, like: SomeFile.txt
2613cab2bb3Spatrick // Returns number of characters considered if successful.
ParseFileName(const std::string & FileName,const size_t Offset)2623cab2bb3Spatrick static size_t ParseFileName(const std::string &FileName, const size_t Offset) {
2633cab2bb3Spatrick size_t Pos = Offset;
2643cab2bb3Spatrick const size_t End = FileName.size();
2653cab2bb3Spatrick for(; Pos < End && !IsSeparator(FileName[Pos]); ++Pos)
2663cab2bb3Spatrick ;
2673cab2bb3Spatrick return Pos - Offset;
2683cab2bb3Spatrick }
2693cab2bb3Spatrick
2703cab2bb3Spatrick // Parse a directory ending in separator, like: `SomeDir\`
2713cab2bb3Spatrick // Returns number of characters considered if successful.
ParseDir(const std::string & FileName,const size_t Offset)2723cab2bb3Spatrick static size_t ParseDir(const std::string &FileName, const size_t Offset) {
2733cab2bb3Spatrick size_t Pos = Offset;
2743cab2bb3Spatrick const size_t End = FileName.size();
2753cab2bb3Spatrick if (Pos >= End || IsSeparator(FileName[Pos]))
2763cab2bb3Spatrick return 0;
2773cab2bb3Spatrick for(; Pos < End && !IsSeparator(FileName[Pos]); ++Pos)
2783cab2bb3Spatrick ;
2793cab2bb3Spatrick if (Pos >= End)
2803cab2bb3Spatrick return 0;
2813cab2bb3Spatrick ++Pos; // Include separator.
2823cab2bb3Spatrick return Pos - Offset;
2833cab2bb3Spatrick }
2843cab2bb3Spatrick
2853cab2bb3Spatrick // Parse a servername and share, like: `SomeServer\SomeShare\`
2863cab2bb3Spatrick // Returns number of characters considered if successful.
ParseServerAndShare(const std::string & FileName,const size_t Offset)2873cab2bb3Spatrick static size_t ParseServerAndShare(const std::string &FileName,
2883cab2bb3Spatrick const size_t Offset) {
2893cab2bb3Spatrick size_t Pos = Offset, Res;
2903cab2bb3Spatrick if (!(Res = ParseDir(FileName, Pos)))
2913cab2bb3Spatrick return 0;
2923cab2bb3Spatrick Pos += Res;
2933cab2bb3Spatrick if (!(Res = ParseDir(FileName, Pos)))
2943cab2bb3Spatrick return 0;
2953cab2bb3Spatrick Pos += Res;
2963cab2bb3Spatrick return Pos - Offset;
2973cab2bb3Spatrick }
2983cab2bb3Spatrick
299*810390e3Srobert // Parse the given Ref string from the position Offset, to exactly match the
300*810390e3Srobert // given string Patt. Returns number of characters considered if successful.
ParseCustomString(const std::string & Ref,size_t Offset,const char * Patt)3013cab2bb3Spatrick static size_t ParseCustomString(const std::string &Ref, size_t Offset,
3023cab2bb3Spatrick const char *Patt) {
3033cab2bb3Spatrick size_t Len = strlen(Patt);
3043cab2bb3Spatrick if (Offset + Len > Ref.size())
3053cab2bb3Spatrick return 0;
3063cab2bb3Spatrick return Ref.compare(Offset, Len, Patt) == 0 ? Len : 0;
3073cab2bb3Spatrick }
3083cab2bb3Spatrick
3093cab2bb3Spatrick // Parse a location, like:
3103cab2bb3Spatrick // \\?\UNC\Server\Share\ \\?\C:\ \\Server\Share\ \ C:\ C:
3113cab2bb3Spatrick // Returns number of characters considered if successful.
ParseLocation(const std::string & FileName)3123cab2bb3Spatrick static size_t ParseLocation(const std::string &FileName) {
3133cab2bb3Spatrick size_t Pos = 0, Res;
3143cab2bb3Spatrick
3153cab2bb3Spatrick if ((Res = ParseCustomString(FileName, Pos, R"(\\?\)"))) {
3163cab2bb3Spatrick Pos += Res;
3173cab2bb3Spatrick if ((Res = ParseCustomString(FileName, Pos, R"(UNC\)"))) {
3183cab2bb3Spatrick Pos += Res;
3193cab2bb3Spatrick if ((Res = ParseServerAndShare(FileName, Pos)))
3203cab2bb3Spatrick return Pos + Res;
3213cab2bb3Spatrick return 0;
3223cab2bb3Spatrick }
3233cab2bb3Spatrick if ((Res = ParseDrive(FileName, Pos, false)))
3243cab2bb3Spatrick return Pos + Res;
3253cab2bb3Spatrick return 0;
3263cab2bb3Spatrick }
3273cab2bb3Spatrick
3283cab2bb3Spatrick if (Pos < FileName.size() && IsSeparator(FileName[Pos])) {
3293cab2bb3Spatrick ++Pos;
3303cab2bb3Spatrick if (Pos < FileName.size() && IsSeparator(FileName[Pos])) {
3313cab2bb3Spatrick ++Pos;
3323cab2bb3Spatrick if ((Res = ParseServerAndShare(FileName, Pos)))
3333cab2bb3Spatrick return Pos + Res;
3343cab2bb3Spatrick return 0;
3353cab2bb3Spatrick }
3363cab2bb3Spatrick return Pos;
3373cab2bb3Spatrick }
3383cab2bb3Spatrick
3393cab2bb3Spatrick if ((Res = ParseDrive(FileName, Pos)))
3403cab2bb3Spatrick return Pos + Res;
3413cab2bb3Spatrick
3423cab2bb3Spatrick return Pos;
3433cab2bb3Spatrick }
3443cab2bb3Spatrick
DirName(const std::string & FileName)3453cab2bb3Spatrick std::string DirName(const std::string &FileName) {
3463cab2bb3Spatrick size_t LocationLen = ParseLocation(FileName);
3473cab2bb3Spatrick size_t DirLen = 0, Res;
3483cab2bb3Spatrick while ((Res = ParseDir(FileName, LocationLen + DirLen)))
3493cab2bb3Spatrick DirLen += Res;
3503cab2bb3Spatrick size_t FileLen = ParseFileName(FileName, LocationLen + DirLen);
3513cab2bb3Spatrick
3523cab2bb3Spatrick if (LocationLen + DirLen + FileLen != FileName.size()) {
3533cab2bb3Spatrick Printf("DirName() failed for \"%s\", invalid path.\n", FileName.c_str());
3543cab2bb3Spatrick exit(1);
3553cab2bb3Spatrick }
3563cab2bb3Spatrick
3573cab2bb3Spatrick if (DirLen) {
3583cab2bb3Spatrick --DirLen; // Remove trailing separator.
3593cab2bb3Spatrick if (!FileLen) { // Path ended in separator.
3603cab2bb3Spatrick assert(DirLen);
3613cab2bb3Spatrick // Remove file name from Dir.
3623cab2bb3Spatrick while (DirLen && !IsSeparator(FileName[LocationLen + DirLen - 1]))
3633cab2bb3Spatrick --DirLen;
3643cab2bb3Spatrick if (DirLen) // Remove trailing separator.
3653cab2bb3Spatrick --DirLen;
3663cab2bb3Spatrick }
3673cab2bb3Spatrick }
3683cab2bb3Spatrick
3693cab2bb3Spatrick if (!LocationLen) { // Relative path.
3703cab2bb3Spatrick if (!DirLen)
3713cab2bb3Spatrick return ".";
3723cab2bb3Spatrick return std::string(".\\").append(FileName, 0, DirLen);
3733cab2bb3Spatrick }
3743cab2bb3Spatrick
3753cab2bb3Spatrick return FileName.substr(0, LocationLen + DirLen);
3763cab2bb3Spatrick }
3773cab2bb3Spatrick
TmpDir()3783cab2bb3Spatrick std::string TmpDir() {
3793cab2bb3Spatrick std::string Tmp;
3803cab2bb3Spatrick Tmp.resize(MAX_PATH + 1);
3813cab2bb3Spatrick DWORD Size = GetTempPathA(Tmp.size(), &Tmp[0]);
3823cab2bb3Spatrick if (Size == 0) {
3833cab2bb3Spatrick Printf("Couldn't get Tmp path.\n");
3843cab2bb3Spatrick exit(1);
3853cab2bb3Spatrick }
3863cab2bb3Spatrick Tmp.resize(Size);
3873cab2bb3Spatrick return Tmp;
3883cab2bb3Spatrick }
3893cab2bb3Spatrick
IsInterestingCoverageFile(const std::string & FileName)3903cab2bb3Spatrick bool IsInterestingCoverageFile(const std::string &FileName) {
3913cab2bb3Spatrick if (FileName.find("Program Files") != std::string::npos)
3923cab2bb3Spatrick return false;
3933cab2bb3Spatrick if (FileName.find("compiler-rt\\lib\\") != std::string::npos)
3943cab2bb3Spatrick return false; // sanitizer internal.
3953cab2bb3Spatrick if (FileName == "<null>")
3963cab2bb3Spatrick return false;
3973cab2bb3Spatrick return true;
3983cab2bb3Spatrick }
3993cab2bb3Spatrick
RawPrint(const char * Str)4003cab2bb3Spatrick void RawPrint(const char *Str) {
4013cab2bb3Spatrick _write(2, Str, strlen(Str));
4023cab2bb3Spatrick }
4033cab2bb3Spatrick
MkDir(const std::string & Path)4043cab2bb3Spatrick void MkDir(const std::string &Path) {
4053cab2bb3Spatrick if (CreateDirectoryA(Path.c_str(), nullptr)) return;
4063cab2bb3Spatrick Printf("CreateDirectoryA failed for %s (Error code: %lu).\n", Path.c_str(),
4073cab2bb3Spatrick GetLastError());
4083cab2bb3Spatrick }
4093cab2bb3Spatrick
RmDir(const std::string & Path)4103cab2bb3Spatrick void RmDir(const std::string &Path) {
4113cab2bb3Spatrick if (RemoveDirectoryA(Path.c_str())) return;
4123cab2bb3Spatrick Printf("RemoveDirectoryA failed for %s (Error code: %lu).\n", Path.c_str(),
4133cab2bb3Spatrick GetLastError());
4143cab2bb3Spatrick }
4153cab2bb3Spatrick
getDevNull()4163cab2bb3Spatrick const std::string &getDevNull() {
4173cab2bb3Spatrick static const std::string devNull = "NUL";
4183cab2bb3Spatrick return devNull;
4193cab2bb3Spatrick }
4203cab2bb3Spatrick
4213cab2bb3Spatrick } // namespace fuzzer
4223cab2bb3Spatrick
4233cab2bb3Spatrick #endif // LIBFUZZER_WINDOWS
424