LCOV - code coverage report
Current view: top level - asar/platform/windows - file-helpers-win32.cpp (source / functions) Coverage Total Hit
Test: asar build #66 Lines: 82.9 % 76 63
Test Date: 2024-01-16 02:45:19 Functions: 100.0 % 10 10
Branches: 56.6 % 53 30

             Branch data     Line data    Source code
       1                 :             : // RPG Hacker: We can't include that here, because it leads to crazy
       2                 :             : // errors in windows.h - probably related to our string class?!?
       3                 :             : //#include "platform/file-helpers.h"
       4                 :             : 
       5                 :             : #if defined(_MSC_VER)
       6                 :             : #       pragma warning(push)
       7                 :             : #       pragma warning(disable : 4668)
       8                 :             : #       pragma warning(disable : 4987)
       9                 :             : #endif
      10                 :             : 
      11                 :             : #define NOMINMAX
      12                 :             : #include <windows.h>
      13                 :             : #include <ctype.h>
      14                 :             : 
      15                 :             : #if defined(_MSC_VER)
      16                 :             : #       pragma warning(pop)
      17                 :             : #endif
      18                 :             : 
      19                 :             : #include <ctype.h>
      20                 :             : 
      21                 :             : #include "../file-helpers.h"
      22                 :             : #include "../../unicode.h"
      23                 :             : 
      24                 :        3263 : bool file_exists(const char * filename)
      25                 :             : {
      26                 :        3263 :         std::wstring u16_str;
      27   [ +  -  -  + ]:        3263 :         if (!utf8_to_utf16(&u16_str, filename)) return false;
      28         [ +  - ]:        3263 :         return (GetFileAttributesW(u16_str.c_str()) != INVALID_FILE_ATTRIBUTES);
      29                 :        3263 : }
      30                 :             : 
      31                 :        6710 : bool path_is_absolute(const char* path)
      32                 :             : {
      33                 :       13393 :         return ((isalpha(path[0]) &&
      34   [ +  +  +  +  :        6683 :                 (':' == path[1]) && (('\\' == path[2]) || ('/' == path[2])))    /* drive letter + root, e.g. C:\dir or C:/dir */
                   -  + ]
      35   [ +  +  +  -  :       13393 :                 || ('\\' == path[0]) || ('/' == path[0]));                                              /* just root, e.g. \dir or /dir */
                   -  + ]
      36                 :             : }
      37                 :             : 
      38                 :          16 : char get_native_path_separator()
      39                 :             : {
      40                 :          16 :         return '\\';
      41                 :             : }
      42                 :             : 
      43                 :         258 : bool check_is_regular_file(const char* path)
      44                 :             : {
      45                 :         258 :         std::wstring u16_str;
      46   [ +  -  -  + ]:         258 :         if (!utf8_to_utf16(&u16_str, path)) return false;
      47         [ +  - ]:         258 :         return !(GetFileAttributesW(u16_str.c_str()) & FILE_ATTRIBUTE_DIRECTORY);
      48                 :         258 : }
      49                 :             : 
      50                 :             : 
      51                 :         686 : FileHandleType open_file(const char* path, FileOpenMode mode, FileOpenError* error)
      52                 :             : {
      53                 :         686 :         HANDLE out_handle = NULL;
      54                 :         686 :         DWORD access_mode = 0;
      55                 :         686 :         DWORD share_mode = 0;
      56                 :         686 :         DWORD disposition = 0;
      57                 :             : 
      58   [ +  +  +  - ]:         686 :         switch (mode)
      59                 :             :         {
      60                 :         115 :         case FileOpenMode_ReadWrite:
      61                 :         115 :                 access_mode = GENERIC_READ | GENERIC_WRITE;
      62                 :         115 :                 disposition = OPEN_EXISTING;
      63                 :         115 :                 break;
      64                 :         482 :         case FileOpenMode_Read:
      65                 :         482 :                 access_mode = GENERIC_READ;
      66                 :             :                 // This should be fine, right?
      67                 :         482 :                 share_mode = FILE_SHARE_READ;
      68                 :         482 :                 disposition = OPEN_EXISTING;
      69                 :         482 :                 break;
      70                 :          89 :         case FileOpenMode_Write:
      71                 :          89 :                 access_mode = GENERIC_WRITE;
      72                 :          89 :                 disposition = CREATE_ALWAYS;
      73                 :          89 :                 break;
      74                 :             :         }
      75                 :             : 
      76                 :        1372 :         std::wstring u16_str;
      77   [ +  -  -  + ]:         686 :         if (!utf8_to_utf16(&u16_str, path))
      78                 :             :         {
      79                 :             :                 // RPG Hacker: I treat encoding error as "file not found", which I guess is what
      80                 :             :                 // Windows would do, anyways.
      81                 :           0 :                 *error = FileOpenError_NotFound;
      82                 :           0 :                 return INVALID_HANDLE_VALUE;
      83                 :             :         }
      84                 :             : 
      85                 :         686 :         out_handle = CreateFileW(u16_str.c_str(), access_mode, share_mode, NULL, disposition, FILE_ATTRIBUTE_NORMAL, NULL);
      86                 :             : 
      87         [ +  + ]:         686 :         if (error != NULL)
      88                 :             :         {
      89         [ +  - ]:         252 :                 if (out_handle != INVALID_HANDLE_VALUE)
      90                 :             :                 {
      91                 :         252 :                         *error = FileOpenError_None;
      92                 :             :                 }
      93                 :             :                 else
      94                 :             :                 {
      95                 :           0 :                         DWORD win_error = GetLastError();
      96                 :             : 
      97      [ #  #  # ]:           0 :                         switch (win_error)
      98                 :             :                         {
      99                 :           0 :                         case ERROR_FILE_NOT_FOUND:
     100                 :           0 :                                 *error = FileOpenError_NotFound;
     101                 :           0 :                                 break;
     102                 :           0 :                         case ERROR_ACCESS_DENIED:
     103                 :           0 :                                 *error = FileOpenError_AccessDenied;
     104                 :           0 :                                 break;
     105                 :           0 :                         default:
     106                 :           0 :                                 *error = FileOpenError_Unknown;
     107                 :           0 :                                 break;
     108                 :             :                         }
     109                 :             :                 }
     110                 :             :         }
     111                 :             : 
     112                 :         686 :         return out_handle;
     113                 :             : }
     114                 :             : 
     115                 :         686 : void close_file(FileHandleType handle)
     116                 :             : {
     117         [ -  + ]:         686 :         if (handle == InvalidFileHandle) return;
     118                 :             : 
     119                 :         686 :         CloseHandle(handle);
     120                 :             : }
     121                 :             : 
     122                 :         597 : uint64_t get_file_size(FileHandleType handle)
     123                 :             : {
     124         [ -  + ]:         597 :         if (handle == InvalidFileHandle) return 0u;
     125                 :             : 
     126                 :             :         LARGE_INTEGER f_size;
     127                 :             : 
     128   [ +  -  -  + ]:         597 :         if (!GetFileSizeEx(handle, &f_size)) return 0u;
     129                 :             : 
     130                 :         597 :         return (uint64_t)f_size.QuadPart;
     131                 :             : }
     132                 :             : 
     133                 :         452 : void set_file_pos(FileHandleType handle, uint64_t pos)
     134                 :             : {
     135         [ -  + ]:         452 :         if (handle == InvalidFileHandle) return;
     136                 :             : 
     137                 :             :         // TODO: Some error handling would be wise here.
     138                 :             : 
     139                 :             :         LARGE_INTEGER new_pos;
     140                 :         452 :         new_pos.QuadPart = (LONGLONG)pos;
     141                 :             : 
     142                 :         452 :         SetFilePointerEx(handle, new_pos, NULL, FILE_BEGIN);
     143                 :             : }
     144                 :             : 
     145                 :         604 : uint32_t read_file(FileHandleType handle, void* buffer, uint32_t num_bytes)
     146                 :             : {
     147         [ -  + ]:         604 :         if (handle == InvalidFileHandle) return 0u;
     148                 :             : 
     149                 :         604 :         DWORD bytes_read = 0u;
     150                 :             : 
     151                 :             :         // TODO: Some error handling would be wise here.
     152                 :             : 
     153                 :         604 :         ReadFile(handle, buffer, (DWORD)num_bytes, &bytes_read, NULL);
     154                 :             : 
     155                 :         604 :         return (uint32_t)bytes_read;
     156                 :             : }
     157                 :             : 
     158                 :          78 : uint32_t write_file(FileHandleType handle, const void* buffer, uint32_t num_bytes)
     159                 :             : {
     160         [ -  + ]:          78 :         if (handle == InvalidFileHandle) return 0u;
     161                 :             : 
     162                 :          78 :         DWORD bytes_written = 0u;
     163                 :             : 
     164                 :             :         // TODO: Some error handling would be wise here.
     165                 :             : 
     166                 :          78 :         WriteFile(handle, buffer, (DWORD)num_bytes, &bytes_written, NULL);
     167                 :             : 
     168                 :          78 :         return (uint32_t)bytes_written;
     169                 :             : }
        

Generated by: LCOV version 2.0-1