关于 win32 下磁盘的遍历方法

时间:2021-11-09 04:16:32

最近要写个在线专杀的东东,虽然是专杀(本来只要清除几个特定的文件和杀几个特定的进程,然后把用户的注册表恢复正常,很多病毒木马最喜欢干的一件事情就是写 映像劫持 然后机器一重启,安全相关的软件全部玩完了,不过这也没什么技术含量,利用了操作系统的“漏洞”而已),但是因为是 磁碟机,这个病毒(木马)很恶心,是感染型的,你磁盘上的exe文件可以全部给你感染成一个个的“小磁碟机”,很恐怖,呵呵,所以没办法,要清除它,必须在杀掉磁碟机的进程之后,对全盘进行扫描,对每一个被感染的exe文件(好像com文件不能感染)进行修复,怎么进行磁盘遍历呢?请看下面的代码:(其实杀毒引擎工作的过程就是一个遍历磁盘上文件的过程,然后再对每个文件进行处理)

// -------------------------------------------------------------------------

// 函数       : ScanDirectory

// 功能       : 遍历一个目录,然后做一些事情(想做什么做什么呗)

// 返回值  : DWORD 

// 参数       : const WCHAR *pwszPath

// 附注       : 可以为磁盘根目录

// -------------------------------------------------------------------------

DWORD ScanDirectory(const WCHAR *pwszPath)

{

    USES_CONVERSION;

    static int nCountFile = 0;

    DWORD dwRet = 1;

    WCHAR *s = NULL;

    HANDLE hFind = NULL;

    WIN32_FIND_DATAW fd = {0};

    WCHAR wszFileName[MAX_PATH] = L"";

    lstrcpyW(wszFileName, pwszPath);

    s = wszFileName + wcslen(wszFileName);

    if (*(s-1) != L‘//‘)

        *s++ = L‘//‘;

    // wcscpy_s(s, 4, L"*.*");

    ::lstrcpyW(s, L"*.*");

    hFind = FindFirstFileW(wszFileName, &fd);

    if (hFind==INVALID_HANDLE_VALUE)

        goto Exit0;

    do 

    {

        // 过滤

        if (_wcsicmp(L".", fd.cFileName) == 0 || _wcsicmp(L"..", fd.cFileName) == 0)

            continue;

        ::lstrcpyW(s, fd.cFileName);

        *(s + lstrlenW(fd.cFileName)) = L‘/0‘;

        // 如果是文件夹则递归

        if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)

        {

            // 删除.svn目录,我做一个小工作,删文件,o(∩_∩)o...

            WCHAR wszSvnCmd[MAX_PATH] = {0};

            ::lstrcpyW(wszSvnCmd, L"rmdir /s/q ");

            ::lstrcatW(wszSvnCmd, wszFileName);

            ::lstrcatW(wszSvnCmd, L"//.svn");

            system(W2A(wszSvnCmd));

            ScanDirectory(wszFileName);

        }

        else

        {

            // 对文件进行扫描

            // 这里你可以放入你对文件的处理代码

        }

    }while(::FindNextFileW(hFind, &fd));

    dwRet = 0;

Exit0:

    if( hFind != INVALID_HANDLE_VALUE )

    {

        ::FindClose( hFind );

        hFind = NULL;

    }

    return dwRet;

}