X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fw32file-win32.c;h=6ecb7ff9d5f40c58d05e8c72cff844bb9b1ee634;hb=1bcf21e0480acf5dc4d68bf4e8b700217e35eb92;hp=953f7926c76a72175b3fef48d6eee9f0efbb344a;hpb=16ada3424ad720db1411ff40131abd905ddacc63;p=mono.git diff --git a/mono/metadata/w32file-win32.c b/mono/metadata/w32file-win32.c index 953f7926c76..6ecb7ff9d5f 100644 --- a/mono/metadata/w32file-win32.c +++ b/mono/metadata/w32file-win32.c @@ -1,5 +1,6 @@ -/* - * w32file-win32.c: Windows File IO internal calls. +/** + * \file + * Windows File IO internal calls. * * Copyright 2016 Microsoft * Licensed under the MIT license. See LICENSE file in the project root for full license information. @@ -53,173 +54,322 @@ void ves_icall_System_IO_MonoIO_DumpHandles (void) gpointer mono_w32file_create(const gunichar2 *name, guint32 fileaccess, guint32 sharemode, guint32 createmode, guint32 attrs) { - return CreateFile (name, fileaccess, sharemode, NULL, createmode, attrs, NULL); + gpointer res; + MONO_ENTER_GC_SAFE; + res = CreateFile (name, fileaccess, sharemode, NULL, createmode, attrs, NULL); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_close (gpointer handle) { - return CloseHandle (handle); + gboolean res; + MONO_ENTER_GC_SAFE; + res = CloseHandle (handle); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_delete (const gunichar2 *name) { - return DeleteFile (name); + gboolean res; + MONO_ENTER_GC_SAFE; + res = DeleteFile (name); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_read(gpointer handle, gpointer buffer, guint32 numbytes, guint32 *bytesread) { - return ReadFile (handle, buffer, numbytes, bytesread, NULL); + gboolean res; + MONO_ENTER_GC_SAFE; + res = ReadFile (handle, buffer, numbytes, bytesread, NULL); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_write (gpointer handle, gconstpointer buffer, guint32 numbytes, guint32 *byteswritten) { - return WriteFile (handle, buffer, numbytes, byteswritten, NULL); + gboolean res; + MONO_ENTER_GC_SAFE; + res = WriteFile (handle, buffer, numbytes, byteswritten, NULL); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_flush (gpointer handle) { - return FlushFileBuffers (handle); + gboolean res; + MONO_ENTER_GC_SAFE; + res = FlushFileBuffers (handle); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_truncate (gpointer handle) { - return SetEndOfFile (handle); + gboolean res; + MONO_ENTER_GC_SAFE; + res = SetEndOfFile (handle); + MONO_EXIT_GC_SAFE; + return res; } guint32 mono_w32file_seek (gpointer handle, gint32 movedistance, gint32 *highmovedistance, guint32 method) { - return SetFilePointer (handle, movedistance, highmovedistance, method); + guint32 res; + MONO_ENTER_GC_SAFE; + res = SetFilePointer (handle, movedistance, highmovedistance, method); + MONO_EXIT_GC_SAFE; + return res; } gint mono_w32file_get_type (gpointer handle) { - return GetFileType (handle); + gint res; + MONO_ENTER_GC_SAFE; + res = GetFileType (handle); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_get_times (gpointer handle, FILETIME *create_time, FILETIME *access_time, FILETIME *write_time) { - return GetFileTime (handle, create_time, access_time, write_time); + gboolean res; + MONO_ENTER_GC_SAFE; + res = GetFileTime (handle, create_time, access_time, write_time); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_set_times (gpointer handle, const FILETIME *create_time, const FILETIME *access_time, const FILETIME *write_time) { - return SetFileTime (handle, create_time, access_time, write_time); + gboolean res; + MONO_ENTER_GC_SAFE; + res = SetFileTime (handle, create_time, access_time, write_time); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_filetime_to_systemtime (const FILETIME *file_time, SYSTEMTIME *system_time) { - return FileTimeToSystemTime (file_time, system_time); + gboolean res; + MONO_ENTER_GC_SAFE; + res = FileTimeToSystemTime (file_time, system_time); + MONO_EXIT_GC_SAFE; + return res; } gpointer mono_w32file_find_first (const gunichar2 *pattern, WIN32_FIND_DATA *find_data) { - return FindFirstFile (pattern, find_data); + gpointer res; + MONO_ENTER_GC_SAFE; + res = FindFirstFile (pattern, find_data); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_find_next (gpointer handle, WIN32_FIND_DATA *find_data) { - return FindNextFile (handle, find_data); + gboolean res; + MONO_ENTER_GC_SAFE; + res = FindNextFile (handle, find_data); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_find_close (gpointer handle) { - return FindClose (handle); + gboolean res; + MONO_ENTER_GC_SAFE; + res = FindClose (handle); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_create_directory (const gunichar2 *name) { - return CreateDirectory (name, NULL); + gboolean res; + MONO_ENTER_GC_SAFE; + res = CreateDirectory (name, NULL); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_remove_directory (const gunichar2 *name) { - return RemoveDirectory (name); + gboolean res; + MONO_ENTER_GC_SAFE; + res = RemoveDirectory (name); + MONO_EXIT_GC_SAFE; + return res; } +/* + * GetFileAttributes|Ex () seems to try opening the file, which might lead to sharing violation errors, whereas + * FindFirstFile always succeeds. + */ guint32 mono_w32file_get_attributes (const gunichar2 *name) { - return GetFileAttributes (name); + guint32 res; + guint32 error; + HANDLE find_handle; + WIN32_FIND_DATA find_data; + + MONO_ENTER_GC_SAFE; + res = GetFileAttributes (name); + MONO_EXIT_GC_SAFE; + + if (res != INVALID_FILE_ATTRIBUTES) + return res; + + error = GetLastError (); + if (error != ERROR_SHARING_VIOLATION) + return INVALID_FILE_ATTRIBUTES; + + MONO_ENTER_GC_SAFE; + find_handle = FindFirstFile (name, &find_data); + MONO_EXIT_GC_SAFE; + + if (find_handle == INVALID_HANDLE_VALUE) + return INVALID_FILE_ATTRIBUTES; + + MONO_ENTER_GC_SAFE; + FindClose (find_handle); + MONO_EXIT_GC_SAFE; + + return find_data.dwFileAttributes; +} + +static gint64 +convert_filetime (const FILETIME *filetime) +{ + return (gint64) ((((guint64) filetime->dwHighDateTime) << 32) + filetime->dwLowDateTime); } gboolean mono_w32file_get_attributes_ex (const gunichar2 *name, MonoIOStat *stat) { - gboolean result; - WIN32_FILE_ATTRIBUTE_DATA data; + gboolean res; + guint32 error; + HANDLE find_handle; + WIN32_FIND_DATA find_data; + WIN32_FILE_ATTRIBUTE_DATA file_attribute_data; - result = GetFileAttributesEx (name, GetFileExInfoStandard, &data); - if (result) { - stat->attributes = data.dwFileAttributes; - stat->creation_time = (gint64) ((((guint64) data.ftCreationTime.dwHighDateTime) << 32) + data.ftCreationTime.dwLowDateTime); - stat->last_access_time = (gint64) ((((guint64) data.ftLastAccessTime.dwHighDateTime) << 32) + data.ftLastAccessTime.dwLowDateTime); - stat->last_write_time = (gint64) ((((guint64) data.ftLastWriteTime.dwHighDateTime) << 32) + data.ftLastWriteTime.dwLowDateTime); - stat->length = ((gint64)data.nFileSizeHigh << 32) | data.nFileSizeLow; + MONO_ENTER_GC_SAFE; + res = GetFileAttributesEx (name, GetFileExInfoStandard, &file_attribute_data); + MONO_EXIT_GC_SAFE; + if (res) { + stat->attributes = file_attribute_data.dwFileAttributes; + stat->creation_time = convert_filetime (&file_attribute_data.ftCreationTime); + stat->last_access_time = convert_filetime (&file_attribute_data.ftLastAccessTime); + stat->last_write_time = convert_filetime (&file_attribute_data.ftLastWriteTime); + stat->length = ((gint64)file_attribute_data.nFileSizeHigh << 32) | file_attribute_data.nFileSizeLow; + return TRUE; } - return result; + error = GetLastError (); + if (error != ERROR_SHARING_VIOLATION) + return FALSE; + + MONO_ENTER_GC_SAFE; + find_handle = FindFirstFile (name, &find_data); + MONO_EXIT_GC_SAFE; + + if (find_handle == INVALID_HANDLE_VALUE) + return FALSE; + + MONO_ENTER_GC_SAFE; + FindClose (find_handle); + MONO_EXIT_GC_SAFE; + + stat->attributes = find_data.dwFileAttributes; + stat->creation_time = convert_filetime (&find_data.ftCreationTime); + stat->last_access_time = convert_filetime (&find_data.ftLastAccessTime); + stat->last_write_time = convert_filetime (&find_data.ftLastWriteTime); + stat->length = ((gint64)find_data.nFileSizeHigh << 32) | find_data.nFileSizeLow; + return TRUE; } gboolean mono_w32file_set_attributes (const gunichar2 *name, guint32 attrs) { - return SetFileAttributes (name, attrs); + gboolean res; + MONO_ENTER_GC_SAFE; + res = SetFileAttributes (name, attrs); + MONO_EXIT_GC_SAFE; + return res; } guint32 mono_w32file_get_cwd (guint32 length, gunichar2 *buffer) { - return GetCurrentDirectory (length, buffer); + guint32 res; + MONO_ENTER_GC_SAFE; + res = GetCurrentDirectory (length, buffer); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_set_cwd (const gunichar2 *path) { - return SetCurrentDirectory (path); + gboolean res; + MONO_ENTER_GC_SAFE; + res = SetCurrentDirectory (path); + MONO_EXIT_GC_SAFE; + return res; } gboolean mono_w32file_create_pipe (gpointer *readpipe, gpointer *writepipe, guint32 size) { + gboolean res; SECURITY_ATTRIBUTES attr; attr.nLength = sizeof(SECURITY_ATTRIBUTES); attr.bInheritHandle = TRUE; attr.lpSecurityDescriptor = NULL; - return CreatePipe (readpipe, writepipe, &attr, size); + MONO_ENTER_GC_SAFE; + res = CreatePipe (readpipe, writepipe, &attr, size); + MONO_EXIT_GC_SAFE; + return res; } gboolean 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) { gboolean result; - ULARGE_INTEGER *wapi_free_bytes_avail; - ULARGE_INTEGER *wapi_total_number_of_bytes; - ULARGE_INTEGER *wapi_total_number_of_free_bytes; + ULARGE_INTEGER wapi_free_bytes_avail; + ULARGE_INTEGER wapi_total_number_of_bytes; + ULARGE_INTEGER wapi_total_number_of_free_bytes; - result = GetDiskFreeSpaceEx (path_name, wapi_free_bytes_avail, wapi_total_number_of_bytes, wapi_total_number_of_free_bytes); + MONO_ENTER_GC_SAFE; + result = GetDiskFreeSpaceEx (path_name, &wapi_free_bytes_avail, &wapi_total_number_of_bytes, &wapi_total_number_of_free_bytes); + MONO_EXIT_GC_SAFE; if (result) { if (free_bytes_avail) - *free_bytes_avail = wapi_free_bytes_avail->QuadPart; + *free_bytes_avail = wapi_free_bytes_avail.QuadPart; if (total_number_of_bytes) - *total_number_of_bytes = wapi_total_number_of_bytes->QuadPart; + *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart; if (total_number_of_free_bytes) - *total_number_of_free_bytes = wapi_total_number_of_free_bytes->QuadPart; + *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart; } return result; @@ -228,7 +378,11 @@ mono_w32file_get_disk_free_space (const gunichar2 *path_name, guint64 *free_byte gboolean mono_w32file_get_volume_information (const gunichar2 *path, gunichar2 *volumename, gint volumesize, gint *outserial, gint *maxcomp, gint *fsflags, gunichar2 *fsbuffer, gint fsbuffersize) { - return GetVolumeInformation (path, volumename, volumesize, outserial, maxcomp, fsflags, fsbuffer, fsbuffersize); + gboolean res; + MONO_ENTER_GC_SAFE; + res = GetVolumeInformation (path, volumename, volumesize, outserial, maxcomp, fsflags, fsbuffer, fsbuffersize); + MONO_EXIT_GC_SAFE; + return res; } #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) @@ -316,19 +470,31 @@ mono_w32file_unlock (gpointer handle, gint64 position, gint64 length, gint32 *er HANDLE mono_w32file_get_console_input (void) { - return GetStdHandle (STD_INPUT_HANDLE); + HANDLE res; + MONO_ENTER_GC_SAFE; + res = GetStdHandle (STD_INPUT_HANDLE); + MONO_EXIT_GC_SAFE; + return res; } HANDLE mono_w32file_get_console_output (void) { - return GetStdHandle (STD_OUTPUT_HANDLE); + HANDLE res; + MONO_ENTER_GC_SAFE; + res = GetStdHandle (STD_OUTPUT_HANDLE); + MONO_EXIT_GC_SAFE; + return res; } HANDLE mono_w32file_get_console_error (void) { - return GetStdHandle (STD_ERROR_HANDLE); + HANDLE res; + MONO_ENTER_GC_SAFE; + res = GetStdHandle (STD_ERROR_HANDLE); + MONO_EXIT_GC_SAFE; + return res; } gint64 @@ -352,13 +518,21 @@ mono_w32file_get_file_size (gpointer handle, gint32 *error) guint32 mono_w32file_get_drive_type (const gunichar2 *root_path_name) { - return GetDriveType (root_path_name); + guint32 res; + MONO_ENTER_GC_SAFE; + res = GetDriveType (root_path_name); + MONO_EXIT_GC_SAFE; + return res; } gint32 mono_w32file_get_logical_drive (guint32 len, gunichar2 *buf) { - return GetLogicalDriveStrings (len, buf); + gint32 res; + MONO_ENTER_GC_SAFE; + res = GetLogicalDriveStrings (len, buf); + MONO_EXIT_GC_SAFE; + return res; } #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */