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 : : }
|