1. 程式人生 > 程式設計 >C/C++ 監控磁碟與目錄操作的示例

C/C++ 監控磁碟與目錄操作的示例

遍歷磁碟容量:

#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的路徑篩選出來.

#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;
}

監控檔案目錄變化:

#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);
		if (FALSE == bRet)
			break;

		// 將寬字元轉換成窄字元,寬位元組字串轉多位元組字串
		WideCharToMultiByte(CP_ACP,(wchar_t *)(&pFileNotifyInfo->FileName),(pFileNotifyInfo->FileNameLength / 2),szFileName,MAX_PATH,NULL);

		// 將路徑與檔案連線成完整檔案路徑
		char FullFilePath[1024] = { 0 };
		strncpy(FullFilePath,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,(LPTHREAD_START_ROUTINE)MonitorFileThreadProc,NULL);
	while (1)
	{
		Sleep(10000);
	}
	system("pause");
	return 0;
}

監控目錄檔案變化:

可以將其改為一個簡單的檔案防篡改程式,也可以用來監控病毒的行為.

#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_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,NULL);
	if (INVALID_HANDLE_VALUE == hFile)
		return 1;

	while (TRUE)
	{
		ZeroMemory(Buffer,sizeof(Buffer));
		// 設定監控目錄回撥函式
		bRet = ReadDirectoryChangesW(hFile,&Buffer,sizeof(Buffer),// 最後一次寫入
			&dwByteReturn,NULL);
		if (TRUE == bRet)
		{
			char szFileName[MAX_PATH] = { 0 };

			// 將寬字元轉換成窄字元,寬位元組字串轉多位元組字串
			WideCharToMultiByte(CP_ACP,pBuffer->FileName,(pBuffer->FileNameLength / 2),NULL);

			// 將路徑與檔案連線成完整檔案路徑
			char FullFilePath[1024] = { 0 };
			strncpy(FullFilePath,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,tmpBuffer->FileName,(tmpBuffer->FileNameLength / 2),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,MonitorFileThreadProc,NULL);
	WaitForSingleObject(hThread,INFINITE);
	CloseHandle(hThread);
	return 0;
}

以上就是C/C++ 監控磁碟與目錄操作的示例的詳細內容,更多關於C/C++ 監控磁碟與目錄操作的資料請關注我們其它相關文章!

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