/* * Descent 3 * Copyright (C) 2024 Parallax Software * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . --- HISTORICAL COMMENTS FOLLOW --- * $Logfile: /DescentIII/Main/ddio_win/winfile.cpp $ * $Revision: 27 $ * $Date: 10/22/99 1:23p $ * $Author: Kevin $ * * File operations not covered properly in ANSI C * * $Log: /DescentIII/Main/ddio_win/winfile.cpp $ * * 27 10/22/99 1:23p Kevin * Made ddio_GetCDDrive return null if the cd isn't found * * 26 7/12/99 6:44p Jeff * added directory lock file API functions * * 25 6/24/99 2:04p Kevin * Fixed bug with 2 CD rom drives & ddio_GetCDDrive * * 24 3/19/99 1:53p Kevin * Fixed a bug with ddio_GetCDDrive * * 23 2/09/99 4:46p Jeff * removed int3 in CopyFileTime * * 22 2/04/99 11:19a Kevin * Added function to find a CD drive letter based on its volume name * * 21 12/08/98 12:17p Jeff * added 3 functions (similar to ddio_FindFiles) for finding directories * in a path * * 20 11/19/98 5:40p Kevin * Demo system * * 19 10/16/98 11:55a Kevin * Made dlls loadable in a hog * * 18 10/08/98 4:23p Kevin * Changed code to comply with memory library usage. Always use mem_malloc * , mem_free and mem_strdup * * 17 8/19/98 2:18p Jeff * changed ddio_CleanPath * * 16 8/16/98 2:04p Matt * Fixed super-stupid bug * * 15 8/15/98 3:42p Matt * Added new function, ddio_GetFullPath() * * 14 7/29/98 5:38p Jeff * added ddio functions to get parent path, and to clean a path name into * the real path * * 13 7/28/98 6:05p Jeff * added functions to get root directories (aka drives in windows/dos) * * 12 6/01/98 10:34a Matt * If can't copy file time, wait half a second and try again. * * 11 5/26/98 7:35p Jason * took out filetime int 3 * * 10 4/06/98 1:24p Samir * support NULL arguments to ddio_SpltPath. * * 9 3/19/98 3:18p Samir * enforce constant char* arguments when needed. done in CFILE and bitmap * libraries as well as ddio. * * 8 2/20/98 3:37p Jason * fixed error message to print out before subsequent file operations * happen * * 7 2/17/98 9:40p Jason * print out error number for copy file time * * 6 2/16/98 11:08a Jason * fixed copyfiletime bug * * 5 2/16/98 1:48a Matt * Added some additional error checking * * 4 9/10/97 12:06p Samir * FIxed FindFile functions. * * 3 8/15/97 6:31p Samir * Added findfile functions. * * 2 7/17/97 3:00p Jason * took out int3 on copy file time * * 10 6/11/97 2:39p Samir * Fixed bools * * 9 5/06/97 4:27p Samir * Added ddio_MakePath * * 8 5/06/97 12:35p Samir * Impllemented DirectoryExists and Save/Restore Working paths. * * 7 4/25/97 6:16p Jason * added ddio_Deletefile function * * 6 4/03/97 4:34p Jason * added CopyFileTime to the cfile, ddio libs * * 5 3/14/97 6:52p Samir * Fixed jeremy bugs. * * 4 3/14/97 6:53 PM Jeremy * added implementation of ddio_GetFileLength, ddio_SplitPath * * 3 3/14/97 6:38p Samir * Added ddio_FileDiff * * 2 3/13/97 11:09a Samir * Moved file stuff from gameos to ddio library * * 1 3/13/97 11:01a Samir * Moved from gameos library * * $NoKeywords: $ */ #include #include #include #include #include #include "ddio.h" #include "log.h" #include "mem.h" #include "pserror.h" // --------------------------------------------------------------------------- // File operations // retrieve the current working folder where file operation will occur. void ddio_GetWorkingDir(char *path, int len) { GetCurrentDirectory(len, path); } bool ddio_SetWorkingDir(const char *path) { return (SetCurrentDirectory(path)) ? true : false; } bool ddio_FileDiff(const std::filesystem::path &path1, const std::filesystem::path &path2) { struct _stat abuf, bbuf; if (_stat(path1.u8string().c_str(), &abuf)) Int3(); // error getting stat info if (_stat(path2.u8string().c_str(), &bbuf)) Int3(); // error getting stat info if ((abuf.st_size != bbuf.st_size) || (abuf.st_mtime != bbuf.st_mtime)) return true; return false; } // get a file's length int ddio_GetFileLength(FILE *filePtr) { return (filelength(fileno(filePtr))); } // Split a pathname into its component parts void ddio_SplitPath(const char *srcPath, char *path, char *filename, char *ext) { char drivename[_MAX_DRIVE], dirname[_MAX_DIR]; _splitpath(srcPath, drivename, dirname, filename, ext); if (path) sprintf(path, "%s%s", drivename, dirname); } void ddio_CopyFileTime(const std::filesystem::path &dest, const std::filesystem::path &src) { HANDLE desthandle, srchandle; FILETIME a, b, c; bool first_time = true; try_again:; desthandle = CreateFile(dest.u8string().c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); srchandle = CreateFile(src.u8string().c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (desthandle == INVALID_HANDLE_VALUE || srchandle == INVALID_HANDLE_VALUE) { LOG_WARNING.printf("Couldn't copy file time for %s! Error=%d", dest.u8string().c_str(), GetLastError()); if (desthandle != INVALID_HANDLE_VALUE) CloseHandle(desthandle); if (srchandle != INVALID_HANDLE_VALUE) CloseHandle(srchandle); if (first_time) { first_time = false; Sleep(500); goto try_again; } // JEFF: This Int3 has become really annoying...all we do is blow by it anyway // removed for sanity. //@@Int3(); //Let Matt know if you hit this! return; } GetFileTime(srchandle, &a, &b, &c); SetFileTime(desthandle, &a, &b, &c); CloseHandle(desthandle); CloseHandle(srchandle); } // deletes a file. Returns 1 if successful, 0 on failure int ddio_DeleteFile(const char *name) { return (DeleteFile(name)); } // Constructs a path in the local file system's syntax // newPath: stores the constructed path // absolutePathHeader: absolute path on which the sub directories will be appended // (specified in local file system syntax) // takes a variable number of subdirectories which will be concatenated on to the path // the last argument in the list of sub dirs *MUST* be NULL to terminate the list void ddio_MakePath(char *newPath, const char *absolutePathHeader, const char *subDir, ...) { const char delimiter = '\\'; va_list args; char *currentDir = NULL; int pathLength = 0; assert(newPath); assert(absolutePathHeader); assert(subDir); if (newPath != absolutePathHeader) { strcpy(newPath, absolutePathHeader); } // Add the first sub directory pathLength = strlen(newPath); if (newPath[pathLength - 1] != delimiter) { newPath[pathLength] = delimiter; // add the delimiter newPath[pathLength + 1] = 0; // terminate the string } strcat(newPath, subDir); // Add the additional subdirectories va_start(args, subDir); while ((currentDir = va_arg(args, char *)) != NULL) { pathLength = strlen(newPath); if (newPath[pathLength - 1] != delimiter) { newPath[pathLength] = delimiter; // add the delimiter newPath[pathLength + 1] = 0; // terminate the string } strcat(newPath, currentDir); } va_end(args); } // retrieve root names, free up roots array (allocated with malloc) after use int ddio_GetFileSysRoots(char **roots, int max_roots) { char buffer[100]; int ret = GetLogicalDriveStrings(100, buffer); if (ret == 0) { // there was an error return 0; } if (ret > 100) { // we didn't have enough space return 0; } int count = 0; bool done = false; char *strptr = buffer; char *string; int strsize; while ((count < max_roots) && (!done)) { if (*strptr != 0) { strsize = strlen(strptr); string = roots[count] = mem_rmalloc(strsize); if (!string) break; // remove the trailing \ from windows strncpy(string, strptr, strsize - 1); string[strsize - 1] = '\0'; strptr += (strsize + 1); count++; } else done = true; } return count; } std::vector ddio_GetSysRoots() { std::vector result = {}; char buffer[100]; int ret = GetLogicalDriveStrings(100, buffer); if (ret == 0 || ret > 100) { // there was an error return result; } bool done = false; char *strptr = buffer; char *string; int strsize; while (!done) { if (*strptr != 0) { strsize = strlen(strptr); string = mem_rmalloc(strsize); if (!string) break; // remove the trailing \ from windows strncpy(string, strptr, strsize - 1); string[strsize - 1] = '\0'; strptr += (strsize + 1); result.push_back(string); mem_free(string); } else { done = true; } } return result; }; bool ddio_CheckProcess(int pid) { HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); if (proc) { DWORD obj_ret = WaitForSingleObject(proc, 0); CloseHandle(proc); if (obj_ret == WAIT_TIMEOUT) { // this process exists still return true; } } return false; } int ddio_GetPID() { return GetCurrentProcessId(); }