Ejemplo n.º 1
0
        // Returns 0 on success, otherwise a Win32 error code.  Note that
        // classes should use -1 as the uninitialized state for dataInitialized.
        internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound)
        {
            int dataInitialised = 0;

            if (tryagain) // someone has a handle to the file open, or other error
            {
                Win32Native.WIN32_FIND_DATA findData;
                findData = new Win32Native.WIN32_FIND_DATA();

                // Remove trialing slash since this can cause grief to FindFirstFile. You will get an invalid argument error
                String tempPath = path.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });

#if !PLATFORM_UNIX
                // For floppy drives, normally the OS will pop up a dialog saying
                // there is no disk in drive A:, please insert one.  We don't want that.
                // SetThreadErrorMode will let us disable this, but we should set the error
                // mode back, since this may have wide-ranging effects.
                uint oldMode;
                bool errorModeSuccess = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode);
                try
                {
#endif
                bool error            = false;
                SafeFindHandle handle = Win32Native.FindFirstFile(tempPath, findData);
                try
                {
                    if (handle.IsInvalid)
                    {
                        error           = true;
                        dataInitialised = Marshal.GetLastWin32Error();

                        if (dataInitialised == Win32Native.ERROR_FILE_NOT_FOUND ||
                            dataInitialised == Win32Native.ERROR_PATH_NOT_FOUND ||
                            dataInitialised == Win32Native.ERROR_NOT_READY)      // floppy device not ready
                        {
                            if (!returnErrorOnNotFound)
                            {
                                // Return default value for backward compatibility
                                dataInitialised     = 0;
                                data.fileAttributes = -1;
                            }
                        }
                        return(dataInitialised);
                    }
                }
                finally
                {
                    // Close the Win32 handle
                    try
                    {
                        handle.Close();
                    }
                    catch
                    {
                        // if we're already returning an error, don't throw another one.
                        if (!error)
                        {
                            Debug.Assert(false, "File::FillAttributeInfo - FindClose failed!");
                            throw Win32Marshal.GetExceptionForLastWin32Error();
                        }
                    }
                }
#if !PLATFORM_UNIX
            }
            finally
            {
                if (errorModeSuccess)
                {
                    Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode);
                }
            }
#endif

                // Copy the information to data
                data.PopulateFrom(findData);
            }
            else
            {
                bool success = false;

#if !PLATFORM_UNIX
                // For floppy drives, normally the OS will pop up a dialog saying
                // there is no disk in drive A:, please insert one.  We don't want that.
                // SetThreadErrorMode will let us disable this, but we should set the error
                // mode back, since this may have wide-ranging effects.
                uint oldMode;
                bool errorModeSuccess = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode);
                try
                {
#endif
                success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data);
#if !PLATFORM_UNIX
            }
            finally
            {
                if (errorModeSuccess)
                {
                    Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode);
                }
            }
#endif

                if (!success)
                {
                    dataInitialised = Marshal.GetLastWin32Error();
                    if (dataInitialised != Win32Native.ERROR_FILE_NOT_FOUND &&
                        dataInitialised != Win32Native.ERROR_PATH_NOT_FOUND &&
                        dataInitialised != Win32Native.ERROR_NOT_READY)  // floppy device not ready
                    {
                        // In case someone latched onto the file. Take the perf hit only for failure
                        return(FillAttributeInfo(path, ref data, true, returnErrorOnNotFound));
                    }
                    else
                    {
                        if (!returnErrorOnNotFound)
                        {
                            // Return default value for backward compbatibility
                            dataInitialised     = 0;
                            data.fileAttributes = -1;
                        }
                    }
                }
            }

            return(dataInitialised);
        }