[w32file] Push win32 specific error to win32 specific implementation (#5665)
authorLudovic Henry <luhenry@microsoft.com>
Tue, 3 Oct 2017 14:38:09 +0000 (10:38 -0400)
committerGitHub <noreply@github.com>
Tue, 3 Oct 2017 14:38:09 +0000 (10:38 -0400)
ERROR_SHARING_VIOLATION can only happen on win32, so pushing the code to deal with this error to w32file-win32.c file.

mono/metadata/w32file-win32.c
mono/metadata/w32file.c

index a0fbf95003d08d3c0ee12cf5de77a73907982910..6ecb7ff9d5f40c58d05e8c72cff844bb9b1ee634 100644 (file)
@@ -221,34 +221,91 @@ mono_w32file_remove_directory (const gunichar2 *name)
        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)
 {
        guint32 res;
+       guint32 error;
+       HANDLE find_handle;
+       WIN32_FIND_DATA find_data;
+
        MONO_ENTER_GC_SAFE;
        res = GetFileAttributes (name);
        MONO_EXIT_GC_SAFE;
-       return res;
+
+       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;
 
        MONO_ENTER_GC_SAFE;
-       result = GetFileAttributesEx (name, GetFileExInfoStandard, &data);
+       res = GetFileAttributesEx (name, GetFileExInfoStandard, &file_attribute_data);
        MONO_EXIT_GC_SAFE;
-       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;
+       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
index f10ae499645e1afd7093c4ca76c1d731d239a85e..03cac78ac1c8e71d6ca5076b44fe5767a24eeaff 100644 (file)
@@ -172,11 +172,6 @@ static guint32 convert_seekorigin(MonoSeekOrigin origin)
        return(w32origin);
 }
 
-static gint64 convert_filetime (const FILETIME *filetime)
-{
-       return (gint64) ((((guint64) filetime->dwHighDateTime) << 32) + filetime->dwLowDateTime);
-}
-
 /* Managed file attributes have nearly but not quite the same values
  * as the w32 equivalents.
  */
@@ -189,70 +184,6 @@ static guint32 convert_attrs(MonoFileAttributes attrs)
        return(attrs);
 }
 
-/*
- * On Win32, mono_w32file_get_attributes|_ex () seems to try opening the file,
- * which might lead to sharing violation errors, whereas mono_w32file_find_first
- * always succeeds. These 2 wrappers resort to mono_w32file_find_first if
- * mono_w32file_get_attributes|_ex () has failed.
- */
-static guint32
-get_file_attributes (const gunichar2 *path)
-{
-       guint32 res;
-       WIN32_FIND_DATA find_data;
-       HANDLE find_handle;
-       gint32 error;
-
-       res = mono_w32file_get_attributes (path);
-       if (res != -1)
-               return res;
-
-       error = mono_w32error_get_last ();
-
-       if (error != ERROR_SHARING_VIOLATION)
-               return res;
-
-       find_handle = mono_w32file_find_first (path, &find_data);
-
-       if (find_handle == INVALID_HANDLE_VALUE)
-               return res;
-
-       mono_w32file_find_close (find_handle);
-
-       return find_data.dwFileAttributes;
-}
-
-static gboolean
-get_file_attributes_ex (const gunichar2 *path, MonoIOStat *stat)
-{
-       gboolean res;
-       WIN32_FIND_DATA find_data;
-       HANDLE find_handle;
-       gint32 error;
-
-       res = mono_w32file_get_attributes_ex (path, stat);
-       if (res)
-               return TRUE;
-
-       error = mono_w32error_get_last ();
-       if (error != ERROR_SHARING_VIOLATION)
-               return FALSE;
-
-       find_handle = mono_w32file_find_first (path, &find_data);
-
-       if (find_handle == INVALID_HANDLE_VALUE)
-               return FALSE;
-
-       mono_w32file_find_close (find_handle);
-       
-       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;
-}
-
 /* System.IO.MonoIO internal calls */
 
 MonoBoolean
@@ -455,7 +386,7 @@ ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
        gint32 ret;
        *error=ERROR_SUCCESS;
        
-       ret=get_file_attributes (mono_string_chars (path));
+       ret = mono_w32file_get_attributes (mono_string_chars (path));
 
        /* 
         * The definition of INVALID_FILE_ATTRIBUTES in the cygwin win32
@@ -510,7 +441,7 @@ ves_icall_System_IO_MonoIO_GetFileStat (MonoString *path, MonoIOStat *stat, gint
 
        *error=ERROR_SUCCESS;
        
-       result = get_file_attributes_ex (mono_string_chars (path), stat);
+       result = mono_w32file_get_attributes_ex (mono_string_chars (path), stat);
 
        if (!result) {
                *error=mono_w32error_get_last ();
@@ -554,7 +485,7 @@ ves_icall_System_IO_MonoIO_Open (MonoString *filename, gint32 mode,
 
        /* If we're opening a directory we need to set the extra flag
         */
-       attrs = get_file_attributes (chars);
+       attrs = mono_w32file_get_attributes (chars);
        if (attrs != INVALID_FILE_ATTRIBUTES) {
                if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
                        attributes |= FILE_FLAG_BACKUP_SEMANTICS;