X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Ffile-io.c;h=ff67e997f05b4b633775601e9450477a4091854f;hb=a5f3c441eef82a7e0e38bbe30e3b5577eebcaf77;hp=8e250b72624d95a259e95ad5da3e17f8921be9e5;hpb=5a5b001f5464e10ce8f49b96db6a54efab0d174c;p=mono.git diff --git a/mono/metadata/file-io.c b/mono/metadata/file-io.c index 8e250b72624..ff67e997f05 100644 --- a/mono/metadata/file-io.c +++ b/mono/metadata/file-io.c @@ -5,8 +5,8 @@ * Dick Porter (dick@ximian.com) * Gonzalo Paniagua Javier (gonzalo@ximian.com) * - * (C) 2001,2002,2003 Ximian, Inc. - * Copyright (c) 2004,2005,2006 Novell, Inc. (http://www.novell.com) + * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) + * Copyright 2004-2009 Novell, Inc (http://www.novell.com) */ #include @@ -14,7 +14,6 @@ #include #include #include -#include #ifdef HAVE_UNISTD_H #include #endif @@ -188,7 +187,7 @@ static void convert_win32_file_attribute_data (const WIN32_FILE_ATTRIBUTE_DATA * while (name [len]) ++ len; - stat->name = mono_string_new_utf16 (mono_domain_get (), name, len); + MONO_STRUCT_SETREF (stat, name, mono_string_new_utf16 (mono_domain_get (), name, len)); } /* Managed file attributes have nearly but not quite the same values @@ -345,8 +344,8 @@ ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path, return(NULL); } + utf8_path = mono_string_to_utf8 (path); /*If this raises there is not memory to release*/ names = g_ptr_array_new (); - utf8_path = mono_string_to_utf8 (path); do { if ((data.cFileName[0] == '.' && data.cFileName[1] == 0) || @@ -386,22 +385,139 @@ ves_icall_System_IO_MonoIO_GetFileSystemEntries (MonoString *path, return result; } +typedef struct { + MonoDomain *domain; + gchar *utf8_path; + HANDLE find_handle; +} IncrementalFind; + +static gboolean +incremental_find_check_match (IncrementalFind *handle, WIN32_FIND_DATA *data, MonoString **result) +{ + gchar *utf8_result; + gchar *full_name; + + if ((data->cFileName[0] == '.' && data->cFileName[1] == 0) || (data->cFileName[0] == '.' && data->cFileName[1] == '.' && data->cFileName[2] == 0)) + return FALSE; + + utf8_result = g_utf16_to_utf8 (data->cFileName, -1, NULL, NULL, NULL); + if (utf8_result == NULL) + return FALSE; + + full_name = g_build_filename (handle->utf8_path, utf8_result, NULL); + g_free (utf8_result); + *result = mono_string_new (mono_domain_get (), full_name); + g_free (full_name); + + return TRUE; +} + +MonoString * +ves_icall_System_IO_MonoIO_FindFirst (MonoString *path, + MonoString *path_with_pattern, + gint32 *result_attr, gint32 *error, + gpointer *handle) +{ + WIN32_FIND_DATA data; + HANDLE find_handle; + IncrementalFind *ifh; + MonoString *result; + + *error = ERROR_SUCCESS; + + find_handle = FindFirstFile (mono_string_chars (path_with_pattern), &data); + + if (find_handle == INVALID_HANDLE_VALUE) { + gint32 find_error = GetLastError (); + *handle = NULL; + + if (find_error == ERROR_FILE_NOT_FOUND) + return NULL; + + *error = find_error; + return NULL; + } + + ifh = g_new (IncrementalFind, 1); + ifh->find_handle = find_handle; + ifh->utf8_path = mono_string_to_utf8 (path); + ifh->domain = mono_domain_get (); + *handle = ifh; + + while (incremental_find_check_match (ifh, &data, &result) == 0){ + if (FindNextFile (find_handle, &data) == FALSE){ + int e = GetLastError (); + if (e != ERROR_NO_MORE_FILES) + *error = e; + return NULL; + } + } + *result_attr = data.dwFileAttributes; + + return result; +} + +MonoString * +ves_icall_System_IO_MonoIO_FindNext (gpointer handle, gint32 *result_attr, gint32 *error) +{ + IncrementalFind *ifh = handle; + WIN32_FIND_DATA data; + MonoString *result; + + error = ERROR_SUCCESS; + do { + if (FindNextFile (ifh->find_handle, &data) == FALSE){ + int e = GetLastError (); + if (e != ERROR_NO_MORE_FILES) + *error = e; + return NULL; + } + } while (incremental_find_check_match (ifh, &data, &result) == 0); + + *result_attr = data.dwFileAttributes; + return result; +} + +int +ves_icall_System_IO_MonoIO_FindClose (gpointer handle) +{ + IncrementalFind *ifh = handle; + gint32 error; + + if (FindClose (ifh->find_handle) == FALSE){ + error = GetLastError (); + } else + error = ERROR_SUCCESS; + g_free (ifh->utf8_path); + g_free (ifh); + + return error; +} + MonoString * ves_icall_System_IO_MonoIO_GetCurrentDirectory (gint32 *error) { MonoString *result; gunichar2 *buf; - int len; + int len, res_len; MONO_ARCH_SAVE_REGS; - len = MAX_PATH + 1; + len = MAX_PATH + 1; /*FIXME this is too smal under most unix systems.*/ buf = g_new (gunichar2, len); *error=ERROR_SUCCESS; result = NULL; - if (GetCurrentDirectory (len, buf) > 0) { + res_len = GetCurrentDirectory (len, buf); + if (res_len > len) { /*buf is too small.*/ + int old_res_len = res_len; + g_free (buf); + buf = g_new (gunichar2, res_len); + res_len = GetCurrentDirectory (res_len, buf) == old_res_len; + } + + if (res_len) { len = 0; while (buf [len]) ++ len; @@ -742,7 +858,7 @@ ves_icall_System_IO_MonoIO_Seek (HANDLE handle, gint64 offset, gint32 origin, *error=ERROR_SUCCESS; offset_hi = offset >> 32; - offset = SetFilePointer (handle, offset & 0xFFFFFFFF, &offset_hi, + offset = SetFilePointer (handle, (gint32) (offset & 0xFFFFFFFF), &offset_hi, convert_seekorigin (origin)); if(offset==INVALID_SET_FILE_POINTER) { @@ -920,10 +1036,28 @@ ves_icall_System_IO_MonoIO_CreatePipe (HANDLE *read_handle, return(TRUE); } +MonoBoolean ves_icall_System_IO_MonoIO_DuplicateHandle (HANDLE source_process_handle, + HANDLE source_handle, HANDLE target_process_handle, HANDLE *target_handle, + gint32 access, gint32 inherit, gint32 options) +{ + /* This is only used on Windows */ + gboolean ret; + + MONO_ARCH_SAVE_REGS; + + ret=DuplicateHandle (source_process_handle, source_handle, target_process_handle, target_handle, access, inherit, options); + if(ret==FALSE) { + /* FIXME: throw an exception? */ + return(FALSE); + } + + return(TRUE); +} + gunichar2 ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar () { -#if defined (PLATFORM_WIN32) +#if defined (TARGET_WIN32) return (gunichar2) ':'; /* colon */ #else return (gunichar2) '/'; /* forward slash */ @@ -933,7 +1067,7 @@ ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar () gunichar2 ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar () { -#if defined (PLATFORM_WIN32) +#if defined (TARGET_WIN32) return (gunichar2) '\\'; /* backslash */ #else return (gunichar2) '/'; /* forward slash */ @@ -943,7 +1077,7 @@ ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar () gunichar2 ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar () { -#if defined (PLATFORM_WIN32) +#if defined (TARGET_WIN32) return (gunichar2) '/'; /* forward slash */ #else return (gunichar2) '/'; /* slash, same as DirectorySeparatorChar */ @@ -953,7 +1087,7 @@ ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar () gunichar2 ves_icall_System_IO_MonoIO_get_PathSeparator () { -#if defined (PLATFORM_WIN32) +#if defined (TARGET_WIN32) return (gunichar2) ';'; /* semicolon */ #else return (gunichar2) ':'; /* colon */ @@ -962,7 +1096,7 @@ ves_icall_System_IO_MonoIO_get_PathSeparator () static const gunichar2 invalid_path_chars [] = { -#if defined (PLATFORM_WIN32) +#if defined (TARGET_WIN32) 0x0022, /* double quote, which seems allowed in MS.NET but should be rejected */ 0x003c, /* less than */ 0x003e, /* greater than */ @@ -1018,12 +1152,11 @@ ves_icall_System_IO_MonoIO_GetTempPath (MonoString **mono_name) if(ret>0) { #ifdef DEBUG - g_message (G_GNUC_PRETTY_FUNCTION - ": Temp path is [%s] (len %d)", name, ret); + g_message ("%s: Temp path is [%s] (len %d)", __func__, name, ret); #endif - *mono_name=mono_string_new_utf16 (mono_domain_get (), name, - ret); + mono_gc_wbarrier_generic_store ((gpointer) mono_name, + (MonoObject*) mono_string_new_utf16 (mono_domain_get (), name, ret)); } g_free (name);