319 lines
12 KiB
Plaintext
319 lines
12 KiB
Plaintext
unit ProcessSoftcampDRM;
|
||
|
||
interface
|
||
|
||
uses
|
||
Winapi.Windows;
|
||
|
||
const
|
||
{$IFDEF WIN64}
|
||
DLL_SCDRM_DSCSLINK = 'DSCSLink64.dll';
|
||
DLL_SCDRM_DSCAN = 'DSScan64.dll';
|
||
|
||
DIR_SC = 'Softcamp\SDS\x64\';
|
||
{$ELSE}
|
||
DLL_SCDRM_DSCSLINK = 'DSCSLink.dll';
|
||
DLL_SCDRM_DSCAN = 'DSScan.dll';
|
||
|
||
DIR_SC = 'Softcamp\SDS\';
|
||
{$ENDIF}
|
||
|
||
SIGN_SOFTCAMP_DRM: array [0..6] of Byte =
|
||
($53, $43, $44, $53, $41, $30, $30); // SCDSA00 시작됨 // 수정 25_0219 11:13:51 kku
|
||
// $53, $43, $44, $53, $41, $30, $30, $34, $00, $00, $52, $00, $20, $88); // SCDSA00 시작됨 // 수정 23_1221 11:02:43 kku
|
||
// ($53, $43, $44, $53, $41, $30, $30, $34, $00, $00, $52, $00, $20, $88, $F1, $53); // SCDSA004 시작됨
|
||
|
||
SCDRM_STATE_NOAGENT = 0;
|
||
SCDRM_STATE_LOGOFF = 1;
|
||
SCDRM_STATE_LOGON = 2;
|
||
|
||
type
|
||
// DSCSLink.dll
|
||
TDSCheckDSAgent = function: Integer; cdecl;
|
||
TDSCSForceDecryptFile = function(sSrcPath, sDestPath: PAnsiChar) : Integer; cdecl;
|
||
TDSCSDecryptFile = function(sSrcPath, sDestPath: PAnsiChar) : Integer; cdecl;
|
||
TDSCSDacEncryptFileV2 = function(sSrcPath: PWideChar): Integer; cdecl;
|
||
TDSCSGradeEncryptFile = function(sSrcPath, sGradeId: PAnsiChar): Integer; cdecl;
|
||
TDSCSIsEncryptedFile = function(sPath: PAnsiChar) : Integer; cdecl;
|
||
TDSCSSetAcl = procedure(hWndServer: HWND; sCateId, sAcl: PAnsiChar; nForceEncMode: Integer); cdecl;
|
||
TDSCSGetGradeID = function(sSrcPath, sGradeId: PAnsiChar): Integer; cdecl;
|
||
TDSCSInstall = procedure; cdecl;
|
||
TDSCSRelease = procedure; cdecl;
|
||
TDSCSAppliedGetAcl = function(nAclIndex: Integer): Integer; cdecl;
|
||
|
||
function DSCheckDSAgent: Integer;
|
||
function DSCSForceDecryptFile(sSrcPath, sDestPath: AnsiString): Integer;
|
||
function DSCSDecryptFile(sSrcPath, sDestPath: AnsiString): Integer;
|
||
function DSCSGradeEncryptFile(sSrcPath, sGradeId: AnsiString): Integer;
|
||
function DSCSDacEncryptFileV2(sSrcPath: WideString): Integer;
|
||
function DSCSIsEncryptedFile(sPath: AnsiString) : Integer;
|
||
procedure DSCSSetAcl(hWndServer: HWND; sCateId, sAcl: AnsiString; nForceEncMode: Integer);
|
||
function DSCSGetGradeID(sSrcPath: AnsiString; sGradeId: PAnsiChar): Integer;
|
||
procedure DSCSInstall;
|
||
procedure DSCSRelease;
|
||
function DSCSAppliedGetAcl(nAclIndex: Integer): Integer;
|
||
|
||
type
|
||
// DSScan.dll
|
||
TDS_IsEncrypted = function(sSrcPath: PWideChar): Boolean; cdecl;
|
||
TDS_DecryptFile = function(sSrcpath: PWideChar): THandle; cdecl;
|
||
TDS_GetDecryptedFileName = function(hFile: THandle; sDecPath: PWideChar; nPathSize: UINT): DWORD; cdecl;
|
||
TDS_Finalize = function(hFile: THandle; bCured: Boolean): DWORD; cdecl;
|
||
TDS_IsLogin = function: Boolean; cdecl;
|
||
|
||
// DSScan.dll
|
||
function ExistsSoftCampScanModule: Boolean; // 다른 DRM 유무 확인 명령과 이름을 맞추기 위해 이렇게 추가 14_0617 09:37:00 sunk
|
||
function DS_IsEncrypted(sSrcPath: WideString): Boolean;
|
||
function DS_IsLoadDLL: Boolean;
|
||
function DS_DecryptFile(sSrcpath: WideString): THandle;
|
||
//function DS_GetDecryptedFileName(hFile: THandle; sDecPath: WideString; nPathSize: UINT): DWORD;
|
||
function DS_GetDecryptedFileName(hFile: THandle; sDecPath: PWideChar; nPathSize: UINT): DWORD;
|
||
function DS_Finalize(hFile: THandle; bCured: Boolean): DWORD;
|
||
function DS_IsLogin: Boolean;
|
||
|
||
implementation
|
||
|
||
uses
|
||
System.SysUtils, Tocsg.Path;
|
||
|
||
// DSScan.dll ------------------------------------------------------------------
|
||
|
||
var
|
||
hScDrm_CSLink: THandle = 0;
|
||
_fnDSCheckDSAgent: TDSCheckDSAgent = nil;
|
||
_fnDSCSForceDecryptFile: TDSCSForceDecryptFile = nil;
|
||
_fnDSCSDecryptFile: TDSCSDecryptFile = nil;
|
||
_fnDSCSGradeEncryptFile: TDSCSGradeEncryptFile = nil;
|
||
_fnDSCSDacEncryptFileV2: TDSCSDacEncryptFileV2 = nil;
|
||
_fnDSCSIsEncryptedFile: TDSCSIsEncryptedFile = nil;
|
||
_fnDSCSSetAcl: TDSCSSetAcl = nil;
|
||
_fnDSCSGetGradeID: TDSCSGetGradeID = nil;
|
||
_fnDSCSInstall: TDSCSInstall = nil;
|
||
_fnDSCSRelease: TDSCSRelease = nil;
|
||
_fnDSCSAppliedGetAcl: TDSCSAppliedGetAcl = nil;
|
||
|
||
function InitScDRM_CSLink_Procedure: Boolean;
|
||
var
|
||
sPath: String;
|
||
begin
|
||
if hScDrm_CSLink = 0 then
|
||
begin
|
||
sPath := GetRunExePathDir + DLL_SCDRM_DSCSLINK;
|
||
if not FileExists(sPath) then
|
||
sPath := GetWindowsDir + DLL_SCDRM_DSCSLINK; // for HEC
|
||
if not FileExists(sPath) then
|
||
sPath := GetRunExePathDir + DLL_SCDRM_DSCSLINK;
|
||
|
||
hScDrm_CSLink := LoadLibrary(PChar(sPath));
|
||
if hScDrm_CSLink <> 0 then
|
||
begin
|
||
@_fnDSCheckDSAgent := GetProcAddress(hScDrm_CSLink, 'DSCheckDSAgent');
|
||
@_fnDSCSForceDecryptFile := GetProcAddress(hScDrm_CSLink, 'DSCSForceDecryptFile');
|
||
@_fnDSCSDecryptFile := GetProcAddress(hScDrm_CSLink, 'DSCSDecryptFile');
|
||
@_fnDSCSDacEncryptFileV2 := GetProcAddress(hScDrm_CSLink, 'DSCSDacEncryptFileV2');
|
||
@_fnDSCSIsEncryptedFile := GetProcAddress(hScDrm_CSLink, 'DSCSIsEncryptedFile');
|
||
@_fnDSCSSetAcl := GetProcAddress(hScDrm_CSLink, 'DSCSSetAcl');
|
||
@_fnDSCSGetGradeID := GetProcAddress(hScDrm_CSLink, 'DSCSGetGradeID');
|
||
@_fnDSCSInstall := GetProcAddress(hScDrm_CSLink, 'DSCSInstall');
|
||
@_fnDSCSRelease := GetProcAddress(hScDrm_CSLink, 'DSCSRelease');
|
||
@_fnDSCSAppliedGetAcl := GetProcAddress(hScDrm_CSLink, 'DSCSAppliedGetAcl');
|
||
end;
|
||
end;
|
||
Result := hScDrm_CSLink <> 0;
|
||
end;
|
||
|
||
// DS Client Agent 실행 유,무 및 로그인 유.무 체크 함수
|
||
// 0: DS Client Agent가 실행 되지 않은 상태
|
||
// 1: DS Client Agent 실행 상태이며 로그아웃 상태
|
||
// 2: DS Client Agent 실행 상태이며 로그인 상태
|
||
function DSCheckDSAgent: Integer;
|
||
begin
|
||
Result := 0;
|
||
if InitScDRM_CSLink_Procedure and Assigned(_fnDSCheckDSAgent) then
|
||
Result := _fnDSCheckDSAgent;
|
||
end;
|
||
|
||
// 로컬 시스템에 있는 파일을 강제적으로 복호화 API (외부 반출용)
|
||
// 0: 복호화 실패
|
||
// 1: 복호화 성공
|
||
// 3: 문서보안 클라이언트 아웃 상태
|
||
function DSCSForceDecryptFile(sSrcPath, sDestPath: AnsiString) : Integer;
|
||
begin
|
||
Result := 0;
|
||
if InitScDRM_CSLink_Procedure and Assigned(_fnDSCSForceDecryptFile) then
|
||
Result := _fnDSCSForceDecryptFile(PAnsiChar(sSrcPath), PAnsiChar(sDestPath));
|
||
end;
|
||
|
||
// 0: 복호화 실패 1: 복호화 성공 3: 문서보안 로그아웃 상태이거나 실행되지 않은 상태 4: Parameter Error
|
||
function DSCSDecryptFile(sSrcPath, sDestPath: AnsiString) : Integer;
|
||
begin
|
||
Result := 0;
|
||
if InitScDRM_CSLink_Procedure and Assigned(_fnDSCSDecryptFile) then
|
||
Result := _fnDSCSDecryptFile(PAnsiChar(sSrcPath), PAnsiChar(sDestPath));
|
||
end;
|
||
|
||
// 0: 암호화 실패, 1: 암호화 성공, 2: 지원하지 않는 확장자, 3: 문서보안 클라이언트 아웃 상태
|
||
function DSCSGradeEncryptFile(sSrcPath, sGradeId: AnsiString): Integer;
|
||
begin
|
||
Result := 0;
|
||
if InitScDRM_CSLink_Procedure and Assigned(_fnDSCSGradeEncryptFile) then
|
||
Result := _fnDSCSGradeEncryptFile(PAnsiChar(sSrcPath), PAnsiChar(sGradeId));
|
||
end;
|
||
|
||
// 0: 암호화 실패, 1: 암호화 성공, 2: 지원하지 않는 확장자, 3: 문서보안 클라이언트 아웃 상태
|
||
function DSCSDacEncryptFileV2(sSrcPath: WideString): Integer;
|
||
begin
|
||
Result := 0;
|
||
if InitScDRM_CSLink_Procedure and Assigned(_fnDSCSDacEncryptFileV2) then
|
||
Result := _fnDSCSDacEncryptFileV2(PWideChar(sSrcPath));
|
||
end;
|
||
|
||
// 파라미터 값으로 전달한 파일명에 대하여 암호화된 문서인지 체크하는 함수
|
||
// -1: C/S 연동 모듈 로드 실패
|
||
// 0: 일반 문서
|
||
// 1: 암호화된 문서
|
||
function DSCSIsEncryptedFile(sPath: AnsiString): Integer;
|
||
begin
|
||
Result := -1;
|
||
if InitScDRM_CSLink_Procedure and Assigned(_fnDSCSIsEncryptedFile) then
|
||
Result := _fnDSCSIsEncryptedFile(PAnsiChar(sPath));
|
||
end;
|
||
|
||
// 권한 적용 API
|
||
// hWndServer : DLL 로드 한 프로세스 윈도우 핸들
|
||
// sCateId : 시스템 보안에 대한 권한 참조 범주 아이디
|
||
// sAcl : 시스템 보안에 대한 강제 권한 적용 "0000" 포맷의 4비트 사용 1bit – 편집, 2bit – 캡쳐, 3bit – 인쇄, 4bit – 마킹
|
||
// nForceEncMode : 시스템에서 다운로드 하는 파일에 대하여 암호화 수행 방식 (1 – 전체그룹으로 암호화, 0 – 범주로 암호화
|
||
procedure DSCSSetAcl(hWndServer: HWND; sCateId, sAcl: AnsiString; nForceEncMode: Integer);
|
||
begin
|
||
if InitScDRM_CSLink_Procedure and Assigned(_fnDSCSSetAcl) then
|
||
_fnDSCSSetAcl(hWndServer, PAnsiChar(sCateId), PAnsiChar(sAcl), nForceEncMode);
|
||
end;
|
||
|
||
// 첫 번째 파라미터의 파일(Full path)의 등급 아이디를 두 번째 파라미터 버퍼에 저장
|
||
// 0: 실패 1: 성공 3: 문서보안 로그아웃 상태이거나 실행되지 않은 상태
|
||
function DSCSGetGradeID(sSrcPath: AnsiString; sGradeId: PAnsiChar): Integer;
|
||
begin
|
||
Result := 0;
|
||
if InitScDRM_CSLink_Procedure and Assigned(_fnDSCSGetGradeID) then
|
||
Result := _fnDSCSGetGradeID(PAnsiChar(sSrcPath), sGradeId);
|
||
end;
|
||
|
||
// CS 연동 시작(해당 프로세스에 대하여 Hooking Start)
|
||
procedure DSCSInstall;
|
||
begin
|
||
if InitScDRM_CSLink_Procedure and Assigned(_fnDSCSInstall) then
|
||
_fnDSCSInstall;
|
||
end;
|
||
|
||
// CS 연동 해제
|
||
// DSCSRelease API사용 후 다시 권한제어를 위해서는 DSCSSecuArea, CSSetAcl API를 다시 호출해야함
|
||
procedure DSCSRelease;
|
||
begin
|
||
if InitScDRM_CSLink_Procedure and Assigned(_fnDSCSRelease) then
|
||
_fnDSCSRelease;
|
||
end;
|
||
|
||
function DSCSAppliedGetAcl(nAclIndex: Integer): Integer;
|
||
begin
|
||
Result := -1;
|
||
if InitScDRM_CSLink_Procedure and Assigned(_fnDSCSAppliedGetAcl) then
|
||
Result := _fnDSCSAppliedGetAcl(nAclIndex);
|
||
end;
|
||
|
||
// DSScan.dll ------------------------------------------------------------------
|
||
|
||
var
|
||
hScDrm_Scan: THandle = 0;
|
||
_fnDS_IsEncrypted: TDS_IsEncrypted;
|
||
_fnDS_DecryptFile: TDS_DecryptFile;
|
||
_fnDS_GetDecryptedFileName: TDS_GetDecryptedFileName;
|
||
_fnDS_Finalize: TDS_Finalize;
|
||
_fnDS_IsLogin: TDS_IsLogin;
|
||
|
||
function InitScDRM_Scan_Procedure: Boolean;
|
||
var
|
||
sWinDir,
|
||
sPath: String;
|
||
begin
|
||
if hScDrm_Scan = 0 then
|
||
begin
|
||
sWinDir := GetWindowsDir;
|
||
sPath := sWinDir + DIR_SC + DLL_SCDRM_DSCAN;
|
||
if not FileExists(sPath) then
|
||
begin
|
||
sPath := sWinDir + DLL_SCDRM_DSCAN;
|
||
if not FileExists(sPath) then
|
||
sPath := GetRunExePathDir + DLL_SCDRM_DSCAN;
|
||
end;
|
||
|
||
hScDrm_Scan := LoadLibrary(PChar(sPath));
|
||
if hScDrm_Scan <> 0 then
|
||
begin
|
||
@_fnDS_IsEncrypted := GetProcAddress(hScDrm_Scan, 'DS_IsEncrypted');
|
||
@_fnDS_DecryptFile := GetProcAddress(hScDrm_Scan, 'DS_DecryptFile');
|
||
@_fnDS_GetDecryptedFileName := GetProcAddress(hScDrm_Scan, 'DS_GetDecryptedFileName');
|
||
@_fnDS_Finalize := GetProcAddress(hScDrm_Scan, 'DS_Finalize');
|
||
@_fnDS_IsLogin := GetProcAddress(hScDrm_Scan, 'DS_IsLogin');
|
||
end;
|
||
end;
|
||
Result := hScDrm_Scan <> 0;
|
||
end;
|
||
|
||
function ExistsSoftCampScanModule: Boolean;
|
||
begin
|
||
Result := InitScDRM_Scan_Procedure;
|
||
end;
|
||
|
||
// 파일이 암호화된 파일인지 검사
|
||
function DS_IsEncrypted(sSrcPath: WideString): Boolean;
|
||
begin
|
||
Result := false;
|
||
if InitScDRM_Scan_Procedure and Assigned(_fnDS_IsEncrypted) then
|
||
Result := _fnDS_IsEncrypted(PWideChar(sSrcPath));
|
||
end;
|
||
|
||
function DS_IsLoadDLL: Boolean;
|
||
begin
|
||
Result := InitScDRM_Scan_Procedure and Assigned(_fnDS_IsEncrypted);
|
||
end;
|
||
|
||
// 파일을 복호화한다
|
||
// 성공할 경우 NULL이 아닌값을 리턴 (파일 핸들), 실패 시 0
|
||
function DS_DecryptFile(sSrcpath: WideString): THandle;
|
||
begin
|
||
Result := 0;
|
||
if InitScDRM_Scan_Procedure and Assigned(_fnDS_DecryptFile) then
|
||
Result := _fnDS_DecryptFile(PWideChar(sSrcPath));
|
||
end;
|
||
|
||
// 복호화된 파일패스를 받는다.
|
||
// Path를 Copy하는데 필요한 크기를 리턴, 에러인 경우 0을 리턴
|
||
//function DS_GetDecryptedFileName(hFile: THandle; sDecPath: WideString; nPathSize: UINT): DWORD;
|
||
function DS_GetDecryptedFileName(hFile: THandle; sDecPath: PWideChar; nPathSize: UINT): DWORD;
|
||
begin
|
||
Result := 0;
|
||
if InitScDRM_Scan_Procedure and Assigned(_fnDS_GetDecryptedFileName) then
|
||
Result := _fnDS_GetDecryptedFileName(hFile, sDecPath, nPathSize);
|
||
// Result := _fnDS_GetDecryptedFileName(hFile, PWideChar(sDecPath), nPathSize);
|
||
end;
|
||
|
||
// 모든 작업을 종료하며 h가 무효화 된다. 할당했던 메모리 해제, 임시로 생성했던 파일삭제
|
||
// 성공할 경우 ERROR_SUCCESS를 리턴
|
||
function DS_Finalize(hFile: THandle; bCured: Boolean): DWORD;
|
||
begin
|
||
Result := 1;
|
||
if InitScDRM_Scan_Procedure and Assigned(_fnDS_Finalize) then
|
||
Result := _fnDS_Finalize(hFile, bCured);
|
||
end;
|
||
|
||
// 문서보안 로그인이 되어있는지 확인
|
||
function DS_IsLogin: Boolean;
|
||
begin
|
||
Result := false;
|
||
if InitScDRM_Scan_Procedure and Assigned(_fnDS_IsLogin) then
|
||
Result := _fnDS_IsLogin;
|
||
end;
|
||
|
||
end.
|