C/C++ 監(jiān)控磁盤與目錄操作的示例
遍歷磁盤容量:
#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("可移動(dòng)磁盤"); break;
case DRIVE_FIXED: puts("固定磁盤"); break;
case DRIVE_REMOTE: puts("網(wǎng)絡(luò)磁盤"); break;
case DRIVE_CDROM: puts("光驅(qū)"); break;
case DRIVE_RAMDISK: puts("內(nèi)存映射盤"); 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 | 總計(jì): %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};
// 獲取邏輯驅(qū)動(dòng)器號(hào)字符串
DWORD dwResult = GetLogicalDriveStringsA(dwSize, szLogicalDrives);
if (dwResult > 0 && dwResult <= MAX_PATH) {
char* szSingleDrive = szLogicalDrives; // 從緩沖區(qū)起始地址開始
while (*szSingleDrive) {
//printf("Drive: %s\n", szSingleDrive); // 輸出單個(gè)驅(qū)動(dòng)器的驅(qū)動(dòng)器號(hào)
// GetDrivesType(szSingleDrive);
GetDrivesFreeSpace(szSingleDrive);
szSingleDrive += strlen(szSingleDrive) + 1; // 獲取下一個(gè)驅(qū)動(dòng)器地址
}
}
system("pause");
return 0;
}
遍歷文件特定路徑:
循環(huán)遍歷文件路徑,并將文件后綴為.exe的路徑篩選出來.
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
void SearchFile(char *pszDirectory)
{
// 搜索指定類型文件
char *pszFileName = NULL;
char *pTempSrc = NULL;
WIN32_FIND_DATA FileData = { 0 };
// 申請動(dòng)態(tài)內(nèi)存
pszFileName = new char[2048];
pTempSrc = new char[2048];
// 構(gòu)造搜索文件類型字符串 *.* 表示搜索所有文件類型
wsprintf(pszFileName, "%s\\*.*", pszDirectory);
HANDLE hFile = ::FindFirstFile(pszFileName, &FileData);
if (INVALID_HANDLE_VALUE != hFile)
{
do
{
// 過濾掉當(dāng)前目錄"." 和上一層目錄".."
if ('.' == FileData.cFileName[0])
continue;
// 拼接文件路徑
wsprintf(pTempSrc, "%s\\%s", pszDirectory, FileData.cFileName);
// 判斷是否是目錄還是文件
if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
SearchFile(pTempSrc); // 如果是目錄則繼續(xù)遞歸
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;
}
監(jiān)控文件目錄變化:
#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;
// 申請一個(gè)足夠大的緩沖區(qū)
BYTE *pBuf = new BYTE[dwBufferSize];
if (NULL == pBuf)
return 2;
FILE_NOTIFY_INFORMATION *pFileNotifyInfo = (FILE_NOTIFY_INFORMATION *)pBuf;
// 開始循環(huán)設(shè)置監(jiān)控
do
{
RtlZeroMemory(pFileNotifyInfo, dwBufferSize);
// 設(shè)置監(jiān)控目錄
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;
// 將寬字符轉(zhuǎn)換成窄字符,寬字節(jié)字符串轉(zhuǎn)多字節(jié)字符串
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("文件被 [創(chuàng)建]: %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:\\";
// 創(chuàng)建線程開始監(jiān)控
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorFileThreadProc, pszDirectory, 0, NULL);
while (1)
{
Sleep(10000);
}
system("pause");
return 0;
}
監(jiān)控目錄文件變化:
可以將其改為一個(gè)簡單的文件防篡改程序,也可以用來監(jiān)控病毒的行為.
#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));
// 設(shè)置監(jiān)控目錄回調(diào)函數(shù)
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 };
// 將寬字符轉(zhuǎn)換成窄字符,寬字節(jié)字符串轉(zhuǎn)多字節(jié)字符串
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++ 監(jiān)控磁盤與目錄操作的示例的詳細(xì)內(nèi)容,更多關(guān)于C/C++ 監(jiān)控磁盤與目錄操作的資料請關(guān)注腳本之家其它相關(guān)文章!
文章作者:lyshark
文章出處:https://www.cnblogs.com/lyshark
相關(guān)文章
Qt物聯(lián)網(wǎng)管理平臺(tái)之實(shí)現(xiàn)自動(dòng)清理早期數(shù)據(jù)功能
隨著時(shí)間的增加,存儲(chǔ)的歷史記錄也在不斷增加,如果設(shè)備數(shù)量很多,存儲(chǔ)間隔很短,不用多久,數(shù)據(jù)庫中的記錄就非常多,至少是百萬級別起步,而且有些用戶還是需要存儲(chǔ)每一次的采集的數(shù)據(jù)。本文將利用Qt實(shí)現(xiàn)自動(dòng)清理早期數(shù)據(jù),需要的可以參考一下2022-07-07
Qt?關(guān)于容器的遍歷迭代器的使用問題小結(jié)
Qt是一個(gè)跨平臺(tái)的 C++ 開發(fā)庫,主要用來開發(fā)圖形用戶界面程序,當(dāng)然也可以開發(fā)不帶界面的命令行程序,本文重點(diǎn)給大家介紹Qt?關(guān)于容器的遍歷迭代器的使用問題小結(jié),感興趣的朋友一起看看吧2022-03-03
Qt音視頻開發(fā)之利用ffmpeg實(shí)現(xiàn)解碼本地?cái)z像頭
一開始用ffmpeg做的是視頻流的解析,后面增加了本地視頻文件的支持,到后面發(fā)現(xiàn)ffmpeg也是支持本地?cái)z像頭設(shè)備的,所以本文就來用ffmpeg實(shí)現(xiàn)解碼本地?cái)z像頭功能吧2023-03-03

