邪恶八进制信息安全团队技术讨论组's Archiver

金州 2005-12-15 20:33

[转载]一个文件分割器源码(MASM32)

文章作者:一块三毛钱



;*************************************************************
;*    Author: 一块三毛钱
;*    E_mail: [email]crazy_soft@163.net[/email]
;*   Homepage: [url]http://zhongts.51.net[/url]
;*************************************************************
;*    Compile: Hutch's Masm32
;* Create Time: 2002.6.5
;*    Modify: 2002.6.5
;* Description: 文件分割器 V1.10
;*************************************************************

.386
.model flat,stdcall
option casemap:none

;****************************************************************************************

include    ztsSplit.inc
include    c:\masm32\include\windows.inc
include    c:\masm32\include\user32.inc
include    c:\masm32\include\kernel32.inc
include    c:\masm32\include\comdlg32.inc
include    c:\masm32\include\comctl32.inc
include    c:\masm32\include\shell32.inc
include    c:\masm32\include\masm32.inc

includelib  c:\masm32\lib\user32.lib
includelib  c:\masm32\lib\kernel32.lib
includelib  c:\masm32\lib\comdlg32.lib
includelib  c:\masm32\lib\comctl32.lib
includelib  c:\masm32\lib\shell32.lib
includelib  c:\masm32\lib\masm32.lib

;****************************************************************************************

DlgProc      proto :DWORD,:DWORD,:DWORD,:DWORD
SetToolTip    proto :DWORD
GetFolder    proto :DWORD,:DWORD
SizeEditProc  proto :DWORD,:DWORD,:DWORD,:DWORD
FileEditProc  proto :DWORD,:DWORD,:DWORD,:DWORD
FolderEditProc proto :DWORD,:DWORD,:DWORD,:DWORD
Split       proto :DWORD,:DWORD,:DWORD
Merge       proto :DWORD,:DWORD

;****************************************************************************************

.data
AppName       db  "ztsSplit",0
DlgName       db  "DLG_MAIN",0
TooltipClassName db  "Tooltips_class32",0
strSysMenu     db  "窗口处在最上",0
strBtnStart01   db  "分割(&C)",0
strBtnStart02   db  "合并(&M)",0
strMergeExt    db  ".mrg",0
strTitleSplit   db  "选择要分割的文件",0
strTitleMerge   db  "选择要合并的文件",0
strFilterSplit  db  "所有文件(*.*)",0,"*.*",0,0
strFilterMerge  db  "合并信息文件(*.mrg)",0,"*.mrg",0,0
strBrowseTitle  db  "选择文件存放目录:",0
strFolderInfo   db  "分割软件 ztsSplit 所在的目录",0
strIniFileName  db  "desktop.ini",0
strIniFileSection  db ".ShellClassInfo",0
strIniFileKeyValue db "InfoTip=分割软件 ztsSplit 所在的目录",0
             db "IconIndex=1",0
             db "IconFile=\",0,0
strError01     db  "打开文件出错",0
strError02     db  "文件创建错误",0
strError03     db  "文件太小,不需要分割",0
strError04     db  "请先指定分割的大小",0
strError05     db  "请先选择需要分割/合并的文件",0
strError06     db  "请选择分割/合并后文件存放的目录",0
strError07     db  "没有合并信息,不能正确合并文件",0
strCopyright    db  "ztsmrg1.1该文件由分割软件 ztsSplit 生成",0
strBatCopy     db  "copy /b ",0
format1       db  "%03d",0

.data?
hInstance    HINSTANCE ?
hToolTip     dd   ?      ;工具提示控件的句柄
hSysMenu     dd   ?      ;系统菜单句柄
hProgress    dd   ?      ;进度条句柄
hEditFile    dd   ?      ;文件名编辑框句柄
hEditFolder   dd   ?      ;目录编辑框句柄
hEditSize    dd   ?      ;分割大小编辑框句柄
hBtnStart    dd   ?      ;分割/合并按钮的句柄
hBtnExit     dd   ?      ;退出按钮的句柄
hBtnFile     dd   ?
hBtnFolder    dd   ?
bSplitOrMerge  BOOL  ?      ;分割还是合并
bKbOrMb      BOOL  ?      ;分割大小的单位是 KB 还是 MB
bSizeEditFocus BOOL  ?      ;“分割大小”编辑框是否拥有焦点
bFileEditFocus BOOL  ?      ;“文件名”编辑框是否拥有焦点
bFolderEditFocus BOOL ?      ;“目录”编辑框是否拥有焦点
strPath      db MAX_PATH dup (?) ;接收拖动来的文件名
strFolder    db MAX_PATH dup (?) ;文件所在的目录
strFileName   db MAX_PATH dup (?) ;可执行文件路径
strModuleDir  db MAX_PATH dup (?) ;可执行文件所在的目录
strIniFilePath db MAX_PATH dup (?)
ofn        OPENFILENAME  <?>
bi         BROWSEINFO   <?>
OldSizeEditProc  dd ?
OldFileEditProc  dd ?
OldFolderEditProc dd ?

;****************************************************************************************

.code
start:
   invoke GetModuleHandle, NULL
   mov   hInstance,eax
   invoke DialogBoxParam,hInstance,addr DlgName,NULL,addr DlgProc,0
   invoke ExitProcess,eax
   invoke InitCommonControls

;对话框窗口过程**************************************************************************

DlgProc  proc  hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
   local  rect:RECT
   local  pt:POINT

   .IF    uMsg==WM_CLOSE

      invoke  GetModuleFileName, hInstance, addr strFileName, MAX_PATH  ;取得文件名
      invoke  GetFolder, addr strModuleDir, addr strFileName         ;计算所属目录
      invoke  SetFileAttributes,addr strModuleDir, FILE_ATTRIBUTE_SYSTEM ;设置目录属性为系统属性

      ;计算 desktop.ini 文件的文件名(包括目录)
      invoke  lstrcat, addr strIniFilePath, addr strModuleDir
      invoke  lstrcat, addr strIniFilePath, addr strIniFileName

      ;计算 desktop.ini 文件中需要写入的内容
      mov    esi, offset strFileName
      mov    edi, offset strIniFileKeyValue
      labelLoop:
        cmp    BYTE ptr [edi], &#39;\&#39;
        je    labelQuit
        inc    edi
        jmp    labelLoop
      labelQuit:
      invoke  StrLen, addr strFileName
      mov    ecx, eax
      rep    movsd

      ;写入 desktop.ini 文件
      invoke  WritePrivateProfileSection, addr strIniFileSection, addr strIniFileKeyValue, addr strIniFilePath
      invoke  SetFileAttributes, addr strIniFilePath, FILE_ATTRIBUTE_HIDDEN ;设置文件属性为隐藏
      invoke  EndDialog, hWnd, NULL

   .ELSEIF uMsg==WM_INITDIALOG

      ;设置图标
      invoke  LoadIcon, hInstance, IDI_MAIN
      invoke  SendMessage, hWnd, WM_SETICON, ICON_SMALL, eax

      ;添加系统菜单项:“窗口处在最上”
      invoke  GetSystemMenu, hWnd, FALSE       ;取得系统菜单的句柄
      mov    hSysMenu, eax               ;句柄 => hSysMenu
      invoke  AppendMenu, hSysMenu, MF_SEPARATOR, NULL,NULL           ;插入分隔线
      invoke  AppendMenu, hSysMenu, MF_STRING or MF_UNCHECKED, IDM_SYSMENU, addr strSysMenu ;插入"窗口处在最上"菜单

      ;取得几个控件的句柄
      invoke  GetDlgItem, hWnd, IDC_PROGRESS
      mov    hProgress, eax
      invoke  GetDlgItem, hWnd, IDC_EDIT_FILE
      mov    hEditFile, eax
      invoke  GetDlgItem, hWnd, IDC_EDIT_FOLDER
      mov    hEditFolder, eax
      invoke  GetDlgItem, hWnd, IDC_EDIT_SIZE
      mov    hEditSize, eax
      invoke  GetDlgItem, hWnd, IDC_BTN_START
      mov    hBtnStart, eax
      invoke  GetDlgItem, hWnd, IDC_BTN_EXIT
      mov    hBtnExit, eax
      invoke  GetDlgItem, hWnd, IDC_BTN_FILE
      mov    hBtnFile, eax
      invoke  GetDlgItem, hWnd, IDC_BTN_FOLDER
      mov    hBtnFolder, eax

      ;初始化为“分割文件”“KB”方式
      invoke  GetDlgItem, hWnd, IDC_RADIO_SPLIT
      invoke  SendMessage, eax, BM_SETCHECK,BST_CHECKED,0
      mov    bSplitOrMerge, TRUE
      invoke  GetDlgItem, hWnd, IDC_RADIO_KB
      invoke  SendMessage, eax, BM_SETCHECK,BST_CHECKED,0
      mov    bKbOrMb, TRUE

      ;创建工具提示控件
      invoke  CreateWindowEx, NULL, addr TooltipClassName, NULL, TTS_ALWAYSTIP, \
           CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, \
           NULL, NULL, hInstance, NULL
      mov    hToolTip, eax
      invoke  SetWindowPos, hToolTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE

      ;设置所有的提示信息
      invoke  SetToolTip, hWnd

      ;子类化编辑框控件
      invoke  SetWindowLong, hEditSize, GWL_WNDPROC, addr SizeEditProc
      mov    OldSizeEditProc, eax
      mov    bSizeEditFocus, FALSE
      invoke  SetWindowLong, hEditFile, GWL_WNDPROC, addr FileEditProc
      mov    OldFileEditProc, eax
      mov    bFileEditFocus, FALSE
      invoke  SetWindowLong, hEditFolder, GWL_WNDPROC, addr FolderEditProc
      mov    OldFolderEditProc, eax
      mov    bFolderEditFocus, FALSE

      invoke  SetFocus, hEditFile          ;设置焦点,加了这条语句后下面要用 mov  eax, FLASE / ret ,否则无效

      mov    eax, FALSE
      ret

   .ELSEIF uMsg==WM_COMMAND

      mov    eax, wParam
      and    eax, 0ffffh
      .IF    eax==IDC_RADIO_SPLIT    ;切换到分割状态
        .IF    !bSplitOrMerge
           invoke  GetDlgItem, hWnd, IDC_EDIT_SIZE
           invoke  EnableWindow, eax, TRUE
           invoke  GetDlgItem, hWnd, IDC_RADIO_KB
           invoke  EnableWindow, eax, TRUE
           invoke  GetDlgItem, hWnd, IDC_RADIO_MB
           invoke  EnableWindow, eax, TRUE
           invoke  GetDlgItem, hWnd, IDC_BTN_START
           invoke  SetWindowText, eax, addr strBtnStart01
           mov    bSplitOrMerge, TRUE
        .ENDIF
      .ELSEIF eax==IDC_RADIO_MERGE    ;切换到合并状态
        .IF    bSplitOrMerge
           invoke  GetDlgItem, hWnd, IDC_EDIT_SIZE
           invoke  EnableWindow, eax, FALSE
           invoke  GetDlgItem, hWnd, IDC_RADIO_KB
           invoke  EnableWindow, eax, FALSE
           invoke  GetDlgItem, hWnd, IDC_RADIO_MB
           invoke  EnableWindow, eax, FALSE
           invoke  GetDlgItem, hWnd, IDC_BTN_START
           invoke  SetWindowText, eax, addr strBtnStart02
           mov    bSplitOrMerge, FALSE
        .ENDIF
      .ELSEIF eax==IDC_RADIO_KB      ;分割大小的单位是 KB
        .IF    !bKbOrMb
           mov    bKbOrMb, TRUE
           invoke  SetFocus, hEditSize    ;“分割大小”编辑框得到焦点
        .ENDIF
      .ELSEIF eax==IDC_RADIO_MB      ;分割大小的单位是 MB
        .IF    bKbOrMb
           mov    bKbOrMb, FALSE
           invoke  SetFocus, hEditSize    ;“分割大小”编辑框得到焦点
        .ENDIF
      .ELSEIF eax==IDC_BTN_FILE      ;选择要分割/合并的文件
        mov    ofn.lStructSize, sizeof ofn
        push   hWnd
        pop    ofn.hwndOwner
        push   hInstance
        pop    ofn.hInstance
        mov    ofn.lpstrFile, offset strPath  ;接收文件名
        mov    ofn.nMaxFile, MAX_PATH
        mov    ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_HIDEREADONLY or OFN_EXPLORER or OFN_LONGNAMES
        .IF    bSplitOrMerge   ;分割状态
           mov    ofn.lpstrFilter, offset strFilterSplit ;文件过滤器
           mov    ofn.lpstrTitle, offset strTitleSplit  ;标题文本
        .ELSE              ;合并状态
           mov    ofn.lpstrFilter, offset strFilterMerge ;文件过滤器
           mov    ofn.lpstrTitle, offset strTitleMerge  ;标题文本
        .ENDIF
        invoke  GetOpenFileName, addr ofn
        .IF    eax
           invoke  SetDlgItemText, hWnd, IDC_EDIT_FILE, addr strPath
           invoke  GetFolder, addr strFolder, addr strPath
           invoke  SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
           .IF    bSplitOrMerge
              invoke  SetFocus, hEditSize  ;“分割大小”编辑框得到焦点
           .ELSE
              invoke  SetFocus, hBtnStart  ;“分割/合并”按钮得到焦点
           .ENDIF
        .ENDIF
      .ELSEIF eax==IDC_BTN_FOLDER    ;选择分割/合并后文件的存放目录
        invoke  RtlZeroMemory, addr bi, sizeof BROWSEINFO ;内存清零
        push   hWnd
        pop    bi.hwndOwner
        mov    eax, offset strFolder         ;接收目录字符串
        mov    bi.pszDisplayName, eax
        mov    eax, offset strBrowseTitle      ;目录选择框上面的文本
        mov    bi.lpszTitle, eax
        mov    bi.ulFlags, BIF_RETURNONLYFSDIRS  ;选择目录
        invoke  SHBrowseForFolder, addr bi
        .IF    eax
           invoke  SHGetPathFromIDList, eax, addr strFolder ;转换 PIDL 为目录名
           invoke  StrLen, addr strFolder     ;取得字符串长度
           mov    esi, offset strFolder      ;esi 指向开始的位置
           add    esi, eax              ;esi 指向结束的位置
           cmp    BYTE ptr [esi-1], &#39;\&#39;      ;判断是不是以&#39;\&#39;结尾
           je    labelExit
              mov    BYTE ptr [esi], &#39;\&#39;  ;如果不是则添加一个&#39;\&#39;
              mov    BYTE ptr [esi+1], 0
           labelExit:
           invoke  SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
           invoke  SetForegroundWindow, hWnd   ;激活窗口
           .IF    bSplitOrMerge
              invoke  SetFocus, hEditSize  ;“分割大小”编辑框得到焦点
           .ELSE
              invoke  SetFocus, hBtnStart  ;“分割/合并”按钮得到焦点
           .ENDIF
        .ENDIF
      .ELSEIF eax==IDC_BTN_START
        .IF    bSplitOrMerge
           invoke  GetDlgItemInt, hWnd, IDC_EDIT_SIZE, NULL, FALSE
           .IF    bKbOrMb
              shl    eax, 10
           .ELSE
              shl    eax, 20
           .ENDIF
           invoke  Split, addr strPath, addr strFolder, eax
           invoke  SendMessage, hProgress, PBM_SETPOS, 0, 0
        .ELSE
           invoke  Merge, addr strPath, addr strFolder
           invoke  SendMessage, hProgress, PBM_SETPOS, 0, 0
        .ENDIF
      .ELSEIF eax==IDC_BTN_EXIT
        invoke  SendMessage, hWnd, WM_CLOSE, 0, 0
      .ENDIF
   
   .ELSEIF uMsg==WM_SYSCOMMAND

      mov    eax,wParam
      movzx  eax,ax
      .IF    eax==IDM_SYSMENU
        invoke  GetMenuState, hSysMenu, IDM_SYSMENU, MF_BYCOMMAND
        .IF    (eax & MF_CHECKED)  ;判断菜单是否是选中的
           invoke  CheckMenuItem, hSysMenu, IDM_SYSMENU, MF_UNCHECKED
           invoke  SetWindowPos, hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE
        .ELSE
           invoke  CheckMenuItem, hSysMenu, IDM_SYSMENU, MF_CHECKED
           invoke  SetWindowPos, hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE
        .ENDIF
      .ELSE
        invoke  DefWindowProc,hWnd,uMsg,wParam,lParam
      .ENDIF

   .ELSEIF uMsg==WM_DROPFILES
      invoke  DragQueryFile, wParam, 0, addr strPath, MAX_PATH  ;得到文件路径
      invoke  GetFileAttributes, addr strPath    ;取得文件属性,判断是否文件夹
      and    eax, FILE_ATTRIBUTE_DIRECTORY
      .IF    eax    ;如果是文件夹
        invoke  SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strPath
        invoke  SetForegroundWindow, hWnd   ;激活窗口
        .IF    bSplitOrMerge
           invoke  SetFocus, hEditSize  ;“分割大小”编辑框得到焦点
        .ELSE
           invoke  SetFocus, hBtnStart  ;“分割/合并”按钮得到焦点
        .ENDIF
      .ELSE
        .IF    bSplitOrMerge   ;当前为分割状态
           invoke  SetDlgItemText, hWnd, IDC_EDIT_FILE, addr strPath
           invoke  GetFolder, addr strFolder, addr strPath
           invoke  SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
           invoke  SetForegroundWindow, hWnd    ;激活窗口
           invoke  SetFocus, hEditSize   ;“分割大小”编辑框得到焦点
        .ELSE  ;当前为合并状态
           mov    esi, offset strPath
           invoke  StrLen, addr strPath
           add    esi, eax
           sub    esi, 4
           invoke  lstrcmp, esi, addr strMergeExt ;判断最后 4 个字符是否为 ".mrg"
           .IF    eax==0
              invoke  SetDlgItemText, hWnd, IDC_EDIT_FILE, addr strPath
              invoke  GetFolder, addr strFolder, addr strPath
              invoke  SetDlgItemText, hWnd, IDC_EDIT_FOLDER, addr strFolder
              invoke  SetForegroundWindow, hWnd ;激活窗口
              invoke  SetFocus, hBtnStart ;“分割/合并”按钮得到焦点
           .ENDIF
        .ENDIF
      .ENDIF
      invoke  DragFinish,wParam  ;释放内存

   .ELSE
      mov  eax,FALSE      
      ret
   .ENDIF
   mov  eax,TRUE
   ret
DlgProc endp

;==========================================
; 设置所有提示信息
;==========================================
SetToolTip  proc  hWnd:DWORD
   local  ti:TOOLINFO

   mov    ti.cbSize, sizeof TOOLINFO
   mov    ti.uFlags, TTF_SUBCLASS or TTF_IDISHWND
   push   hWnd
   pop    ti.hWnd

   ;先设置主界面提示信息
   push   hWnd
   pop    ti.uId
   mov    ti.lpszText, offset strMainTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;------------------------------------------------
   ; 设置其他控件的提示信息
   ;------------------------------------------------

   ;“分割文件”单选框提示信息
   invoke  GetDlgItem, hWnd, IDC_RADIO_SPLIT
   mov    ti.uId, eax
   mov    ti.lpszText, offset strSplitTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;“合并文件”单选框提示信息
   invoke  GetDlgItem, hWnd, IDC_RADIO_MERGE
   mov    ti.uId, eax
   mov    ti.lpszText, offset strMergeTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;“文件名”编辑框提示信息
   invoke  GetDlgItem, hWnd, IDC_EDIT_FILE
   mov    ti.uId, eax
   mov    ti.lpszText, offset strFileTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;“目录”编辑框提示信息
   invoke  GetDlgItem, hWnd, IDC_EDIT_FOLDER
   mov    ti.uId, eax
   mov    ti.lpszText, offset strFolderTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;“选择文件”按钮提示信息
   invoke  GetDlgItem, hWnd, IDC_BTN_FILE
   mov    ti.uId, eax
   mov    ti.lpszText, offset strBtnFileTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;“选择文件夹”按钮提示信息
   invoke  GetDlgItem, hWnd, IDC_BTN_FOLDER
   mov    ti.uId, eax
   mov    ti.lpszText, offset strBtnFolderTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;“分割大小”编辑框提示信息
   invoke  GetDlgItem, hWnd, IDC_EDIT_SIZE
   mov    ti.uId, eax
   mov    ti.lpszText, offset strSizeTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;“KB”单选框提示信息
   invoke  GetDlgItem, hWnd, IDC_RADIO_KB
   mov    ti.uId, eax
   mov    ti.lpszText, offset strKbTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;“MB”单选框提示信息
   invoke  GetDlgItem, hWnd, IDC_RADIO_MB
   mov    ti.uId, eax
   mov    ti.lpszText, offset strMbTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;进度条提示信息
   invoke  GetDlgItem, hWnd, IDC_PROGRESS
   mov    ti.uId, eax
   mov    ti.lpszText, offset strProgressTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;“分割/合并”按钮提示信息
   invoke  GetDlgItem, hWnd, IDC_BTN_START
   mov    ti.uId, eax
   mov    ti.lpszText, offset strStartTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ;“退出”按钮提示信息
   invoke  GetDlgItem, hWnd, IDC_BTN_EXIT
   mov    ti.uId, eax
   mov    ti.lpszText, offset strExitTip
   invoke  SendMessage, hToolTip, TTM_ADDTOOL, NULL, addr ti

   ret
SetToolTip  endp

;==========================================
; 根据文件名得到文件夹
;==========================================
GetFolder  proc  lpFolder:HWND, lpFile:DWORD

   ;把 lpFile 地址处的字符串传送到 lpFolder 地址处
   mov    esi, lpFile
   mov    edi, lpFolder
   invoke  StrLen, lpFile
   mov    ecx, eax
   rep    movsd

   mov    esi, lpFolder      ; esi 指向 lpFolder,也就是字符串开始的位置
   add    esi, eax         ; esi 加上 eax(字符串长度)后指向字符串结束的位置
   dec    esi            ; esi 指向字符串末尾的一个字符

;从字符串末尾向前测试每一个字符,如果为 &#39;\&#39; 则说明再往前就是文件夹
labelTest:
   cmp    BYTE ptr [esi], &#39;\&#39;
   je    labelExit
   dec    esi
   jmp    labelTest
labelExit:
   inc    esi
   mov    BYTE ptr [esi], 0

   ret
GetFolder  endp

;==========================================
; “分割大小”编辑框窗口过程
;    当窗口获得焦点时选中所有文本
;==========================================
SizeEditProc  proc  hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

   .IF uMsg==WM_SETFOCUS
      mov    bSizeEditFocus, TRUE            ;拥有焦点
      invoke  SendMessage, hWnd, EM_SETSEL, 0, -1  ;选中全部文本
      invoke  CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
      ret
   .ELSEIF uMsg==WM_LBUTTONDOWN
      .IF    !bSizeEditFocus       ;如果没有焦点
        invoke  SetFocus, hWnd  ;则设置焦点
      .ELSE                   ;如果已经有焦点,则按缺省处理
        invoke  CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
        ret
      .ENDIF
   .ELSEIF uMsg==WM_KILLFOCUS
      mov    bSizeEditFocus, FALSE   ;失去焦点
      invoke  CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
      ret
   .ELSE
      invoke  CallWindowProc, OldSizeEditProc, hWnd, uMsg, wParam, lParam
      ret
   .ENDIF

   xor  eax, eax
   ret
SizeEditProc  endp

;==================================================
; “文件名”编辑框窗口过程
;    当窗口获得焦点时光标滚到最后,方便修改
;    当窗口失去焦点时光标滚到最前,方便观看
;==================================================
FileEditProc  proc  hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

   .IF uMsg==WM_SETFOCUS
      mov    bFileEditFocus, TRUE               ;拥有焦点
      invoke  SendMessage, hWnd, WM_GETTEXTLENGTH, 0, 0 ;取得文本长度
      invoke  SendMessage, hWnd, EM_SETSEL, eax, eax   ;光标滚到最后
      invoke  CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
      ret
   .ELSEIF uMsg==WM_LBUTTONDOWN
      .IF    !bFileEditFocus       ;如果没有焦点
        invoke  SetFocus, hWnd  ;则设置焦点
      .ELSE                   ;如果已经有焦点,则按缺省处理
        invoke  CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
        ret
      .ENDIF
   .ELSEIF uMsg==WM_KILLFOCUS
      mov    bFileEditFocus, FALSE              ;失去焦点
      invoke  SendMessage, hWnd, EM_SETSEL, 0, 0      ;光标滚到最前
      invoke  CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
      ret
   .ELSE
      invoke  CallWindowProc, OldFileEditProc, hWnd, uMsg, wParam, lParam
      ret
   .ENDIF

   xor  eax, eax
   ret
FileEditProc  endp

;==================================================
; “目录”编辑框窗口过程
;    当窗口获得焦点时光标滚到最后,方便修改
;    当窗口失去焦点时光标滚到最前,方便观看
;==================================================
FolderEditProc  proc  hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

   .IF uMsg==WM_SETFOCUS
      mov    bFolderEditFocus, TRUE              ;拥有焦点
      invoke  SendMessage, hWnd, WM_GETTEXTLENGTH, 0, 0 ;取得文本长度
      invoke  SendMessage, hWnd, EM_SETSEL, eax, eax   ;光标滚到最后
      invoke  CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
      ret
   .ELSEIF uMsg==WM_LBUTTONDOWN
      .IF    !bFolderEditFocus      ;如果没有焦点
        invoke  SetFocus, hWnd  ;则设置焦点
      .ELSE                   ;如果已经有焦点,则按缺省处理
        invoke  CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
        ret
      .ENDIF
   .ELSEIF uMsg==WM_KILLFOCUS
      mov    bFolderEditFocus, FALSE             ;失去焦点
      invoke  SendMessage, hWnd, EM_SETSEL, 0, 0      ;光标滚到最前
      invoke  CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
      ret
   .ELSE
      invoke  CallWindowProc, OldFolderEditProc, hWnd, uMsg, wParam, lParam
      ret
   .ENDIF

   xor  eax, eax
   ret
FolderEditProc  endp

;=========================================
; 分割过程
; 参数:待分割文件,存放目录,分割大小
;=========================================
Split  proc  lpfile:DWORD, lpfolder:DWORD, blocksize:DWORD
   local  hSourceFile, hDestFile:DWORD
   local  hMrgFile:DWORD
   local  buffer[1024]:BYTE            ;缓冲区
   local  sourcefilename[128]:BYTE       ;被分割的文件名(包括扩展名)
   local  filetitle[128]:BYTE          ;文件名(不包括扩展名)
   local  fileExt[10]:BYTE            ;扩展名
   local  filename[128]:BYTE           ;文件名(包括路径和扩展名)
   local  ActualReaded:DWORD           ;实际读出来的字节
   local  BufCount:DWORD              ;记录每个分割文件已经写入的字节
   local  number:DWORD               ;分割文件的个数

   ;没指定需要分割的文件
   mov    esi, lpfile
   mov    al, byte ptr [esi]
   .IF    al == 0
      invoke  MessageBox, NULL, addr strError05, addr AppName, MB_OK or MB_ICONERROR
      ret
   .ENDIF

   ;没指定分割后文件存放的目录
   mov    esi, lpfolder
   mov    al, byte ptr [esi]
   .IF    al == 0
      invoke  MessageBox, NULL, addr strError06, addr AppName, MB_OK or MB_ICONERROR
      ret
   .ENDIF

   ;没指定分割大小
   .IF    blocksize==0
      invoke  MessageBox, NULL, addr strError04, addr AppName, MB_OK or MB_ICONERROR
      ret
   .ENDIF

   ;打开文件失败
   invoke  CreateFile, lpfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
   .IF    eax==INVALID_HANDLE_VALUE
      invoke  MessageBox, NULL, addr strError01, addr AppName, MB_OK or MB_ICONERROR
      ret
   .ENDIF
   mov    hSourceFile, eax

   ;文件太小(比指定的分割大小)
   invoke  GetFileSize, hSourceFile, NULL
   .IF    eax<blocksize
      invoke  CloseHandle, hSourceFile
      invoke  MessageBox, NULL, addr strError03, addr AppName, MB_OK or MB_ICONERROR
      ret
   .ENDIF

   ;计算文件名(包括扩展名)
   mov    esi, lpfile
   lea    edi, filetitle
   invoke  StrLen, lpfile
   add    esi, eax
   xor    ecx, ecx
   labelTest:
      cmp    BYTE ptr [esi], &#39;\&#39;
      je    labelExit
      dec    esi
      inc    ecx
      jmp    labelTest
   labelExit:
   inc    esi
   dec    ecx
   rep    movsd

   invoke  lstrcpy, addr sourcefilename, addr filetitle  ;保存文件名到 sourcefilename 中

   ;计算文件名(不包括扩展名)
   lea    esi, filetitle
   mov    ebx, esi
   invoke  StrLen, addr filetitle
   add    ebx, eax
   labelLoop:
      cmp    BYTE ptr [esi], &#39;.&#39;
      je    labelQuit
      inc    esi
      cmp    esi, ebx
      je    labelQuit
      jmp    labelLoop
   labelQuit:
   mov    BYTE ptr [esi], &#39;.&#39;
   mov    BYTE ptr [esi+1], 0

   ;mrg 文件的扩展名
   lea    esi, fileExt
   mov    BYTE ptr [esi], &#39;m&#39;
   mov    BYTE ptr [esi+1], &#39;r&#39;
   mov    BYTE ptr [esi+2], &#39;g&#39;
   mov    BYTE ptr [esi+3], 0

   ;计算 mrg 文件的文件名(包括路径)
   invoke  lstrcpy, addr filename, lpfolder
   invoke  lstrcat, addr filename, addr filetitle
   invoke  lstrcat, addr filename, addr fileExt

   invoke  CreateFile, addr filename, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
   .IF    eax==INVALID_HANDLE_VALUE
      invoke  MessageBox, NULL, addr strError02, addr AppName, MB_OK or MB_ICONERROR
      ret
   .ENDIF
   mov    hMrgFile, eax

   ;写入版本信息
   invoke  StrLen, addr strCopyright
   mov    ebx, eax
   invoke  WriteFile, hMrgFile, addr strCopyright, ebx, addr ActualReaded, NULL

   ;初始化一些数据
   mov    number, -1
   mov    eax, blocksize
   mov    BufCount, eax

   invoke  ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
   mov    eax, ActualReaded
   .WHILE  eax!=0   ;文件没到末尾就继续读
      ;当一个分割文件写完后创建一个新的分割文件来写
      mov    eax, BufCount
      .IF    eax==blocksize
        invoke  CloseHandle, hDestFile

        ;计算分割文件的扩展名
        inc    number
        invoke  wsprintf, addr fileExt, addr format1, number
        invoke  lstrcpy, addr filename, lpfolder
        invoke  lstrcat, addr filename, addr filetitle
        invoke  lstrcat, addr filename, addr fileExt

        invoke  CreateFile, addr filename, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
        .IF    eax==INVALID_HANDLE_VALUE
           invoke  MessageBox, NULL, addr strError02, addr AppName, MB_OK or MB_ICONERROR
           ret
        .ENDIF
        mov    hDestFile, eax
        mov    BufCount, 0    ;每次新创建的分割文件,写入的大小为零
      .ENDIF

      ;写入数据
      mov    ebx, ActualReaded
      invoke  WriteFile, hDestFile, addr buffer, ebx, addr ActualReaded, NULL
      add    BufCount, 1024        ;写入的大小递增

      ;根据已经读出的大小和需要分割文件的大小来设置进度条
      invoke  GetFileSize, hSourceFile, NULL
      mov    ebx, eax
      mov    eax, number
      inc    eax
      mul    blocksize
      mov    ecx, 100
      mul    ecx
      div    ebx
      invoke  SendMessage, hProgress, PBM_SETPOS, eax, 0

      ;读出数据
      invoke  ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
      mov    eax, ActualReaded
   .ENDW

   ;把分割文件的个数和原文件名(包括扩展名)写入 mrg 文件中
   inc    number
   invoke  wsprintf, addr fileExt, addr format1, number
   invoke  WriteFile, hMrgFile, addr fileExt, 3, addr ActualReaded, NULL
   invoke  StrLen, addr sourcefilename
   mov    ebx, eax
   invoke  WriteFile, hMrgFile, addr sourcefilename, ebx, addr ActualReaded, NULL
   invoke  CloseHandle, hMrgFile

   invoke  CloseHandle, hDestFile
   invoke  CloseHandle, hSourceFile
   ret
Split  endp

;=================================
; 合并过程
; 参数:待合并文件,存放目录
;=================================
Merge  proc  lpfile:DWORD, lpfolder:DWORD
   local  hSourceFile, hDestFile:DWORD
   local  buffer[1024]:BYTE            ;缓冲区
   local  srcFolder[MAX_PATH]:BYTE       ;分割文件所在目录
   local  filetitle[128]:BYTE          ;文件名(不包括扩展名)
   local  fileExt[10]:BYTE            ;扩展名
   local  filename[128]:BYTE           ;文件名(包括路径和扩展名)
   local  nfile,ntotal:DWORD                ;分割文件的个数
   local  number:DWORD               ;用来计算扩展名
   local  ActualReaded:DWORD           ;实际读出的字节

   ;没指定需要分割的文件
   mov    esi, lpfile
   mov    al, byte ptr [esi]
   .IF    al == 0
      invoke  MessageBox, NULL, addr strError05, addr AppName, MB_OK or MB_ICONERROR
      ret
   .ENDIF

   ;没指定分割后文件存放的目录
   mov    esi, lpfolder
   mov    al, byte ptr [esi]
   .IF    al == 0
      invoke  MessageBox, NULL, addr strError06, addr AppName, MB_OK or MB_ICONERROR
      ret
   .ENDIF

   ;打开 mrg 文件
   invoke  CreateFile, lpfile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
   .IF    eax==INVALID_HANDLE_VALUE
      invoke  MessageBox, NULL, addr strError01, addr AppName, MB_OK or MB_ICONERROR
      ret
   .ENDIF
   mov    hSourceFile, eax

   ;读出版本信息,比较是否为合法的文件
   invoke  StrLen, addr strCopyright
   mov    ebx, eax
   invoke  ReadFile, hSourceFile, addr buffer, ebx, addr ActualReaded, NULL
   invoke  lstrcmp, addr buffer, addr strCopyright
   .IF    eax!=0
      invoke  CloseHandle, hSourceFile
      invoke  MessageBox, NULL, addr strError07, addr AppName, MB_OK or MB_ICONERROR
      ret
   .ENDIF

   ;读出分割文件的个数,保存在 nfile 中
   invoke  ReadFile, hSourceFile, addr buffer, 3, addr ActualReaded, NULL
   lea    esi, buffer
   xor    eax, eax
   mov    al, byte ptr [esi]
   sub    al, 48
   mov    ebx, 100
   mul    ebx
   mov    nfile, eax
   xor    eax, eax
   mov    al, byte ptr [esi+1]
   sub    al, 48
   mov    ebx, 10
   mul    ebx
   add    nfile, eax
   xor    eax, eax
   mov    al, byte ptr [esi+2]
   sub    al, 48
   add    nfile, eax
   mov    ntotal, eax

   ;读出合并后的文件名(包括扩展名)
   invoke  RtlZeroMemory, addr buffer, 1024
   invoke  GetFileSize, hSourceFile, NULL
   mov    ebx, eax
   invoke  StrLen, addr strCopyright
   sub    ebx, eax
   invoke  ReadFile, hSourceFile, addr buffer, ebx, addr ActualReaded, NULL

   invoke  lstrcpy, addr filename, lpfolder
   invoke  lstrcat, addr filename, addr buffer

   ;创建文件准备写
   invoke  CreateFile, addr filename, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
   .IF    eax==INVALID_HANDLE_VALUE
      invoke  MessageBox, NULL, addr strError02, addr AppName, MB_OK or MB_ICONERROR
      ret
   .ENDIF
   mov    hDestFile, eax

   ;取得分割文件所在的目录
   invoke  GetFolder, addr srcFolder, lpfile

   ;计算文件名(不包括扩展名)
   invoke  lstrcpy, addr filetitle, addr buffer
   lea    esi, filetitle
   mov    ebx, esi
   invoke  StrLen, addr filetitle
   add    ebx, eax
   labelLoop:
      cmp    BYTE ptr [esi], &#39;.&#39;
      je    labelQuit
      inc    esi
      cmp    esi, ebx
      je    labelQuit
      jmp    labelLoop
   labelQuit:
   mov    BYTE ptr [esi], &#39;.&#39;
   mov    BYTE ptr [esi+1], 0

   mov    number, -1
   .WHILE  nfile  ;用分割文件的个数来控制循环
      invoke  CloseHandle, hSourceFile

      ;计算扩展名,然后得出文件名(包括路径和扩展名)
      inc    number
      invoke  wsprintf, addr fileExt, addr format1, number
      invoke  lstrcpy, addr filename, addr srcFolder
      invoke  lstrcat, addr filename, addr filetitle
      invoke  lstrcat, addr filename, addr fileExt

      ;打开文件准备读
      invoke  CreateFile, addr filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
      .IF    eax==INVALID_HANDLE_VALUE
        invoke  MessageBox, NULL, addr strError01, addr AppName, MB_OK or MB_ICONERROR
        ret
      .ENDIF
      mov    hSourceFile, eax

      invoke  ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
      mov    eax, ActualReaded
      .WHILE  eax    ;循环读,一直到文件末尾
        mov    ebx, eax
        invoke  WriteFile, hDestFile, addr buffer, ebx, addr ActualReaded, NULL
        invoke  ReadFile, hSourceFile, addr buffer, 1024, addr ActualReaded, NULL
        mov    eax, ActualReaded
      .ENDW

      dec    nfile

      mov    eax, nfile
      mov    ebx, 100
      mul    ebx
      div    ntotal
      invoke  SendMessage, hProgress, PBM_SETPOS, eax, 0
   .ENDW

   invoke  CloseHandle, hDestFile
   invoke  CloseHandle, hSourceFile

   ret
Merge  endp

end start

页: [1]
© 1999-2008 EvilOctal Security Team