BSOne.SFC/Tocsg.Module/SoftCampTest/ProcessSoftcampDRM.pas

319 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.