Exemple #1
0
        [System.Security.SecurityCritical]  // auto-generated
        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();
                
                // Open a Find handle
                using (SafeFindHandle hnd = Win32Native.FindFirstFile(fullPath+Path.DirectorySeparatorCharAsString+"*", data)) {
                    if (hnd.IsInvalid) {
                        hr = Marshal.GetLastWin32Error();
                        __Error.WinIOError(hr, fullPath);
                    }
        
                    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 = Path.InternalCombine(fullPath, data.cFileName);
                                String newUserPath = Path.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 = Path.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 = Path.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 = Path.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 race condition
                // between two Directory.Delete callers
                if (hr == Win32Native.ERROR_PATH_NOT_FOUND && !throwOnTopLevelDirectoryNotFound)
                    return;  

                __Error.WinIOError(hr, fullPath);
            }
        }
Exemple #2
0
 internal static extern SafeFindHandle FindFirstFile(String fileName, [In, Out] Win32Native.WIN32_FIND_DATA data);
Exemple #3
0
        /// <include file='doc\Directory.uex' path='docs/doc[@for="Directory.Delete1"]/*' />
        public static void Delete(String path, bool recursive)
        {
            String fullPath = Path.GetFullPathInternal(path);
            String demandPath;
            if (!recursive) { // Do normal check only on this directory
                if (fullPath.EndsWith( Path.DirectorySeparatorChar ))
                    demandPath = fullPath + ".";
                else
                    demandPath = fullPath + Path.DirectorySeparatorChar + ".";
            }
            else { // Check for deny anywhere below and fail
                if (fullPath.EndsWith( Path.DirectorySeparatorChar ))
                    demandPath = fullPath.Substring(0,fullPath.Length - 1);
                else
                    demandPath = fullPath;
            }

            // Make sure we have write permission to this directory
            new FileIOPermission(FileIOPermissionAccess.Write, new String[] { demandPath }, false, false ).Demand();

            bool r;
            int hr;
            Exception ex = null;

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

                // Open a Find handle (Win32 is weird)
                IntPtr hnd = Win32Native.FindFirstFile(fullPath+Path.DirectorySeparatorChar+"*", data);
                if (hnd==Win32Native.INVALID_HANDLE_VALUE) {
                    hr = Marshal.GetLastWin32Error();
                    __Error.WinIOError(hr, path);
                }

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

                        // recurse
                        DirectoryInfo d = new DirectoryInfo(Path.InternalCombine(fullPath, data.cFileName), false);
                        try {
                            d.Delete(true);
                        }
                        catch(Exception e) {
                            if (ex == null) {
                                ex = e;
                            }
                        }
                    }
                    else {
                        String fileName = path + Path.DirectorySeparatorChar + 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();
                Win32Native.FindClose(hnd);  // Close Find handle in all cases.
                if (ex != null)
                    throw ex;
                if (hr!=0 && hr!=Win32Native.ERROR_NO_MORE_FILES) __Error.WinIOError(hr, path);
            }

            r = Win32Native.RemoveDirectory(fullPath);
            hr = Marshal.GetLastWin32Error();
            if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // Win32 is weird, it gives back a file not found
                hr = Win32Native.ERROR_PATH_NOT_FOUND;
            if (hr == Win32Native.ERROR_ACCESS_DENIED) // WinNT throws IOException. Win9x hack to do the same.
                throw new IOException(String.Format(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path"), path));

            if (!r) __Error.WinIOError(hr, path);
        }
        // From IO.Directory class (make that internal if possible)
    	private static String[] GetFileDirectoryNames(String path, String msg, bool file)
    	{
    		int hr;

    		if (path==null) throw new ArgumentNullException("path", Environment.GetResourceString("ArgumentNull_Path"));
    		
            bool fEndsWithDirectory = false;
    		char lastChar = path[path.Length-1];
    		if (lastChar == Path.DirectorySeparatorChar || 
                lastChar == Path.AltDirectorySeparatorChar || 
                lastChar == '.')
                fEndsWithDirectory = true;
    			

    		// Get an absolute path and do a security check
    		String fullPath = Path.GetFullPathInternal(path);

            // GetFullPath() removes '\', "\." etc from path, we will restore 
            // it here. If path ends in a trailing slash (\), append a * 
            // or we'll  get a "Cannot find the file specified" exception
            if ((fEndsWithDirectory) && 
                (fullPath[fullPath.Length - 1] != lastChar))
               fullPath += "\\*";

    		// Check for read permission to the directory, not to the contents.
    		String dir = Path.GetDirectoryName(fullPath);

            if (dir != null)
                dir += "\\";
    
#if _DEBUG
            if (s_fDebug)
            {
                Console.WriteLine("path = " + path);
                Console.WriteLine("fullPath = " + fullPath);
                Console.WriteLine("dir = " + dir);
            }
#endif

            new FileIOPermission(FileIOPermissionAccess.Read, dir == null ? fullPath : dir).Demand();
    		
    
            String[] list = new String[10];
            int listSize = 0;
    		Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
    				
    		// Open a Find handle (Win32 is weird)
    		IntPtr hnd = Win32Native.FindFirstFile(fullPath, data);
    		if (hnd==Win32Native.INVALID_HANDLE_VALUE) {
    			// Calls to GetLastWin32Error clobber HResult.  Store HResult.
    			hr = Marshal.GetLastWin32Error();
    			if (hr==Win32Native.ERROR_FILE_NOT_FOUND)
    				return new String[0];
    			__Error.WinIOError(hr, msg);
    		}
    
    		// Keep asking for more matching files, adding file names to list
    		int numEntries = 0;  // Number of directory entities we see.
    		do {
                bool includeThis;  // Should this file/directory be included in the output?
    			if (file)
    				includeThis = (0==(data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
    			else {
    				includeThis = (0!=(data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
                    // Don't add "." nor ".."
                    if (includeThis && (data.cFileName.Equals(".") || data.cFileName.Equals(".."))) 
                        includeThis = false;
                }
    			
    			if (includeThis) {
    				numEntries++;
    				if (listSize==list.Length) {
    					String[] newList = new String[list.Length*2];
    	                Array.Copy(list, 0, newList, 0, listSize);
    		            list = newList;
    			    }
    				list[listSize++] = data.cFileName;
    			}
     
    		} while (Win32Native.FindNextFile(hnd, data));
    		
    		// Make sure we quit with a sensible error.
    		hr = Marshal.GetLastWin32Error();
    		Win32Native.FindClose(hnd);  // Close Find handle in all cases.
    		if (hr!=0 && hr!=Win32Native.ERROR_NO_MORE_FILES) __Error.WinIOError(hr, msg);
    		
    		// Check for a string such as "C:\tmp", in which case we return
    		// just the directory name.  FindNextFile fails first time, and
    		// data still contains a directory.
    		if (!file && numEntries==1 && (0!=(data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY))) {
    			String[] sa = new String[1];
    			sa[0] = data.cFileName;
    			return sa;
    		}
    		
    		// Return list of files/directories as an array of strings
            if (listSize == list.Length)
                return list;
    		String[] items = new String[listSize];
            Array.Copy(list, 0, items, 0, listSize);
    		return items;
    	}
        [System.Security.SecurityCritical] // auto-generated
        #endif
        private static String[] GetFileDirectoryNames(String path, String msg, bool file, IsolatedStorageFile isf) {
            int hr;

            if(path == null) throw new ArgumentNullException("path", Environment.GetResourceString("ArgumentNull_Path"));
            Contract.EndContractBlock();

            bool fEndsWithDirectory = false;
            char lastChar = path[path.Length - 1];
            if(lastChar == Path.DirectorySeparatorChar ||
                lastChar == Path.AltDirectorySeparatorChar ||
                lastChar == '.')
                fEndsWithDirectory = true;


            // Get an absolute path and do a security check
            String fullPath = Path.GetFullPathInternal(path);

            // GetFullPath() removes '\', "\." etc from path, we will restore 
            // it here. If path ends in a trailing slash (\), append a * 
            // or we'll  get a "Cannot find the file specified" exception
            if((fEndsWithDirectory) &&
                (fullPath[fullPath.Length - 1] != lastChar))
                fullPath += "\\*";

            // Check for read permission to the directory, not to the contents.
            String dir = Path.GetDirectoryName(fullPath);

            if(dir != null)
                dir += "\\";

            if(isf != null) {
                try {
                    isf.Demand(dir == null ? fullPath : dir);
                } catch (Exception e) {
                    throw GetIsolatedStorageException("IsolatedStorage_Operation", e);
                }
            }

            if(CompatibilitySwitches.IsAppEarlierThanWindowsPhoneMango)
            {
                // Pre Mango Windows Phone had very odd behavior for this function.  It would take the parent directory of the search pattern and do a *
                // in there.  That means something like GetDirectories("Dir1") would be treated as GetDirectories("*") and GetDirectories("Dir2\Dir3") would be
                // treated as GetDirectories("Dir2\*").

                // This also means that GetDirectories("") returned "IsolatedStorage" since it was looking at the directory above the root of Isolated Storage.
                fullPath = Path.Combine(Path.GetDirectoryName(fullPath), "*");                
            }

            String[] list = new String[10];
            int listSize = 0;
            Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();

            // Open a Find handle 
            SafeFindHandle hnd = Win32Native.FindFirstFile(fullPath, data);
            if(hnd.IsInvalid) {
                // Calls to GetLastWin32Error overwrites HResult.  Store HResult.
                hr = Marshal.GetLastWin32Error();
                if(hr == Win32Native.ERROR_FILE_NOT_FOUND)
                    return new String[0];

                // Mango would throw DirectoryNotFoundException if we got ERROR_PATH_NOT_FOUND instead of IsolatedStorageException
                if(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && hr == Win32Native.ERROR_PATH_NOT_FOUND)
                    __Error.WinIOError(hr, msg);

#if FEATURE_ISOSTORE_LIGHT
                throw GetIsolatedStorageException("IsolatedStorage_Operation", Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error(), new IntPtr(-1)));
#else
                __Error.WinIOError(hr, msg);
#endif
            }

            // Keep asking for more matching files, adding file names to list
            int numEntries = 0;  // Number of directory entities we see.
            do {
                bool includeThis;  // Should this file/directory be included in the output?
                if(file)
                    includeThis = (0 == (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
                else {
                    includeThis = (0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
                    // Don't add "." nor ".."
                    if(includeThis && (data.cFileName.Equals(".") || data.cFileName.Equals("..")))
                        includeThis = false;
                }

                if(includeThis) {
                    numEntries++;
                    if(listSize == list.Length) {
                        String[] newList = new String[list.Length * 2];
                        Array.Copy(list, 0, newList, 0, listSize);
                        list = newList;
                    }
                    list[listSize++] = data.cFileName;
                }

            } while(Win32Native.FindNextFile(hnd, data));

            // Make sure we quit with a sensible error.
            hr = Marshal.GetLastWin32Error();
            hnd.Close();  // Close Find handle in all cases.
            if(hr != 0 && hr != Win32Native.ERROR_NO_MORE_FILES) __Error.WinIOError(hr, msg);

            // Check for a string such as "C:\tmp", in which case we return
            // just the directory name.  FindNextFile fails first time, and
            // data still contains a directory.
            if(!file && numEntries == 1 && (0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY))) {
                String[] sa = new String[1];
                sa[0] = data.cFileName;
                return sa;
            }

            // Return list of files/directories as an array of strings
            if(listSize == list.Length)
                return list;
            String[] items = new String[listSize];
            Array.Copy(list, 0, items, 0, listSize);
            return items;
        }
Exemple #6
0
        // Private helper function that does not do any security checks
        internal static String[] InternalGetFileDirectoryNames(String fullPath, bool file)
        {
            int hr;


            // If path ends in a trailing slash (\), append a * or we'll
            // get a "Cannot find the file specified" exception
            char lastChar = fullPath[fullPath.Length-1];
            if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar || lastChar == Path.VolumeSeparatorChar)
                fullPath = fullPath + '*';

            String[] list = new String[10];
            int listSize = 0;
            Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();

            // Open a Find handle (Win32 is weird)
            IntPtr hnd = Win32Native.FindFirstFile(fullPath, data);
            if (hnd==Win32Native.INVALID_HANDLE_VALUE) {
                // Calls to GetLastWin32Error clobber HResult.  Store HResult.
                hr = Marshal.GetLastWin32Error();
                if (hr==Win32Native.ERROR_FILE_NOT_FOUND)
                    return new String[0];
                __Error.WinIOError(hr, Path.GetDirectoryName(fullPath));
            }

            // Keep asking for more matching files, adding file names to list
            int numEntries = 0;  // Number of DirectoryInfo entities we see.
            do {
                bool includeThis;  // Should this file/DirectoryInfo be included in the output?
                if (file)
                    includeThis = (0==(data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
                else {
                    includeThis = (0!=(data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
                    // Don't add "." nor ".."
                    if (includeThis && (data.cFileName.Equals(".") || data.cFileName.Equals("..")))
                        includeThis = false;
                }

                if (includeThis) {
                    numEntries++;
                    if (listSize==list.Length) {
                        String[] newList = new String[list.Length*2];
                        Array.Copy(list, 0, newList, 0, listSize);
                        list = newList;
                    }
                    list[listSize++] = data.cFileName;
                }

            } while (Win32Native.FindNextFile(hnd, data));

            // Make sure we quit with a sensible error.
            hr = Marshal.GetLastWin32Error();
            Win32Native.FindClose(hnd);  // Close Find handle in all cases.
            if (hr!=0 && hr!=Win32Native.ERROR_NO_MORE_FILES) __Error.WinIOError(hr, Path.GetDirectoryName(fullPath));

            // Check for a string such as "C:\tmp", in which case we return
            // just the DirectoryInfo name.  FindNextFile fails first time, and
            // data still contains a directory.

            if (!file && numEntries==1 && (0!=(data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY))) {
                String[] sa = new String[1];
                sa[0] = data.cFileName;
                return sa;
            }

            // Return list of files/directories as an array of strings
            if (listSize == list.Length)
                return list;
            String[] items = new String[listSize];
            Array.Copy(list, 0, items, 0, listSize);
            return items;
        }
        private static void DeleteHelper(string fullPath, string userPath, bool recursive)
        {
            int num;
            Exception exception = null;
            if (recursive)
            {
                Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
                using (SafeFindHandle handle = Win32Native.FindFirstFile(fullPath + Path.DirectorySeparatorChar + "*", data))
                {
                    if (handle.IsInvalid)
                    {
                        num = Marshal.GetLastWin32Error();
                        __Error.WinIOError(num, fullPath);
                    }
                    do
                    {
                        if (0 != (data.dwFileAttributes & 0x10))
                        {
                            if (!data.cFileName.Equals(".") && !data.cFileName.Equals(".."))
                            {
                                if (0 == (data.dwFileAttributes & 0x400))
                                {
                                    string str = Path.InternalCombine(fullPath, data.cFileName);
                                    string str2 = Path.InternalCombine(userPath, data.cFileName);
                                    try
                                    {
                                        DeleteHelper(str, str2, recursive);
                                    }
                                    catch (Exception exception2)
                                    {
                                        if (exception == null)
                                        {
                                            exception = exception2;
                                        }
                                    }
                                }
                                else
                                {
                                    if ((data.dwReserved0 == -1610612733) && !Win32Native.DeleteVolumeMountPoint(Path.InternalCombine(fullPath, data.cFileName + Path.DirectorySeparatorChar)))
                                    {
                                        num = Marshal.GetLastWin32Error();
                                        try
                                        {
                                            __Error.WinIOError(num, data.cFileName);
                                        }
                                        catch (Exception exception3)
                                        {
                                            if (exception == null)
                                            {
                                                exception = exception3;
                                            }
                                        }
                                    }
                                    if (!Win32Native.RemoveDirectory(Path.InternalCombine(fullPath, data.cFileName)))
                                    {
                                        num = Marshal.GetLastWin32Error();
                                        try
                                        {
                                            __Error.WinIOError(num, data.cFileName);
                                        }
                                        catch (Exception exception4)
                                        {
                                            if (exception == null)
                                            {
                                                exception = exception4;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else if (!Win32Native.DeleteFile(Path.InternalCombine(fullPath, data.cFileName)))
                        {
                            num = Marshal.GetLastWin32Error();
                            if (num != 2)
                            {
                                try
                                {
                                    __Error.WinIOError(num, data.cFileName);
                                }
                                catch (Exception exception5)
                                {
                                    if (exception == null)
                                    {
                                        exception = exception5;
                                    }
                                }
                            }
                        }
                    }
                    while (Win32Native.FindNextFile(handle, data));
                    num = Marshal.GetLastWin32Error();
                }
                if (exception != null)
                {
                    throw exception;
                }
                if ((num != 0) && (num != 0x12))
                {
                    __Error.WinIOError(num, userPath);
                }
            }
            if (!Win32Native.RemoveDirectory(fullPath))
            {
                num = Marshal.GetLastWin32Error();
                switch (num)
                {
                    case 2:
                        num = 3;
                        break;

                    case 5:
                        throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", new object[] { userPath }));
                }
                __Error.WinIOError(num, fullPath);
            }
        }
 internal static string[] GetFileDirectoryNames(string path, string userSearchPattern, bool file)
 {
     int num;
     if (path == null)
     {
         throw new ArgumentNullException("path", Environment.GetResourceString("ArgumentNull_Path"));
     }
     userSearchPattern = NormalizeSearchPattern(userSearchPattern);
     if (userSearchPattern.Length == 0)
     {
         return new string[0];
     }
     bool flag = false;
     char ch = path[path.Length - 1];
     if (((ch == Path.DirectorySeparatorChar) || (ch == Path.AltDirectorySeparatorChar)) || (ch == '.'))
     {
         flag = true;
     }
     string str = LongPath.NormalizePath(path);
     if (flag && (str[str.Length - 1] != ch))
     {
         str = str + @"\*";
     }
     string directoryName = LongPath.GetDirectoryName(str);
     if (directoryName != null)
     {
         directoryName = directoryName + @"\";
     }
     try
     {
         string[] pathList = new string[] { (directoryName == null) ? str : directoryName };
         new FileIOPermission(FileIOPermissionAccess.Read, pathList, false, false).Demand();
     }
     catch
     {
         throw new IsolatedStorageException(Environment.GetResourceString("IsolatedStorage_Operation"));
     }
     string[] sourceArray = new string[10];
     int length = 0;
     Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
     SafeFindHandle hndFindFile = Win32Native.FindFirstFile(Path.AddLongPathPrefix(str), data);
     if (hndFindFile.IsInvalid)
     {
         num = Marshal.GetLastWin32Error();
         if (num == 2)
         {
             return new string[0];
         }
         __Error.WinIOError(num, userSearchPattern);
     }
     int num3 = 0;
     do
     {
         bool flag2;
         if (file)
         {
             flag2 = 0 == (data.dwFileAttributes & 0x10);
         }
         else
         {
             flag2 = 0 != (data.dwFileAttributes & 0x10);
             if (flag2 && (data.cFileName.Equals(".") || data.cFileName.Equals("..")))
             {
                 flag2 = false;
             }
         }
         if (flag2)
         {
             num3++;
             if (length == sourceArray.Length)
             {
                 string[] strArray3 = new string[sourceArray.Length * 2];
                 Array.Copy(sourceArray, 0, strArray3, 0, length);
                 sourceArray = strArray3;
             }
             sourceArray[length++] = data.cFileName;
         }
     }
     while (Win32Native.FindNextFile(hndFindFile, data));
     num = Marshal.GetLastWin32Error();
     hndFindFile.Close();
     if ((num != 0) && (num != 0x12))
     {
         __Error.WinIOError(num, userSearchPattern);
     }
     if ((!file && (num3 == 1)) && ((data.dwFileAttributes & 0x10) != 0))
     {
         return new string[] { data.cFileName };
     }
     if (length == sourceArray.Length)
     {
         return sourceArray;
     }
     string[] destinationArray = new string[length];
     Array.Copy(sourceArray, 0, destinationArray, 0, length);
     return destinationArray;
 }
Exemple #9
0
 internal SearchResult(string fullPath, string userPath, Win32Native.WIN32_FIND_DATA findData)
 {
     this.fullPath = fullPath;
     this.userPath = userPath;
     this.findData = findData;
 }
 internal static int FillAttributeInfo(string path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound)
 {
     int num = 0;
     if (tryagain)
     {
         Win32Native.WIN32_FIND_DATA win_find_data = new Win32Native.WIN32_FIND_DATA();
         string fileName = path.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
         int num2 = Win32Native.SetErrorMode(1);
         try
         {
             bool flag = false;
             SafeFindHandle handle = Win32Native.FindFirstFile(fileName, win_find_data);
             try
             {
                 if (handle.IsInvalid)
                 {
                     flag = true;
                     num = Marshal.GetLastWin32Error();
                     if ((((num == 2) || (num == 3)) || (num == 0x15)) && !returnErrorOnNotFound)
                     {
                         num = 0;
                         data.fileAttributes = -1;
                     }
                     return num;
                 }
             }
             finally
             {
                 try
                 {
                     handle.Close();
                 }
                 catch
                 {
                     if (!flag)
                     {
                         __Error.WinIOError();
                     }
                 }
             }
         }
         finally
         {
             Win32Native.SetErrorMode(num2);
         }
         data.PopulateFrom(win_find_data);
         return num;
     }
     bool flag2 = false;
     int newMode = Win32Native.SetErrorMode(1);
     try
     {
         flag2 = Win32Native.GetFileAttributesEx(path, 0, ref data);
     }
     finally
     {
         Win32Native.SetErrorMode(newMode);
     }
     if (!flag2)
     {
         num = Marshal.GetLastWin32Error();
         if (((num != 2) && (num != 3)) && (num != 0x15))
         {
             return FillAttributeInfo(path, ref data, true, returnErrorOnNotFound);
         }
         if (!returnErrorOnNotFound)
         {
             num = 0;
             data.fileAttributes = -1;
         }
     }
     return num;
 }
        internal static String[] InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, bool includeFiles, bool includeDirs, SearchOption searchOption)
        {
            int hr = 0;

            if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
                throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));

            searchPattern = searchPattern.TrimEnd();
            if (searchPattern.Length == 0)
                return new String[0];
            
            Path.CheckSearchPattern(searchPattern);

            // Build various paths and query strings

            // Must fully qualify the path for the security check
            String fullPath = Path.GetFullPathInternal(path);

            // Any illegal chars such as *, ? will be caught by FileIOPermission.HasIllegalCharacters
            String[] demandPaths = new String[] {GetDemandDir(fullPath, true)};
            new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPaths, false, false).Demand();

            String userPath = userPathOriginal;
            String tempPath = Path.GetDirectoryName(searchPattern);

            if (tempPath != null && tempPath.Length != 0) { // For filters like foo\*.cs we need to verify if the directory foo is not denied access.
                // Do a demand on the combined path so that we can fail early in case of deny
                demandPaths = new String[] {GetDemandDir(Path.InternalCombine(fullPath, tempPath), true)};
                new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPaths, false, false).Demand();

                userPath = Path.Combine(userPath, tempPath); // Need to add the searchPath to return correct path and for right security checks
            }
            
            String tempStr = Path.InternalCombine(fullPath, searchPattern);

            // If path ends in a trailing slash (\), append a * or we'll 
            // get a "Cannot find the file specified" exception
            char lastChar = tempStr[tempStr.Length-1];
            if (lastChar == Path.DirectorySeparatorChar || lastChar == Path.AltDirectorySeparatorChar || lastChar == Path.VolumeSeparatorChar)
                tempStr = tempStr + '*';

            fullPath = Path.GetDirectoryName(tempStr);
            BCLDebug.Assert((fullPath != null),"fullpath can't be null!");
            
            String searchCriteria;
            bool trailingSlash = false;
            bool trailingSlashUserPath = false;

            lastChar = fullPath[fullPath.Length-1];
            trailingSlash = (lastChar == Path.DirectorySeparatorChar) || (lastChar == Path.AltDirectorySeparatorChar);

            if (trailingSlash) {
                // Can happen if the path is C:\temp, in which case GetDirectoryName would return C:\
                searchCriteria = tempStr.Substring(fullPath.Length);
            }
            else
                searchCriteria = tempStr.Substring(fullPath.Length + 1);

            Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
            SafeFindHandle hnd = null;

            // Heap based search stack
            SearchData searchData = new SearchData(fullPath, userPath, searchOption);
            List<SearchData> searchStack = new List<SearchData>();
            searchStack.Add(searchData);

            List<string> demandPathList = new List<string>();

            int numEntries = 0;  // Number of directory entities we see.
            int listSize = 0;
            String[] list = new String[10];
            String searchPath; 

            int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
            try {
                // Traverse directory structure. We need to get '*'
                while(searchStack.Count > 0) {
                    searchData = searchStack[searchStack.Count - 1];
                    searchStack.RemoveAt(searchStack.Count - 1);
                    BCLDebug.Assert((searchData.fullPath != null),"fullpath can't be null!");

                    lastChar = searchData.fullPath[searchData.fullPath.Length -1]; 
                    trailingSlash = (lastChar == Path.DirectorySeparatorChar) || (lastChar == Path.AltDirectorySeparatorChar);
                    
                    if (searchData.userPath.Length > 0) {
                        lastChar = searchData.userPath[searchData.userPath.Length -1]; 
                        trailingSlashUserPath = (lastChar == Path.DirectorySeparatorChar) || (lastChar == Path.AltDirectorySeparatorChar);
                    }

                    // Traverse the subdirs if specified
                    if (searchData.searchOption != SearchOption.TopDirectoryOnly) {
                        try {
                            if (trailingSlash) 
                                searchPath = searchData.fullPath + "*";
                            else
                                searchPath = searchData.fullPath + Path.DirectorySeparatorChar + "*";

                            // Get all files and dirs
                            hnd = Win32Native.FindFirstFile(searchPath, data);

                            if (hnd.IsInvalid) {
                                hr = Marshal.GetLastWin32Error();

                                // This could happen if the dir doesn't contain any files.
                                // Continue with the recursive search though, eventually
                                // searchStack will become empty
                                if (hr==Win32Native.ERROR_FILE_NOT_FOUND)
                                    continue;
                                __Error.WinIOError(hr, searchData.fullPath);
                            }

                            // Add subdirs to searchStack. Exempt ReparsePoints as appropriate
                            do {
                                if ((0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY))
                                    && !data.cFileName.Equals(".") && !data.cFileName.Equals("..")) {

                                    // Setup search data for the sub directory and push it into the stack
                                    SearchData searchDataSubDir = new SearchData();

                                    // FullPath
                                    StringBuilder strBldr = new StringBuilder(searchData.fullPath);
                                    if (!trailingSlash) 
                                        strBldr.Append(Path.DirectorySeparatorChar);
                                    strBldr.Append(data.cFileName);
                                    searchDataSubDir.fullPath = strBldr.ToString();

                                    // UserPath
                                    strBldr.Length = 0;
                                    strBldr.Append(searchData.userPath);
                                    if (!trailingSlashUserPath)
                                        strBldr.Append(Path.DirectorySeparatorChar);
                                    strBldr.Append(data.cFileName);
                                    searchDataSubDir.userPath = strBldr.ToString();

                                    // SearchOption
                                    searchDataSubDir.searchOption = searchData.searchOption;

                                    searchStack.Add(searchDataSubDir);
                                }
                            } while (Win32Native.FindNextFile(hnd, data));
                            // We don't care about any error here
                        }
                        finally {
                            if (hnd != null)
                                hnd.Dispose();
                        }
                    }

                    // Execute searchCriteria against the current directory
                    try{
                        if (trailingSlash) 
                            searchPath = searchData.fullPath + searchCriteria;
                        else
                            searchPath = searchData.fullPath + Path.DirectorySeparatorChar + searchCriteria;

                        // Open a Find handle
                        hnd = Win32Native.FindFirstFile(searchPath, data);
                        if (hnd.IsInvalid) {
                            hr = Marshal.GetLastWin32Error();
                            if (hr == Win32Native.ERROR_FILE_NOT_FOUND)
                                continue;
                            __Error.WinIOError(hr, searchData.fullPath);
                        }

                        numEntries = 0;
                        
                        // Keep asking for more matching files/dirs, add it to the list 
                        do {
                            bool includeThis = false;  // Should this file/directory be included in the output?
                            
                            if (includeFiles)
                                includeThis = (0 == (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
                            
                            if (includeDirs) {
                                // Don't add "." nor ".."
                                if ((0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY)) 
                                    && !data.cFileName.Equals(".") && !data.cFileName.Equals("..")) {
                                    
                                    BCLDebug.Assert(!includeThis, data.cFileName + ": current item can't be both file and dir!");
                                    includeThis = true;
                                }
                            }

                            if (includeThis) {
                                numEntries++;
                                if (listSize==list.Length) {
                                    String[] newList = new String[list.Length*2];
                                    Array.Copy(list, 0, newList, 0, listSize);
                                    list = newList;
                                }
                                list[listSize++] = Path.InternalCombine(searchData.userPath, data.cFileName);
                            }
                        } while (Win32Native.FindNextFile(hnd, data));

                        // Make sure we quit with a sensible error.
                        hr = Marshal.GetLastWin32Error();

                        // Demand pathdiscovery for all the parent dirs that are returned
                        // I.e, if C:\temp\foo\bar is returned, demand C:\temp\foo
                        if (numEntries > 0)  {
                            demandPathList.Add(GetDemandDir(searchData.fullPath, true));
                        }
                    }
                    finally {
                        if (hnd != null)
                            hnd.Dispose();
                    }
                } // End while
            }
            finally {
                Win32Native.SetErrorMode(oldMode);
            }

            // ERROR_FILE_NOT_FOUND is valid here because if the top level
            // dir doen't contain any subdirs and matching files then 
            // we will get here with this errorcode from the searchStack walk
            if ((hr != 0) && (hr != Win32Native.ERROR_NO_MORE_FILES) 
                && (hr != Win32Native.ERROR_FILE_NOT_FOUND)) {
                __Error.WinIOError(hr, searchData.fullPath);
            }
            
            // Demand pathdiscovery for all the parent dirs that are returned
            // I.e, if C:\temp\foo\bar is returned, demand C:\temp\foo
            if (demandPathList.Count > 0) {
                demandPaths = new String[demandPathList.Count];
                demandPathList.CopyTo(demandPaths, 0);

                // No need to check for dupls as the demandPathList entries should be unique
                new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPaths, false, false ).Demand();
            }
            
            // Check for a string such as "C:\tmp", in which case we return
            // just the DirectoryInfo name.  FindNextFile fails first time, and
            // data still contains a directory.
/*
            if (includeDirs && numEntries==1 && (0!=(data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY))) {
                String[] sa = new String[1];
                sa[0] = Path.InternalCombine(searchData.userPath, data.cFileName);
                return sa;
            }
*/
            // Return list of files/directories as an array of strings
            if (listSize == list.Length)
                return list;
            String[] items = new String[listSize];
            Array.Copy(list, 0, items, 0, listSize);
            return items;
        }