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
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.
*/
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
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
*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 ();
/* 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;