BSOne.SFC/Tocsg.Module/MtpMon/ThdMtpMon.pas

347 lines
10 KiB
Plaintext

{*******************************************************}
{ }
{ ThdMtpMon }
{ }
{ Copyright (C) 2022 kku }
{ }
{*******************************************************}
unit ThdMtpMon;
interface
uses
Tocsg.Thread, System.SysUtils, System.Classes, Winapi.Windows, Tocsg.MTP,
Winapi.Messages, System.Generics.Collections, ManagerModel;
const
WM_MTP_NOTIFY = WM_USER + 8523;
type
TPreventMtp = record
bPrevent: Boolean;
sIgrDevId: String;
end;
PBlockMtp = ^TBlockMtp;
TBlockMtp = record
sDevId: String;
nTryCnt: Integer;
end;
TBlockMtpList = TList<PBlockMtp>;
TThdMtpMon = class(TTgThread)
protected
hRcvWnd_: HWND;
PreventMtp_: TPreventMtp;
MgMtp_: TManagerMtpDev;
BlockMtpList_: TBlockMtpList;
procedure OnBlockMtpNotify(Sender: TObject; const Item: PBlockMtp; Action: TCollectionNotification);
procedure Execute; override;
public
Constructor Create; overload;
Constructor Create(hRcvWnd: HWND; aPreventMtp: TPreventMtp); overload;
Destructor Destroy; override;
end;
implementation
uses
{$IFDEF _HE_}
ManagerService, GlobalDefine,
{$ENDIF}
Tocsg.Exception, Tocsg.Driver, Tocsg.Safe, Tocsg.Strings, Condition;
{ TThdMtpMon }
Constructor TThdMtpMon.Create;
begin
Inherited Create;
hRcvWnd_ := 0;
BlockMtpList_ := TBlockMtpList.Create;
BlockMtpList_.OnNotify := OnBlockMtpNotify;
ZeroMemory(@PreventMtp_, SizeOf(PreventMtp_));
MgMtp_ := TManagerMtpDev.Create;
// MgMtp_.RefreshMptDev;
end;
Constructor TThdMtpMon.Create(hRcvWnd: HWND; aPreventMtp: TPreventMtp);
begin
Create;
hRcvWnd_ := hRcvWnd;
PreventMtp_ := aPreventMtp;
end;
Destructor TThdMtpMon.Destroy;
begin
Inherited;
if MgMtp_ <> nil then
FreeAndNil(MgMtp_);
FreeAndNil(BlockMtpList_);
end;
procedure TThdMtpMon.OnBlockMtpNotify(Sender: TObject; const Item: PBlockMtp; Action: TCollectionNotification);
begin
if Action = cnRemoved then
Dispose(Item);
end;
procedure TThdMtpMon.Execute;
var
ChkMgMtp: TManagerMtpDev;
bPrevent: Boolean;
IgrDevList,
IgrDevVdList: TStringList;
sChkName: String;
bIgrVender: Boolean;
pBlockEnt: PBlockMtp;
pEnt: PMtpEnt;
{$IFDEF _HE_}
sMsg,
sData,
sExcept,
sExceptVender: String;
MtpBlockKind: TUsbBlockKind;
{$ENDIF}
procedure ProcessMtpDev(aMtpBlockKind: TUsbBlockKind; var aMtpDevs: TManagerMtpDev);
var
i, c: Integer;
begin
try
for i := aMtpDevs.MtpEntList.Count - 1 downto 0 do
begin
// if aMtpDevs.MtpEntList[i].sName = '' then
// begin
// // 이름이 비어 있는 경우 차단은 가능하지만 정확한 장치 이름을 남길수가 없기때문에
// // 이름이 채워질때까지 차단하지 않는다 25_0923 09:50:58 kku
// aMtpDevs.MtpEntList.Delete(i);
// continue;
// end;
if MgMtp_.GetMtpEntByDevId(aMtpDevs.MtpEntList[i].sDevId) = nil then
begin
bPrevent := false;
{$IFDEF _HE_}
if aMtpBlockKind = ubkBlock then
{$ELSE}
if PreventMtp_.bPrevent then
{$ENDIF}
begin
if IgrDevList.IndexOf(aMtpDevs.MtpEntList[i].sDevId) = -1 then
begin
sChkName := UpperCase(aMtpDevs.MtpEntList[i].sName + '|' + aMtpDevs.MtpEntList[i].sDesc + '|' +
aMtpDevs.MtpEntList[i].sDevId);
bIgrVender := false;
for c := 0 to IgrDevVdList.Count - 1 do
begin
if Pos(IgrDevVdList[c], sChkName) > 0 then
begin
bIgrVender := true;
break;
end;
end;
if not bIgrVender then
begin
bPrevent := RemoveUsbDevEnableByDevPath(aMtpDevs.MtpEntList[i].sDevId) < 2;
if not bPrevent then
begin
_Trace('Fail .. BlockMTP, Reg, DevId="%s"', [aMtpDevs.MtpEntList[i].sDevId]);
New(pBlockEnt);
pBlockEnt.sDevId := aMtpDevs.MtpEntList[i].sDevId;
pBlockEnt.nTryCnt := 0;
BlockMtpList_.Add(pBlockEnt);
continue;
end;
end;
end;
end;
{$IFDEF _HE_}
with aMtpDevs.MtpEntList[i]^ do
begin
sMsg := Format('Name : %s, Desc : %s, Serial : %s', [sName, sDesc, sDevId]);
sData := sName + '|' + sDesc + '|' + sDevId;
if bPrevent then
begin
sData := sData + '|PV';
if gMgSvc.IsNewApi then
begin
var LogInfo: TLogInfo;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := LOGCODE_PREVENT_MTP;
LogInfo.sSummary := sMsg;
LogInfo.sDevName := sName;
LogInfo.sDevSerial := sDevId;
LogInfo.sDevClassId := sDesc;
gMgSvc.SendEventLogEx(@LogInfo);
end else
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_MTP, sMsg);
if gMgSvc.ModePolicy.MTPPopup then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_MTP, sData);
end else begin
case MtpBlockKind of
ubkBlock : sMsg := 'Excepted, ' + sMsg;
ubkLog,
ubkReadOnly :
begin
if IsDivPopup then
begin
if gMgSvc.ModePolicy.MtpAllowPopup then
begin
if IgrDevList.IndexOf(sDevId) = -1 then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_MTP, sData);
end;
end else begin
if gMgSvc.ModePolicy.MTPPopup then
begin
if IgrDevList.IndexOf(sDevId) = -1 then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_MTP, sData);
end;
end;
end;
end;
if gMgSvc.IsNewApi then
begin
var LogInfo: TLogInfo;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := LOGCODE_EVENT_MTP;
LogInfo.sSummary := sMsg;
LogInfo.sDevName := sName;
LogInfo.sDevSerial := sDevId;
LogInfo.sDevClassId := sDesc;
gMgSvc.SendEventLogEx(@LogInfo, false);
end else
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_EVENT_MTP, sMsg, false);
end;
end;
{$ELSE}
if hRcvWnd_ <> 0 then
SendMessage(hRcvWnd_, WM_MTP_NOTIFY, Integer(bPrevent), NativeUInt(aMtpDevs.MtpEntList[i]));
{$ENDIF}
if bPrevent then
aMtpDevs.MtpEntList.Delete(i);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessMtpDev()');
end;
end;
var
i: Integer;
begin
ChkMgMtp := nil;
Guard(IgrDevList, TStringList.Create);
IgrDevList.CaseSensitive := false;
Guard(IgrDevVdList, TStringList.Create);
// 이미지 연결되어 있는 MTP 장치 차단을 위해 추가 23_1226 14:49:15 kku
ChkMgMtp := TManagerMtpDev.Create;
ChkMgMtp.RefreshMptDev;
ProcessMtpDev(gMgSvc.ModePolicy.MtpBlockKind, ChkMgMtp);
FreeAndNil(ChkMgMtp);
MgMtp_.RefreshMptDev;
{$IFDEF _HE_}
sExcept := '';
sExceptVender := '';
{$ELSE}
SplitString(PreventMtp_.sIgrDevId, ';', IgrDevList);
{$ENDIF}
try
while not Terminated and not GetWorkStop do
begin
try
if ChkMgMtp = nil then
begin
ChkMgMtp := TManagerMtpDev.Create;
ChkMgMtp.RefreshMptDev;
end;
{$IFDEF _HE_}
if sExcept <> gMgSvc.ModePolicy.MtpExcept then
begin
sExcept := gMgSvc.ModePolicy.MtpExcept;
SplitString(sExcept, ';', IgrDevList);
end;
if sExceptVender <> gMgSvc.ModePolicy.MtpExceptVender then
begin
sExceptVender := gMgSvc.ModePolicy.MtpExceptVender;
SplitString(UpperCase(sExceptVender), ';', IgrDevVdList);
end;
MtpBlockKind := gMgSvc.ModePolicy.MtpBlockKind;
{$ENDIF}
// 차단 실패 시 재시도 추가 23_0323 09:54:17 kku
if BlockMtpList_.Count > 0 then
begin
for i := BlockMtpList_.Count - 1 downto 0 do
begin
pBlockEnt := BlockMtpList_[i];
pEnt := MgMtp_.GetMtpEntByDevId(pBlockEnt.sDevId);
if pEnt = nil then
begin
BlockMtpList_.Delete(i);
continue;
end;
sData := pEnt.sName + '|' + pEnt.sDesc + '|' + pEnt.sDevId;
bPrevent := RemoveUsbDevEnableByDevPath(pEnt.sDevId) < 2;
if bPrevent then
begin
sData := sData + '|PV';
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_MTP,
Format('Name : %s, Desc : %s, Serial : %s', [pEnt.sName, pEnt.sDesc, pEnt.sDevId]));
if gMgSvc.ModePolicy.MTPPopup then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_MTP, sData);
end else begin
Inc(pBlockEnt.nTryCnt);
_Trace('Fail .. BlockMTP, TryCnt=%d, DevId="%s"', [pBlockEnt.nTryCnt, pEnt.sDevId]);
if pBlockEnt.nTryCnt >= 30 then // 4번에서 30번으로 변경 23_0329 14:51:07 kku
begin
BlockMtpList_.Delete(i);
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_EVENT_MTP,
Format('BF > Name : %s, Desc : %s, Serial : %s', [pEnt.sName, pEnt.sDesc, pEnt.sDevId]), false);
if IsDivPopup then
begin
if gMgSvc.ModePolicy.MtpAllowPopup then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_MTP, sData);
end else
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_MTP, sData);
end;
end;
end;
end;
ProcessMtpDev(MtpBlockKind, ChkMgMtp);
FreeAndNil(MgMtp_);
MgMtp_ := ChkMgMtp;
ChkMgMtp := nil;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. Execute()');
end;
Sleep(1000);
end;
finally
if ChkMgMtp <> nil then
FreeAndNil(ChkMgMtp);
end;
end;
end.