服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C/C++ 监控磁盘与目录操作的示例

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

2021-09-29 13:00lyshark C/C++

这篇文章主要介绍了C/C++ 监控磁盘与目录操作的示例,帮助大家更好的理解和学习C/C++编程,感兴趣的朋友可以了解下

遍历磁盘容量:

?
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

延伸 · 阅读

精彩推荐
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29