BSOne.SFC/Tocsg.Module/UsbMon/DUsbMonMain.pas

298 lines
7.6 KiB
Plaintext

unit DUsbMonMain;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, ThdUsbMon, Bs1FltCtrl,
Tocsg.Trace;
type
TDlgUsbMonMain = class(TForm)
pnTop: TPanel;
btnPreventUsb: TButton;
rdReadOnly: TRadioButton;
rdBlock: TRadioButton;
mmLog: TMemo;
rdMonitor: TRadioButton;
edDrive: TEdit;
btnDismount: TButton;
btnDrvInfo: TButton;
chkKernel: TCheckBox;
rbUsbEnable: TRadioButton;
rbUsbDisable: TRadioButton;
btnBs1SetPolicy: TButton;
grpBs1CtrlUsb: TGroupBox;
procedure btnPreventUsbClick(Sender: TObject);
procedure btnDismountClick(Sender: TObject);
procedure btnDrvInfoClick(Sender: TObject);
procedure btnBs1SetPolicyClick(Sender: TObject);
private
{ Private declarations }
ThdUsbMon_: TThdUsbMon;
Trace_: TTgTrace;
public
{ Public declarations }
Bs1Ctrl: TBs1fltControl;
kernelUsed_: Boolean;
Constructor Create(aOwner: TComponent); override;
Destructor Destroy; override;
procedure process_WM_USBCONTROL_NOTIFY(var msg: TMessage); Message WM_USBCONTROL_NOTIFY;
end;
var
DlgUsbMonMain: TDlgUsbMonMain;
implementation
uses
Tocsg.Driver, Tocsg.Convert, Tocsg.Path, Tocsg.Disk;
{$R *.dfm}
function MyLogCallback(Context: Pointer): DWORD; stdcall;
var
logMsg: string;
begin
// 로그 처리 로직 (Context는 문자열 포인터일 가능성이 높음)
if Context = nil then Exit;
LogMsg := string(PWideChar(Context));
OutputDebugString(PWideChar(Context));
TThread.Queue(nil,
procedure
begin
// 폼이 살아있는지 확인 후 로그 추가
if Assigned(DlgUsbMonMain) and Assigned(DlgUsbMonMain.mmLog) then
begin
if DlgUsbMonMain.mmLog.Lines.Count > 1000 then
DlgUsbMonMain.mmLog.Lines.Delete(0);
DlgUsbMonMain.mmLog.Lines.Add(LogMsg);
end;
end);
Result := 0;
end;
Constructor TDlgUsbMonMain.Create(aOwner: TComponent);
var
state: DWORD;
path: string;
begin
Inherited Create(aOwner);
Trace_ := TTgTrace.Create(GetRunExePathDir, CutFileExt(GetRunExeName) + '.log');
Trace_.Level := 10;
ThdUsbMon_ := nil;
kernelUsed_:= FALSE;
rdBlock.Checked:= True;
chkKernel.Checked:= True;
path:= GetRunExePathDir;
Bs1Ctrl := TBs1fltControl.Create;
try
// 커널 드라이버의 위치를 정한다.
state := Bs1Ctrl.Init(path, MyLogCallback);
if state = 0 then
begin
// ShowMessage('Bs1Ctrl 초기화 성공');
mmLog.Lines.Add('Bs1Ctrl 초기화 성공');
Bs1Ctrl.Bs1FltBegin(1);
end
else
begin
mmLog.Lines.Add('Bs1Ctrl 초기화 실패: ' + IntToStr(state));
end;
finally
// 전역 변수로 관리하거나 필요 없으면 해제
// Bs1Ctrl.Free;
end;
end;
Destructor TDlgUsbMonMain.Destroy;
begin
if ThdUsbMon_ <> nil then
FreeAndNil(ThdUsbMon_);
if Bs1Ctrl <> nil then
begin
if Assigned(Bs1Ctrl.Bs1FltCleanup) then
Bs1Ctrl.Bs1FltCleanup;
Bs1Ctrl.Free;
end;
Inherited;
FreeAndNil(Trace_);
end;
procedure TDlgUsbMonMain.btnBs1SetPolicyClick(Sender: TObject);
var
state: enum_devicestate;
protect: DWORD;
begin
if rbUsbEnable.Checked then
begin
state:= dsEnable;
protect:= 0;
end
else
begin
state:= dsDisable;
protect:= 1;
end;
if not Assigned(Bs1Ctrl.Bs1FltCleanup) then
exit;
Bs1Ctrl.Bs1fltSetDeviceProtect(protect);
Bs1Ctrl.Bs1FltSetPolicy(DWORD(BDC_USB_DISK), DWORD(state), 1);
Bs1Ctrl.Bs1FltSetPolicy(DWORD(BDC_EXTERNALHDD), DWORD(state), 1);
end;
procedure TDlgUsbMonMain.btnDismountClick(Sender: TObject);
begin
edDrive.Text := Trim(edDrive.Text);
if (edDrive.Text = '') and (not DirectoryExists(edDrive.Text)) then
begin
ShowMessage('실패 1');
exit;
end;
// ShowMessage(GetVolumeName(edDrive.Text));
// exit;
if EjectDrive(edDrive.Text, nil, true, true) = FAIL_EJECT then
ShowMessage('실패 2')
else
ShowMessage('성공');
end;
procedure TDlgUsbMonMain.btnDrvInfoClick(Sender: TObject);
var
DriveInfo: TDriveInfo;
begin
edDrive.Text := Trim(edDrive.Text);
if (edDrive.Text = '') and (not DirectoryExists(edDrive.Text)) then
begin
ShowMessage('실패 1');
exit;
end;
GetDriveDetail(edDrive.Text, @DriveInfo, true);
mmLog.Lines.Add('Drive : ' + DriveInfo.sDrive);
mmLog.Lines.Add('Drive Type : ' + GetDriveTypeToStr(GetDriveType(PChar(DriveInfo.sDrive))));
mmLog.Lines.Add('Serial : ' + DriveInfo.sSerial);
mmLog.Lines.Add('Class : ' + DriveInfo.sClass);
mmLog.Lines.Add('ClassGuid : ' + DriveInfo.sClassGuid);
mmLog.Lines.Add('Description : ' + DriveInfo.sDesc);
mmLog.Lines.Add('FriendlyName : ' + DriveInfo.sFriendlyName);
mmLog.Lines.Add(Format('Size : %s (%d)', [ByteSizeToStr(DriveInfo.llSize), DriveInfo.llSize]));
mmLog.Lines.Add('DiskNum : ' + IntToStr(DriveInfo.nDiskNum));
end;
procedure TDlgUsbMonMain.btnPreventUsbClick(Sender: TObject);
var
ActionKind: TUsbProcKind;
begin
if ThdUsbMon_ = nil then
begin
if rdMonitor.Checked then
ActionKind := upkMonitor
else if rdReadOnly.Checked then
ActionKind := upkReadOnly
else
ActionKind := upkBlock;
mmLog.Clear;
ThdUsbMon_ := TThdUsbMon.Create(Handle, ActionKind);
ThdUsbMon_.StartThread;
if chkKernel.Checked then
begin
kernelUsed_:= True;
Bs1Ctrl.Bs1fltSetDeviceProtect(1);
Bs1Ctrl.Bs1FltSetPolicy(DWORD(BDC_USB_DISK), DWORD(dsDisable), 1);
Bs1Ctrl.Bs1FltSetPolicy(DWORD(BDC_EXTERNALHDD), DWORD(dsDisable), 1);
end
else
kernelUsed_:= False;
chkKernel.Enabled:= False;
end else begin
if MessageBox(Handle, PChar('중지하시겠습니까?'),
PChar(Caption), MB_ICONQUESTION or MB_YESNO) = IDNO then exit;
FreeAndNil(ThdUsbMon_);
if kernelUsed_ then
begin
Bs1Ctrl.Bs1fltSetDeviceProtect(0);
Bs1Ctrl.Bs1FltSetPolicy(DWORD(BDC_USB_DISK), DWORD(dsEnable), 0);
Bs1Ctrl.Bs1FltSetPolicy(DWORD(BDC_EXTERNALHDD), DWORD(dsEnable), 0);
end;
chkKernel.Enabled:= True;
end;
rdMonitor.Enabled := ThdUsbMon_ = nil;
rdReadOnly.Enabled := rdMonitor.Enabled;
rdBlock.Enabled := rdMonitor.Enabled;
if rdMonitor.Enabled then
btnPreventUsb.Caption := 'USB 제어 시작'
else
btnPreventUsb.Caption := 'USB 제어 중지';
Application.ProcessMessages;
end;
procedure TDlgUsbMonMain.process_WM_USBCONTROL_NOTIFY(var msg: TMessage);
procedure WriteLog(sLog: String);
begin
mmLog.Lines.Add(Format('[%s] %s', [DateTimeToStr(Now), sLog]));
end;
var
pEnt: PUsbEnt;
begin
pEnt := PUsbEnt(msg.LParam);
case msg.WParam of
ACTION_USBCONTROL_ARRIVAL :
begin
WriteLog(Format('연결됨 : Drive=%s, Size=%s, DevName=%s',
[pEnt.DriveInfo.sDrive, ByteSizeToStr(pEnt.DriveInfo.llSize), pEnt.DriveInfo.sFriendlyName]));
end;
ACTION_USBCONTROL_REMOVE :
begin
WriteLog(Format('해제됨 : Drive=%s, Size=%s, DevName=%s',
[pEnt.DriveInfo.sDrive, ByteSizeToStr(pEnt.DriveInfo.llSize), pEnt.DriveInfo.sFriendlyName]));
end;
ACTION_USBCONTROL_READONLY :
begin
WriteLog(Format('읽기전용 적용! : Drive=%s, Size=%s, DevName=%s',
[pEnt.DriveInfo.sDrive, ByteSizeToStr(pEnt.DriveInfo.llSize), pEnt.DriveInfo.sFriendlyName]));
end;
ACTION_USBCONTROL_READONLY_RETRAY : ;
ACTION_USBCONTROL_BLOCK :
begin
WriteLog(Format('차단!! : Drive=%s, Size=%s, DevName=%s',
[pEnt.DriveInfo.sDrive, ByteSizeToStr(pEnt.DriveInfo.llSize), pEnt.DriveInfo.sFriendlyName]));
end;
end;
end;
end.