使用扩展功能在整个系统中搜索文件

Searching file in the whole system using extended functions

本文关键字:系统 搜索 文件 扩展 功能      更新时间:2023-10-16

以下代码产生运行时错误:

Window文件Search.exe中0x773315de处未处理的异常:0xC0000005:访问冲突。

我不知道是什么原因造成的。你能指出我的错误吗?

以下是可能包含罪魁祸首的函数:

int fileSearcher::findFilesRecursivelly(const TCHAR* curDir,const TCHAR* fileName,bool caseSensitive,TCHAR* output)
{
    HANDLE hFoundFile;
    WIN32_FIND_DATA foundFileData;
    TCHAR nextDirBuffer[MAX_PATH]=TEXT("");
    SetCurrentDirectory(curDir);
    //Fetch inside current directory
    hFoundFile = FindFirstFileEx(fileName,FINDEX_INFO_LEVELS::FindExInfoBasic,&foundFileData ,FINDEX_SEARCH_OPS::FindExSearchNameMatch ,NULL , FIND_FIRST_EX_LARGE_FETCH);
    if(hFoundFile != INVALID_HANDLE_VALUE)
    {       
        do
        {
            nothingFound = false;
            wcscat(output,curDir);
            wcscat(output,TEXT("\"));
            wcscat(output,foundFileData.cFileName);
            wcscat(output,TEXT("n"));
        }   
        while(FindNextFile(hFoundFile,&foundFileData));
    }
    //Go to the subdirs
    hFoundFile = FindFirstFileEx(TEXT("*"),FINDEX_INFO_LEVELS::FindExInfoBasic,&foundFileData ,FINDEX_SEARCH_OPS::FindExSearchLimitToDirectories ,NULL , FIND_FIRST_EX_LARGE_FETCH); //This line of code was on the call stack
    if(hFoundFile != INVALID_HANDLE_VALUE)
    {
        do
        {
            wcscat(nextDirBuffer,curDir);
            wcscat(nextDirBuffer,TEXT("\"));
            wcscat(nextDirBuffer,foundFileData.cFileName);
            findFilesRecursivelly(nextDirBuffer,fileName,caseSensitive,outputBuffer);
        }
        while(FindNextFile(hFoundFile,&foundFileData));
    } 
    return 0;
}

不太重要的代码:

文件搜索.h

#ifndef UNICODE
#define UNICODE
#endif
#include <Windows.h>
namespace fileSearch
{
class fileSearcher
{
public: 
    fileSearcher();
    void getAllPaths(const TCHAR* fileName,bool caseSensitive,TCHAR* output);   
    /*Returns all matching pathes at the current local system. Format:
    [A-Z]:[FirstPathfoo1...fileName]
    [A-Z]:[SecondPathfoo2...fileName]
    [A-Z]:[ThirdPathfoo3...fileName]
    ...
    [A-Z]:[FourthPathfoo4...fileName]
    Also an asterisk sign is supported, as in regular expressions.
    This functions uses WinApi methods.
    */
    int findFilesRecursivelly(const TCHAR* curDir,const TCHAR* fileName,bool caseSensitive,TCHAR* output);
    //Searches for the file in the current and in sub directories. NOT IN PARENT!!!!!!!!!!!!!!!!!!!!! Returns true if the file is found.
private:
    static const int MAX_NUMBER_OF_FILES = 100;
    static const int MAX_OUTPUT_SIZE = 2000;
    bool nothingFound;
    TCHAR outputBuffer[MAX_OUTPUT_SIZE];
};
}

和FileSeach.cpp 的其余部分

#ifndef UNICODE
#define UNICODE
#endif
#include "File Search.h"
using namespace fileSearch;
fileSearcher::fileSearcher()
{
    nothingFound = true;
}
void fileSearcher::getAllPaths(const TCHAR* fileName,bool caseSensitive, TCHAR* output)
{
    TCHAR localDrives[50];
    TCHAR currentDrive;
    int voluminesChecked=0;
    TCHAR searchedVolumine[5];

    GetLogicalDriveStrings(sizeof(localDrives)/sizeof(TCHAR),localDrives);
    //For all drives:
    for(int i=0; i < sizeof(localDrives)/sizeof(TCHAR); i++)
    {       
            if(localDrives[i] >= 65 && localDrives[i] <= 90)
            {   
                currentDrive = localDrives[i];
                voluminesChecked++;
            }
            else continue;

    searchedVolumine[0] = currentDrive;
    searchedVolumine[1] = L':';
    searchedVolumine[2] = 0;

    outputBuffer[0]=0;
    findFilesRecursivelly(searchedVolumine,fileName,caseSensitive,outputBuffer);
    (nothingFound) ? wcscpy(output,L"File not found") : wcscpy(output,outputBuffer);
    }
}

编辑

经过一些迭代后curDir的值为-

+curDir 0x003df234"C:\.\$Recycle.Bin\.\.\.\.\.\.\.\.\.\.\.\.\.\..\.\.\.\.\..\.\"const wchar_t*

但我不知道为什么。

每个非根目录都包含它自己(".")和它的父目录("..")。您需要明确地将它们从递归搜索中排除:

if (wcscmp(foundFileData.cFileName, L".") != 0 
     && wcscmp(foundFileData.cFileName, L"..") != 0) 
{
  wcscat(nextDirBuffer,curDir);
  wcscat(nextDirBuffer,TEXT("\"));
  wcscat(nextDirBuffer,foundFileData.cFileName);
  findFilesRecursivelly(nextDirBuffer,fileName,caseSensitive,outputBuffer);
}

看起来像是缓冲区溢出。在通过目录树递归时,您忘记了每个目录都包含对其自身的引用(名称为".")和对其父目录的引用(姓名为".."),您必须将它们从递归中排除。所以做这个

    do
    {
        if (wcscmp(foundFileData.cFileName, TEXT(".") == 0 ||
            wcscmp(foundFileData.cFileName, TEXT("..") == 0)
        {
            continue;
        }
        wcscat(nextDirBuffer,curDir);
        wcscat(nextDirBuffer,TEXT("\"));
        wcscat(nextDirBuffer,foundFileData.cFileName);
        findFilesRecursivelly(nextDirBuffer,fileName,caseSensitive,outputBuffer);
    }
    while(FindNextFile(hFoundFile,&foundFileData));

按照你的编码方式,你只是在同一个目录中循环。