Author: robertj
Date: 2008-01-26 09:02:42 -0500 (Sat, 26 Jan 2008)
New Revision: 93987

Modified:
   trunk/mono/mono/metadata/ChangeLog
   trunk/mono/mono/metadata/file-io.c
Log:
2008-01-26  Robert Jordan  <[EMAIL PROTECTED]>

        * file-io.c: Implement and use wrappers for GetFileAttribute|Ex ()
        which resort to FindFirstFile when a certain error condition
        (ERROR_SHARING_VIOLATION) occured. Fixes bug #325212.
        Code is contributed under MIT/X11 license.



Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog  2008-01-26 13:59:39 UTC (rev 93986)
+++ trunk/mono/mono/metadata/ChangeLog  2008-01-26 14:02:42 UTC (rev 93987)
@@ -1,3 +1,10 @@
+2008-01-26  Robert Jordan  <[EMAIL PROTECTED]>
+
+       * file-io.c: Implement and use wrappers for GetFileAttribute|Ex ()
+       which resort to FindFirstFile when a certain error condition
+       (ERROR_SHARING_VIOLATION) occured. Fixes bug #325212.
+       Code is contributed under MIT/X11 license.
+
 2008-01-24  Jonathan Chambers  <[EMAIL PROTECTED]>
 
        * marshal.c (emit_marshal_string): Fix out string marshalling

Modified: trunk/mono/mono/metadata/file-io.c
===================================================================
--- trunk/mono/mono/metadata/file-io.c  2008-01-26 13:59:39 UTC (rev 93986)
+++ trunk/mono/mono/metadata/file-io.c  2008-01-26 14:02:42 UTC (rev 93987)
@@ -207,6 +207,73 @@
        return(attrs);
 }
 
+/*
+ * On Win32, GetFileAttributes|Ex () seems to try opening the file,
+ * which might lead to sharing violation errors, whereas FindFirstFile
+ * always succeeds. These 2 wrappers resort to FindFirstFile if
+ * GetFileAttributes|Ex () has failed.
+ */
+static guint32
+get_file_attributes (const gunichar2 *path)
+{
+       guint32 res;
+       WIN32_FIND_DATA find_data;
+       HANDLE find_handle;
+       gint32 error;
+
+       res = GetFileAttributes (path);
+       if (res != -1)
+               return res;
+
+       error = GetLastError ();
+
+       if (error != ERROR_SHARING_VIOLATION)
+               return res;
+
+       find_handle = FindFirstFile (path, &find_data);
+
+       if (find_handle == INVALID_HANDLE_VALUE)
+               return res;
+
+       FindClose (find_handle);
+
+       return find_data.dwFileAttributes;
+}
+
+static gboolean
+get_file_attributes_ex (const gunichar2 *path, WIN32_FILE_ATTRIBUTE_DATA *data)
+{
+       gboolean res;
+       WIN32_FIND_DATA find_data;
+       HANDLE find_handle;
+       gint32 error;
+
+       res = GetFileAttributesEx (path, GetFileExInfoStandard, data);
+       if (res)
+               return TRUE;
+
+       error = GetLastError ();
+
+       if (error != ERROR_SHARING_VIOLATION)
+               return FALSE;
+
+       find_handle = FindFirstFile (path, &find_data);
+
+       if (find_handle == INVALID_HANDLE_VALUE)
+               return FALSE;
+
+       FindClose (find_handle);
+
+       data->dwFileAttributes = find_data.dwFileAttributes;
+       data->ftCreationTime = find_data.ftCreationTime;
+       data->ftLastAccessTime = find_data.ftLastAccessTime;
+       data->ftLastWriteTime = find_data.ftLastWriteTime;
+       data->nFileSizeHigh = find_data.nFileSizeHigh;
+       data->nFileSizeLow = find_data.nFileSizeLow;
+       
+       return TRUE;
+}
+
 /* System.IO.MonoIO internal calls */
 
 MonoBoolean
@@ -462,7 +529,7 @@
 
        *error=ERROR_SUCCESS;
        
-       ret=GetFileAttributes (mono_string_chars (path));
+       ret=get_file_attributes (mono_string_chars (path));
 
        /* 
         * The definition of INVALID_FILE_ATTRIBUTES in the cygwin win32
@@ -528,7 +595,7 @@
 
        *error=ERROR_SUCCESS;
        
-       result = GetFileAttributesEx (mono_string_chars (path), 
GetFileExInfoStandard, &data);
+       result = get_file_attributes_ex (mono_string_chars (path), &data);
 
        if (result) {
                convert_win32_file_attribute_data (&data,
@@ -580,7 +647,7 @@
 
        /* If we're opening a directory we need to set the extra flag
         */
-       attrs = GetFileAttributes (chars);
+       attrs = get_file_attributes (chars);
        if (attrs != INVALID_FILE_ATTRIBUTES) {
                if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
                        attributes |= FILE_FLAG_BACKUP_SEMANTICS;

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to