示例#1
0
        private static void DeleteHelper(String fullPath, String userPath, bool recursive)
        {
            bool r; 
            int hr;
            Exception ex = null; 
 
            // Do not recursively delete through reparse points.  Perhaps in a
            // future version we will add a new flag to control this behavior, 
            // but for now we're much safer if we err on the conservative side.
            // This applies to symbolic links and mount points.
            // Note the logic to check whether fullPath is a reparse point is
            // in Delete(String, String, bool), and will set "recursive" to false. 
            // Note that Win32's DeleteFile and RemoveDirectory will just delete
            // the reparse point itself. 
 
            if (recursive)
            { 
                Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();

                String searchPath = null;
                if (fullPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) 
                {
                    searchPath = fullPath + "*"; 
                } 
                else
                { 
                    searchPath = fullPath + Path.DirectorySeparatorChar + "*";
                }

                // Open a Find handle 
                using (SafeFindHandle hnd = Win32Native.FindFirstFile(searchPath, data))
                { 
                    if (hnd.IsInvalid) 
                    {
                        hr = Marshal.GetLastWin32Error(); 
                        __Error.WinIOError(hr, userPath);
                    }

                    do 
                    {
                        bool isDir = (0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY)); 
                        if (isDir) 
                        {
                            // Skip ".", "..". 
                            if (data.cFileName.Equals(".") || data.cFileName.Equals(".."))
                                continue;

                            // Recurse for all directories, unless they are 
                            // reparse points.  Do not follow mount points nor
                            // symbolic links, but do delete the reparse point 
                            // itself. 
                            bool shouldRecurse = (0 == (data.dwFileAttributes & (int)FileAttributes.ReparsePoint));
                            if (shouldRecurse) 
                            {
                                String newFullPath = LongPath.InternalCombine(fullPath, data.cFileName);
                                String newUserPath = LongPath.InternalCombine(userPath, data.cFileName);
                                try 
                                {
                                    DeleteHelper(newFullPath, newUserPath, recursive); 
                                } 
                                catch (Exception e)
                                { 
                                    if (ex == null)
                                    {
                                        ex = e;
                                    } 
                                }
                            } 
                            else 
                            {
                                // Check to see if this is a mount point, and 
                                // unmount it.
                                if (data.dwReserved0 == Win32Native.IO_REPARSE_TAG_MOUNT_POINT)
                                {
                                    // Use full path plus a trailing '\' 
                                    String mountPoint = LongPath.InternalCombine(fullPath, data.cFileName + Path.DirectorySeparatorChar);
                                    r = Win32Native.DeleteVolumeMountPoint(mountPoint); 
                                    if (!r) 
                                    {
                                        hr = Marshal.GetLastWin32Error(); 
                                        try
                                        {
                                            __Error.WinIOError(hr, data.cFileName);
                                        } 
                                        catch (Exception e)
                                        { 
                                            if (ex == null) 
                                            {
                                                ex = e; 
                                            }
                                        }
                                    }
                                } 

                                // RemoveDirectory on a symbolic link will 
                                // remove the link itself. 
                                String reparsePoint = LongPath.InternalCombine(fullPath, data.cFileName);
                                r = Win32Native.RemoveDirectory(reparsePoint); 
                                if (!r)
                                {
                                    hr = Marshal.GetLastWin32Error();
                                    try 
                                    {
                                        __Error.WinIOError(hr, data.cFileName); 
                                    } 
                                    catch (Exception e)
                                    { 
                                        if (ex == null)
                                        {
                                            ex = e;
                                        } 
                                    }
                                } 
                            } 
                        }
                        else 
                        {
                            String fileName = LongPath.InternalCombine(fullPath, data.cFileName);
                            r = Win32Native.DeleteFile(fileName);
                            if (!r) 
                            {
                                hr = Marshal.GetLastWin32Error(); 
                                try 
                                {
                                    __Error.WinIOError(hr, data.cFileName); 
                                }
                                catch (Exception e)
                                {
                                    if (ex == null) 
                                    {
                                        ex = e; 
                                    } 
                                }
                            } 
                        }
                    } while (Win32Native.FindNextFile(hnd, data));
                    // Make sure we quit with a sensible error.
                    hr = Marshal.GetLastWin32Error(); 
                }
 
                if (ex != null) 
                    throw ex;
                if (hr != 0 && hr != Win32Native.ERROR_NO_MORE_FILES) 
                    __Error.WinIOError(hr, userPath);
            }

            r = Win32Native.RemoveDirectory(fullPath); 

            if (!r) 
            { 
                hr = Marshal.GetLastWin32Error();
                if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // A dubious error code. 
                    hr = Win32Native.ERROR_PATH_NOT_FOUND;
                // This check was originally put in for Win9x (unfortunately without special casing it to be for Win9x only). We can't change the NT codepath now for backcomp reasons.
                if (hr == Win32Native.ERROR_ACCESS_DENIED)
                    throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", userPath)); 
                __Error.WinIOError(hr, userPath);
            } 
        } 
示例#2
0
文件: File.cs 项目: uonun/coreclr
        // 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);
        }
示例#3
0
        internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain)
        {
            int dataInitialised = 0;

            if (Environment.OSInfo == Environment.OSName.Win95 || tryagain)
            // We are running under Windows 95 and we don't have GetFileAttributesEx API or someone has a handle to the file open
            {
                Win32Native.WIN32_FIND_DATA win95data; // We do this only on Win95 machines
                win95data = 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 });

                // 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.
                // SetErrorMode will let us disable this, but we should set the error
                // mode back, since this may have wide-ranging effects.
                int    oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
                IntPtr handle  = Win32Native.FindFirstFile(tempPath, win95data);
                Win32Native.SetErrorMode(oldMode);
                if (handle == Win32Native.INVALID_HANDLE_VALUE)
                {
                    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
                    {
                        data.fileAttributes = -1;
                        dataInitialised     = 0;
                    }

                    return(dataInitialised);
                }
                // Close the Win32 handle
                bool r = Win32Native.FindClose(handle);
                if (!r)
                {
                    BCLDebug.Assert(false, "File::FillAttributeInfo - FindClose failed!");
                    __Error.WinIOError();
                }

                // Copy the information to data
                data.fileAttributes       = win95data.dwFileAttributes;
                data.ftCreationTimeLow    = (uint)win95data.ftCreationTime_dwLowDateTime;
                data.ftCreationTimeHigh   = (uint)win95data.ftCreationTime_dwHighDateTime;
                data.ftLastAccessTimeLow  = (uint)win95data.ftLastAccessTime_dwLowDateTime;
                data.ftLastAccessTimeHigh = (uint)win95data.ftLastAccessTime_dwHighDateTime;
                data.ftLastWriteTimeLow   = (uint)win95data.ftLastWriteTime_dwLowDateTime;
                data.ftLastWriteTimeHigh  = (uint)win95data.ftLastWriteTime_dwHighDateTime;
                data.fileSizeHigh         = win95data.nFileSizeHigh;
                data.fileSizeLow          = win95data.nFileSizeLow;
            }
            else
            {
                // 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.
                // SetErrorMode will let us disable this, but we should set the error
                // mode back, since this may have wide-ranging effects.
                int  oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
                bool success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data);

                Win32Native.SetErrorMode(oldMode);
                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
                    {
                        data.fileAttributes = -1;
                        dataInitialised     = 0;
                    }
                    else
                    {
                        // In case someone latched onto the file. Take the perf hit only for failure
                        return(FillAttributeInfo(path, ref data, true));
                    }
                }
            }

            return(dataInitialised);
        }
示例#4
0
        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 win95data; // We do this only on Win95 machines
                win95data =  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});

                // 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.
                // SetErrorMode will let us disable this, but we should set the error
                // mode back, since this may have wide-ranging effects.
                int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
                try {
                    bool error = false;
                    SafeFindHandle handle = Win32Native.FindFirstFile(tempPath,win95data);
                    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 compbatibility
                                    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) {
                                BCLDebug.Assert(false, "File::FillAttributeInfo - FindClose failed!");
                                __Error.WinIOError();
                            }
                        }
                    }
                }
                finally {
                    Win32Native.SetErrorMode(oldMode);
                }

                // Copy the information to data
                data.fileAttributes = win95data.dwFileAttributes; 
                data.ftCreationTimeLow = (uint)win95data.ftCreationTime_dwLowDateTime; 
                data.ftCreationTimeHigh = (uint)win95data.ftCreationTime_dwHighDateTime; 
                data.ftLastAccessTimeLow = (uint)win95data.ftLastAccessTime_dwLowDateTime; 
                data.ftLastAccessTimeHigh = (uint)win95data.ftLastAccessTime_dwHighDateTime; 
                data.ftLastWriteTimeLow = (uint)win95data.ftLastWriteTime_dwLowDateTime; 
                data.ftLastWriteTimeHigh = (uint)win95data.ftLastWriteTime_dwHighDateTime; 
                data.fileSizeHigh = win95data.nFileSizeHigh; 
                data.fileSizeLow = win95data.nFileSizeLow; 
            }
            else
            {   
                                  
                 // 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.
                // SetErrorMode will let us disable this, but we should set the error
                // mode back, since this may have wide-ranging effects.
                bool success = false;
                int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
                try {
                    success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data);
                }
                finally {
                    Win32Native.SetErrorMode(oldMode);
                }

                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;
        }
        private static void DeleteHelper(String fullPath, String userPath, bool recursive, bool throwOnTopLevelDirectoryNotFound)
        {
            bool      r;
            int       hr;
            Exception ex = null;

            // Do not recursively delete through reparse points.  Perhaps in a
            // future version we will add a new flag to control this behavior,
            // but for now we're much safer if we err on the conservative side.
            // This applies to symbolic links and mount points.
            // Note the logic to check whether fullPath is a reparse point is
            // in Delete(String, String, bool), and will set "recursive" to false.
            // Note that Win32's DeleteFile and RemoveDirectory will just delete
            // the reparse point itself.

            if (recursive)
            {
                Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();

                String searchPath = null;
                if (fullPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
                {
                    searchPath = fullPath + "*";
                }
                else
                {
                    searchPath = fullPath + Path.DirectorySeparatorChar + "*";
                }

                // Open a Find handle
                using (SafeFindHandle hnd = Win32Native.FindFirstFile(searchPath, data))
                {
                    if (hnd.IsInvalid)
                    {
                        hr = Marshal.GetLastWin32Error();
                        __Error.WinIOError(hr, userPath);
                    }

                    do
                    {
                        bool isDir = (0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
                        if (isDir)
                        {
                            // Skip ".", "..".
                            if (data.cFileName.Equals(".") || data.cFileName.Equals(".."))
                            {
                                continue;
                            }

                            // Recurse for all directories, unless they are
                            // reparse points.  Do not follow mount points nor
                            // symbolic links, but do delete the reparse point
                            // itself.
                            bool shouldRecurse = (0 == (data.dwFileAttributes & (int)FileAttributes.ReparsePoint));
                            if (shouldRecurse)
                            {
                                String newFullPath = LongPath.InternalCombine(fullPath, data.cFileName);
                                String newUserPath = LongPath.InternalCombine(userPath, data.cFileName);
                                try
                                {
                                    DeleteHelper(newFullPath, newUserPath, recursive, false);
                                }
                                catch (Exception e)
                                {
                                    if (ex == null)
                                    {
                                        ex = e;
                                    }
                                }
                            }
                            else
                            {
                                // Check to see if this is a mount point, and
                                // unmount it.
                                if (data.dwReserved0 == Win32Native.IO_REPARSE_TAG_MOUNT_POINT)
                                {
                                    // Use full path plus a trailing '\'
                                    String mountPoint = LongPath.InternalCombine(fullPath, data.cFileName + Path.DirectorySeparatorChar);
                                    r = Win32Native.DeleteVolumeMountPoint(mountPoint);
                                    if (!r)
                                    {
                                        hr = Marshal.GetLastWin32Error();
                                        if (hr != Win32Native.ERROR_PATH_NOT_FOUND)
                                        {
                                            try
                                            {
                                                __Error.WinIOError(hr, data.cFileName);
                                            }
                                            catch (Exception e)
                                            {
                                                if (ex == null)
                                                {
                                                    ex = e;
                                                }
                                            }
                                        }
                                    }
                                }

                                // RemoveDirectory on a symbolic link will
                                // remove the link itself.
                                String reparsePoint = LongPath.InternalCombine(fullPath, data.cFileName);
                                r = Win32Native.RemoveDirectory(reparsePoint);
                                if (!r)
                                {
                                    hr = Marshal.GetLastWin32Error();
                                    if (hr != Win32Native.ERROR_PATH_NOT_FOUND)
                                    {
                                        try
                                        {
                                            __Error.WinIOError(hr, data.cFileName);
                                        }
                                        catch (Exception e)
                                        {
                                            if (ex == null)
                                            {
                                                ex = e;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            String fileName = LongPath.InternalCombine(fullPath, data.cFileName);
                            r = Win32Native.DeleteFile(fileName);
                            if (!r)
                            {
                                hr = Marshal.GetLastWin32Error();
                                if (hr != Win32Native.ERROR_FILE_NOT_FOUND)
                                {
                                    try
                                    {
                                        __Error.WinIOError(hr, data.cFileName);
                                    }
                                    catch (Exception e)
                                    {
                                        if (ex == null)
                                        {
                                            ex = e;
                                        }
                                    }
                                }
                            }
                        }
                    } while (Win32Native.FindNextFile(hnd, data));
                    // Make sure we quit with a sensible error.
                    hr = Marshal.GetLastWin32Error();
                }

                if (ex != null)
                {
                    throw ex;
                }
                if (hr != 0 && hr != Win32Native.ERROR_NO_MORE_FILES)
                {
                    __Error.WinIOError(hr, userPath);
                }
            }

            r = Win32Native.RemoveDirectory(fullPath);

            if (!r)
            {
                hr = Marshal.GetLastWin32Error();
                if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // A dubious error code.
                {
                    hr = Win32Native.ERROR_PATH_NOT_FOUND;
                }
                // This check was originally put in for Win9x (unfortunately without special casing it to be for Win9x only). We can't change the NT codepath now for backcomp reasons.
                if (hr == Win32Native.ERROR_ACCESS_DENIED)
                {
                    throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", userPath));
                }

                // don't throw the DirectoryNotFoundException since this is a subdir and there could be a ----
                // between two Directory.Delete callers
                if (hr == Win32Native.ERROR_PATH_NOT_FOUND && !throwOnTopLevelDirectoryNotFound)
                {
                    return;
                }

                __Error.WinIOError(hr, userPath);
            }
        }
示例#6
0
文件: file.cs 项目: ArildF/masters
        internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data ,bool tryagain)
        {
            int dataInitialised = 0;
            if (tryagain) // someone has a handle to the file open, or other error
            {
                Win32Native.WIN32_FIND_DATA win95data;
                win95data =  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});

                // 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.
                // SetErrorMode will let us disable this, but we should set the error
                // mode back, since this may have wide-ranging effects.
                int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
                IntPtr handle = Win32Native.FindFirstFile(tempPath,win95data);
                Win32Native.SetErrorMode(oldMode);
                if (handle == Win32Native.INVALID_HANDLE_VALUE) {
                    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
                        {
                            data.fileAttributes = -1;
                            dataInitialised = 0;
                        }

                    return dataInitialised;
                }
                // Close the Win32 handle
                Win32Native.FindClose(handle);

                // Copy the information to data
                data.fileAttributes = win95data.dwFileAttributes;
                data.ftCreationTimeLow = (uint)win95data.ftCreationTime_dwLowDateTime;
                data.ftCreationTimeHigh = (uint)win95data.ftCreationTime_dwHighDateTime;
                data.ftLastAccessTimeLow = (uint)win95data.ftLastAccessTime_dwLowDateTime;
                data.ftLastAccessTimeHigh = (uint)win95data.ftLastAccessTime_dwHighDateTime;
                data.ftLastWriteTimeLow = (uint)win95data.ftLastWriteTime_dwLowDateTime;
                data.ftLastWriteTimeHigh = (uint)win95data.ftLastWriteTime_dwHighDateTime;
                data.fileSizeHigh = win95data.nFileSizeHigh;
                data.fileSizeLow = win95data.nFileSizeLow;
            }
            else
            {

                 // 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.
                // SetErrorMode will let us disable this, but we should set the error
                // mode back, since this may have wide-ranging effects.
                int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
                bool success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data);

                Win32Native.SetErrorMode(oldMode);
                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
                    {
                        data.fileAttributes = -1;
                        dataInitialised = 0;
                    }
                    else
                    {
                     // In case someone latched onto the file. Take the perf hit only for failure
                        return FillAttributeInfo(path,ref data,true);
                    }
                }
            }

            return dataInitialised;
        }
示例#7
0
        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 win95data; // We do this only on Win95 machines
                win95data = 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 });

                // 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.
                // SetErrorMode will let us disable this, but we should set the error
                // mode back, since this may have wide-ranging effects.
                int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
                try {
                    bool           error  = false;
                    SafeFindHandle handle = Win32Native.FindFirstFile(tempPath, win95data);
                    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 compbatibility
                                    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)
                            {
                                BCLDebug.Assert(false, "File::FillAttributeInfo - FindClose failed!");
                                __Error.WinIOError();
                            }
                        }
                    }
                }
                finally {
                    Win32Native.SetErrorMode(oldMode);
                }

                // Copy the information to data
                data.fileAttributes       = win95data.dwFileAttributes;
                data.ftCreationTimeLow    = (uint)win95data.ftCreationTime_dwLowDateTime;
                data.ftCreationTimeHigh   = (uint)win95data.ftCreationTime_dwHighDateTime;
                data.ftLastAccessTimeLow  = (uint)win95data.ftLastAccessTime_dwLowDateTime;
                data.ftLastAccessTimeHigh = (uint)win95data.ftLastAccessTime_dwHighDateTime;
                data.ftLastWriteTimeLow   = (uint)win95data.ftLastWriteTime_dwLowDateTime;
                data.ftLastWriteTimeHigh  = (uint)win95data.ftLastWriteTime_dwHighDateTime;
                data.fileSizeHigh         = win95data.nFileSizeHigh;
                data.fileSizeLow          = win95data.nFileSizeLow;
            }
            else
            {
                // 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.
                // SetErrorMode will let us disable this, but we should set the error
                // mode back, since this may have wide-ranging effects.
                bool success = false;
                int  oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
                try {
                    success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data);
                }
                finally {
                    Win32Native.SetErrorMode(oldMode);
                }

                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);
        }