[io-layer] Extract file (#4255)
[mono.git] / mono / metadata / w32file-win32.c
1 /*
2  * w32file-win32.c: Windows File IO internal calls.
3  *
4  * Copyright 2016 Microsoft
5  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
6  */
7 #include <config.h>
8 #include <glib.h>
9
10 #include <winsock2.h>
11 #include <windows.h>
12 #include "mono/metadata/w32file-win32-internals.h"
13
14 void
15 mono_w32file_init (void)
16 {
17 }
18
19 void
20 mono_w32file_cleanup (void)
21 {
22 }
23
24 gunichar2
25 ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar ()
26 {
27         return (gunichar2) ':'; /* colon */
28 }
29
30 gunichar2
31 ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar ()
32 {
33         return (gunichar2) '\\';        /* backslash */
34 }
35
36 gunichar2
37 ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar ()
38 {
39         return (gunichar2) '/'; /* forward slash */
40 }
41
42 gunichar2
43 ves_icall_System_IO_MonoIO_get_PathSeparator ()
44 {
45         return (gunichar2) ';'; /* semicolon */
46 }
47
48 void ves_icall_System_IO_MonoIO_DumpHandles (void)
49 {
50         return;
51 }
52
53 gpointer
54 mono_w32file_create(const gunichar2 *name, guint32 fileaccess, guint32 sharemode, guint32 createmode, guint32 attrs)
55 {
56         return CreateFile (name, fileaccess, sharemode, NULL, createmode, attrs, NULL);
57 }
58
59 gboolean
60 mono_w32file_delete (const gunichar2 *name)
61 {
62         return DeleteFile (name);
63 }
64
65 gboolean
66 mono_w32file_read(gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread)
67 {
68         return ReadFile (handle, buffer, numbytes, bytesread, NULL);
69 }
70
71 gboolean
72 mono_w32file_write (gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten)
73 {
74         return WriteFile (handle, buffer, numbytes, byteswritten, NULL);
75 }
76
77 gboolean
78 mono_w32file_flush (gpointer handle)
79 {
80         return FlushFileBuffers (handle);
81 }
82
83 gboolean
84 mono_w32file_truncate (gpointer handle)
85 {
86         return SetEndOfFile (handle);
87 }
88
89 guint32
90 mono_w32file_seek (gpointer handle, gint32 movedistance, gint32 *highmovedistance, guint32 method)
91 {
92         return SetFilePointer (handle, movedistance, highmovedistance, method);
93 }
94
95 gint
96 mono_w32file_get_type (gpointer handle)
97 {
98         return GetFileType (handle);
99 }
100
101 gboolean
102 mono_w32file_get_times (gpointer handle, FILETIME *create_time, FILETIME *access_time, FILETIME *write_time)
103 {
104         return GetFileTime (handle, create_time, access_time, write_time);
105 }
106
107 gboolean
108 mono_w32file_set_times (gpointer handle, const FILETIME *create_time, const FILETIME *access_time, const FILETIME *write_time)
109 {
110         return SetFileTime (handle, create_time, access_time, write_time);
111 }
112
113 gboolean
114 mono_w32file_filetime_to_systemtime (const FILETIME *file_time, SYSTEMTIME *system_time)
115 {
116         return FileTimeToSystemTime (file_time, system_time);
117 }
118
119 gpointer
120 mono_w32file_find_first (const gunichar2 *pattern, WIN32_FIND_DATA *find_data)
121 {
122         return FindFirstFile (pattern, find_data);
123 }
124
125 gboolean
126 mono_w32file_find_next (gpointer handle, WIN32_FIND_DATA *find_data)
127 {
128         return FindNextFile (handle, find_data);
129 }
130
131 gboolean
132 mono_w32file_find_close (gpointer handle)
133 {
134         return FindClose (handle);
135 }
136
137 gboolean
138 mono_w32file_create_directory (const gunichar2 *name)
139 {
140         return CreateDirectory (name, NULL);
141 }
142
143 gboolean
144 mono_w32file_remove_directory (const gunichar2 *name)
145 {
146         return RemoveDirectory (name);
147 }
148
149 guint32
150 mono_w32file_get_attributes (const gunichar2 *name)
151 {
152         return GetFileAttributes (name);
153 }
154
155 gboolean
156 mono_w32file_get_attributes_ex (const gunichar2 *name, MonoIOStat *stat)
157 {
158         gboolean result;
159         WIN32_FILE_ATTRIBUTE_DATA data;
160
161         result = GetFileAttributesEx (name, GetFileExInfoStandard, &data);
162         if (result) {
163                 stat->attributes = data.dwFileAttributes;
164                 stat->creation_time = (gint64) ((((guint64) data.ftCreationTime.dwHighDateTime) << 32) + data.ftCreationTime.dwLowDateTime);
165                 stat->last_access_time = (gint64) ((((guint64) data.ftLastAccessTime.dwHighDateTime) << 32) + data.ftLastAccessTime.dwLowDateTime);
166                 stat->last_write_time = (gint64) ((((guint64) data.ftLastWriteTime.dwHighDateTime) << 32) + data.ftLastWriteTime.dwLowDateTime);
167                 stat->length = ((gint64)data.nFileSizeHigh << 32) | data.nFileSizeLow;
168         }
169
170         return result;
171 }
172
173 gboolean
174 mono_w32file_set_attributes (const gunichar2 *name, guint32 attrs)
175 {
176         return SetFileAttributes (name, attrs);
177 }
178
179 guint32
180 mono_w32file_get_cwd (guint32 length, gunichar2 *buffer)
181 {
182         return GetCurrentDirectory (length, buffer);
183 }
184
185 gboolean
186 mono_w32file_set_cwd (const gunichar2 *path)
187 {
188         return SetCurrentDirectory (path);
189 }
190
191 gboolean
192 mono_w32file_create_pipe (gpointer *readpipe, gpointer *writepipe, guint32 size)
193 {
194         SECURITY_ATTRIBUTES attr;
195         attr.nLength = sizeof(SECURITY_ATTRIBUTES);
196         attr.bInheritHandle = TRUE;
197         attr.lpSecurityDescriptor = NULL;
198         return CreatePipe (readpipe, writepipe, &attr, size);
199 }
200
201 gboolean
202 mono_w32file_get_disk_free_space (const gunichar2 *path_name, guint64 *free_bytes_avail, guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes)
203 {
204         gboolean result;
205         ULARGE_INTEGER *wapi_free_bytes_avail;
206         ULARGE_INTEGER *wapi_total_number_of_bytes;
207         ULARGE_INTEGER *wapi_total_number_of_free_bytes;
208
209         result = GetDiskFreeSpaceEx (path_name, wapi_free_bytes_avail, wapi_total_number_of_bytes, wapi_total_number_of_free_bytes);
210         if (result) {
211                 if (free_bytes_avail)
212                         *free_bytes_avail = wapi_free_bytes_avail->QuadPart;
213                 if (total_number_of_bytes)
214                         *total_number_of_bytes = wapi_total_number_of_bytes->QuadPart;
215                 if (total_number_of_free_bytes)
216                         *total_number_of_free_bytes = wapi_total_number_of_free_bytes->QuadPart;
217         }
218
219         return result;
220 }
221
222 gboolean
223 mono_w32file_get_volume_information (const gunichar2 *path, gunichar2 *volumename, gint volumesize, gint *outserial, gint *maxcomp, gint *fsflags, gunichar2 *fsbuffer, gint fsbuffersize)
224 {
225         return GetVolumeInformation (path, volumename, volumesize, outserial, maxcomp, fsflags, fsbuffer, fsbuffersize);
226 }
227
228 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
229
230 gboolean
231 mono_w32file_move (gunichar2 *path, gunichar2 *dest, gint32 *error)
232 {
233         gboolean result;
234
235         MONO_ENTER_GC_SAFE;
236
237         result = MoveFile (path, dest);
238         if (!result)
239                 *error = GetLastError ();
240
241         MONO_EXIT_GC_SAFE;
242
243         return result;
244 }
245
246 gboolean
247 mono_w32file_replace (gunichar2 *destinationFileName, gunichar2 *sourceFileName, gunichar2 *destinationBackupFileName, guint32 flags, gint32 *error)
248 {
249         gboolean result;
250
251         MONO_ENTER_GC_SAFE;
252
253         result = ReplaceFile (destinationFileName, sourceFileName, destinationBackupFileName, flags, NULL, NULL);
254         if (!result)
255                 *error = GetLastError ();
256
257         MONO_EXIT_GC_SAFE;
258
259         return result;
260 }
261
262 gboolean
263 mono_w32file_copy (gunichar2 *path, gunichar2 *dest, gboolean overwrite, gint32 *error)
264 {
265         gboolean result;
266
267         MONO_ENTER_GC_SAFE;
268
269         result = CopyFile (path, dest, !overwrite);
270         if (!result)
271                 *error = GetLastError ();
272
273         MONO_EXIT_GC_SAFE;
274
275         return result;
276 }
277
278 gboolean
279 mono_w32file_lock (gpointer handle, gint64 position, gint64 length, gint32 *error)
280 {
281         gboolean result;
282
283         MONO_ENTER_GC_SAFE;
284
285         result = LockFile (handle, position & 0xFFFFFFFF, position >> 32, length & 0xFFFFFFFF, length >> 32);
286         if (!result)
287                 *error = GetLastError ();
288
289         MONO_EXIT_GC_SAFE;
290
291         return result;
292 }
293
294 gboolean
295 mono_w32file_unlock (gpointer handle, gint64 position, gint64 length, gint32 *error)
296 {
297         gboolean result;
298
299         MONO_ENTER_GC_SAFE;
300
301         result = UnlockFile (handle, position & 0xFFFFFFFF, position >> 32, length & 0xFFFFFFFF, length >> 32);
302         if (!result)
303                 *error = GetLastError ();
304
305         MONO_EXIT_GC_SAFE;
306
307         return result;
308 }
309
310 HANDLE
311 mono_w32file_get_console_input (void)
312 {
313         return GetStdHandle (STD_INPUT_HANDLE);
314 }
315
316 HANDLE
317 mono_w32file_get_console_output (void)
318 {
319         return GetStdHandle (STD_OUTPUT_HANDLE);
320 }
321
322 HANDLE
323 mono_w32file_get_console_error (void)
324 {
325         return GetStdHandle (STD_ERROR_HANDLE);
326 }
327
328 gint64
329 mono_w32file_get_file_size (gpointer handle, gint32 *error)
330 {
331         gint64 length;
332         guint32 length_hi;
333
334         MONO_ENTER_GC_SAFE;
335
336         length = GetFileSize (handle, &length_hi);
337         if(length==INVALID_FILE_SIZE) {
338                 *error=GetLastError ();
339         }
340
341         MONO_EXIT_GC_SAFE;
342
343         return length | ((gint64)length_hi << 32);
344 }
345
346 guint32
347 mono_w32file_get_drive_type (const gunichar2 *root_path_name)
348 {
349         return GetDriveType (root_path_name);
350 }
351
352 gint32
353 mono_w32file_get_logical_drive (guint32 len, gunichar2 *buf)
354 {
355         return GetLogicalDriveStrings (len, buf);
356 }
357
358 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */