服务器之家

服务器之家 > 正文

C/C++ 监控磁盘与目录操作的示例

时间:2021-09-29 13:00     来源/作者:lyshark

遍历磁盘容量:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h>
#include <Windows.h>
 
void GetDrivesType(const char* lpRootPathName)
{
    UINT uDriverType = GetDriveType(lpRootPathName);
    switch (uDriverType)
    {
        case DRIVE_UNKNOWN:puts("未知磁盘"); break;
        case DRIVE_NO_ROOT_DIR: puts("路径无效"); break;
        case DRIVE_REMOVABLE: puts("可移动磁盘"); break;
        case DRIVE_FIXED: puts("固定磁盘"); break;
        case DRIVE_REMOTE: puts("网络磁盘"); break;
        case DRIVE_CDROM: puts("光驱"); break;
        case DRIVE_RAMDISK: puts("内存映射盘"); break;
        default: break;
    }
}
 
void GetDrivesFreeSpace(const char* lpRootPathName)
{
    unsigned long long available, total, free;
    if (GetDiskFreeSpaceEx(lpRootPathName, (ULARGE_INTEGER*)&available,
        (ULARGE_INTEGER*)&total, (ULARGE_INTEGER*)&free))
    {
        printf("磁盘: %s | 总计: %lld MB 已用: %lld MB 剩余: %lld MB \n",
            lpRootPathName, total >> 20, available >> 20, free >> 20);
    }
}
 
int main(int argc,char *argv[])
{
    DWORD dwSize = MAX_PATH;
  char szLogicalDrives[MAX_PATH] = {0};
 
  // 获取逻辑驱动器号字符串
    DWORD dwResult = GetLogicalDriveStringsA(dwSize, szLogicalDrives);
    
    if (dwResult > 0 && dwResult <= MAX_PATH) {
        char* szSingleDrive = szLogicalDrives;      // 从缓冲区起始地址开始
        while (*szSingleDrive) {
            //printf("Drive: %s\n", szSingleDrive);   // 输出单个驱动器的驱动器号
            // GetDrivesType(szSingleDrive);
            GetDrivesFreeSpace(szSingleDrive);
            szSingleDrive += strlen(szSingleDrive) + 1; // 获取下一个驱动器地址
        }
    }
 
    system("pause");
    return 0;
}

遍历文件特定路径:

循环遍历文件路径,并将文件后缀为.exe的路径筛选出来.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
 
void SearchFile(char *pszDirectory)
{
    // 搜索指定类型文件
    char *pszFileName = NULL;
    char *pTempSrc = NULL;
    WIN32_FIND_DATA FileData = { 0 };
 
    // 申请动态内存
    pszFileName = new char[2048];
    pTempSrc = new char[2048];
 
    // 构造搜索文件类型字符串 *.* 表示搜索所有文件类型
    wsprintf(pszFileName, "%s\\*.*", pszDirectory);
 
    HANDLE hFile = ::FindFirstFile(pszFileName, &FileData);
    if (INVALID_HANDLE_VALUE != hFile)
    {
        do
        {
            // 过滤掉当前目录"." 和上一层目录".."
            if ('.' == FileData.cFileName[0])
                continue;
 
            // 拼接文件路径  
            wsprintf(pTempSrc, "%s\\%s", pszDirectory, FileData.cFileName);
            // 判断是否是目录还是文件
            if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                SearchFile(pTempSrc);     // 如果是目录则继续递归
            else
            {
                char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
                _splitpath(pTempSrc, drive, dir, fname, ext);
                // 如果是文件并且后缀为.exe则输出具体路径
                if (strcmp(ext, ".exe") == 0)
                    printf("%s \n", pTempSrc);
            }
        } while (::FindNextFile(hFile, &FileData));
    }
    FindClose(hFile);
    delete[]pTempSrc;
    delete[]pszFileName;
}
 
int main(int argc, char * argv[])
{
    SearchFile("c:\\MinGW7");
    system("pause");
    return 0;
}

监控文件目录变化:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
 
UINT MonitorFileThreadProc(LPVOID lpVoid)
{
    char *pszDirectory = (char *)lpVoid;
 
    // 打开目录, 获取文件句柄
    HANDLE hDirectory = CreateFile(pszDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (INVALID_HANDLE_VALUE == hDirectory)
        return 1;
 
    char szFileName[MAX_PATH] = { 0 };
    BOOL bRet = FALSE;
    DWORD dwRet = 0;
    DWORD dwBufferSize = 2048;
 
    // 申请一个足够大的缓冲区
    BYTE *pBuf = new BYTE[dwBufferSize];
    if (NULL == pBuf)
        return 2;
 
    FILE_NOTIFY_INFORMATION *pFileNotifyInfo = (FILE_NOTIFY_INFORMATION *)pBuf;
 
    // 开始循环设置监控
    do
    {
        RtlZeroMemory(pFileNotifyInfo, dwBufferSize);
        // 设置监控目录
        bRet = ReadDirectoryChangesW(hDirectory, pFileNotifyInfo, dwBufferSize, TRUE,
            FILE_NOTIFY_CHANGE_FILE_NAME |          // 修改文件名
            FILE_NOTIFY_CHANGE_ATTRIBUTES |         // 修改文件属性
            FILE_NOTIFY_CHANGE_LAST_WRITE,          // 最后一次写入
            &dwRet, NULL, NULL);
        if (FALSE == bRet)
            break;
 
        // 将宽字符转换成窄字符,宽字节字符串转多字节字符串
        WideCharToMultiByte(CP_ACP, 0, (wchar_t *)(&pFileNotifyInfo->FileName),
            (pFileNotifyInfo->FileNameLength / 2),szFileName,MAX_PATH,NULL,NULL);
 
        // 将路径与文件连接成完整文件路径
        char FullFilePath[1024] = { 0 };
        strncpy(FullFilePath, pszDirectory, strlen(pszDirectory));
        strcat(FullFilePath, szFileName);
 
        // 判断操作类型并显示
        switch (pFileNotifyInfo->Action)
        {
            case FILE_ACTION_ADDED:
                printf("文件被 [创建]: %s \n", FullFilePath); break;
            case FILE_ACTION_REMOVED:
                printf("文件被 [删除]: %s \n", FullFilePath); break;
            case FILE_ACTION_MODIFIED:
                printf("文件被 [修改]: %s \n", FullFilePath); break;
            case FILE_ACTION_RENAMED_OLD_NAME:
                printf("文件被 [重命名]: %s \n", FullFilePath); break;
        }
    } while (bRet);
 
    CloseHandle(hDirectory);
    delete[] pBuf;
    pBuf = NULL;
    return 0;
}
 
int main(int argc, char * argv[])
{
    char *pszDirectory = "C:\\";
    // 创建线程开始监控
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorFileThreadProc, pszDirectory, 0, NULL);
    while (1)
    {
        Sleep(10000);
    }
    system("pause");
    return 0;
}

监控目录文件变化:

可以将其改为一个简单的文件防篡改程序,也可以用来监控病毒的行为.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdio.h>
#include <Windows.h>
#include <tlhelp32.h>
 
DWORD WINAPI MonitorFileThreadProc(LPVOID lParam)
{
    char *pszDirectory = (char *)lParam;
    BOOL bRet = FALSE;
    BYTE Buffer[1024] = { 0 };
 
    FILE_NOTIFY_INFORMATION *pBuffer = (FILE_NOTIFY_INFORMATION *)Buffer;
    DWORD dwByteReturn = 0;
    HANDLE hFile = CreateFile(pszDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (INVALID_HANDLE_VALUE == hFile)
        return 1;
 
    while (TRUE)
    {
        ZeroMemory(Buffer, sizeof(Buffer));
        // 设置监控目录回调函数
        bRet = ReadDirectoryChangesW(hFile,&Buffer,sizeof(Buffer),TRUE,
            FILE_NOTIFY_CHANGE_FILE_NAME |          // 修改文件名
            FILE_NOTIFY_CHANGE_ATTRIBUTES |         // 修改文件属性
            FILE_NOTIFY_CHANGE_LAST_WRITE,          // 最后一次写入
            &dwByteReturn, NULL, NULL);
        if (TRUE == bRet)
        {
            char szFileName[MAX_PATH] = { 0 };
 
            // 将宽字符转换成窄字符,宽字节字符串转多字节字符串
            WideCharToMultiByte(CP_ACP,0,pBuffer->FileName,(pBuffer->FileNameLength / 2),
                szFileName,MAX_PATH,NULL,NULL);
 
            // 将路径与文件连接成完整文件路径
            char FullFilePath[1024] = { 0 };
            strncpy(FullFilePath, pszDirectory, strlen(pszDirectory));
            strcat(FullFilePath, szFileName);
 
            switch (pBuffer->Action)
            {
                case FILE_ACTION_ADDED:
                {
                    printf("添加: %s \n", FullFilePath); break;
                }
                case FILE_ACTION_REMOVED:
                {
                    printf("删除: %s \n", FullFilePath); break;
                }
                case FILE_ACTION_MODIFIED:
                {
                    printf("修改: %s \n", FullFilePath); break;
                }
                case FILE_ACTION_RENAMED_OLD_NAME:
                {
                    printf("重命名: %s", szFileName);
                    if (0 != pBuffer->NextEntryOffset)
                    {
                        FILE_NOTIFY_INFORMATION *tmpBuffer = (FILE_NOTIFY_INFORMATION *)
                            ((DWORD)pBuffer + pBuffer->NextEntryOffset);
                        switch (tmpBuffer->Action)
                            {
                                case FILE_ACTION_RENAMED_NEW_NAME:
                                {
                                    ZeroMemory(szFileName, MAX_PATH);
                                    WideCharToMultiByte(CP_ACP,0,tmpBuffer->FileName,
                                        (tmpBuffer->FileNameLength / 2),
                                        szFileName,MAX_PATH,NULL,NULL);
                                    printf(" -> %s \n", szFileName);
                                    break;
                                }
                            }
                    }
                    break;
                }
                case FILE_ACTION_RENAMED_NEW_NAME:
                {
                    printf("重命名(new): %s \n", FullFilePath); break;
                }
            }
        }
    }
    CloseHandle(hFile);
    return 0;
}
 
int main(int argc, char * argv[])
{
    char *pszDirectory = "C:\\";
 
    HANDLE hThread = CreateThread(NULL, 0, MonitorFileThreadProc, pszDirectory, 0, NULL);
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    return 0;
}

以上就是C/C++ 监控磁盘与目录操作的示例的详细内容,更多关于C/C++ 监控磁盘与目录操作的资料请关注服务器之家其它相关文章!

文章作者:lyshark
文章出处:https://www.cnblogs.com/lyshark

标签:

相关文章

热门资讯

yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
返回顶部