1

次のコードでは、実行時エラーが発生します。

Window File 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]:\[FirstPath\foo1...\fileName]
    [A-Z]:\[SecondPath\foo2...\fileName]
    [A-Z]:\[ThirdPath\foo3...\fileName]
    ...
    [A-Z]:\[FourthPath\foo4...\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 *

しかし、理由はわかりません。

4

2 に答える 2

2

バッファオーバーフローのようです。ディレクトリ ツリーを再帰する際に、各ディレクトリに自身への参照 (名前は「.」) とその親ディレクトリへの参照 (名前は「..」) が含まれていることを忘れています。これらを再帰から除外する必要があります。だからこうしろ

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

あなたがそれをコーディングした方法は、同じディレクトリでループしてループするだけです。

于 2012-08-02T20:15:15.913 に答える
2

すべての非ルート ディレクトリには、それ自体 (".") とその親 ("..") の両方が含まれます。それらを再帰検索から明示的に除外する必要があります。

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);
}
于 2012-08-02T20:15:37.443 に答える