zoukankan      html  css  js  c++  java
  • USN日志

    转载:https://www.iteye.com/blog/univasity-805234    https://blog.51cto.com/velika/1440105

    源码:https://files.cnblogs.com/files/Toya/USN.7z

    本程序需要管理员权限

      1 #include<iostream>
      2 #include<stdio.h>
      3 #include<string>
      4 #include<tchar.h>
      5 #include<Windows.h>
      6 
      7 using namespace std;
      8 
      9 bool isNTFS(string path);
     10 HANDLE getHandle(string volName);
     11 bool createUSN(HANDLE hVol, CREATE_USN_JOURNAL_DATA& cujd);
     12 bool getUSNInfo(HANDLE hVol, USN_JOURNAL_DATA& ujd);
     13 bool getUSNJournal(HANDLE hVol, USN_JOURNAL_DATA& ujd);
     14 bool deleteUSN(HANDLE hVol, USN_JOURNAL_DATA& ujd);
     15 
     16 int main(){
     17     //isNTFS("C:/");
     18     CREATE_USN_JOURNAL_DATA* cujd = new CREATE_USN_JOURNAL_DATA;
     19     USN_JOURNAL_DATA* ujd = new USN_JOURNAL_DATA;
     20     HANDLE hVol = getHandle("C:");
     21     createUSN(hVol, *cujd);
     22     getUSNInfo(hVol, *ujd);
     23     getUSNJournal(hVol, *ujd);
     24     deleteUSN(hVol, *ujd);
     25     system("pause");
     26     return 0;
     27 }
     28 
     29 //判断是否是NTFS盘
     30 bool isNTFS(string path){//"C:/"
     31     char sysNameBuf[MAX_PATH];
     32     int status = GetVolumeInformationA(path.c_str(),
     33         NULL,
     34         0,
     35         NULL,
     36         NULL,
     37         NULL,
     38         sysNameBuf,
     39         MAX_PATH);
     40 
     41     if (0 != status){
     42         if (0 == strcmp(sysNameBuf, "NTFS")){
     43             //printf(" 文件系统名 : %s
    ", sysNameBuf);
     44             cout << "盘符:" << path << "
    文件系统名:" << sysNameBuf << endl;
     45             return true;
     46         }
     47         else {
     48             printf(" 该驱动盘非 NTFS 格式 
    ");
     49             return false;
     50         }
     51 
     52     }
     53     return false;
     54 }
     55 
     56 /**
     57 * step 02. 获取驱动盘句柄
     58 */
     59 HANDLE getHandle(string volName){
     60 
     61     char fileName[MAX_PATH];
     62     fileName[0] = '';
     63 
     64     // 传入的文件名必须为\.C:的形式  
     65     strcpy_s(fileName, "\\.\");
     66     strcat_s(fileName, volName.c_str());
     67     // 为了方便操作,这里转为string进行去尾  
     68     string fileNameStr = (string)fileName;
     69     fileNameStr.erase(fileNameStr.find_last_of(":") + 1);
     70 
     71     printf("驱动盘地址: %s
    ", fileNameStr.data());
     72 
     73     // 调用该函数需要管理员权限  
     74     HANDLE hVol = CreateFileA(fileNameStr.data(),
     75         GENERIC_READ | GENERIC_WRITE, // 可以为0  
     76         FILE_SHARE_READ | FILE_SHARE_WRITE, // 必须包含有FILE_SHARE_WRITE  
     77         NULL, // 这里不需要  
     78         OPEN_EXISTING, // 必须包含OPEN_EXISTING, CREATE_ALWAYS可能会导致错误  
     79         FILE_ATTRIBUTE_READONLY, // FILE_ATTRIBUTE_NORMAL可能会导致错误  
     80         NULL); // 这里不需要  
     81 
     82     if (INVALID_HANDLE_VALUE != hVol){
     83         //getHandleSuccess = true;
     84         cout << "获取驱动盘句柄成功!
    ";
     85         return hVol;
     86     }
     87     else{
     88         printf("获取驱动盘句柄失败 —— handle:%x error:%d
    ", hVol, GetLastError());
     89         return 0;
     90     }
     91     return 0;
     92 }
     93 
     94 /**
     95 * step 03. 初始化USN日志文件
     96 */
     97 bool createUSN(HANDLE hVol, CREATE_USN_JOURNAL_DATA& cujd){
     98     DWORD br;    
     99     cujd.MaximumSize = 0; // 0表示使用默认值  
    100     cujd.AllocationDelta = 0; // 0表示使用默认值  
    101     bool status = DeviceIoControl(hVol,
    102         FSCTL_CREATE_USN_JOURNAL,
    103         &cujd,
    104         sizeof(cujd),
    105         NULL,
    106         0,
    107         &br,
    108         NULL);
    109 
    110     if (0 != status){
    111         //initUsnJournalSuccess = true;
    112         return true;
    113     }
    114     else{
    115         printf("初始化USN日志文件失败 —— status:%x error:%d
    ", status, GetLastError());
    116         return false;
    117     }
    118     return false;
    119 }
    120 
    121 /**
    122 
    123 * step 04. 获取USN日志基本信息(用于后续操作)
    124 
    125 * msdn:http://msdn.microsoft.com/en-us/library/aa364583%28v=VS.85%29.aspx
    126 
    127 */
    128 bool getUSNInfo(HANDLE hVol, USN_JOURNAL_DATA& ujd){
    129     bool getBasicInfoSuccess = false;
    130     DWORD br;
    131     bool status = DeviceIoControl(hVol,
    132         FSCTL_QUERY_USN_JOURNAL,
    133         NULL,
    134         0,
    135         &ujd,
    136         sizeof(ujd),
    137         &br,
    138         NULL);
    139     if (0 != status){
    140         //getBasicInfoSuccess = true;
    141         printf("获取USN日志基本信息成功
    ");
    142         return true;
    143     }
    144     else{
    145         printf("获取USN日志基本信息失败 —— status:%x error:%d
    ", status, GetLastError());
    146         return false;
    147     }
    148     return false;
    149 }
    150 
    151 bool getUSNJournal(HANDLE hVol, USN_JOURNAL_DATA& ujd){
    152     MFT_ENUM_DATA_V0 med;
    153     med.StartFileReferenceNumber = 0;
    154     med.LowUsn = ujd.FirstUsn;
    155     med.HighUsn = ujd.NextUsn;
    156 #define BUF_LEN 4096  
    157     CHAR buffer[BUF_LEN]; // 用于储存记录的缓冲 , 尽量足够地大  
    158     DWORD usnDataSize = 0;
    159     PUSN_RECORD UsnRecord;
    160     while (0 != DeviceIoControl(hVol,
    161         FSCTL_ENUM_USN_DATA,
    162         &med,
    163         sizeof (med),
    164         buffer,
    165         BUF_LEN,
    166         &usnDataSize,
    167         NULL))
    168     {
    169         DWORD dwRetBytes = usnDataSize - sizeof (USN);
    170         // 找到第一个 USN 记录  
    171         // from MSDN(http://msdn.microsoft.com/en-us/library/aa365736%28v=VS.85%29.aspx ):  
    172         // return a USN followed by zero or more change journal records, each in a USN_RECORD structure.  
    173         UsnRecord = (PUSN_RECORD)(((PCHAR)buffer) + sizeof (USN));
    174         printf(" ********************************** 
    ");
    175         while (dwRetBytes>0){
    176             // 打印获取到的信息  
    177             const int strLen = UsnRecord->FileNameLength;
    178             char fileName[MAX_PATH] = { 0 };
    179             WideCharToMultiByte(CP_OEMCP, NULL, UsnRecord->FileName, strLen / 2, fileName, strLen, NULL, FALSE);
    180             printf("FileName: %s
    ", fileName);
    181             // 下面两个 file reference number 可以用来获取文件的路径信息  
    182             printf("FileReferenceNumber: %xI64
    ", UsnRecord->FileReferenceNumber);
    183             printf("ParentFileReferenceNumber: %xI64
    ", UsnRecord->ParentFileReferenceNumber);
    184             printf("
    ");
    185             // 获取下一个记录  
    186             DWORD recordLen = UsnRecord->RecordLength;
    187             dwRetBytes -= recordLen;
    188             UsnRecord = (PUSN_RECORD)(((PCHAR)UsnRecord) + recordLen);
    189         }
    190         // 获取下一页数据, MTF 大概是分多页来储存的吧?  
    191         // from MSDN(http://msdn.microsoft.com/en-us/library/aa365736%28v=VS.85%29.aspx ):  
    192         // The USN returned as the first item in the output buffer is the USN of the next record number to be retrieved.  
    193         // Use this value to continue reading records from the end boundary forward.  
    194         med.StartFileReferenceNumber = *(USN *)&buffer;
    195     }
    196     return true;
    197 }
    198 
    199 /**
    200 * step 06. 删除 USN 日志文件 ( 当然也可以不删除 )
    201 */
    202 bool deleteUSN(HANDLE hVol, USN_JOURNAL_DATA& ujd){
    203     DELETE_USN_JOURNAL_DATA dujd;
    204     dujd.UsnJournalID = ujd.UsnJournalID;
    205     dujd.DeleteFlags = USN_DELETE_FLAG_DELETE;
    206     DWORD br;
    207     int status = DeviceIoControl(hVol,
    208         FSCTL_DELETE_USN_JOURNAL,
    209         &dujd,
    210         sizeof (dujd),
    211         NULL,
    212         0,
    213         &br,
    214         NULL);
    215     if (0 != status){
    216         CloseHandle(hVol);
    217         printf(" 成功删除 USN 日志文件 !
    ");
    218         return true;
    219     }
    220     else {
    221         CloseHandle(hVol);
    222         printf(" 删除 USN 日志文件失败 —— status:%x error:%d
    ", status, GetLastError());
    223         return false;
    224     }
    225     return false;
    226 }

    运行结果:

  • 相关阅读:
    poj 2478 Farey Sequence
    “玲珑杯”第七届郑州轻工业学院ACM程序设计大赛 ------- D:社交网络
    bnu oj 13288 Bi-shoe and Phi-shoe
    uva 11029 Leading and Trailing
    hdu 1198 Farm Irrigation
    hdu 4965 Fast Matrix Calculation
    Preparing Olympiad---cf550B(DFS或者状态压缩模板)
    squee_spoon and his Cube VI---郑大校赛(求最长子串)
    确定比赛名次---hdu1285(拓扑排序)
    Buy the souvenirs---hdu2126(01背包输出方案数)
  • 原文地址:https://www.cnblogs.com/Toya/p/11398817.html
Copyright © 2011-2022 走看看