diff --git a/AutoDiskCopier_v3/.gitignore b/AutoDiskCopier_v3/.gitignore new file mode 100644 index 0000000..ac462d3 --- /dev/null +++ b/AutoDiskCopier_v3/.gitignore @@ -0,0 +1,2 @@ +build +*.aps diff --git a/AutoDiskCopier_v3/CMakeLists.txt b/AutoDiskCopier_v3/CMakeLists.txt new file mode 100644 index 0000000..e78da75 --- /dev/null +++ b/AutoDiskCopier_v3/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.10) +project(AutoDiskCopier) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +file(GLOB_RECURSE INC src/*.h) +file(GLOB_RECURSE SRC src/*.cpp) +file(GLOB_RECURSE RES src/*.rc) + +add_executable(AutoDiskCopier WIN32 ${SRC} ${INC} ${RES}) diff --git a/AutoDiskCopier_v3/build.bat b/AutoDiskCopier_v3/build.bat new file mode 100644 index 0000000..36eaf23 --- /dev/null +++ b/AutoDiskCopier_v3/build.bat @@ -0,0 +1,30 @@ +cd %~dp0 + +set BUILD_BITS=%1 +set BUILD_TYPE=%2 +set BUILD_COMPILE=%3 + +rem script params: build.bat [BUILD_BITS] [BUILD_TYPE] [BUILD_COMPILE] +rem default value: BUILD_BITS=x86 BUILD_TYPE=Release BUILD_COMPILE=VS2015 + +if "%BUILD_TYPE%"=="" (set BUILD_TYPE=Release) +if "%BUILD_COMPILE%"=="" (set BUILD_COMPILE=VS2017) + +if "%BUILD_COMPILE%"=="VS2015" (set BUILD_COMPILE=Visual Studio 14 2015) +if "%BUILD_COMPILE%"=="VS2017" (set BUILD_COMPILE=Visual Studio 15 2017) +if "%BUILD_COMPILE%"=="VS2019" (set BUILD_COMPILE=Visual Studio 16 2019) + +rem only VS2019 uses "BUILD_ARCH_ARG" +set BUILD_ARCH_ARG= +if "%BUILD_COMPILE%"=="Visual Studio 16 2019" ( +if "%BUILD_BITS%"=="x64" (set BUILD_ARCH_ARG=-A x64) ^ +else (set BUILD_ARCH_ARG=-A Win32) +) else ( +if "%BUILD_BITS%"=="x64" (set BUILD_COMPILE=%BUILD_COMPILE% Win64) +) + +mkdir build +cd build +cmake -G "%BUILD_COMPILE%" %BUILD_ARCH_ARG% .. +cmake --build . --config %BUILD_TYPE% -j 8 -- /p:CharacterSet=Unicode +cd .. diff --git a/AutoDiskCopier_v3/clean.bat b/AutoDiskCopier_v3/clean.bat new file mode 100644 index 0000000..03499bb --- /dev/null +++ b/AutoDiskCopier_v3/clean.bat @@ -0,0 +1 @@ +rd %~dp0build /S /Q diff --git a/AutoDiskCopier_v3/config.bat b/AutoDiskCopier_v3/config.bat new file mode 100644 index 0000000..d166dcd --- /dev/null +++ b/AutoDiskCopier_v3/config.bat @@ -0,0 +1,14 @@ +:: Manually configure the local environment. + +PATH=D:\CMake\cmake-3.16.0-win64-x64\bin;%PATH% +PATH=D:\CMake\cmake-3.19.8-win64-x64\bin;%PATH% +echo Env PATH: %PATH% + +:: The version of CMake finally used: +cmake --version + +:: The default build uses VS2015, if we have a higher version of VS, +:: use the higher version of MSBuild to build, then we need to add +:: the path of MSBuild.exe to the environment PATH. +:: And we need to install vc140 compatible compile and build tools. +PATH=D:\VS\2017\Enterprise\MSBuild\15.0\Bin;%PATH% diff --git a/AutoDiskCopier_v3/src/AutoDiskCopier.cpp b/AutoDiskCopier_v3/src/AutoDiskCopier.cpp new file mode 100644 index 0000000..7877355 --- /dev/null +++ b/AutoDiskCopier_v3/src/AutoDiskCopier.cpp @@ -0,0 +1,280 @@ +#include"AutoDiskCopier.h" + +#pragma comment(linker, \ + "/manifestdependency:\"" \ + "type='win32' " \ + "name='Microsoft.Windows.Common-Controls' " \ + "version='6.0.0.0' " \ + "processorArchitecture='*' " \ + "publicKeyToken='6595b64144ccf1df' " \ + "language='*'\"") + +static const TCHAR szAppNameEng[] = TEXT("AutoDiskCopier"); +static const TCHAR szAppNameChn[] = TEXT("自动磁盘拷贝器"); + +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + + +INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, INT iCmdShow) +{ + //--- Create a no show window to get other msg. ---// + + HWND hwnd; + MSG msg; + WNDCLASS wndclass; + memset(&hwnd, 0, sizeof(HWND)); + memset(&msg, 0, sizeof(MSG)); + memset(&wndclass, 0, sizeof(WNDCLASS)); + + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hInstance; + wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = szAppNameEng; + + if (!RegisterClass(&wndclass)) + { + MessageBox(NULL, TEXT("错误:主窗口类注册失败,该应用程序最低版本限制为WindowsNT!"), szAppNameChn, MB_ICONERROR | MB_OK); + return 0; + } + + hwnd = CreateWindow( + szAppNameEng, szAppNameChn, WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME, + 0, 0, 0, 0, GetDesktopWindow(), NULL, hInstance, NULL); + + //--- Program init. ---// + + //Accel. + + HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); + + //--- Message loop. ---// + + while (GetMessage(&msg, NULL, 0, 0)) + { + if (TranslateAccelerator(hwnd, hAccel, &msg)) + { + continue; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + //--- Program end. ---// + + return (int)msg.wParam; +} + + +LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static CAutoDiskCopier adc(hwnd); + + static HWND hDlgMain = NULL; + + switch (message) + { + + case WM_CREATE: + + hDlgMain = CreateDialogParam( + ((CREATESTRUCT*)lParam)->hInstance, MAKEINTRESOURCE(IDD_DIALOG), + hwnd, DlgProc, (LPARAM)(&adc)); + + //热键启动(Control + Alt + Shift + U) + RegisterHotKey(hwnd, 0, MOD_CONTROL | MOD_ALT | MOD_SHIFT, 'U'); + + //托盘图标 + adc.m_ni.SetTip(TEXT("AutoDiskCopier v3.0")); + adc.m_ni.SetIcon(((CREATESTRUCT*)lParam)->hInstance, MAKEINTRESOURCE(IDI_ICON)); + + if (adc.m_bEnableNotifyIcon) + { + adc.m_ni.AddNotificationIcon(); + } + + return 0; + + + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDR_ACCELERATOR_HIDE: + SendMessage(hDlgMain, WM_COMMAND, wParam, lParam); + } + break; + + case WM_HOTKEY: + + ShowWindow(hDlgMain, SW_NORMAL); + return 0; + + + case WM_NOTIFYICON: + + if (wParam == IDI_ICON && lParam == WM_RBUTTONDBLCLK) + { + adc.m_ni.DeleteNotificationIcon(); + ShowWindow(hDlgMain, SW_SHOWNORMAL); + } + break; + + + case WM_DEVICECHANGE: + + if ((DBT_DEVICEARRIVAL != wParam) || + (DBT_DEVTYP_VOLUME != ((PDEV_BROADCAST_HDR)lParam)->dbch_devicetype)) + { + //忽略设备安装不成功或非逻辑磁盘的消息 + return BROADCAST_QUERY_DENY; + } + else + { + DWORD dwDiskMask = ((PDEV_BROADCAST_VOLUME)lParam)->dbcv_unitmask; + UINT uiPos = 0; + TCHAR szCopyDiskPath[4]; + + for (uiPos = 0; !(dwDiskMask & 1); uiPos++) + { + dwDiskMask >>= 1; + } + + if (uiPos >= 26) + { + //磁盘盘符超标 + return BROADCAST_QUERY_DENY; + } + else + { + wsprintf(szCopyDiskPath, TEXT("%c%s"), 'A' + uiPos, TEXT(":\\")); + } + + adc.Copying(szCopyDiskPath); + + return TRUE; + } + + + case WM_DESTROY: + + PostQuitMessage(0); + return 0; + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} + + +INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + static CAutoDiskCopier * padc; + + switch (message) + { + case WM_INITDIALOG: + padc = (CAutoDiskCopier *)lParam; + padc->SetDlgInfo(hDlg); + padc->m_bfdlg.SetOwnerWindow(hDlg); + padc->m_osdlg.SetOwnerWindow(hDlg); + padc->m_osdlg.SetFilter(2, TEXT("签名文件(*.key)"), TEXT("*.key"), TEXT("所有文件(*.*)"), TEXT("*.*")); + padc->m_osdlg.SetDefExt(TEXT("key")); + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDCANCEL: + case IDC_BTN_HIDE: + case IDR_ACCELERATOR_HIDE: + ShowWindow(hDlg, SW_HIDE); + if (padc->m_bEnableNotifyIcon) + { + padc->m_ni.AddNotificationIcon(); + } + return TRUE; + + case IDC_BTN_QUIT: + SendMessage(GetParent(hDlg), WM_DESTROY, 0, 0); + return TRUE; + + case IDC_BTN_SAVESETTING: + padc->GetDlgInfo(hDlg); + padc->RegisterAutorun(hDlg); // 注册失败时会自动更改标记 + padc->SetDlgInfo(hDlg); // 因此重新获取一遍标记再SaveSetting + padc->SaveSetting(hDlg); + return TRUE; + + case IDC_BTN_BROWSECOPYFILEPATH: + if (padc->m_bfdlg.CmmDlgBrowse()) + { + TCHAR szPath[MAX_PATH]; + wsprintf(szPath, TEXT("%s%s"), padc->m_bfdlg.GetDir(), TEXT("\\")); + SetDlgItemText(hDlg, IDC_EDIT_COPYFILEPATH, szPath); + } + return TRUE; + + case IDC_BTN_CREATEKEYFILE: + if(padc->m_osdlg.CmnDlgSaveFile()) + { + HANDLE hFile = CreateFile(padc->m_osdlg.GetFilePath(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (INVALID_HANDLE_VALUE == hFile) + { + MessageBox(hDlg, TEXT("生成签名文件失败!"), TEXT("ADC - 签名"), MB_ICONERROR); + } + else + { + int iRand[2]; + char szMD5[33]; + for (UINT ui = 0; ui < 2; ui++) + { + srand(GetTickCount()); + iRand[ui] = rand(); + + padc->m_md5.CalcMD5((void *)(&iRand[ui]), sizeof(int)); + padc->m_md5.GetMD5(szMD5); + padc->m_md5.Reset(); + + DWORD dwWrited; + WriteFile(hFile, szMD5, 32 * sizeof(char), &dwWrited, NULL); + } + + CloseHandle(hFile); + MessageBox(hDlg, TEXT("已生成签名文件。"), TEXT("ADC - 签名"), MB_OK); + } + } + return TRUE; + + case IDC_BTN_BROWSEKEYFILEPATH: + if (padc->m_osdlg.CmnDlgOpenFile()) + { + SetDlgItemText(hDlg, IDC_EDIT_KEYFILEPATH, padc->m_osdlg.GetFilePath()); + } + return TRUE; + } + break; + + case WM_NOTIFY: + switch (((LPNMHDR)lParam)->code) + { + case NM_CLICK: + case NM_RETURN: + { + PNMLINK pnmLink = (PNMLINK)lParam; + if (((LPNMHDR)lParam)->hwndFrom == GetDlgItem(hDlg, IDC_SYSLINK)) + { + ShellExecute(NULL, TEXT("open"), TEXT("https://github.com/KondeU/AutoDiskCopier"), NULL, NULL, SW_SHOW); + return TRUE; + } + } + } + break; + } + return FALSE; +} diff --git a/AutoDiskCopier_v3/src/AutoDiskCopier.h b/AutoDiskCopier_v3/src/AutoDiskCopier.h new file mode 100644 index 0000000..78ade6c --- /dev/null +++ b/AutoDiskCopier_v3/src/AutoDiskCopier.h @@ -0,0 +1,403 @@ +#pragma once + +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include + +#include +#pragma comment(lib, "shlwapi.lib") + +#include +#pragma comment(lib, "shell32.lib") + +#include +#pragma comment(lib, "imagehlp.lib") + +#include"resource.h" + +#include"CmnDlg.h" +#include"NotifyIcon.h" +#include"MD5.h" + +using namespace COMMONDIALOG; +using namespace NOTIFYICON; +using namespace MD5; + +#define WM_NOTIFYICON (WM_USER + 1) + + +class CAutoDiskCopier +{ +public: + + CMD5 m_md5; + COSDlg m_osdlg; + CBrowseFolderDlg m_bfdlg; + CNotifyIcon m_ni; + + char m_szSettingFilePath[MAX_PATH]; + + bool m_bEnableNotifyIcon; + bool m_bMD5Check; + bool m_bPopupConfirmDialog; + bool m_bAutorun; + bool m_bLastAutorun; + + TCHAR m_szCopyFileSavePath[MAX_PATH]; + + bool m_bCheckKeyFile; + TCHAR m_szKey[MAX_PATH]; + + CAutoDiskCopier(HWND hwnd) : m_md5(), m_osdlg(NULL), m_bfdlg(NULL), m_ni(hwnd, IDI_ICON, WM_NOTIFYICON, false) + { + SHGetSpecialFolderPathA(hwnd, m_szSettingFilePath, 26/*“C:/Program Files”*/, TRUE); + + sprintf(m_szSettingFilePath, "%s%s", m_szSettingFilePath, "\\AutoDiskCopier\\Setting\\"); + MakeSureDirectoryPathExists(m_szSettingFilePath); + sprintf(m_szSettingFilePath, "%s%s", m_szSettingFilePath, "ADC_Setting.set"); + + HANDLE hFile = CreateFileA(m_szSettingFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (INVALID_HANDLE_VALUE == hFile) + { + //打开配置文件失败 -> 初始化 + + hFile = CreateFileA(m_szSettingFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (INVALID_HANDLE_VALUE == hFile) + { + //初始化失败 -> 程序退出 + + MessageBox(NULL, TEXT("程序初始化失败!\n创建配置文件失败!"), TEXT("ADC - 初始化错误"), MB_ICONERROR); + PostQuitMessage(GetLastError()); + } + else + { + //初始化成功 + + SHGetSpecialFolderPath(hwnd, m_szCopyFileSavePath, 26/*“C:/Program Files”*/, TRUE); + wsprintf(m_szCopyFileSavePath, TEXT("%s%s"), m_szCopyFileSavePath, TEXT("\\AutoDiskCopier\\CopiedFiles\\")); + CreateDirectory(m_szCopyFileSavePath, NULL); + + m_bEnableNotifyIcon = true; + m_bAutorun = false; + m_bLastAutorun = m_bAutorun; + m_bPopupConfirmDialog = true; + m_bMD5Check = false; + + m_bCheckKeyFile = false; + wsprintf(m_szKey, TEXT("")); + + DWORD dwWrited = 0; + WriteFile(hFile, &m_bEnableNotifyIcon, sizeof(bool), &dwWrited, NULL); + WriteFile(hFile, &m_bAutorun, sizeof(bool), &dwWrited, NULL); + WriteFile(hFile, &m_bPopupConfirmDialog, sizeof(bool), &dwWrited, NULL); + WriteFile(hFile, &m_bMD5Check, sizeof(bool), &dwWrited, NULL); + WriteFile(hFile, &m_bCheckKeyFile, sizeof(bool), &dwWrited, NULL); + WriteFile(hFile, m_szCopyFileSavePath, MAX_PATH * sizeof(TCHAR), &dwWrited, NULL); + WriteFile(hFile, m_szKey, MAX_PATH * sizeof(TCHAR), &dwWrited, NULL); + + CloseHandle(hFile); + + MessageBox(NULL, TEXT("程序初始化完成。"), TEXT("ADC - 初始化完成"), MB_OK); + } + } + else + { + //打开配置文件成功 + + DWORD dwReaded = 0; + ReadFile(hFile, &m_bEnableNotifyIcon, sizeof(bool), &dwReaded, NULL); + ReadFile(hFile, &m_bAutorun, sizeof(bool), &dwReaded, NULL); + ReadFile(hFile, &m_bPopupConfirmDialog, sizeof(bool), &dwReaded, NULL); + ReadFile(hFile, &m_bMD5Check, sizeof(bool), &dwReaded, NULL); + ReadFile(hFile, &m_bCheckKeyFile, sizeof(bool), &dwReaded, NULL); + ReadFile(hFile, m_szCopyFileSavePath, MAX_PATH * sizeof(TCHAR), &dwReaded, NULL); + ReadFile(hFile, m_szKey, MAX_PATH * sizeof(TCHAR), &dwReaded, NULL); + CloseHandle(hFile); + m_bLastAutorun = m_bAutorun; + } + } + + void Copying(PCTSTR szCopyDiskPath) + { + if (m_bPopupConfirmDialog) + { + if (IDYES != MessageBox(NULL, TEXT("已检测到磁盘接入,是否执行复制?"), TEXT("ADC - 确认复制"), MB_YESNO)) + { + return; + } + } + + /*_beginthread(&(CAutoDiskCopier::CopyingThread), 0, (void *)szCopyDiskPath);*/ + CopyingThread(szCopyDiskPath); // + } + + void SetDlgInfo(HWND hwnd) + { + CheckDlgButton(hwnd, IDC_CHCK_SHOWNOTIFYICON, m_bEnableNotifyIcon ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwnd, IDC_CHCK_MD5, m_bMD5Check ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwnd, IDC_CHCK_CONFIRMDIALOG, m_bPopupConfirmDialog ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwnd, IDC_CHCK_AUTORUN, m_bAutorun ? BST_CHECKED : BST_UNCHECKED); + + SetDlgItemText(hwnd, IDC_EDIT_COPYFILEPATH, m_szCopyFileSavePath); + + CheckDlgButton(hwnd, IDC_CHCK_CHECKKEY, m_bCheckKeyFile ? BST_CHECKED : BST_UNCHECKED); + SetDlgItemText(hwnd, IDC_EDIT_KEYFILEPATH, m_szKey); + } + + void GetDlgInfo(HWND hwnd) + { + m_bEnableNotifyIcon = (BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_CHCK_SHOWNOTIFYICON)) ? true : false; + m_bMD5Check = (BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_CHCK_MD5)) ? true : false; + m_bPopupConfirmDialog = (BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_CHCK_CONFIRMDIALOG)) ? true : false; + m_bAutorun = (BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_CHCK_AUTORUN)) ? true : false; + + GetDlgItemText(hwnd, IDC_EDIT_COPYFILEPATH, m_szCopyFileSavePath, MAX_PATH); + + m_bCheckKeyFile = (BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_CHCK_CHECKKEY)) ? true : false; + GetDlgItemText(hwnd, IDC_EDIT_KEYFILEPATH, m_szKey, MAX_PATH); + } + + void SaveSetting(HWND hwnd) + { + HANDLE hFile = CreateFileA(m_szSettingFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + if (INVALID_HANDLE_VALUE == hFile) + { + MessageBox(hwnd, TEXT("保存设置失败!"), TEXT("ADC - 保存设置"), MB_ICONERROR); + } + else + { + DWORD dwWrited = 0; + WriteFile(hFile, &m_bEnableNotifyIcon, sizeof(bool), &dwWrited, NULL); + WriteFile(hFile, &m_bAutorun, sizeof(bool), &dwWrited, NULL); + WriteFile(hFile, &m_bPopupConfirmDialog, sizeof(bool), &dwWrited, NULL); + WriteFile(hFile, &m_bMD5Check, sizeof(bool), &dwWrited, NULL); + WriteFile(hFile, &m_bCheckKeyFile, sizeof(bool), &dwWrited, NULL); + WriteFile(hFile, m_szCopyFileSavePath, MAX_PATH * sizeof(TCHAR), &dwWrited, NULL); + WriteFile(hFile, m_szKey, MAX_PATH * sizeof(TCHAR), &dwWrited, NULL); + + CloseHandle(hFile); + + MessageBox(hwnd, TEXT("保存设置成功!"), TEXT("ADC - 保存设置"), MB_OK); + } + } + + void RegisterAutorun(HWND hwnd) + { + TCHAR szFilePath[MAX_PATH]; + GetModuleFileName(NULL, szFilePath, MAX_PATH); + + if (m_bAutorun != m_bLastAutorun) + { + HKEY hReg; + RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), &hReg); + if (m_bAutorun) + { + if (ERROR_SUCCESS == RegSetValueEx(hReg, TEXT("AutoDiskCopier"), 0, REG_SZ, (BYTE*)szFilePath, (lstrlen(szFilePath) + 1) * sizeof(TCHAR))) + { + m_bLastAutorun = m_bAutorun; + } + else + { + MessageBox(hwnd, TEXT("自启动设置失败,请检查是否有注册表写权限(管理员权限)!"), TEXT("ADC - 保存设置"), MB_ICONWARNING); + m_bAutorun = m_bLastAutorun; + } + } + else + { + if (ERROR_SUCCESS == RegDeleteValue(hReg, TEXT("AutoDiskCopier"))) + { + m_bLastAutorun = m_bAutorun; + } + else + { + MessageBox(hwnd, TEXT("自启动设置失败,请检查是否有注册表写权限(管理员权限)!"), TEXT("ADC - 保存设置"), MB_ICONWARNING); + m_bAutorun = m_bLastAutorun; + } + } + RegCloseKey(hReg); + } + } + + +private: + + void CopyingThread(PCTSTR szCopyDiskPath) + { + if ((m_bCheckKeyFile) && + (1 == this->CheckIsKeyFileSame(szCopyDiskPath, m_szKey))) + { + //检测:开关打开;存在不进行复制命令的Key文件 + return; + } + + //获得电脑当地当前时间以建立相关文件夹 + SYSTEMTIME st; + TCHAR szSavePath[MAX_PATH] = { 0 }; + wsprintf(szSavePath, m_szCopyFileSavePath); + GetLocalTime(&st); + wsprintf( szSavePath, TEXT("%s%d年"), szSavePath, st.wYear ); + wsprintf( szSavePath, TEXT("%s%d月"), szSavePath, st.wMonth ); + wsprintf( szSavePath, TEXT("%s%d日"), szSavePath, st.wDay ); + wsprintf( szSavePath, TEXT("%s%d时"), szSavePath, st.wHour ); + wsprintf( szSavePath, TEXT("%s%d分"), szSavePath, st.wMinute ); + wsprintf( szSavePath, TEXT("%s%d秒\\"), szSavePath, st.wSecond ); + if (!CreateDirectory(szSavePath, NULL)) + { + SHGetSpecialFolderPath(NULL, szSavePath, 26/*“C:/Program Files”*/, TRUE); + wsprintf(szSavePath, TEXT("%s%s"), szSavePath, TEXT("\\AutoDiskCopier\\CopiedFiles\\")); + GetLocalTime(&st); + wsprintf( szSavePath, TEXT("%s%d年"), szSavePath, st.wYear ); + wsprintf( szSavePath, TEXT("%s%d月"), szSavePath, st.wMonth ); + wsprintf( szSavePath, TEXT("%s%d日"), szSavePath, st.wDay ); + wsprintf( szSavePath, TEXT("%s%d时"), szSavePath, st.wHour ); + wsprintf( szSavePath, TEXT("%s%d分"), szSavePath, st.wMinute ); + wsprintf( szSavePath, TEXT("%s%d秒\\"), szSavePath, st.wSecond ); + CreateDirectory(szSavePath, NULL); + } + + //复制文件 + Copy(szSavePath, szCopyDiskPath); + + /*_endthread();*/ + } + + int CheckIsKeyFileSame(PCTSTR szCopyDiskPath, PCTSTR szKeyFilePath) + { + TCHAR szDiskPath [260] = { 0 }; + TCHAR szKeyFileName [260] = { 0 }; + wsprintf(szDiskPath, TEXT("%s%s"), szCopyDiskPath, TEXT("*")); + wsprintf(szKeyFileName, PathFindFileName(szKeyFilePath)); + + WIN32_FIND_DATA wfd; + HANDLE hFindFile = FindFirstFile(szDiskPath, &wfd); + + if (INVALID_HANDLE_VALUE == hFindFile) + { + return -1; + } + + do + { + if (!lstrcmp(wfd.cFileName, szKeyFileName)) + { + TCHAR szCheckFile[MAX_PATH] = { 0 }; + wsprintf(szCheckFile, TEXT("%s%s"), szCopyDiskPath, szKeyFileName); + + HANDLE hFileCheck = CreateFile(szCheckFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE hFileKey = CreateFile(szKeyFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if ((INVALID_HANDLE_VALUE == hFileCheck) || (INVALID_HANDLE_VALUE == hFileKey)) + { + return -1; + } + + BYTE byCheck [64] = { 0 }; + BYTE byKey [64] = { 0 }; + DWORD dwReaded = 0; + + ReadFile(hFileCheck, byCheck, 64, &dwReaded, NULL); + ReadFile(hFileKey, byKey, 64, &dwReaded, NULL); + + for (UINT ui = 0; ui < 64; ui++) + { + if (byCheck[ui] != byKey[ui]) + { + CloseHandle(hFileCheck); + CloseHandle(hFileKey); + + return 0; + } + } + + CloseHandle(hFileCheck); + CloseHandle(hFileKey); + + return 1; + } + } + while (FindNextFile(hFindFile, &wfd)); + + return 0; + } + + void Copy(PCTSTR szStorePath, PCTSTR szResourcePath) + { + TCHAR szFileStorePath[MAX_PATH]; //目标存储位置路径 C:\A.D.C.\CopiedFiles\DIRECTORY\.... + TCHAR szFileResourcePath[MAX_PATH]; //源文件位置路径 U:\DIRECTORY\.... + TCHAR szFileRsrcSrchPath[MAX_PATH]; //源文件位置路径搜索 U:\* + + lstrcpy(szFileStorePath, szStorePath); //获取目标存储位置路径 + lstrcpy(szFileResourcePath, szResourcePath); //获取源文件位置路径 + wsprintf(szFileRsrcSrchPath, TEXT("%s%s"), szFileResourcePath, TEXT("*")); //设置目标存储位置路径搜索 + + HANDLE hFindFile = NULL; + WIN32_FIND_DATA wfd; + + TCHAR szBuffer[MAX_PATH]; + + if ((hFindFile = FindFirstFile(szFileRsrcSrchPath, &wfd)) == INVALID_HANDLE_VALUE) + { + return; + } + + do + { + if ((lstrcmp(wfd.cFileName, TEXT(".")) && lstrcmp(wfd.cFileName, TEXT("..")))) + { + wsprintf(szBuffer, TEXT("%s%s"), szFileResourcePath, wfd.cFileName); + + if (wfd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) + { + wsprintf(szFileRsrcSrchPath, TEXT("%s\\"), szBuffer); + wsprintf(szFileStorePath, TEXT("%s%s\\"), szFileStorePath, wfd.cFileName); + CreateDirectory(szFileStorePath, NULL); + Copy(szFileStorePath, szFileRsrcSrchPath); + } + else + { + lstrcat(szFileStorePath, wfd.cFileName); + + for (UINT ui = 0; ui < 3; ui++) + { + CopyFile(szBuffer, szFileStorePath, FALSE); + + if (m_bMD5Check) + { + //MD5文件校验 - 此处有Unicode和Ansi的冲突,需要处理BUG + char szOrgnMD5[33] = { 0 }; + char szDestMD5[33] = { 0 }; + m_md5.CalcMD5(szBuffer, true); + m_md5.GetMD5(szOrgnMD5); + m_md5.Reset(); + m_md5.CalcMD5(szFileStorePath, true); + m_md5.GetMD5(szDestMD5); + m_md5.Reset(); + if (!strcmp(szOrgnMD5, szDestMD5)) + { + break; + } + } + else + { + break; + } + } + } + } + + lstrcpy(szFileStorePath, szStorePath); + lstrcpy(szFileResourcePath, szResourcePath); + wsprintf(szFileRsrcSrchPath, TEXT("%s%s"), szFileResourcePath, TEXT("*")); + } + while (FindNextFile(hFindFile, &wfd)); + + FindClose(hFindFile); + + return; + } + +}; diff --git a/AutoDiskCopier_v3/src/AutoDiskCopier.rc b/AutoDiskCopier_v3/src/AutoDiskCopier.rc new file mode 100644 index 0000000..c92fadf Binary files /dev/null and b/AutoDiskCopier_v3/src/AutoDiskCopier.rc differ diff --git a/AutoDiskCopier_v3/src/CmnDlg.h b/AutoDiskCopier_v3/src/CmnDlg.h new file mode 100644 index 0000000..9201edd --- /dev/null +++ b/AutoDiskCopier_v3/src/CmnDlg.h @@ -0,0 +1,307 @@ +#pragma once + +#include + +namespace COMMONDIALOG +{ + class COSDlg + { + + public: + + COSDlg(HWND hOwnerWnd); + ~COSDlg(); + + inline void SetOwnerWindow(HWND hwnd); + + void SetTitle(LPCTSTR szTitle = nullptr); + void SetFilter(UINT uiExtCount, ...); + void SetDefExt(const TCHAR szDefExt[4] = nullptr); + + inline const TCHAR * GetFilePath() const; + inline DWORD GetFilterIndex() const; + inline WORD GetFileNameOffset() const; + inline WORD GetFileExtOffset() const; + + inline BOOL CmnDlgOpenFile(); + inline BOOL CmnDlgSaveFile(); + + private: + + OPENFILENAME m_ofn; + + TCHAR * m_szFilter; + TCHAR * m_szTitle; + TCHAR * m_szDefExt; + TCHAR m_szFilePath [MAX_PATH]; + + }; + + class CBrowseFolderDlg + { + + public: + + CBrowseFolderDlg::CBrowseFolderDlg(HWND hOwnerWnd); + + inline void SetOwnerWindow(HWND hwnd); + + inline bool CmmDlgBrowse(); + + inline const TCHAR * GetDir() const; + + private: + + BROWSEINFO m_bi; + + TCHAR m_szSelectDir[MAX_PATH]; + TCHAR m_szTitle[64]; + + }; + + + + //COSDlg实现: + + COSDlg::COSDlg(HWND hOwnerWnd) +{ + m_szFilter = nullptr; + m_szTitle = nullptr; + m_szDefExt = nullptr; + memset(m_szFilePath, 0, sizeof(m_szFilePath)); + + //--------------------- 初始化ofn ---------------------// + + memset(&m_ofn, 0, sizeof(OPENFILENAME)); + m_ofn.lStructSize = sizeof(OPENFILENAME); + + //---------- 使用的参数 ----------// + + m_ofn.hwndOwner = hOwnerWnd; //[in]------打开、保存对话框父窗口 + m_ofn.Flags = 0; //[in]------功能选择子(在函数中具体设置) + m_ofn.lpstrTitle = nullptr; //[in]------打开、保存对话框窗口标题栏字符串(独立函数设置) + m_ofn.lpstrFilter = nullptr; //[in]------筛选器字符串(独立函数设置) + m_ofn.nFilterIndex = 0; //[in/out]--控件中当前选择的筛选器的索引 + m_ofn.lpstrFile = m_szFilePath; //[in/out]--控件当前获取的文件及其路径 + m_ofn.nMaxFile = MAX_PATH; //[in]------ofn.lpstrFile的最大字符个数 + m_ofn.lpstrDefExt = nullptr; //[in]------默认扩展名(独立函数设置) + m_ofn.nFileOffset = 0; //[out]-----从路径开始到文件名的偏移字符个数 + m_ofn.nFileExtension = 0; //[out]-----从路径开始到文件名的扩展名的偏移字符个数 + + //--------- 未启用的参数 ---------// + + m_ofn.hInstance = NULL; //[in]---对话框模板对象实例句柄 + m_ofn.lpTemplateName = nullptr; //[in]---对话框模板资源的名字 + m_ofn.lpstrCustomFilter = nullptr; //[out]--定制筛选器缓冲区指针 + m_ofn.nMaxCustFilter = 0; //[in]---ofn.lpstrCustomFilter的最大字符个数 + m_ofn.lpstrTitle = nullptr; //[out]--控件当前获取的文件的文件名 + m_ofn.nMaxFileTitle = 0; //[in]---ofn.lpstrTitle的最大字符个数 + m_ofn.lpstrInitialDir = nullptr; //[in]---打开、保存对话框的初始目录 + m_ofn.lpfnHook = nullptr; //[in]---钩子函数 + m_ofn.lCustData = 0; //[in]---传递到钩子函数的数据 +} + + COSDlg::~COSDlg() + { + if (m_szFilter) + { + delete [] m_szFilter; + m_szFilter = nullptr; + } + + if (m_szTitle) + { + delete [] m_szTitle; + m_szTitle = nullptr; + } + + if (m_szDefExt) + { + delete [] m_szDefExt; + m_szDefExt = nullptr; + } + } + + inline void COSDlg::SetOwnerWindow(HWND hwnd) + { + m_ofn.hwndOwner = hwnd; + } + + void COSDlg::SetTitle(LPCTSTR szTitle) + { + if (m_szTitle) + { + delete [] m_szTitle; + } + + if (szTitle) + { + m_szTitle = new TCHAR [lstrlen(szTitle) + 1]; + lstrcpy(m_szTitle, szTitle); + } + else + { + m_szTitle = nullptr; + } + + m_ofn.lpstrTitle = m_szTitle; + } + + void COSDlg::SetFilter(UINT uiExtCount, ...) + { + if (m_szFilter) + { + delete [] m_szFilter; + } + + if (!uiExtCount) + { + m_szFilter = nullptr; + m_ofn.lpstrFilter = m_szFilter; + return; + } + + UINT uiTotalStringLen = 0; + TCHAR ** pszFilterPart = new TCHAR * [2 * uiExtCount]; + + va_list arg_ptr; + va_start(arg_ptr, uiExtCount); + + for (UINT ui = 0; ui < 2 * uiExtCount; ui++) + { + pszFilterPart[ui] = va_arg(arg_ptr, TCHAR *); + uiTotalStringLen += lstrlen(pszFilterPart[ui]) + 1; + } + uiTotalStringLen++; + + va_end(arg_ptr); + + m_szFilter = new TCHAR [uiTotalStringLen]; + memset(m_szFilter, '\0', uiTotalStringLen * sizeof(TCHAR)); + + TCHAR * pPos = &m_szFilter[0]; + for (UINT ui = 0; ui < 2 * uiExtCount; ui++) + { + lstrcat(pPos, pszFilterPart[ui]); + pPos += lstrlen(pszFilterPart[ui]) + 1; + } + + m_ofn.lpstrFilter = m_szFilter; + } + + void COSDlg::SetDefExt(const TCHAR szDefExt[4]) + { + if (szDefExt) + { + if (!m_szDefExt) + { + m_szDefExt = new TCHAR [4]; + } + lstrcpy(m_szDefExt, szDefExt); + } + else + { + if (m_szDefExt) + { + delete [] m_szDefExt; + m_szDefExt = nullptr; + } + } + + m_ofn.lpstrDefExt = m_szDefExt; + } + + inline const TCHAR * COSDlg::GetFilePath() const + { + return m_szFilePath; + } + + inline DWORD COSDlg::GetFilterIndex() const + { + return m_ofn.nFilterIndex; + } + + inline WORD COSDlg::GetFileNameOffset() const + { + return m_ofn.nFileOffset; + } + + inline WORD COSDlg::GetFileExtOffset() const + { + return m_ofn.nFileExtension; + } + + inline BOOL COSDlg::CmnDlgOpenFile() + { + m_ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; + return GetOpenFileName(&m_ofn); + } + + inline BOOL COSDlg::CmnDlgSaveFile() + { + m_ofn.Flags = OFN_EXPLORER | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT; + return GetSaveFileName(&m_ofn); + } + + + + //CBrowseFolderDlg实现: + + CBrowseFolderDlg::CBrowseFolderDlg(HWND hOwnerWnd) + { + m_bi.hwndOwner = hOwnerWnd; + m_bi.pidlRoot = NULL; + m_bi.pszDisplayName = m_szSelectDir; + m_bi.lpszTitle = m_szTitle; + m_bi.ulFlags = /*BIF_RETURNONLYFSDIRS*/0; + + m_bi.lpfn = NULL; + m_bi.lParam = 0; + m_bi.iImage = 0; + + wsprintf(m_szTitle, TEXT("选择文件夹:")); + } + + inline void CBrowseFolderDlg::SetOwnerWindow(HWND hwnd) + { + m_bi.hwndOwner = hwnd; + } + + inline bool CBrowseFolderDlg::CmmDlgBrowse() + { + LPITEMIDLIST pItemIDList = SHBrowseForFolder(&m_bi); + + if (!pItemIDList) + { + return false; + } + + if (!SHGetPathFromIDList(pItemIDList, m_szSelectDir)) + { + //获取文件夹信息失败 + //MessageBox(NULL, TEXT("获取文件夹信息失败!"), TEXT("错误"), MB_ICONERROR); + } + + //使用IMalloc接口防止内存泄漏 + IMalloc * pMalloc; + if (NOERROR != SHGetMalloc(&pMalloc)) + { + //未返回有效的IMalloc接口指针,无法取得外壳程序的IMalloc接口 + //MessageBox(NULL, TEXT("释放接口指针失败!"), TEXT("错误"), MB_ICONERROR); + } + + pMalloc->Free(pItemIDList); + + if (pMalloc) + { + pMalloc->Release(); + } + + return true; + } + + inline const TCHAR * CBrowseFolderDlg::GetDir() const + { + return m_szSelectDir; + } +} diff --git a/AutoDiskCopier_v3/src/MD5.h b/AutoDiskCopier_v3/src/MD5.h new file mode 100644 index 0000000..6b676d7 --- /dev/null +++ b/AutoDiskCopier_v3/src/MD5.h @@ -0,0 +1,531 @@ +#pragma once + +#define _CRT_SECURE_NO_WARNINGS + +#include + +namespace MD5 +{ + typedef unsigned int uint; + typedef unsigned char uint8; + typedef unsigned long uint32; + typedef unsigned long long uint64; + + + class CMD5 + { + + public: + + CMD5( + uint32 ui32MD5ChainingA = 0x67452301ul, //标准幻数A:(01234567)hex + uint32 ui32MD5ChainingB = 0xEFCDAB89ul, //标准幻数B:(89ABCDEF)hex + uint32 ui32MD5ChainingC = 0x98BADCFEul, //标准幻数C:(FEDCBA98)hex + uint32 ui32MD5ChainingD = 0x10325476ul //标准幻数D:(76543210)hex + ); + + //重置数据 + inline void Reset(); + + //获取MD5值 + inline char * GetMD5(char * szMD5) const; + + //MD5:字节流 + void CalcMD5(const void * pvDataStream, uint32 ui32DataBytes); + //MD5:字符串 + void CalcMD5(const char * szString); + //MD5:文件 + void CalcMD5(const char * szFilePath, bool bIsBinary); + + private: + + static const uint msk_uiMD5TransformShiftMatrix[4][4]; //MD5变换移位矩阵 + static const uint32 msk_ui32MD5TransformAddMatrix[4][16]; //MD5变换增量矩阵 + + static const uint8 msk_ui8MD5PaddingArray[64]; //MD5拓展长度数组 + + uint32 m_ui32MD5ChainingA; //MD5链接变量A + uint32 m_ui32MD5ChainingB; //MD5链接变量B + uint32 m_ui32MD5ChainingC; //MD5链接变量C + uint32 m_ui32MD5ChainingD; //MD5链接变量D + + uint32 m_ui32State[4]; //MD5算法当前计算状态值 + + uint32 m_ui32ByteCounts[2]; //数据总字节数 + + uint8 m_ui8InputBuffer[64]; //输入缓冲区 + + char m_szMD5[33]; //MD5计算结果 + + bool m_bResetFlag; //复位标志 + + inline void Uint32to8(uint8 * pui8Output, const uint32 * pui32Input, uint uiInputByteCounts) const; + inline void Uint8to32(uint32 * pui32Output, const uint8 * pui8Input, uint uiInputByteCounts) const; + + inline uint32 F(const uint32 x, const uint32 y, const uint32 z) const; + inline uint32 G(const uint32 x, const uint32 y, const uint32 z) const; + inline uint32 H(const uint32 x, const uint32 y, const uint32 z) const; + inline uint32 I(const uint32 x, const uint32 y, const uint32 z) const; + + inline uint32 RotateLeft(const uint32 x, const uint uiShiftCount) const; + + inline void FF(uint32 & a, uint32 b, uint32 c, uint32 d, uint32 x, uint s, uint32 ac); + inline void GG(uint32 & a, uint32 b, uint32 c, uint32 d, uint32 x, uint s, uint32 ac); + inline void HH(uint32 & a, uint32 b, uint32 c, uint32 d, uint32 x, uint s, uint32 ac); + inline void II(uint32 & a, uint32 b, uint32 c, uint32 d, uint32 x, uint s, uint32 ac); + + void Transform(const uint8 ui8Block[64]); + + void Update(const uint8 * pui8Input, uint32 ui32InputBytes); + + void Calculate(); + + }; + + //初始化MD5变换移位矩阵 + const uint CMD5::msk_uiMD5TransformShiftMatrix[4][4] = + { + {7, 12, 17, 22}, + {5, 9, 14, 20}, + {4, 11, 16, 23}, + {6, 10, 15, 21} + }; + + //初始化MD5变换增量矩阵 + const uint32 CMD5::msk_ui32MD5TransformAddMatrix[4][16] = + { + /* + loop i=1..64 : 4294967296 * abs(sin(i)) + 4294967296 = 2^32 + */ + + { + 0xD76AA478, //0xd76aa478 + 0xE8C7B756, //0xe8c7b756 + 0x242070DB, //0x242070db + 0xC1BDCEEE, //0xc1bdceee + 0xF57C0FAF, //0xf57c0faf + 0x4787C62A, //0x4787c62a + 0xA8304613, //0xa8304613 + 0xFD469501, //0xfd469501 + 0x698098D8, //0x698098d8 + 0x8B44F7AF, //0x8b44f7af + 0xFFFF5BB1, //0xffff5bb1 + 0x895CD7BE, //0x895cd7be + 0x6B901122, //0x6b901122 + 0xFD987193, //0xfd987193 + 0xA679438E, //0xa679438e + 0x49B40821 //0x49b40821 + }, + + { + 0xF61E2562, //0xf61e2562 + 0xC040B340, //0xc040b340 + 0x265E5A51, //0x265e5a51 + 0xE9B6C7AA, //0xe9b6c7aa + 0xD62F105D, //0xd62f105d + 0x02441453, //0x02441453 + 0xD8A1E681, //0xd8a1e681 + 0xE7D3FBC8, //0xe7d3fbc8 + 0x21E1CDE6, //0x21e1cde6 + 0xC33707D6, //0xc33707d6 + 0xF4D50D87, //0xf4d50d87 + 0x455A14ED, //0x455a14ed + 0xA9E3E905, //0xa9e3e905 + 0xFCEFA3F8, //0xfcefa3f8 + 0x676F02D9, //0x676f02d9 + 0x8D2A4C8A //0x8d2a4c8a + }, + + { + 0xFFFA3942, //0xfffa3942 + 0x8771F681, //0x8771f681 + 0x6D9D6122, //0x6d9d6122 + 0xFDE5380C, //0xfde5380c + 0xA4BEEA44, //0xa4beea44 + 0x4BDECFA9, //0x4bdecfa9 + 0xF6BB4B60, //0xf6bb4b60 + 0xBEBFBC70, //0xbebfbc70 + 0x289B7EC6, //0x289b7ec6 + 0xEAA127FA, //0xeaa127fa + 0xD4EF3085, //0xd4ef3085 + 0x04881D05, //0x04881d05 + 0xD9D4D039, //0xd9d4d039 + 0xE6DB99E5, //0xe6db99e5 + 0x1FA27CF8, //0x1fa27cf8 + 0xC4AC5665 //0xc4ac5665 + }, + + { + 0xF4292244, //0xf4292244 + 0x432AFF97, //0x432aff97 + 0xAB9423A7, //0xab9423a7 + 0xFC93A039, //0xfc93a039 + 0x655B59C3, //0x655b59c3 + 0x8F0CCC92, //0x8f0ccc92 + 0xFFEFF47D, //0xffeff47d + 0x85845DD1, //0x85845dd1 + 0x6FA87E4F, //0x6fa87e4f + 0xFE2CE6E0, //0xfe2ce6e0 + 0xA3014314, //0xa3014314 + 0x4E0811A1, //0x4e0811a1 + 0xF7537E82, //0xf7537e82 + 0xBD3AF235, //0xbd3af235 + 0x2AD7D2BB, //0x2ad7d2bb + 0xEB86D391 //0xeb86d391 + } + }; + + //初始化MD5拓展长度数组 + const uint8 CMD5::msk_ui8MD5PaddingArray[64] = { 0x80 }; + + + //CMD5实现: + + CMD5::CMD5(uint32 ui32MD5ChainingA, uint32 ui32MD5ChainingB, uint32 ui32MD5ChainingC, uint32 ui32MD5ChainingD) + { + m_ui32MD5ChainingA = ui32MD5ChainingA; + m_ui32MD5ChainingB = ui32MD5ChainingB; + m_ui32MD5ChainingC = ui32MD5ChainingC; + m_ui32MD5ChainingD = ui32MD5ChainingD; + + this->Reset(); + } + + inline void CMD5::Reset() + { + m_bResetFlag = true; + + m_ui32State[0] = m_ui32MD5ChainingA; + m_ui32State[1] = m_ui32MD5ChainingB; + m_ui32State[2] = m_ui32MD5ChainingC; + m_ui32State[3] = m_ui32MD5ChainingD; + + memset(m_ui32ByteCounts, 0, sizeof(uint32) * 2); + + memset(m_ui8InputBuffer, 0, sizeof(uint8) * 64); + + memset(m_szMD5, 0, sizeof(char) * 33); + + return; + } + + inline char * CMD5::GetMD5(char * szMD5) const + { + strcpy(szMD5, m_szMD5); + return szMD5; + } + + void CMD5::CalcMD5(const void * pvDataStream, uint32 ui32DataBytes) + { + if (false == m_bResetFlag) + { + return; + } + else + { + m_bResetFlag = false; + } + + this->Update((uint8 *)(pvDataStream), ui32DataBytes); + this->Calculate(); + + return; + } + + void CMD5::CalcMD5(const char * szString) + { + if (false == m_bResetFlag) + { + return; + } + else + { + m_bResetFlag = false; + } + + this->Update((uint8 *)(szString), strlen(szString)); + this->Calculate(); + + return; + } + + void CMD5::CalcMD5(const char * szFilePath, bool bIsBinary) + { + if (false == m_bResetFlag) + { + return; + } + else + { + m_bResetFlag = false; + } + + std::ifstream fin(szFilePath, bIsBinary ? (std::ios::binary) : (std::ios_base::in)); + + if (!fin) + { + return; + } + + std::streamsize ReadBytes = 0; + char cReadBuffer[1024] = { 0 }; + + while (!fin.eof()) + { + fin.read(cReadBuffer, 1024); + ReadBytes = fin.gcount(); + if (ReadBytes > 0) + { + //streamsize-->uint32可能丢失数据,限制缓冲区大小为1024bytes + this->Update((uint8 *)cReadBuffer, MD5::uint32(ReadBytes)); + } + } + + fin.close(); + + this->Calculate(); + + return; + } + + inline void CMD5::Uint32to8(uint8 * pui8Output, const uint32 * pui32Input, uint uiInputByteCounts) const + { + for (uint uiInputPos = 0, uiOutputPos = 0; uiOutputPos < uiInputByteCounts; uiInputPos++) + { + pui8Output[uiOutputPos++] = (uint8)((pui32Input[uiInputPos]) & 0xFF); + pui8Output[uiOutputPos++] = (uint8)((pui32Input[uiInputPos] >> 8) & 0xFF); + pui8Output[uiOutputPos++] = (uint8)((pui32Input[uiInputPos] >> 16) & 0xFF); + pui8Output[uiOutputPos++] = (uint8)((pui32Input[uiInputPos] >> 24) & 0xFF); + } + + return; + } + + inline void CMD5::Uint8to32(uint32 * pui32Output, const uint8 * pui8Input, uint uiInputByteCounts) const + { + for (uint uiInputPos = 0, uiOutputPos = 0; uiInputPos < uiInputByteCounts; uiOutputPos++) + { + pui32Output[uiOutputPos] = (uint32)(pui8Input[uiInputPos++]); + pui32Output[uiOutputPos] |= (uint32)(pui8Input[uiInputPos++]) << 8; + pui32Output[uiOutputPos] |= (uint32)(pui8Input[uiInputPos++]) << 16; + pui32Output[uiOutputPos] |= (uint32)(pui8Input[uiInputPos++]) << 24; + } + + return; + } + + inline uint32 CMD5::F(const uint32 x, const uint32 y, const uint32 z) const + { + return ((x & y) | ((~x) & z)); + } + + inline uint32 CMD5::G(const uint32 x, const uint32 y, const uint32 z) const + { + return ((x & z) | (y & (~z))); + } + + inline uint32 CMD5::H(const uint32 x, const uint32 y, const uint32 z) const + { + return x^y^z; + } + + inline uint32 CMD5::I(const uint32 x, const uint32 y, const uint32 z) const + { + return (y ^ (x | (~z))); + } + + inline uint32 CMD5::RotateLeft(const uint32 x, const uint uiShiftCount) const + { + return ((x << uiShiftCount) | (x >> (32 - uiShiftCount))); + } + + inline void CMD5::FF(uint32 & a, uint32 b, uint32 c, uint32 d, uint32 x, uint s, uint32 ac) + { + a += F(b, c, d) + x + ac; + a = RotateLeft(a, s); + a += b; + } + + inline void CMD5::GG(uint32 & a, uint32 b, uint32 c, uint32 d, uint32 x, uint s, uint32 ac) + { + a += G(b, c, d) + x + ac; + a = RotateLeft(a, s); + a += b; + } + + inline void CMD5::HH(uint32 & a, uint32 b, uint32 c, uint32 d, uint32 x, uint s, uint32 ac) + { + a += H(b, c, d) + x + ac; + a = RotateLeft(a, s); + a += b; + } + + inline void CMD5::II(uint32 & a, uint32 b, uint32 c, uint32 d, uint32 x, uint s, uint32 ac) + { + a += I(b, c, d) + x + ac; + a = RotateLeft(a, s); + a += b; + } + + void CMD5::Transform(const uint8 ui8Block[64]) + { + register uint32 a = m_ui32State[0]; + register uint32 b = m_ui32State[1]; + register uint32 c = m_ui32State[2]; + register uint32 d = m_ui32State[3]; + + uint32 ui32Block[16]; + + this->Uint8to32(ui32Block, ui8Block, 64); + + /* Round 1 */ + FF(a, b, c, d, ui32Block[ 0], msk_uiMD5TransformShiftMatrix[0][0], msk_ui32MD5TransformAddMatrix[0][ 0]); /* 1 */ + FF(d, a, b, c, ui32Block[ 1], msk_uiMD5TransformShiftMatrix[0][1], msk_ui32MD5TransformAddMatrix[0][ 1]); /* 2 */ + FF(c, d, a, b, ui32Block[ 2], msk_uiMD5TransformShiftMatrix[0][2], msk_ui32MD5TransformAddMatrix[0][ 2]); /* 3 */ + FF(b, c, d, a, ui32Block[ 3], msk_uiMD5TransformShiftMatrix[0][3], msk_ui32MD5TransformAddMatrix[0][ 3]); /* 4 */ + FF(a, b, c, d, ui32Block[ 4], msk_uiMD5TransformShiftMatrix[0][0], msk_ui32MD5TransformAddMatrix[0][ 4]); /* 5 */ + FF(d, a, b, c, ui32Block[ 5], msk_uiMD5TransformShiftMatrix[0][1], msk_ui32MD5TransformAddMatrix[0][ 5]); /* 6 */ + FF(c, d, a, b, ui32Block[ 6], msk_uiMD5TransformShiftMatrix[0][2], msk_ui32MD5TransformAddMatrix[0][ 6]); /* 7 */ + FF(b, c, d, a, ui32Block[ 7], msk_uiMD5TransformShiftMatrix[0][3], msk_ui32MD5TransformAddMatrix[0][ 7]); /* 8 */ + FF(a, b, c, d, ui32Block[ 8], msk_uiMD5TransformShiftMatrix[0][0], msk_ui32MD5TransformAddMatrix[0][ 8]); /* 9 */ + FF(d, a, b, c, ui32Block[ 9], msk_uiMD5TransformShiftMatrix[0][1], msk_ui32MD5TransformAddMatrix[0][ 9]); /* 10 */ + FF(c, d, a, b, ui32Block[10], msk_uiMD5TransformShiftMatrix[0][2], msk_ui32MD5TransformAddMatrix[0][10]); /* 11 */ + FF(b, c, d, a, ui32Block[11], msk_uiMD5TransformShiftMatrix[0][3], msk_ui32MD5TransformAddMatrix[0][11]); /* 12 */ + FF(a, b, c, d, ui32Block[12], msk_uiMD5TransformShiftMatrix[0][0], msk_ui32MD5TransformAddMatrix[0][12]); /* 13 */ + FF(d, a, b, c, ui32Block[13], msk_uiMD5TransformShiftMatrix[0][1], msk_ui32MD5TransformAddMatrix[0][13]); /* 14 */ + FF(c, d, a, b, ui32Block[14], msk_uiMD5TransformShiftMatrix[0][2], msk_ui32MD5TransformAddMatrix[0][14]); /* 15 */ + FF(b, c, d, a, ui32Block[15], msk_uiMD5TransformShiftMatrix[0][3], msk_ui32MD5TransformAddMatrix[0][15]); /* 16 */ + + /* Round 2 */ + GG(a, b, c, d, ui32Block[ 1], msk_uiMD5TransformShiftMatrix[1][0], msk_ui32MD5TransformAddMatrix[1][ 0]); /* 17 */ + GG(d, a, b, c, ui32Block[ 6], msk_uiMD5TransformShiftMatrix[1][1], msk_ui32MD5TransformAddMatrix[1][ 1]); /* 18 */ + GG(c, d, a, b, ui32Block[11], msk_uiMD5TransformShiftMatrix[1][2], msk_ui32MD5TransformAddMatrix[1][ 2]); /* 19 */ + GG(b, c, d, a, ui32Block[ 0], msk_uiMD5TransformShiftMatrix[1][3], msk_ui32MD5TransformAddMatrix[1][ 3]); /* 20 */ + GG(a, b, c, d, ui32Block[ 5], msk_uiMD5TransformShiftMatrix[1][0], msk_ui32MD5TransformAddMatrix[1][ 4]); /* 21 */ + GG(d, a, b, c, ui32Block[10], msk_uiMD5TransformShiftMatrix[1][1], msk_ui32MD5TransformAddMatrix[1][ 5]); /* 22 */ + GG(c, d, a, b, ui32Block[15], msk_uiMD5TransformShiftMatrix[1][2], msk_ui32MD5TransformAddMatrix[1][ 6]); /* 23 */ + GG(b, c, d, a, ui32Block[ 4], msk_uiMD5TransformShiftMatrix[1][3], msk_ui32MD5TransformAddMatrix[1][ 7]); /* 24 */ + GG(a, b, c, d, ui32Block[ 9], msk_uiMD5TransformShiftMatrix[1][0], msk_ui32MD5TransformAddMatrix[1][ 8]); /* 25 */ + GG(d, a, b, c, ui32Block[14], msk_uiMD5TransformShiftMatrix[1][1], msk_ui32MD5TransformAddMatrix[1][ 9]); /* 26 */ + GG(c, d, a, b, ui32Block[ 3], msk_uiMD5TransformShiftMatrix[1][2], msk_ui32MD5TransformAddMatrix[1][10]); /* 27 */ + GG(b, c, d, a, ui32Block[ 8], msk_uiMD5TransformShiftMatrix[1][3], msk_ui32MD5TransformAddMatrix[1][11]); /* 28 */ + GG(a, b, c, d, ui32Block[13], msk_uiMD5TransformShiftMatrix[1][0], msk_ui32MD5TransformAddMatrix[1][12]); /* 29 */ + GG(d, a, b, c, ui32Block[ 2], msk_uiMD5TransformShiftMatrix[1][1], msk_ui32MD5TransformAddMatrix[1][13]); /* 30 */ + GG(c, d, a, b, ui32Block[ 7], msk_uiMD5TransformShiftMatrix[1][2], msk_ui32MD5TransformAddMatrix[1][14]); /* 31 */ + GG(b, c, d, a, ui32Block[12], msk_uiMD5TransformShiftMatrix[1][3], msk_ui32MD5TransformAddMatrix[1][15]); /* 32 */ + + /* Round 3 */ + HH(a, b, c, d, ui32Block[ 5], msk_uiMD5TransformShiftMatrix[2][0], msk_ui32MD5TransformAddMatrix[2][ 0]); /* 33 */ + HH(d, a, b, c, ui32Block[ 8], msk_uiMD5TransformShiftMatrix[2][1], msk_ui32MD5TransformAddMatrix[2][ 1]); /* 34 */ + HH(c, d, a, b, ui32Block[11], msk_uiMD5TransformShiftMatrix[2][2], msk_ui32MD5TransformAddMatrix[2][ 2]); /* 35 */ + HH(b, c, d, a, ui32Block[14], msk_uiMD5TransformShiftMatrix[2][3], msk_ui32MD5TransformAddMatrix[2][ 3]); /* 36 */ + HH(a, b, c, d, ui32Block[ 1], msk_uiMD5TransformShiftMatrix[2][0], msk_ui32MD5TransformAddMatrix[2][ 4]); /* 37 */ + HH(d, a, b, c, ui32Block[ 4], msk_uiMD5TransformShiftMatrix[2][1], msk_ui32MD5TransformAddMatrix[2][ 5]); /* 38 */ + HH(c, d, a, b, ui32Block[ 7], msk_uiMD5TransformShiftMatrix[2][2], msk_ui32MD5TransformAddMatrix[2][ 6]); /* 39 */ + HH(b, c, d, a, ui32Block[10], msk_uiMD5TransformShiftMatrix[2][3], msk_ui32MD5TransformAddMatrix[2][ 7]); /* 40 */ + HH(a, b, c, d, ui32Block[13], msk_uiMD5TransformShiftMatrix[2][0], msk_ui32MD5TransformAddMatrix[2][ 8]); /* 41 */ + HH(d, a, b, c, ui32Block[ 0], msk_uiMD5TransformShiftMatrix[2][1], msk_ui32MD5TransformAddMatrix[2][ 9]); /* 42 */ + HH(c, d, a, b, ui32Block[ 3], msk_uiMD5TransformShiftMatrix[2][2], msk_ui32MD5TransformAddMatrix[2][10]); /* 43 */ + HH(b, c, d, a, ui32Block[ 6], msk_uiMD5TransformShiftMatrix[2][3], msk_ui32MD5TransformAddMatrix[2][11]); /* 44 */ + HH(a, b, c, d, ui32Block[ 9], msk_uiMD5TransformShiftMatrix[2][0], msk_ui32MD5TransformAddMatrix[2][12]); /* 45 */ + HH(d, a, b, c, ui32Block[12], msk_uiMD5TransformShiftMatrix[2][1], msk_ui32MD5TransformAddMatrix[2][13]); /* 46 */ + HH(c, d, a, b, ui32Block[15], msk_uiMD5TransformShiftMatrix[2][2], msk_ui32MD5TransformAddMatrix[2][14]); /* 47 */ + HH(b, c, d, a, ui32Block[ 2], msk_uiMD5TransformShiftMatrix[2][3], msk_ui32MD5TransformAddMatrix[2][15]); /* 48 */ + + /* Round 4 */ + II(a, b, c, d, ui32Block[ 0], msk_uiMD5TransformShiftMatrix[3][0], msk_ui32MD5TransformAddMatrix[3][ 0]); /* 49 */ + II(d, a, b, c, ui32Block[ 7], msk_uiMD5TransformShiftMatrix[3][1], msk_ui32MD5TransformAddMatrix[3][ 1]); /* 50 */ + II(c, d, a, b, ui32Block[14], msk_uiMD5TransformShiftMatrix[3][2], msk_ui32MD5TransformAddMatrix[3][ 2]); /* 51 */ + II(b, c, d, a, ui32Block[ 5], msk_uiMD5TransformShiftMatrix[3][3], msk_ui32MD5TransformAddMatrix[3][ 3]); /* 52 */ + II(a, b, c, d, ui32Block[12], msk_uiMD5TransformShiftMatrix[3][0], msk_ui32MD5TransformAddMatrix[3][ 4]); /* 53 */ + II(d, a, b, c, ui32Block[ 3], msk_uiMD5TransformShiftMatrix[3][1], msk_ui32MD5TransformAddMatrix[3][ 5]); /* 54 */ + II(c, d, a, b, ui32Block[10], msk_uiMD5TransformShiftMatrix[3][2], msk_ui32MD5TransformAddMatrix[3][ 6]); /* 55 */ + II(b, c, d, a, ui32Block[ 1], msk_uiMD5TransformShiftMatrix[3][3], msk_ui32MD5TransformAddMatrix[3][ 7]); /* 56 */ + II(a, b, c, d, ui32Block[ 8], msk_uiMD5TransformShiftMatrix[3][0], msk_ui32MD5TransformAddMatrix[3][ 8]); /* 57 */ + II(d, a, b, c, ui32Block[15], msk_uiMD5TransformShiftMatrix[3][1], msk_ui32MD5TransformAddMatrix[3][ 9]); /* 58 */ + II(c, d, a, b, ui32Block[ 6], msk_uiMD5TransformShiftMatrix[3][2], msk_ui32MD5TransformAddMatrix[3][10]); /* 59 */ + II(b, c, d, a, ui32Block[13], msk_uiMD5TransformShiftMatrix[3][3], msk_ui32MD5TransformAddMatrix[3][11]); /* 60 */ + II(a, b, c, d, ui32Block[ 4], msk_uiMD5TransformShiftMatrix[3][0], msk_ui32MD5TransformAddMatrix[3][12]); /* 61 */ + II(d, a, b, c, ui32Block[11], msk_uiMD5TransformShiftMatrix[3][1], msk_ui32MD5TransformAddMatrix[3][13]); /* 62 */ + II(c, d, a, b, ui32Block[ 2], msk_uiMD5TransformShiftMatrix[3][2], msk_ui32MD5TransformAddMatrix[3][14]); /* 63 */ + II(b, c, d, a, ui32Block[ 9], msk_uiMD5TransformShiftMatrix[3][3], msk_ui32MD5TransformAddMatrix[3][15]); /* 64 */ + + m_ui32State[0] += a; + m_ui32State[1] += b; + m_ui32State[2] += c; + m_ui32State[3] += d; + + return; + } + + void CMD5::Update(const uint8 * pui8Input, uint32 ui32InputBytes) + { + //计算m_ui32ByteCounts[0]对64的余数,即:uiPos = m_ui32ByteCounts[0] mod 64 + uint uiMod = (uint)((m_ui32ByteCounts[0] >> 3) & 0x3F); /* (0x3F)hex = (63)dec = (0011,1111)bin */ + + //更新字节数 + if ((m_ui32ByteCounts[0] += (ui32InputBytes << 3)) < (ui32InputBytes << 3)) + { + m_ui32ByteCounts[1]++; + } + m_ui32ByteCounts[1] += (ui32InputBytes >> 29); + + //尽可能多的进行MD5变换 + uint32 ui32 = 0; + uint uiPartBytes = 64 - uiMod; + if (ui32InputBytes >= uiPartBytes) + { + memcpy(&m_ui8InputBuffer[uiMod], pui8Input, uiPartBytes); + this->Transform(m_ui8InputBuffer); + for (ui32 = uiPartBytes; (ui32 + 63) < ui32InputBytes; ui32 += 64) + { + this->Transform(&pui8Input[ui32]); + } + } + + //输入区内剩余的数据 + memcpy(&m_ui8InputBuffer[uiMod], &pui8Input[ui32], ui32InputBytes - ui32); + + return; + } + + void CMD5::Calculate() + { + //整个数据流的字节数 + uint8 ui8TotalBytes[8] = { 0 }; + + //转换uint类型 + this->Uint32to8(ui8TotalBytes, m_ui32ByteCounts, 8); //2 * sizeof(uint32) + + //拓展字节到 56 mod 64 + uint uiMod = (uint)((m_ui32ByteCounts[0] >> 3) & 0x3f); + uint uiPad = (uiMod < 56) ? (56 - uiMod) : (120 - uiMod); + this->Update(msk_ui8MD5PaddingArray, uiPad); + + //附加数据流的字节大小的数据 + this->Update(ui8TotalBytes, 8); + + //处理MD5字符串 + uint8 ui8MD5Str[16] = { 0 }; + this->Uint32to8(ui8MD5Str, m_ui32State, 16); //4 * sizeof(uint32) + for (uint ui = 0; ui < 16; ui++) + { + if (ui8MD5Str[ui] == 0) + { + strcat(m_szMD5, "00"); + } + else if (ui8MD5Str[ui] <= 15) + { + sprintf(m_szMD5, "%s0%X", m_szMD5, ui8MD5Str[ui]); + } + else + { + sprintf(m_szMD5, "%s%X", m_szMD5, ui8MD5Str[ui]); + } + } + + return; + } + +} diff --git a/AutoDiskCopier_v3/src/NotifyIcon.h b/AutoDiskCopier_v3/src/NotifyIcon.h new file mode 100644 index 0000000..cc3149f --- /dev/null +++ b/AutoDiskCopier_v3/src/NotifyIcon.h @@ -0,0 +1,169 @@ +#pragma once + +#include +#include + +namespace NOTIFYICON +{ + + class CNotifyIcon + { + + public: + + CNotifyIcon(HWND hOwnerWnd, UINT uiID, UINT uiCallbackMessage, bool bHighVersion = false); + + inline void SetValidParamFlags(UINT uiFlags); + + inline void SetOwnerWindow(HWND hwnd); + inline void SetID(UINT uiID); + inline void SetCallbackMessageCode(UINT uiCallbackMessage); + inline void SetIcon(HINSTANCE hInst, PCTSTR szIconResourceName); + inline void SetTip(PCTSTR szTip); + + inline void SetBalloonTimeout(UINT uiTimeoutMS); + inline void SetBalloonTitle(PCTSTR szTitle = nullptr); + inline void SetBalloonInfo(PCTSTR szInfo = nullptr); + inline void SetBalloonIcon(DWORD dwFlags, HINSTANCE hInst = NULL, PCTSTR szIconResourceName = nullptr); + inline void SetBalloonLargeIcon(HINSTANCE hInst = NULL, PCWSTR szIconResourceName = MAKEINTRESOURCEW(IDI_APPLICATION)); + + inline BOOL AddNotificationIcon(); + inline BOOL DeleteNotificationIcon(); + inline BOOL ShowBalloon(); + + + private: + + NOTIFYICONDATA m_nid; + + }; + + + //CNotifyIcon实现: + + CNotifyIcon::CNotifyIcon(HWND hOwnerWnd, UINT uiID, UINT uiCallbackMessage, bool bHighVersion) + { + memset(&m_nid, 0, sizeof(NOTIFYICONDATA)); + + m_nid.cbSize = sizeof(NOTIFYICONDATA); + + m_nid.hWnd = hOwnerWnd; + m_nid.uID = uiID; + m_nid.uCallbackMessage = uiCallbackMessage; + + m_nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; + m_nid.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)); + wsprintf(m_nid.szTip, TEXT("标准工具提示信息。")); + + if (bHighVersion) //Version 5.0 (Version 6.0: NIIF_NOSOUND) + { + m_nid.uFlags |= NIF_INFO; + + //气球提示超时时间(10000ms-30000ms) + m_nid.uTimeout = 15000; + + //气球提示标题 + wsprintf(m_nid.szInfoTitle, TEXT("气球提示标题")); + + //气球提示内容(是否显示气球和立即去除气球通过m_nid.szInfo的值和NIM_MODIFY设置) + wsprintf(m_nid.szInfo, TEXT("气球提示内容。")); + + //气球提示框图标(若m_nid.szInfoTitle为空字符串,图标不显示) + m_nid.dwInfoFlags = NIIF_INFO; + } + } + + inline void CNotifyIcon::SetValidParamFlags(UINT uiFlags) + { + m_nid.uFlags = uiFlags; + } + + inline void CNotifyIcon::SetOwnerWindow(HWND hwnd) + { + m_nid.hWnd = hwnd; + } + + inline void CNotifyIcon::SetID(UINT uiID) + { + m_nid.uID = uiID; + } + + inline void CNotifyIcon::SetCallbackMessageCode(UINT uiCallbackMessage) + { + m_nid.uCallbackMessage = uiCallbackMessage; + } + + inline void CNotifyIcon::SetIcon(HINSTANCE hInst, PCTSTR szIconResourceName) + { + m_nid.hIcon = LoadIcon(hInst, szIconResourceName); + } + + inline void CNotifyIcon::SetTip(PCTSTR szTip) + { + wsprintf(m_nid.szTip, szTip); + } + + inline void CNotifyIcon::SetBalloonTimeout(UINT uiTimeoutMS) + { + m_nid.uTimeout = uiTimeoutMS; + } + + inline void CNotifyIcon::SetBalloonTitle(PCTSTR szTitle) + { + if (szTitle) + { + wsprintf(m_nid.szInfoTitle, szTitle); + } + else + { + wsprintf(m_nid.szInfoTitle, TEXT("")); + } + } + + inline void CNotifyIcon::SetBalloonInfo(PCTSTR szInfo) + { + if (szInfo) + { + wsprintf(m_nid.szInfo, szInfo); + } + else + { + wsprintf(m_nid.szInfo, TEXT("")); + } + } + + inline void CNotifyIcon::SetBalloonIcon(DWORD dwFlags, HINSTANCE hInst, PCTSTR szIconResourceName) + { + m_nid.dwInfoFlags = dwFlags; + + if (dwFlags & NIIF_USER) + { + m_nid.hBalloonIcon = LoadIcon(hInst, szIconResourceName); + } + } + + inline void CNotifyIcon::SetBalloonLargeIcon(HINSTANCE hInst, PCWSTR szIconResourceName) + { + m_nid.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON; + + LoadIconMetric(hInst, szIconResourceName, LIM_LARGE, &m_nid.hBalloonIcon); + } + + inline BOOL CNotifyIcon::AddNotificationIcon() + { + return Shell_NotifyIcon(NIM_ADD, &m_nid); + } + + inline BOOL CNotifyIcon::DeleteNotificationIcon() + { + return Shell_NotifyIcon(NIM_DELETE, &m_nid); + } + + inline BOOL CNotifyIcon::ShowBalloon() + { + //要求启用高版本 + //更改m_nid的:dwInfoFlags(气泡图标选择子)、szInfoTitle(气泡标题)、szInfo(气泡内容) + return Shell_NotifyIcon(NIM_MODIFY, &m_nid); + } + +} diff --git a/AutoDiskCopier_v3/src/Removable.ico b/AutoDiskCopier_v3/src/Removable.ico new file mode 100644 index 0000000..25779dc Binary files /dev/null and b/AutoDiskCopier_v3/src/Removable.ico differ diff --git a/AutoDiskCopier_v3/src/resource.h b/AutoDiskCopier_v3/src/resource.h new file mode 100644 index 0000000..5e2187e --- /dev/null +++ b/AutoDiskCopier_v3/src/resource.h @@ -0,0 +1,34 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ 生成的包含文件。 +// 供 AutoDiskCopier.rc 使用 +// +#define IDD_DIALOG 101 +#define IDB_BITMAP 102 +#define IDI_ICON 103 +#define IDR_ACCELERATOR 104 +#define IDC_BTN_HIDE 1001 +#define IDC_BTN_QUIT 1002 +#define IDC_BTN_BROWSECOPYFILEPATH 1003 +#define IDC_BTN_BROWSEKEYFILEPATH 1004 +#define IDC_BTN_CREATEKEYFILE 1005 +#define IDC_EDIT_COPYFILEPATH 1006 +#define IDC_EDIT_KEYFILEPATH 1007 +#define IDC_CHCK_CHECKKEY 1008 +#define IDC_CHCK_SHOWNOTIFYICON 1009 +#define IDC_CHCK_AUTORUN 1010 +#define IDC_CHCK_CONFIRMDIALOG 1011 +#define IDC_CHCK_MD5 1012 +#define IDC_BTN_SAVESETTING 1013 +#define IDC_SYSLINK 1014 +#define IDR_ACCELERATOR_HIDE 40001 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_COMMAND_VALUE 40002 +#define _APS_NEXT_CONTROL_VALUE 1015 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/README.asset/ADC0.PNG b/README.asset/ADC0.PNG new file mode 100644 index 0000000..f5ff86d Binary files /dev/null and b/README.asset/ADC0.PNG differ diff --git a/README.asset/ADC1.PNG b/README.asset/ADC1.PNG new file mode 100644 index 0000000..c89ca90 Binary files /dev/null and b/README.asset/ADC1.PNG differ diff --git a/README.asset/ADC2.PNG b/README.asset/ADC2.PNG new file mode 100644 index 0000000..cbb58ef Binary files /dev/null and b/README.asset/ADC2.PNG differ diff --git a/README.asset/ADC3.PNG b/README.asset/ADC3.PNG new file mode 100644 index 0000000..3f9f8a8 Binary files /dev/null and b/README.asset/ADC3.PNG differ diff --git a/README.asset/ADC4-1.PNG b/README.asset/ADC4-1.PNG new file mode 100644 index 0000000..efef7fc Binary files /dev/null and b/README.asset/ADC4-1.PNG differ diff --git a/README.asset/ADC4-2.PNG b/README.asset/ADC4-2.PNG new file mode 100644 index 0000000..321a199 Binary files /dev/null and b/README.asset/ADC4-2.PNG differ diff --git a/README.asset/ADC4-3.PNG b/README.asset/ADC4-3.PNG new file mode 100644 index 0000000..739b100 Binary files /dev/null and b/README.asset/ADC4-3.PNG differ diff --git a/README.asset/ADC4.PNG b/README.asset/ADC4.PNG new file mode 100644 index 0000000..bee6ae8 Binary files /dev/null and b/README.asset/ADC4.PNG differ diff --git a/README.md b/README.md index a3e1bea..17f0104 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,110 @@ # AutoDiskCopier - + +开源一个**自动磁盘拷贝器(U盘小偷)**。使用该软件请遵守相关法律法规,未经他人许可访问及拷贝他人文件是违法行为。 + +这个应用是我高二刚接触Windows程序设计时开始写的,后来被我改版重写了一番,又成为了我大学时的大作业项目还获得了优秀大项目(然鹅我并不是计算机/软件专业的)…囧rz + +(PS:每隔几年回过头来看看自己曾经写的代码,大概都觉得很挫吧) + +AutoDiskCopier的更多扯淡内容请访问: + +AutoDiskCopier开源代码地址: + +--- + +## 使用手册 + +### 引言 + +非常感谢您抽空阅读Win32应用程序“自动磁盘拷贝器”的用户手册。本手册将向您详细展示该软件所能实现的功能及其操作方法,并为软件的维护与反馈提供了必要的信息。 + +### 软件概述 + +#### 软件功能 + +该软件的主要功能为,在运行该软件时,该软件会监测USB端口,当检测到有移动磁盘接入时,对接入的设备内的文件进行静默拷贝。该软件可用于对移动磁盘的文件备份或文件截取。 +该软件提供了一些可供用户配置的附属功能,合理配置可对程序进行一些个性化的扩展。 +用户可配置的功能有: + +- 决定是否在程序后台运行时显示系统托盘图标(系统托盘图标,即Windows操作系统桌面底端的任务栏右方的小图标,如下图); + + ![](README.asset/ADC0.PNG) + +- 决定该软件是否开机自启动; + +- 决定是否弹出确认复制移动磁盘的对话框,若勾选该选项框,则软件在检测到有移动磁盘接入时,会弹出对话框,用户可选择是否对该磁盘进行拷贝; + +- 决定是否启用MD5文件校验(MD5值是一种Hash值,可用于校验两个文件是否相同),该功能可以保证拷贝文件的准确性,若MD5校验失败,文件会重新复制,若连续校验失败次数超过3次,将跳过对该文件的复制。启用该功能会影响拷贝速度,尤其针对大文件。在不启用该功能时,软件对磁盘文件的平均拷贝速度大约为60MB/s。测试结果表明,对于500MB左右大小的文件,MD5校验的时间大约为40s,因此,若开启此功能,在对大文件进行拷贝时则有可能发生阻塞; + +- 自定义拷贝到的文件的存储路径; + +- 检测签名文件。若勾选该选项框,则软件在对接入的移动磁盘进行拷贝前会先对该磁盘的根目录进行检索,若找到指定的签名文件且内容一致,则跳过对该磁盘的拷贝。 + +#### 运行环境 + +本软件要求运行在PC及其兼容机上,处理器为小端序架构(MD5算法以小端序处理)。软件需要运行在Windows NT及高版本上,发行前用于测试的操作系统为Windows 10。 + +用户需要保证存储路径所在的磁盘有足够的空间,否则拷贝任务将失败。 + +#### 应用分析 + +该软件由纯Win32代码编写,相较于MFC、Java或其他方式开发出的程序,该程序的可执行文件体积小,代码执行效率高,内存占用少,不依赖于更多的外部链接库。Release构建产物大小仅为50KB。在执行拷贝任务时,静默拷贝,内存占用的峰值低,CPU资源消耗小,对电脑的普通使用无影响,是一款轻量级的工具。 + +### 使用说明 + +#### 启动程序 + +双击该软件即可启动。 + +![](README.asset/ADC1.PNG) + +若用户为第一次启动该软件或该软件的配置文件失效,该软件将会自动执行初始化操作,并在完成初始化操作后显示“完成初始化”的对话框。以后再运行该软件,将不再弹出该对话框。 + +![](README.asset/ADC2.PNG) + +#### 激活设置窗口 + +软件启动后,不会显示设置窗口。若要显示设置窗口,可同时按下Ctrl + Alt + Shift + U键。或者若在设置界面勾选了显示系统托盘图标的选项,则也可以通过鼠标右键双击系统托盘图标以显示设置窗口。 + +![](README.asset/ADC3.PNG) + +#### 设置 + +如图所示,分1-8点进行详细说明: + +![](README.asset/ADC4.PNG) + +1. 若勾选该选项框,则该软件在后台运行时会显示系统托盘图标,用户可以通过右键双击该图标以显示设置对话框。 + +2. 若勾选该选项框,则该软件会通过读写注册表为该软件自身添加开机启动项,当windows启动时,该软件自启动。勾选该选项后,不能改变该软件的位置及文件名,否则自启动将无效。 + +3. 若勾选该选项框,则软件在检测到有移动磁盘接入时,会弹出一个确认对话框并进行等待,用户可选择是否对该磁盘进行拷贝,若用户选择“是”,则对磁盘进行拷贝(注:用户选择“是”后,若启用检测签名文件且签名文件存在,将跳过拷贝)。 + + ![](README.asset/ADC4-1.PNG) + +4. 若勾选该选项框,则软件在拷贝文件时执行MD5文件校验,保证拷贝文件的准确性。若MD5校验失败,文件会重新复制,若连续校验失败次数超过3次,将跳过对该文件的复制。启用该功能会在一定程度上影响拷贝速度,尤其在大文件上更加明显。测试结果显示,对于100MB以内的文件,MD5校验的时间在5s以内。但对于500MB左右大小的文件,MD5校验的时间大约为40s,因此,若开启此功能,在对大文件进行拷贝时则有可能发生阻塞,影响拷贝速度。 + +5. 填写一个正确的路径或选择一个可以读写的文件夹以保存拷贝到的文件,需要保证该文件夹所在的磁盘有足够的空间,否则拷贝任务会失败。 + + ![](README.asset/ADC4-2.PNG) + +6. 若勾选该选项框,则软件在对接入的移动磁盘进行拷贝前会先对该磁盘的根目录进行检索,若找到指定的签名文件且内容一致,则跳过对该磁盘的拷贝。可通过按下“生成...”按钮生成签名文件,签名文件是一个64bytes的字节流。 + +7. 在对设置进行更改后,请务必按下“保存设置”按钮,只有在弹出保存成功的对话框后,设置才生效。 + + ![](README.asset/ADC4-3.PNG) + +8. 点击该软件的关闭按钮该软件不会退出,该软件会隐藏设置界面并在后台运行。退出的唯一方法是点击“退出”按钮。 + +### 维护与反馈 + +开源协议:**BSD 2-Clause License** + +反馈请直接提交`github issue`。 + +### 声明 + +本软件为免费开源软件,仅用于技术交流与讨论,任何人或组织不可直接将其作为商业用途,使用本软件造成的一切后果,开发者概不负责。 + +请遵守当地法律法规,正当使用该软件,切勿将该软件用于非法用途,否则带来的一切后果,将由用户自行承担! +