unit DAip2KessDrm; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VirtualTrees, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Menus; const WM_CLICK_DECRYPT = WM_USER + 8548; type PDrmEnt = ^TDrmEnt; TDrmEnt = record sDir, sExt, sFName: String; bDrm: Boolean; nImgIdx: Integer; end; TDlgAip2KessDrm = class(TForm) pnTop: TPanel; pnClient: TPanel; vtList: TVirtualStringTree; btnDecrypt: TButton; Label1: TLabel; popFun: TPopupMenu; miDelFile: TMenuItem; miDelNoDrm: TMenuItem; N1: TMenuItem; miClear: TMenuItem; btnAddFile: TButton; btnAddDir: TButton; OpenDialog: TOpenDialog; FileOpenDialog: TFileOpenDialog; procedure vtListGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer); procedure vtListGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: string); procedure vtListGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); procedure vtListPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); procedure vtListGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: TImageIndex); procedure vtListAfterPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas); procedure vtListFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); procedure miDelFileClick(Sender: TObject); procedure miDelNoDrmClick(Sender: TObject); procedure btnDecryptClick(Sender: TObject); procedure vtListContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean); procedure miClearClick(Sender: TObject); procedure btnAddFileClick(Sender: TObject); procedure btnAddDirClick(Sender: TObject); private { Private declarations } FileImageList_: TImageList; vtListOldWndProc_: TWndMethod; CheckFList_: TStringList; sExceptReason_: String; procedure vtListWndProc(var msg: TMessage); function CountEncFile: Integer; procedure AddFile(sPath: String); procedure ExtrctFilesFromDir(sDir: String); public { Public declarations } Constructor Create(aOwner: TComponent); override; procedure CreateParams(var Params: TCreateParams); override; // 작업표시줄에 표시 Destructor Destroy; override; procedure AddFiles(aList: TStringList); procedure process_WM_COPYDATA(var msg: TMessage); Message WM_COPYDATA; end; var DlgAip2KessDrm: TDlgAip2KessDrm; implementation uses {$IFDEF _HE_} ManagerService, ManagerModel, {$ENDIF} Tocsg.Convert, Tocsg.Shell, Winapi.ShellAPI, Tocsg.Path, GlobalDefine, Condition, Tocsg.Files, Tocsg.Strings, Tocsg.VTUtil, superobject, DefineHelper, Define, Tocsg.Exception, Tocsg.Process, Tocsg.User32, Tocsg.AIP, CrmUtil, Tocsg.Kess; resourcestring RS_MsgAddFile = '먼저 파일을 추가해 주십시오.'; RS_NoTgFile = '변환 할 파일이 없습니다.'; RS_FileDec = '파일 복호화'; RS_Q_DrmDec = '암호화를 변환 하시겠습니까?'; RS_MsgError = '작업을 준비하는 중 오류가 발생했습니다.'; RS_CompleteWork1 = '작업을 완료했습니다.'; RS_CompleteWork2 = '(성공 : %d, 실패 : %d, 무시 : %d)'; RS_Q_Clear = '목록을 초기화 하시겠습니까?'; RS_SelExceptFile = '제외 할 파일을 선택해 주십시오.'; RS_Q_ExceptFile = '선택한 파일들을 제외 하시겠습니까?'; RS_NoExceptFile = '제외 할 파일이 없습니다.'; RS_DrmFileDragDrop = '파일을 드래그/드롭 해주십시오.'; RS_Ok = '확인'; {$R *.dfm} Constructor TDlgAip2KessDrm.Create(aOwner: TComponent); var hSysIcons: THandle; begin Inherited Create(aOwner); sExceptReason_ := ''; FileImageList_ := TImageList.Create(Self); FileImageList_.ShareImages := true; FileImageList_.BlendColor := clHighlight; hSysIcons := GetShellImageHandle; if hSysIcons <> 0 then begin FileImageList_.Handle := hSysIcons; vtList.Images := FileImageList_; end; CheckFList_ := TStringList.Create; CheckFList_.CaseSensitive := false; vtListOldWndProc_ := vtList.WindowProc; vtList.WindowProc := vtListWndProc; DragAcceptFiles(vtList.Handle, true); ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD); ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD); ChangeWindowMessageFilterEx(vtList.Handle, WM_DROPFILES, MSGFLT_ALLOW, nil); ChangeWindowMessageFilter(WM_COPYGLOBALDATA, MSGFLT_ADD); ASSERT(CUSTOMER_TYPE = CUSTOMER_KDNVN); end; procedure TDlgAip2KessDrm.CreateParams(var Params: TCreateParams); begin Inherited CreateParams(Params); Params.ExStyle := WS_EX_APPWINDOW; end; Destructor TDlgAip2KessDrm.Destroy; begin FreeAndNil(CheckFList_); Inherited; end; function TDlgAip2KessDrm.CountEncFile: Integer; var pData: PDrmEnt; pNode: PVirtualNode; begin Result := 0; vtList.BeginUpdate; try pNode := vtList.GetFirst; while pNode <> nil do begin pData := vtList.GetNodeData(pNode); if pData.bDrm then Inc(Result); pNode := vtList.GetNext(pNode); end; finally vtList.EndUpdate; end; end; procedure TDlgAip2KessDrm.AddFile(sPath: String); var pData: PDrmEnt; begin try if CheckFList_.IndexOf(sPath) <> -1 then exit; CheckFList_.Add(sPath); pData := VT_AddChildData(vtList); pData.sDir := ExtractFilePath(sPath); pData.sFName := ExtractFileName(sPath); pData.sExt := GetFileExt(pData.sFName).ToUpper; pData.nImgIdx := -1; try pData.bDrm := IsAipEncryted(sPath, 'C:\ProgramData\HE\AEN\'); except pData.bDrm := false; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. AddFile()'); end; end; procedure TDlgAip2KessDrm.AddFiles(aList: TStringList); var sPath: String; i: Integer; begin vtList.BeginUpdate; try for i := 0 to aList.Count - 1 do begin sPath := aList[i]; if not FileExists(sPath) then continue; AddFile(sPath); end; finally vtList.EndUpdate; end; end; procedure TDlgAip2KessDrm.ExtrctFilesFromDir(sDir: String); var wfd: TWin32FindData; hSc: THandle; sPath: String; begin sDir := IncludeTrailingPathDelimiter(sDir); sPath := sDir + '*.*'; hSc := FindFirstFile(PChar(sPath), wfd); if hSc = INVALID_HANDLE_VALUE then exit; try Repeat if (String(wfd.cFileName) <> '.') and (String(wfd.cFileName) <> '..') then if ((wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0) then begin ExtrctFilesFromDir(sDir + wfd.cFileName); end else begin AddFile(sDir + wfd.cFileName); end; Until not FindNextFile(hSc, wfd); finally WinApi.Windows.FindClose(hSc); end; end; procedure TDlgAip2KessDrm.btnAddDirClick(Sender: TObject); var O: ISuperObject; sExe: String; ProcInfo: TProcessInformation; Label LB_Direct; begin try sExe := GetRunExePathDir + DIR_CONF + EXE_HLP; if FileExists(sExe) then begin O := SO; O.I['RcvWnd'] := Handle; O.I['Cmd'] := HPCMD_SELECT_FOLDER; O.I['Ctrl'] := 1; SaveJsonObjToFile(O, GetRunExePathDir + DIR_CONF + DAT_PARAM); // ProcInfo := ExecuteApp(sExe, '', SW_SHOWNORMAL); ProcInfo := ExecuteAppAsUser('explorer.exe', sExe, '', SW_SHOWNORMAL); if ProcInfo.dwProcessId = 0 then goto LB_Direct; end else begin LB_Direct : {$IFDEF _HE_} if FileOpenDialog.FileName = '' then FileOpenDialog.DefaultFolder := Format('C:\Users\%s\Desktop', [gMgSvc.UserName]); {$ENDIF} if FileOpenDialog.Execute then begin ExtrctFilesFromDir(FileOpenDialog.FileName); end; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. btnAddDirClick()'); end; end; procedure TDlgAip2KessDrm.btnAddFileClick(Sender: TObject); var i: Integer; O: ISuperObject; sExe: String; ProcInfo: TProcessInformation; Label LB_Direct; begin try sExe := GetRunExePathDir + DIR_CONF + EXE_HLP; if FileExists(sExe) then begin O := SO; O.I['RcvWnd'] := Handle; O.I['Cmd'] := HPCMD_SELECT_FILE; O.I['Ctrl'] := 99; O.S['Filter'] := 'All files|*.*'; SaveJsonObjToFile(O, GetRunExePathDir + DIR_CONF + DAT_PARAM); ProcInfo := ExecuteAppAsUser('explorer.exe', sExe, '', SW_SHOWNORMAL); if ProcInfo.dwProcessId = 0 then goto LB_Direct; end else begin LB_Direct : {$IFDEF _HE_} if (OpenDialog.Files.Count = 0) or (OpenDialog.FileName = '') then OpenDialog.InitialDir := Format('C:\Users\%s\Desktop', [gMgSvc.UserName]); {$ENDIF} if OpenDialog.Execute(Handle) then begin vtList.BeginUpdate; try for i := 0 to OpenDialog.Files.Count - 1 do AddFile(OpenDialog.Files[i]); finally vtList.EndUpdate; end; end; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. btnAddFileClick()'); end; end; procedure TDlgAip2KessDrm.btnDecryptClick(Sender: TObject); var nSuccess, nFail, nNorCnt: Integer; pNode: PVirtualNode; pData: PDrmEnt; bDecResult: Boolean; sPath, sTaskDir, sDecPath: String; h: HWND; O: ISuperObject; nResult: Integer; LogInfo: TLogInfo; begin if vtList.RootNodeCount = 0 then begin MessageBox(Handle, PChar(RS_MsgAddFile), PChar(Caption), MB_ICONWARNING or MB_OK); exit; end; if CountEncFile = 0 then begin MessageBox(Handle, PChar(RS_NoTgFile), PChar(Caption), MB_ICONWARNING or MB_OK); exit; end; if (sExceptReason_ = '') and (MessageBox(Handle, PChar(RS_Q_DrmDec), PChar(Caption), MB_ICONQUESTION or MB_YESNO) = IDNO) then exit; sTaskDir := 'C:\ProgramData\HE\Taskd\'; DeleteDir(sTaskDir); if not ForceDirectories(sTaskDir) then begin MessageBox(Handle, PChar(RS_MsgError), PChar(Caption), MB_ICONWARNING or MB_OK); exit; end; vtList.BeginUpdate; try nSuccess := 0; nFail := 0; nNorCnt := 0; pNode := vtList.GetFirst; while pNode <> nil do begin pData := vtList.GetNodeData(pNode); pNode := vtList.GetNext(pNode); if pData.bDrm then begin try bDecResult := true; sPath := pData.sDir + pData.sFName; if not IsAipEncryted(sPath) then begin pData.bDrm := false; Inc(nNorCnt); continue; end; h := gMgSvc.FindAipMdWnd; if h <> 0 then begin sDecPath := GetSameFileNameInc(sTaskDir + '$Tmpd' + ExtractFileName(sPath)); O := SO; O.S['src'] := sPath; O.S['dst'] := sDecPath; if gMgSvc.Email <> '' then O.S['mail'] := gMgSvc.Email; nResult := SendData(h, 7, O.AsString); // _Trace('SetAipLabel() .. Result=%d, Path=%s, EncPath=%s', [nResult, sPath, sEncPath]); // 0 : 레이블 추출, 1 : 암호화, 2 : 복호화, 3 : 암호화 확인, 4 : 레이블 확인, 5 : 레이블 설정, 6 : 레이블 확인, 7 : 레이블 제거 if (nResult = 10) and FileExists(sDecPath) then begin // if DeleteFileForce(sPath) then if MoveFile_wait(sPath, sDecPath + '@') then begin // if CopyFile(PChar(sDecPath), PChar(sPath), false) then // 이거 실패 대비를 해야 할까... 23_1024 09:04:08 kku if KCT_Encrypt(sDecPath, 2, sPath) = RESULT_SUCCESS then begin DeleteFile_wait(sDecPath + '@'); ZeroMemory(@LogInfo, SizeOf(LogInfo)); LogInfo.sCode := PREVENT_DRM_ENCRYPT; LogInfo.sSummary := '[AIP → KESS] ' + ExtractFileName(sPath); LogInfo.sPath := sPath; gMgSvc.SendEventLogEx(@LogInfo); Inc(nSuccess); pData.bDrm := false; end else begin MoveFile_wait(sDecPath + '@', sPath); Inc(nFail); end; end else Inc(nFail); end else Inc(nFail); if FileExists(sDecPath) then DeleteFile_wait(sDecPath); end else Inc(nFail); except Inc(nFail); end; end else Inc(nNorCnt); end; finally DeleteDir(sTaskDir); vtList.EndUpdate; end; MessageBox(Handle, PChar(Format(RS_CompleteWork1+#13+#10+RS_CompleteWork2, [nSuccess, nFail, nNorCnt])), PChar(Caption), MB_ICONINFORMATION or MB_OK); end; procedure TDlgAip2KessDrm.miClearClick(Sender: TObject); begin if MessageBox(Handle, PChar(RS_Q_Clear), PChar(Caption), MB_ICONQUESTION or MB_YESNO) = IDNO then exit; CheckFList_.Clear; VT_Clear(vtList); end; procedure TDlgAip2KessDrm.miDelFileClick(Sender: TObject); var pNode: PVirtualNode; pData: PDrmEnt; nIdx: Integer; begin pNode := vtList.GetFirstSelected; if pNode = nil then begin MessageBox(Handle, PChar(RS_SelExceptFile), PChar(Caption), MB_ICONWARNING or MB_OK); exit; end; if MessageBox(Handle, PChar(RS_Q_ExceptFile), PChar(Caption), MB_ICONQUESTION or MB_YESNO) = IDNO then exit; vtList.BeginUpdate; try while pNode <> nil do begin pData := vtList.GetNodeData(pNode); nIdx := CheckFList_.IndexOf(pData.sDir + pData.sFName); if nIdx <> -1 then CheckFList_.Delete(nIdx); pNode := vtList.GetNextSelected(pNode); end; vtList.DeleteSelectedNodes; finally vtList.EndUpdate; end; end; procedure TDlgAip2KessDrm.miDelNoDrmClick(Sender: TObject); var pNode, pDNode: PVirtualNode; pData: PDrmEnt; nIdx: Integer; begin pNode := vtList.GetFirst; if pNode = nil then begin MessageBox(Handle, PChar(RS_NoExceptFile), PChar(Caption), MB_ICONWARNING or MB_OK); exit; end; vtList.BeginUpdate; try while pNode <> nil do begin pData := vtList.GetNodeData(pNode); if not pData.bDrm then begin // nIdx := CheckFList_.IndexOf(pData.sDir + pData.sFName); // if nIdx <> -1 then // CheckFList_.Delete(nIdx); pDNode := pNode; end else pDNode := nil; pNode := vtList.GetNext(pNode); if pDNode <> nil then vtList.DeleteNode(pDNode); end; finally vtList.EndUpdate; end; end; procedure TDlgAip2KessDrm.vtListWndProc(var msg: TMessage); procedure ExtrctFilesFromDir(sDir: String); var wfd: TWin32FindData; hSc: THandle; sPath: String; begin sDir := IncludeTrailingPathDelimiter(sDir); sPath := sDir + '*.*'; hSc := FindFirstFile(PChar(sPath), wfd); if hSc = INVALID_HANDLE_VALUE then exit; try Repeat if (String(wfd.cFileName) <> '.') and (String(wfd.cFileName) <> '..') then if ((wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0) then begin ExtrctFilesFromDir(sDir + wfd.cFileName); end else begin AddFile(sDir + wfd.cFileName); end; Until not FindNextFile(hSc, wfd); finally WinApi.Windows.FindClose(hSc); end; end; var sPath: String; nCnt: Integer; i, nLen: Integer; pNode: PVirtualNode; pData: PDrmEnt; begin if msg.Msg = WM_DROPFILES then begin nCnt := DragQueryFile(msg.WParam, DWORD(-1), nil, MAX_PATH); vtList.BeginUpdate; try for i := 0 to nCnt - 1 do begin nLen := DragQueryFile(msg.WParam, i, nil, 0) + 1; SetLength(sPath, nLen); DragQueryFile(msg.WParam, i, PChar(sPath), nLen); sPath := DeleteNullTail(sPath); if FileExists(sPath) then AddFile(sPath) else if DirectoryExists(sPath) then ExtrctFilesFromDir(sPath); end; finally vtList.EndUpdate; end; DragFinish(msg.WParam); exit; end; vtListOldWndProc_(msg); end; procedure TDlgAip2KessDrm.vtListAfterPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas); var nX, nY, nW, nH: Integer; msg: String; begin if CUSTOMER_TYPE <> CUSTOMER_SERVE1 then // 서브원은 권한때문에 드래그드롭을 못함 24_0711 08:47:40 kku begin if TVirtualStringTree(Sender).RootNodeCount = 0 then begin TargetCanvas.Font.Color := clGray; msg := RS_DrmFileDragDrop; nW := TargetCanvas.TextWidth(msg); nH := TargetCanvas.TextHeight(msg); if Sender.Width > nW then nX := (Sender.Width div 2) - (nW div 2) else nX := 0; if Sender.Height > nH then nY := (Sender.Height div 2) - (nH div 2) - 20 else nY := 0; TargetCanvas.TextOut(nX, nY, msg); end; end; end; procedure TDlgAip2KessDrm.vtListContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean); var pNode: PVirtualNode; begin pNode := vtList.GetNodeAt(MousePos); miDelFile.Visible := pNode <> nil; miClear.Visible := vtList.RootNodeCount > 0; end; procedure TDlgAip2KessDrm.vtListFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); var pData: PDrmEnt; begin pData := Sender.GetNodeData(Node); Finalize(pData^); end; procedure TDlgAip2KessDrm.vtListGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: string); begin HintText := vtList.Text[Node, Column]; end; procedure TDlgAip2KessDrm.vtListGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: TImageIndex); var pData: PDrmEnt; begin case Kind of ikNormal, ikSelected: begin if Column = 1 then begin pData := Sender.GetNodeData(Node); if pData.nImgIdx = -1 then pData.nImgIdx := GetShellImageIndex_path(pData.sDir + pData.sFName); ImageIndex := pData.nImgIdx; end; end; end; end; procedure TDlgAip2KessDrm.vtListGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer); begin NodeDataSize := SizeOf(TDrmEnt); end; procedure TDlgAip2KessDrm.vtListGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); var pData: PDrmEnt; begin pData := Sender.GetNodeData(Node); case Column of 0 : CellText := IntToStr(Node.Index + 1); 1 : CellText := pData.sFName; 2 : CellText := pData.sExt; 3 : CellText := BooleanToStr(pData.bDrm, 'O', 'X'); 4 : CellText := pData.sDir; end; end; procedure TDlgAip2KessDrm.vtListPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); var pData: PDrmEnt; begin if not (vsSelected in Node.States) then begin pData := Sender.GetNodeData(Node); if pData.bDrm then TargetCanvas.Font.Color := clGreen; end; end; procedure TDlgAip2KessDrm.process_WM_COPYDATA(var msg: TMessage); var dwData: DWORD; pCpData: PCopyDataStruct; O: ISuperObject; sTemp: String; i: Integer; begin msg.Result := 0; dwData := 0; pCpData := PCopyDataStruct(msg.LParam); try dwData := pCpData.dwData; case dwData of HPCMD_SELECT_FILE : begin O := SO(Copy(PChar(pCpData.lpData), 1, pCpData.cbData)); if (O.O['List'] <> nil) and (O.O['List'].DataType = stArray) then begin for i := 0 to O.A['List'].Length - 1 do AddFile(O.A['List'].S[i]); end; // 일반권한으로 실행해서 안 지워진다.. 그래서 후처리 추가 22_0614 12:40:00 kku sTemp := GetRunExePathDir + DIR_CONF + DAT_PARAM; if FileExists(sTemp) then DeleteFile(sTemp); end; HPCMD_SELECT_FOLDER : begin O := SO(Copy(PChar(pCpData.lpData), 1, pCpData.cbData)); ExtrctFilesFromDir(O.S['Path']); // 일반권한으로 실행해서 안 지워진다.. 그래서 후처리 추가 22_0614 12:40:00 kku sTemp := GetRunExePathDir + DIR_CONF + DAT_PARAM; if FileExists(sTemp) then DeleteFile(sTemp); end; end; except on E: Exception do ETgException.TraceException(Self, E, Format('Fail .. process_WM_COPYDATA(), dwData=%d', [dwData])); end; end; end.