Merge pull request #4274 from kumpera/cctor-abort
[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_close (gpointer handle)
61 {
62         return CloseHandle (handle);
63 }
64
65 gboolean
66 mono_w32file_delete (const gunichar2 *name)
67 {
68         return DeleteFile (name);
69 }
70
71 gboolean
72 mono_w32file_read(gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread)
73 {
74         return ReadFile (handle, buffer, numbytes, bytesread, NULL);
75 }
76
77 gboolean
78 mono_w32file_write (gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten)
79 {
80         return WriteFile (handle, buffer, numbytes, byteswritten, NULL);
81 }
82
83 gboolean
84 mono_w32file_flush (gpointer handle)
85 {
86         return FlushFileBuffers (handle);
87 }
88
89 gboolean
90 mono_w32file_truncate (gpointer handle)
91 {
92         return SetEndOfFile (handle);
93 }
94
95 guint32
96 mono_w32file_seek (gpointer handle, gint32 movedistance, gint32 *highmovedistance, guint32 method)
97 {
98         return SetFilePointer (handle, movedistance, highmovedistance, method);
99 }
100
101 gint
102 mono_w32file_get_type (gpointer handle)
103 {
104         return GetFileType (handle);
105 }
106
107 gboolean
108 mono_w32file_get_times (gpointer handle, FILETIME *create_time, FILETIME *access_time, FILETIME *write_time)
109 {
110         return GetFileTime (handle, create_time, access_time, write_time);
111 }
112
113 gboolean
114 mono_w32file_set_times (gpointer handle, const FILETIME *create_time, const FILETIME *access_time, const FILETIME *write_time)
115 {
116         return SetFileTime (handle, create_time, access_time, write_time);
117 }
118
119 gboolean
120 mono_w32file_filetime_to_systemtime (const FILETIME *file_time, SYSTEMTIME *system_time)
121 {
122         return FileTimeToSystemTime (file_time, system_time);
123 }
124
125 gpointer
126 mono_w32file_find_first (const gunichar2 *pattern, WIN32_FIND_DATA *find_data)
127 {
128         return FindFirstFile (pattern, find_data);
129 }
130
131 gboolean
132 mono_w32file_find_next (gpointer handle, WIN32_FIND_DATA *find_data)
133 {
134         return FindNextFile (handle, find_data);
135 }
136
137 gboolean
138 mono_w32file_find_close (gpointer handle)
139 {
140         return FindClose (handle);
141 }
142
143 gboolean
144 mono_w32file_create_directory (const gunichar2 *name)
145 {
146         return CreateDirectory (name, NULL);
147 }
148
149 gboolean
150 mono_w32file_remove_directory (const gunichar2 *name)
151 {
152         return RemoveDirectory (name);
153 }
154
155 guint32
156 mono_w32file_get_attributes (const gunichar2 *name)
157 {
158         return GetFileAttributes (name);
159 }
160
161 gboolean
162 mono_w32file_get_attributes_ex (const gunichar2 *name, MonoIOStat *stat)
163 {
164         gboolean result;
165         WIN32_FILE_ATTRIBUTE_DATA data;
166
167         result = GetFileAttributesEx (name, GetFileExInfoStandard, &data);
168         if (result) {
169                 stat->attributes = data.dwFileAttributes;
170                 stat->creation_time = (gint64) ((((guint64) data.ftCreationTime.dwHighDateTime) << 32) + data.ftCreationTime.dwLowDateTime);
171                 stat->last_access_time = (gint64) ((((guint64) data.ftLastAccessTime.dwHighDateTime) << 32) + data.ftLastAccessTime.dwLowDateTime);
172                 stat->last_write_time = (gint64) ((((guint64) data.ftLastWriteTime.dwHighDateTime) << 32) + data.ftLastWriteTime.dwLowDateTime);
173                 stat->length = ((gint64)data.nFileSizeHigh << 32) | data.nFileSizeLow;
174         }
175
176         return result;
177 }
178
179 gboolean
180 mono_w32file_set_attributes (const gunichar2 *name, guint32 attrs)
181 {
182         return SetFileAttributes (name, attrs);
183 }
184
185 guint32
186 mono_w32file_get_cwd (guint32 length, gunichar2 *buffer)
187 {
188         return GetCurrentDirectory (length, buffer);
189 }
190
191 gboolean
192 mono_w32file_set_cwd (const gunichar2 *path)
193 {
194         return SetCurrentDirectory (path);
195 }
196
197 gboolean
198 mono_w32file_create_pipe (gpointer *readpipe, gpointer *writepipe, guint32 size)
199 {
200         SECURITY_ATTRIBUTES attr;
201         attr.nLength = sizeof(SECURITY_ATTRIBUTES);
202         attr.bInheritHandle = TRUE;
203         attr.lpSecurityDescriptor = NULL;
204         return CreatePipe (readpipe, writepipe, &attr, size);
205 }
206
207 gboolean
208 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)
209 {
210         gboolean result;
211         ULARGE_INTEGER *wapi_free_bytes_avail;
212         ULARGE_INTEGER *wapi_total_number_of_bytes;
213         ULARGE_INTEGER *wapi_total_number_of_free_bytes;
214
215         result = GetDiskFreeSpaceEx (path_name, wapi_free_bytes_avail, wapi_total_number_of_bytes, wapi_total_number_of_free_bytes);
216         if (result) {
217                 if (free_bytes_avail)
218                         *free_bytes_avail = wapi_free_bytes_avail->QuadPart;
219                 if (total_number_of_bytes)
220                         *total_number_of_bytes = wapi_total_number_of_bytes->QuadPart;
221                 if (total_number_of_free_bytes)
222                         *total_number_of_free_bytes = wapi_total_number_of_free_bytes->QuadPart;
223         }
224
225         return result;
226 }
227
228 gboolean
229 mono_w32file_get_volume_information (const gunichar2 *path, gunichar2 *volumename, gint volumesize, gint *outserial, gint *maxcomp, gint *fsflags, gunichar2 *fsbuffer, gint fsbuffersize)
230 {
231         return GetVolumeInformation (path, volumename, volumesize, outserial, maxcomp, fsflags, fsbuffer, fsbuffersize);
232 }
233
234 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
235
236 gboolean
237 mono_w32file_move (gunichar2 *path, gunichar2 *dest, gint32 *error)
238 {
239         gboolean result;
240
241         MONO_ENTER_GC_SAFE;
242
243         result = MoveFile (path, dest);
244         if (!result)
245                 *error = GetLastError ();
246
247         MONO_EXIT_GC_SAFE;
248
249         return result;
250 }
251
252 gboolean
253 mono_w32file_replace (gunichar2 *destinationFileName, gunichar2 *sourceFileName, gunichar2 *destinationBackupFileName, guint32 flags, gint32 *error)
254 {
255         gboolean result;
256
257         MONO_ENTER_GC_SAFE;
258
259         result = ReplaceFile (destinationFileName, sourceFileName, destinationBackupFileName, flags, NULL, NULL);
260         if (!result)
261                 *error = GetLastError ();
262
263         MONO_EXIT_GC_SAFE;
264
265         return result;
266 }
267
268 gboolean
269 mono_w32file_copy (gunichar2 *path, gunichar2 *dest, gboolean overwrite, gint32 *error)
270 {
271         gboolean result;
272
273         MONO_ENTER_GC_SAFE;
274
275         result = CopyFile (path, dest, !overwrite);
276         if (!result)
277                 *error = GetLastError ();
278
279         MONO_EXIT_GC_SAFE;
280
281         return result;
282 }
283
284 gboolean
285 mono_w32file_lock (gpointer handle, gint64 position, gint64 length, gint32 *error)
286 {
287         gboolean result;
288
289         MONO_ENTER_GC_SAFE;
290
291         result = LockFile (handle, position & 0xFFFFFFFF, position >> 32, length & 0xFFFFFFFF, length >> 32);
292         if (!result)
293                 *error = GetLastError ();
294
295         MONO_EXIT_GC_SAFE;
296
297         return result;
298 }
299
300 gboolean
301 mono_w32file_unlock (gpointer handle, gint64 position, gint64 length, gint32 *error)
302 {
303         gboolean result;
304
305         MONO_ENTER_GC_SAFE;
306
307         result = UnlockFile (handle, position & 0xFFFFFFFF, position >> 32, length & 0xFFFFFFFF, length >> 32);
308         if (!result)
309                 *error = GetLastError ();
310
311         MONO_EXIT_GC_SAFE;
312
313         return result;
314 }
315
316 HANDLE
317 mono_w32file_get_console_input (void)
318 {
319         return GetStdHandle (STD_INPUT_HANDLE);
320 }
321
322 HANDLE
323 mono_w32file_get_console_output (void)
324 {
325         return GetStdHandle (STD_OUTPUT_HANDLE);
326 }
327
328 HANDLE
329 mono_w32file_get_console_error (void)
330 {
331         return GetStdHandle (STD_ERROR_HANDLE);
332 }
333
334 gint64
335 mono_w32file_get_file_size (gpointer handle, gint32 *error)
336 {
337         gint64 length;
338         guint32 length_hi;
339
340         MONO_ENTER_GC_SAFE;
341
342         length = GetFileSize (handle, &length_hi);
343         if(length==INVALID_FILE_SIZE) {
344                 *error=GetLastError ();
345         }
346
347         MONO_EXIT_GC_SAFE;
348
349         return length | ((gint64)length_hi << 32);
350 }
351
352 guint32
353 mono_w32file_get_drive_type (const gunichar2 *root_path_name)
354 {
355         return GetDriveType (root_path_name);
356 }
357
358 gint32
359 mono_w32file_get_logical_drive (guint32 len, gunichar2 *buf)
360 {
361         return GetLogicalDriveStrings (len, buf);
362 }
363
364 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */