Inheritance: Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
Exemplo n.º 1
0
        void CommonInit()
        {
            Contract.Assert(searchCriteria != null && searchData != null, "searchCriteria and searchData should be initialized");

            // Execute searchCriteria against the current directory
            String searchPath = searchData.fullPath + searchCriteria;

            var data = new FindData();

            // Open a Find handle
            safeFindHandle = Win32Api.IO.FindFirstFile(searchPath, data);

            if (safeFindHandle.IsInvalid)
            {
                int hr = Marshal.GetLastWin32Error();
                if (hr != Win32Error.ERROR_FILE_NOT_FOUND && hr != Win32Error.ERROR_NO_MORE_FILES)
                {
                    HandleError(hr, searchData.fullPath);
                }
                else
                {
                    // flag this as empty only if we're searching just top directory
                    // Used in fast path for top directory only
                    isEmpty = searchData.searchOptions == SearchOption.TopDirectoryOnly;
                }
            }
            // fast path for TopDirectoryOnly. If we have a result, go ahead and set it to
            // current. If empty, dispose handle.
            if (searchData.searchOptions == SearchOption.TopDirectoryOnly)
            {
                if (isEmpty)
                {
                    safeFindHandle.Dispose();
                }
                else
                {
                    SearchResult searchResult = CreateSearchResult(searchData, data);
                    if (resultHandler.IsResultIncluded(searchResult))
                    {
                        current = resultHandler.CreateObject(searchResult);
                    }
                }
            }
            // for AllDirectories, we first recurse into dirs, so cleanup and add searchData
            // to the stack
            else
            {
                safeFindHandle.Dispose();
                searchStack.Add(searchData);
            }
        }
Exemplo n.º 2
0
        [SecurityCritical] // auto-generated
        void AddSearchableDirsToStack(SearchData localSearchData)
        {
            Contract.Requires(localSearchData != null);

            String         searchPath = localSearchData.fullPath + "*";
            SafeFindHandle hnd        = null;
            var            data       = new FindData();

            try
            {
                // Get all files and dirs
                hnd = Win32Api.IO.FindFirstFile(searchPath, data);

                if (hnd.IsInvalid)
                {
                    int 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 == Win32Error.ERROR_ACCESS_DENIED || hr == Win32Error.ERROR_FILE_NOT_FOUND || hr == Win32Error.ERROR_NO_MORE_FILES || hr == Win32Error.ERROR_PATH_NOT_FOUND)
                    {
                        return;
                    }

                    HandleError(hr, localSearchData.fullPath);
                }

                // Add subdirs to searchStack. Exempt ReparsePoints as appropriate
                int incr = 0;
                do
                {
                    if (data.IsDir)
                    {
                        // FullPath
                        var pathBuffer = new StringBuilder(localSearchData.fullPath);
                        pathBuffer.Append(data.FileName);
                        String tempFullPath = pathBuffer.ToString();

                        // UserPath
                        pathBuffer.Length = 0;
                        pathBuffer.Append(localSearchData.userPath);
                        pathBuffer.Append(data.FileName);

                        SearchOption option = localSearchData.searchOptions;

#if EXCLUDE_REPARSEPOINTS
                        // Traverse reparse points depending on the searchoption specified
                        if ((searchDataSubDir.searchOption == SearchOption.AllDirectories) && (0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_REPARSE_POINT)))
                        {
                            option = SearchOption.TopDirectoryOnly;
                        }
#endif
                        // Setup search data for the sub directory and push it into the stack
                        var searchDataSubDir = new SearchData(tempFullPath, pathBuffer.ToString(), option);

                        searchStack.Insert(incr++, searchDataSubDir);
                    }
                } while(Win32Api.IO.FindNextFile(hnd, data));
                // We don't care about errors here
            }
            finally
            {
                if (hnd != null)
                {
                    hnd.Dispose();
                }
            }
        }
Exemplo n.º 3
0
        public override bool MoveNext()
        {
            var data = new FindData();

            switch (state)
            {
            case stateInit:
            {
                if (isEmpty)
                {
                    state = stateFinish;
                    goto case stateFinish;
                }
                if (searchData.searchOptions == SearchOption.TopDirectoryOnly)
                {
                    state = stateFindNextFile;
                    if (current != null)
                    {
                        return(true);
                    }
                    goto case stateFindNextFile;
                }
                state = stateSearchNextDir;
                goto case stateSearchNextDir;
            }

            case stateSearchNextDir:
            {
                Contract.Assert(searchData.searchOptions != SearchOption.TopDirectoryOnly, "should not reach this code path if searchOption == TopDirectoryOnly");
                // Traverse directory structure. We need to get '*'
                while (searchStack.Count > 0)
                {
                    searchData = searchStack[0];
                    Contract.Assert((searchData.fullPath != null), "fullpath can't be null!");
                    searchStack.RemoveAt(0);

                    // Traverse the subdirs
                    AddSearchableDirsToStack(searchData);

                    // Execute searchCriteria against the current directory
                    String searchPath = searchData.fullPath + searchCriteria;

                    // Open a Find handle
                    safeFindHandle = Win32Api.IO.FindFirstFile(searchPath, data);
                    if (safeFindHandle.IsInvalid)
                    {
                        int hr = Marshal.GetLastWin32Error();
                        if (hr == Win32Error.ERROR_ACCESS_DENIED || hr == Win32Error.ERROR_FILE_NOT_FOUND || hr == Win32Error.ERROR_NO_MORE_FILES || hr == Win32Error.ERROR_PATH_NOT_FOUND)
                        {
                            continue;
                        }

                        safeFindHandle.Dispose();
                        HandleError(hr, searchData.fullPath);
                    }

                    state = stateFindNextFile;
                    needsParentPathDiscoveryDemand = true;
                    SearchResult searchResult = CreateSearchResult(searchData, data);
                    if (resultHandler.IsResultIncluded(searchResult))
                    {
                        if (needsParentPathDiscoveryDemand)
                        {
                            DoDemand(searchData.fullPath);
                            needsParentPathDiscoveryDemand = false;
                        }
                        current = resultHandler.CreateObject(searchResult);
                        return(true);
                    }
                    goto case stateFindNextFile;
                }
                state = stateFinish;
                goto case stateFinish;
            }

            case stateFindNextFile:
            {
                if (searchData != null && safeFindHandle != null)
                {
                    // Keep asking for more matching files/dirs, add it to the list
                    while (Win32Api.IO.FindNextFile(safeFindHandle, data))
                    {
                        SearchResult searchResult = CreateSearchResult(searchData, data);
                        if (resultHandler.IsResultIncluded(searchResult))
                        {
                            if (needsParentPathDiscoveryDemand)
                            {
                                DoDemand(searchData.fullPath);
                                needsParentPathDiscoveryDemand = false;
                            }
                            current = resultHandler.CreateObject(searchResult);
                            return(true);
                        }
                    }

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

                    if (safeFindHandle != null)
                    {
                        safeFindHandle.Dispose();
                    }

                    // 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 != Win32Error.ERROR_NO_MORE_FILES) &&
                        (hr != Win32Error.ERROR_FILE_NOT_FOUND))
                    {
                        HandleError(hr, searchData.fullPath);
                    }
                }
                if (searchData.searchOptions == SearchOption.TopDirectoryOnly)
                {
                    state = stateFinish;
                    goto case stateFinish;
                }
                state = stateSearchNextDir;
                goto case stateSearchNextDir;
            }

            case stateFinish:
            {
                Dispose();
                break;
            }
            }
            return(false);
        }