Usb 연결 정보 보기 수정

- 기존의 Serial 정보를 VID,PID,Serial로 분리
- Deivce Instance ID 정보의 문자열 VID,PID에 추가

USB 장치 차단

- 커널드라이브의 차단, 읽기 전용, 허용 구조로 변경

빌드 스크립트 수정

- bs1flt.sys, bsonex32.sys, bsonex64.sys, bs1fltctrl.dll 추가
This commit is contained in:
mgkim 2026-02-05 13:49:32 +09:00
parent 74834264bf
commit 2d79f46f4e
607 changed files with 758083 additions and 526 deletions

View File

@ -69,6 +69,10 @@ type
procedure Notify(const Item: PDevPathLetter; Action: TCollectionNotification); override;
end;
TDevInfo = record
sVID, sPID, sSerial: String;
end;
function GetDriveFromMask(dwMask: DWORD): String;
function GetDrivesFromMask(dwMask: DWORD; bLetterOnly: Boolean = false; bFixedOnly: Boolean = false): String;
function GetDrivesDevPathLetterList(aList: TDevPathLetterList): Integer;

View File

@ -937,6 +937,14 @@ type
var RequiredSize: DWORD; Device: PSPDevInfoData): BOOL; stdcall; external 'SetupApi.dll' name 'SetupDiGetDeviceInterfaceDetailW';
function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL; stdcall; external 'SetupApi.dll' name 'SetupDiDestroyDeviceInfoList';
function SetupDiGetDeviceInstanceId(
DeviceInfoSet: HDEVINFO;
const DeviceInfoData: SP_DEVINFO_DATA;
DeviceInstanceId: PWideChar;
DeviceInstanceIdSize: DWORD;
var RequiredSize: DWORD
): BOOL; stdcall; external 'setupapi.dll' name 'SetupDiGetDeviceInstanceIdW';
function SetupDiRemoveDevice(DeviceInfoSet: HDEVINFO; var DeviceInfoData: TSPDevInfoData): BOOL; stdcall; external 'SetupApi.dll' name 'SetupDiRemoveDevice';
function CM_Get_Parent(var dnDevInstParent: DEVINST; dnDevInst: DEVINST; ulFlags: ULONG): CONFIGRET; stdcall; external 'CfgMgr32.dll';
@ -1034,6 +1042,7 @@ type
sClass,
sClassGuid,
sDesc,
sInstanceId,
sFriendlyName: String;
llSize: LONGLONG;
nDiskNum: Integer;
@ -1341,6 +1350,35 @@ begin
end;
end;
function GetDeviceInstanceId(hDev: HDEVINFO; spdd: TSPDevInfoData): string;
var
ReqSize: DWORD;
Buffer: array of Char; // 동적 배열 사용
begin
Result := '';
ReqSize := 0;
// 1. 필요한 버퍼 크기 구하기
// 함수가 False를 리턴하고 GetLastError가 ERROR_INSUFFICIENT_BUFFER일 때 정상
if not SetupDiGetDeviceInstanceId(hDev, spdd, nil, 0, ReqSize) then
begin
if GetLastError <> ERROR_INSUFFICIENT_BUFFER then Exit;
end;
if ReqSize = 0 then Exit;
// 2. 버퍼 메모리 할당
SetLength(Buffer, ReqSize);
// 3. 실제 데이터 가져오기
if SetupDiGetDeviceInstanceId(hDev, spdd, @Buffer[0], ReqSize, ReqSize) then
begin
// PChar로 변환하여 델파이 스트링에 담기
Result := PChar(@Buffer[0]);
Result := Trim(Result); // 혹시 모를 공백 제거
end;
end;
function GetDriveDetail(sDrive: String; pInfo: PDriveInfo; bAddInfo: Boolean = false): Boolean;
var
sVol: String;
@ -1425,6 +1463,8 @@ begin
if sdn.DeviceNumber = pInfo.nDiskNum then
begin
pInfo.sFriendlyName := GetDevPropertyStr(hDev, spdd, SPDRP_FRIENDLYNAME);
pInfo.sInstanceId := GetDeviceInstanceId(hDev, spdd);
if bAddInfo then
begin
pInfo.sClass := GetDevPropertyStr(hDev, spdd, SPDRP_CLASS);

View File

@ -6,7 +6,9 @@ uses
Tocsg.KvFilter in 'Tocsg.KvFilter.pas',
Tocsg.KvFilter.types in 'Tocsg.KvFilter.types.pas',
Tocsg.KvFilter.Kwautdef in 'Tocsg.KvFilter.Kwautdef.pas',
Tocsg.KvFilter.adinfo in 'Tocsg.KvFilter.adinfo.pas';
Tocsg.KvFilter.adinfo in 'Tocsg.KvFilter.adinfo.pas',
CttSchDefine in '..\ContentSearch\LIB_Common\CttSchDefine.pas',
GlobalDefine in '..\..\eCrmHE\LIB_Common\GlobalDefine.pas';
{$R *.res}

View File

@ -1,7 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{EC25E39E-CF7A-4CF8-9015-A66FAF307958}</ProjectGuid>
<ProjectVersion>19.4</ProjectVersion>
<ProjectVersion>20.3</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
@ -9,6 +9,7 @@
<TargetedPlatforms>3</TargetedPlatforms>
<AppType>Application</AppType>
<MainSource>KvFilter.dpr</MainSource>
<ProjectName Condition="'$(ProjectName)'==''">KvFilter</ProjectName>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
@ -108,6 +109,8 @@
<DCCReference Include="Tocsg.KvFilter.types.pas"/>
<DCCReference Include="Tocsg.KvFilter.Kwautdef.pas"/>
<DCCReference Include="Tocsg.KvFilter.adinfo.pas"/>
<DCCReference Include="..\ContentSearch\LIB_Common\CttSchDefine.pas"/>
<DCCReference Include="..\..\eCrmHE\LIB_Common\GlobalDefine.pas"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
@ -133,13 +136,20 @@
<Excluded_Packages Name="$(BDSBIN)\dclofficexp280.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment Version="3">
<DeployFile LocalName="..\OUT_Debug - Win32\KvFilter.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<Deployment Version="5">
<DeployFile LocalName="..\OUT_Debug - Win32\KvFilter.exe" Configuration="Debug" Class="ProjectOutput"/>
<DeployFile LocalName="OUT_Debug - Win64\KvFilter.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win64">
<RemoteName>KvFilter.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployFile LocalName="OUT_Debug - Win64\KvFilter.rsm" Configuration="Debug" Class="DebugSymbols">
<Platform Name="Win64">
<RemoteName>KvFilter.rsm</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
@ -152,16 +162,6 @@
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClasses">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>classes</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidFileProvider">
<Platform Name="Android">
<RemoteDir>res\xml</RemoteDir>
@ -172,12 +172,6 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
@ -230,6 +224,16 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDefV21">
<Platform Name="Android">
<RemoteDir>res\drawable-anydpi-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-anydpi-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
@ -250,6 +254,76 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV31">
<Platform Name="Android">
<RemoteDir>res\values-v31</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v31</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStylesV35">
<Platform Name="Android">
<RemoteDir>res\values-v35</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-v35</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_AdaptiveIcon">
<Platform Name="Android">
<RemoteDir>res\drawable-anydpi-v26</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-anydpi-v26</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_AdaptiveIconBackground">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_AdaptiveIconForeground">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_AdaptiveIconMonochrome">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_AdaptiveIconV33">
<Platform Name="Android">
<RemoteDir>res\drawable-anydpi-v33</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-anydpi-v33</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_Colors">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
@ -260,6 +334,16 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_ColorsDark">
<Platform Name="Android">
<RemoteDir>res\values-night-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\values-night-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
@ -430,6 +514,56 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_VectorizedNotificationIcon">
<Platform Name="Android">
<RemoteDir>res\drawable-anydpi-v24</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-anydpi-v24</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_VectorizedSplash">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_VectorizedSplashDark">
<Platform Name="Android">
<RemoteDir>res\drawable-night-anydpi-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-night-anydpi-v21</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_VectorizedSplashV31">
<Platform Name="Android">
<RemoteDir>res\drawable-anydpi-v31</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-anydpi-v31</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_VectorizedSplashV31Dark">
<Platform Name="Android">
<RemoteDir>res\drawable-night-anydpi-v31</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Android64">
<RemoteDir>res\drawable-night-anydpi-v31</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
@ -471,7 +605,7 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
@ -504,7 +638,7 @@
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
@ -541,7 +675,7 @@
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
@ -560,202 +694,6 @@
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iOS_AppStore1024">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon167">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_SpotLight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon180">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification60">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting87">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
@ -764,58 +702,6 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements">
<Platform Name="iOSDevice32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSLaunchScreen">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="iOSSimulator">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXDebug">
<Platform Name="OSX64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
@ -883,7 +769,7 @@
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
@ -918,6 +804,69 @@
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64x">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements">
<Platform Name="iOSDevice32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSLaunchScreen">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen</RemoteDir>
<Operation>64</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
@ -939,10 +888,211 @@
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iOS_AppStore1024">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon152">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_AppIcon167">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_SpotLight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_AppIcon180">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark2x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_LaunchDark3x">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification40">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Notification60">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting58">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Setting87">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight120">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Spotlight80">
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimARM64">
<RemoteDir>..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimARM64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>
@ -950,6 +1100,7 @@
<ProjectRoot Platform="OSXARM64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win64x" Name="$(PROJECTNAME)"/>
</Deployment>
<Platforms>
<Platform value="Win32">True</Platform>

View File

@ -5,7 +5,7 @@
<FrameworkType>VCL</FrameworkType>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config>
<Platform Condition="'$(Platform)'==''">Win64</Platform>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>3</TargetedPlatforms>
<AppType>Library</AppType>
<MainSource>eCrmHeHelper.dpr</MainSource>

View File

@ -15,10 +15,12 @@ object DlgUsbInfo: TDlgUsbInfo
OnClose = FormClose
TextHeight = 15
object vtList: TVirtualStringTree
Left = 8
Top = 16
Width = 536
Height = 186
Left = 0
Top = 0
Width = 552
Height = 210
AccessibleName = 'DriveInstance'
Align = alClient
Colors.BorderColor = 15987699
Colors.DisabledColor = clGray
Colors.DropMarkColor = 15385233
@ -53,6 +55,10 @@ object DlgUsbInfo: TDlgUsbInfo
OnHeaderClick = vtListHeaderClick
Touch.InteractiveGestures = [igPan, igPressAndTap]
Touch.InteractiveGestureOptions = [igoPanSingleFingerHorizontal, igoPanSingleFingerVertical, igoPanInertia, igoPanGutter, igoParentPassthrough]
ExplicitLeft = 8
ExplicitTop = 8
ExplicitWidth = 536
ExplicitHeight = 194
Columns = <
item
Position = 0
@ -71,7 +77,7 @@ object DlgUsbInfo: TDlgUsbInfo
item
Position = 3
Text = #51109#52824' '#51060#47492
Width = 120
Width = 124
end
item
Position = 4
@ -80,18 +86,36 @@ object DlgUsbInfo: TDlgUsbInfo
end
item
Position = 5
Text = #49884#47532#50620
Width = 100
Text = #51064#49828#53556#49828' '#44221#47196
Width = 150
end
item
Position = 6
Text = 'VID'
end
item
Position = 7
Text = 'PID'
end
item
Position = 8
Text = #49884#47532#50620
Width = 80
end
item
Position = 9
Text = #54028#51068#49884#49828#53596
Width = 80
end
item
Position = 7
Position = 10
Text = #46356#49828#53356' '#48264#54840
Width = 80
end
item
Position = 11
Text = 'DriveInstance'
Width = 150
end>
DefaultText = ''
end
@ -108,12 +132,16 @@ object DlgUsbInfo: TDlgUsbInfo
Caption = '-'
end
object miCopyAll: TMenuItem
Caption = #49440#53469#54620' USB '#51221#48372#47484' '#53364#47549#48372#46300#50640' '#48373#49324
Caption = #49440#53469#54620' USB '#51204#52404' '#51221#48372#47484' '#53364#47549#48372#46300#50640' '#48373#49324
OnClick = miCopyAllClick
end
object miCopySerial: TMenuItem
Caption = #49440#53469#54620' USB'#51032' '#49884#47532#50620' '#51221#48372#47484' '#53364#47549#48372#46300#50640' '#48373#49324
OnClick = miCopySerialClick
object miInstanceId: TMenuItem
Caption = #49440#53469#54620' USB('#51064#49828#53556#49828') '#51221#48372#47484' '#53364#47549#48372#46300#50640' '#48373#49324
OnClick = miInstanceIdClick
end
object miCopyVidPidSerial: TMenuItem
Caption = #49440#53469#54620' USB(VID,PID,SERIAL) '#51221#48372#47484' '#53364#47549#48372#46300#50640' '#48373#49324
OnClick = miVidPidSerialClick
end
end
end

View File

@ -12,6 +12,9 @@ type
sDrive,
sFsType,
sVolName: String;
sVid,
sPid,
sSerial : string;
Info: TDriveInfo;
end;
@ -21,7 +24,8 @@ type
miRefresh: TMenuItem;
N2: TMenuItem;
miCopyAll: TMenuItem;
miCopySerial: TMenuItem;
miInstanceId: TMenuItem;
miCopyVidPidSerial: TMenuItem;
procedure vtListGetNodeDataSize(Sender: TBaseVirtualTree;
var NodeDataSize: Integer);
procedure vtListGetHint(Sender: TBaseVirtualTree; Node: PVirtualNode;
@ -35,9 +39,10 @@ type
procedure miRefreshClick(Sender: TObject);
procedure vtListFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
procedure miCopyAllClick(Sender: TObject);
procedure miCopySerialClick(Sender: TObject);
procedure miInstanceIdClick(Sender: TObject);
procedure popFunPopup(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure miVidPidSerialClick(Sender: TObject);
private
{ Private declarations }
procedure RefreshList;
@ -84,7 +89,7 @@ begin
MessageBox(Handle, PChar(RS_CopyCB), PChar(Caption), MB_ICONINFORMATION or MB_OK);
end;
procedure TDlgUsbInfo.miCopySerialClick(Sender: TObject);
procedure TDlgUsbInfo.miInstanceIdClick(Sender: TObject);
var
pNode: PVirtualNode;
pData: PUsbInfo;
@ -111,13 +116,37 @@ begin
RefreshList;
end;
procedure TDlgUsbInfo.miVidPidSerialClick(Sender: TObject);
var
pNode: PVirtualNode;
pData: PUsbInfo;
cbd: TClipboard;
begin
try
pNode := vtList.GetFirstSelected;
if pNode = nil then
exit;
pData := vtList.GetNodeData(pNode);
Guard(cbd, TClipboard.Create);
cbd.AsText := '0x' + pData.sVid + ', 0x' + pData.sPid + ', ' + pData.sSerial;
MessageBox(Handle, PChar(RS_CopyCB), PChar(Caption), MB_ICONINFORMATION or MB_OK);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. miCopySerialClick()');
end;
end;
procedure TDlgUsbInfo.popFunPopup(Sender: TObject);
var
pNode: PVirtualNode;
begin
pNode := vtList.GetFirstSelected;
miCopyAll.Visible := pNode <> nil;
miCopySerial.Visible := pNode <> nil;
miInstanceId.Visible := pNode <> nil;
end;
procedure TDlgUsbInfo.RefreshList;
@ -127,6 +156,8 @@ var
i: Integer;
sDrive: String;
DriveInfo: TDriveInfo;
Parts, SubParts: TArray<string>;
sTemp: string;
begin
vtList.BeginUpdate;
try
@ -149,6 +180,46 @@ begin
pData.sVolName := GetVolumeName(sDrive);
pData.sFsType := GetVolumeFilesystem(sDrive);
pData.Info := DriveInfo;
//파싱 시작
Parts := DriveInfo.sSerial.Split(['\']);
if Length(Parts) >= 3 then
begin
pData.sSerial := Parts[2];
if Pos('VID_', Parts[1]) > 0 then
begin
pData.sVID := '0x';
pData.sVID := pData.sVID + Copy(Parts[1], Pos('VID_', Parts[1]) + 4, 4);
end;
if Pos('PID_', Parts[1]) > 0 then
begin
pData.sPID := '0x';
pData.sPID := Copy(Parts[1], Pos('PID_', Parts[1]) + 4, 4);
end;
end;
//USBSTOR\DISK&VEN_VENDORCO&PROD_PRODUCTCODE&REV_2.00\8328501217610604362&0
Parts := DriveInfo.sInstanceId.Split(['\']);
if Length(Parts) >= 3 then
begin
sTemp := Parts[Length(Parts) - 1]; // "8328501217610604362&0"
if Pos('&', sTemp) > 0 then
pData.sSerial := pData.sSerial + '(' + Copy(sTemp, 1, Pos('&', sTemp) - 1) + ')'
else
pData.sSerial := pData.sSerial + '(' + sTemp + ')';
SubParts := Parts[1].Split(['&']);
for sTemp in SubParts do
begin
if Pos('VEN_', sTemp) = 1 then
pData.sVID := pData.sVID + '(' + Copy(sTemp, 5, MaxInt) + ')'
else if Pos('PROD_', sTemp) = 1 then
pData.sPID := pData.sPID + '(' + Copy(sTemp, 6, MaxInt) + ')';
end;
end;
end;
end;
end;
@ -216,11 +287,15 @@ begin
3 : CellText := pData.Info.sFriendlyName;
4 : CellText := ByteSizeToStr(pData.Info.llSize);
5 : CellText := pData.Info.sSerial;
6 : CellText := pData.sFsType;
7 : CellText := IntToStr(pData.Info.nDiskNum);
8 : CellText := pData.Info.sClass;
9 : CellText := pData.Info.sClassGuid;
10 : CellText := pData.Info.sDesc;
6 : CellText := pData.sVid;
7 : CellText := pData.sPid;
8 : CellText := pData.sSerial;
9 : CellText := pData.sFsType;
10 : CellText := IntToStr(pData.Info.nDiskNum);
11 : CellText := pData.Info.sInstanceId;
12 : CellText := pData.Info.sClass;
13 : CellText := pData.Info.sClassGuid;
14 : CellText := pData.Info.sDesc;
end;
end;

View File

@ -539,7 +539,8 @@ type
UseOffLogMaxMB: Boolean;
IgrUsbSerialList: TStringList;
IgrUsbSerials: String;
IgrUsbSerials,
IgrUsbSerialsKn: String;
Print: TPrintPolicy;
PrinterIpExcept: String;

View File

@ -22,7 +22,7 @@ uses
Tocsg.Process, HandleSecurity, AppCtrlDefine, Tocsg.WndUtil,
ManagerCampaign, ManagerRule, superobject, Define, ThdReaction,
Vcl.Graphics, DSchPiNoti, Tocsg.Win32, Tocsg.Fasoo,
ThdPrintWork, xPrintLogService, ManagerPrint, ThdScreenRecord, ProcessRecentDoc;
ThdPrintWork, xPrintLogService, ManagerPrint, ThdScreenRecord, ProcessRecentDoc, Bs1FltCtrl;
{$I Define.inc}
@ -310,6 +310,7 @@ type
// USB 최근 연결 USB
sExceptUsbDev_,
sExceptUsbDevKn_,
sRecentUsbDrv_: String;
UsbConnList_: TStringList; // 연결된 USB드라이브 목록
DriveList_: TStringList;
@ -409,6 +410,12 @@ type
// 문서 파일 열람 확인 (임시, for LG디스플레이) 25_1106
RecentDocWatch_: TRecentDocWatch;
// 필터 드라이버를 통한 장치제어
FltCtrl_: TBs1fltControl;
bFltCtrlInit_ : Boolean;
FltCtrlPolicy_: DWORD;
DcFltCtrlEnt_: TDictionary<String,String>;
sEjectWbDrive_: String;
hEjectWbDrive_: THandle;
@ -453,6 +460,10 @@ type
function GetLastPolicy: String;
procedure SetLastPolicy(sLP: String);
procedure UpdateFltCtrlEnts(sDrive, sDevInfo: String);
function GetFltCrltEntInfo(sDrive: String): String;
procedure UpdateIgrUsbSerial4FltCtr(sData: String);
procedure ProcessUSBArrival(sDrive: String);
procedure OnUSBArrival(Sender: TObject; pInfo: PDevBroadcastVolume);
procedure OnUSBQueryRemove(Sender: TObject; sDrive: String; var bAccept: Boolean);
@ -863,7 +874,128 @@ begin
end;
end;
function FltCtrlCallback(sContext: Pointer): DWORD; stdcall;
var
sLog: String;
nPos: Integer;
O: ISuperObject;
begin
if sContext = nil then
exit;
sLog := String(PChar(sContext));
TThread.Queue(nil,
procedure
begin
{$IFDEF DEBUG}
gMgSvc._Trace(sLog, 1);
{$ELSE}
gMgSvc._Trace(sLog, 100);
{$ENDIF}
nPos := Pos('{', sLog);
if nPos > 0 then
begin
Delete(sLog, 1, nPos - 1);
O := SO(sLog);
if O.S['name'] <> '' then
gMgSvc.UpdateFltCtrlEnts(O.S['name'] + '\', Trim(O.S['vid']) + '§' + Trim(O.S['pid']) + '§' + Trim(O.S['serial']));
end;
end);
Result := 0;
end;
{ TManagerService }
procedure TManagerService.UpdateIgrUsbSerial4FltCtr(sData: String);
var
ExpList, InfoList: TStringList;
i: Integer;
DevInfo: TDevInfo;
begin
if not bFltCtrlInit_ or (FltCtrlPolicy_ = 0) then
exit;
try
FltCtrl_.ClearUsbException;
Guard(ExpList, TStringList.Create);
SplitString(sData, '|', ExpList, false, true);
Guard(InfoList, TStringList.Create);
for i := 0 to ExpList.Count - 1 do
begin
SplitString(ExpList[i], '§', InfoList);
if InfoList.Count = 3 then
FltCtrl_.SetUsbException(PChar(InfoList[0]), PChar(InfoList[1]), 0, PChar(InfoList[2]));
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. UpdateIgrUsbSerial4FltCtr()');
end;
end;
procedure TManagerService.UpdateFltCtrlEnts(sDrive, sDevInfo: String);
begin
Lock;
try
sDrive := sDrive.ToUpper;
if DcFltCtrlEnt_.ContainsKey(sDrive) then
DcFltCtrlEnt_[sDrive] := sDevInfo
else
DcFltCtrlEnt_.Add(sDrive, sDevInfo);
finally
Unlock;
end;
end;
function TManagerService.GetFltCrltEntInfo(sDrive: String): String;
function GetSameSerialDevs(sSerial: String; var nSameCnt: Integer): String;
var
enum: TEnumerator<String>;
begin
Result := '';
Lock;
try
Guard(enum, DcFltCtrlEnt_.Values.GetEnumerator);
while enum.MoveNext do
begin
if enum.Current.EndsWith(sSerial) then
begin
SumString(Result, enum.Current, '<!>');
Inc(nSameCnt);
end;
end;
finally
Unlock;
end;
end;
begin
Result := '';
Lock;
try
sDrive := sDrive.ToUpper;
if DcFltCtrlEnt_.ContainsKey(sDrive) then
Result := DcFltCtrlEnt_[sDrive];
finally
Unlock;
end;
if Result <> '' then
begin
var nSameCnt: Integer := 0;
var sSerial: String := ExtrLastDelimiterStr(Result, '§');
var sSame: String;
// 오래된 SD 멀티 허브의 경우 빈드라이브가 여러개 생성되는데
// 이거 모두 동일한 시리얼로 인식될 경우 정보 모두 처리하도록 보완 25_0202 14:43:43 kku
sSame := GetSameSerialDevs(sSerial, nSameCnt);
if nSameCnt > 1 then
Result := sSame;
end;
end;
Constructor TManagerService.Create(hRcvHwnd: HWND);
@ -1246,6 +1378,19 @@ begin
ThdWndMon_ := nil;
xPrintLogService_ := nil;
bFltCtrlInit_ := false;
FltCtrlPolicy_ := 0;
FltCtrl_ := TBs1fltControl.Create;
DcFltCtrlEnt_ := TDictionary<String,String>.Create;
if FltCtrl_.InitDriver(GetRunExePathDir, FltCtrlCallback) = 0 then
begin
_Trace('장치 접근 제어 준비 .. OK', 1);
FltCtrl_.BeginControl(1);
bFltCtrlInit_ := true;
end else
_Trace('장치 접근 제어 준비 .. Fail', 1);
sUtcOffset_ := '+00:00';
try
var TS: TTimeSpan := TTimeZone.Local.GetUtcOffset(Now);
@ -1673,6 +1818,9 @@ begin
// CoUninitialize;
gMgSvc := nil;
Inherited;
FltCtrl_.Cleanup;
FreeAndNil(FltCtrl_);
FreeAndNil(DcFltCtrlEnt_);
FreeAndNil(MgPrint_);
FreeAndNil(DriveList_);
FreeAndNil(UsbConnList_);
@ -2430,141 +2578,7 @@ begin
exit;
end;
// 감시중인 드라이브 해제 22_0923 12:29:07 kku
// bFileMon := false;
// if FileService_ <> nil then
// bFileMon := FileService_.DelDriveWatch(sDrive);
case CUSTOMER_TYPE of
CUSTOMER_WELFND,
CUSTOMER_WELFNI :
begin
// 알약 때문에 차단 안되는 이슈가 이는데,
// 아래 반복문으로 최적화 확인 25_1113 11:18:11 kku
// var nTO: Integer := 0;
// while nTO < 5 do
// begin
// Sleep(1000);
// CloseAlyacScanWindow;
// Sleep(500);
// CloseAlyacScanWindow;
// Sleep(500);
//
// sBlkSerial := EjectDrive2(sDrive, ModePolicy.IgrUsbSerialList, true, true);
// if (sBlkSerial <> '') and (sBlkSerial <> FAIL_EJECT) then
// begin
// Sleep(500);
// CloseAlyacScanWindow;
// break;
// end;
// Inc(nTO);
// end
// diskaprt로 처리 25_1120 16:23:50 kku
// Sleep(500);
// CloseAlyacScanWindow;
// Sleep(500);
// CloseAlyacScanWindow;
// var nTO: Integer := 0;
// while nTO < 5 do
// begin
// var sScptPath: String := GetRunExePathDir + Format('$d-scrpt=%d.txt', [GetTickCount]);
// var StrList: TStringList;
// Guard(StrList, TStringList.Create);
// StrList.Add(Format(DISKPART_FMT_SELECT, [DriveInfo.nDiskNum]));
// StrList.Add(DISKPART_OFFLINE_DISK);
// StrList.SaveToFile(sScptPath, TEncoding.ANSI);
// ExecuteAppWaitUntilTerminate('diskpart.exe', Format('/s "%s"', [sScptPath]), SW_HIDE, 10000);
// if not DirectoryExists(sDrive) then
// begin
// Sleep(2500);
// StrList.Clear;
// StrList.Add(Format(DISKPART_FMT_SELECT, [DriveInfo.nDiskNum]));
// StrList.Add(DISKPART_ONLINE_DISK);
// StrList.SaveToFile(sScptPath, TEncoding.ANSI);
// ExecuteAppWaitUntilTerminate('diskpart.exe', Format('/s "%s"', [sScptPath]), SW_HIDE, 10000);
// Sleep(1500);
// end;
// DeleteFile_wait(PChar(sScptPath), 2);
//
// sBlkSerial := EjectDrive2(sDrive, ModePolicy.IgrUsbSerialList, true, true);
// if (sBlkSerial <> '') and (sBlkSerial <> FAIL_EJECT) then
// begin
//// Sleep(500);
//// CloseAlyacScanWindow;
// break;
// end;
// Inc(nTO);
// end;
// if (nType = DRIVE_FIXED) and (Pos('seagate', LowerCase(DriveInfo.sFriendlyName)) > 0) then
if nType = DRIVE_FIXED then
begin
if IsReadOnlyByWriteProbe(sDrive) = 0 then
begin
_Trace('디스크 속성 변경 Lock, Drive=%s, Name=%s', [sDrive, DriveInfo.sFriendlyName], 5);
SetReadOnly(sDrive, DriveInfo.nDiskNum, true);
Sleep(1000);
end;
_Trace('디스크 offline 처리 시작, Drive=%s, Name=%s', [sDrive, DriveInfo.sFriendlyName], 5);
var sScptPath: String := GetRunExePathDir + Format('$d-scrpt=%d.txt', [GetTickCount]);
var StrList: TStringList;
Guard(StrList, TStringList.Create);
StrList.Add(Format(DISKPART_FMT_SELECT, [DriveInfo.nDiskNum]));
StrList.Add(DISKPART_OFFLINE_DISK);
StrList.SaveToFile(sScptPath, TEncoding.ANSI);
ExecuteAppWaitUntilTerminate('diskpart.exe', Format('/s "%s"', [sScptPath]), SW_HIDE, 10000);
if not DirectoryExists(sDrive) then
begin
Sleep(500);
StrList.Clear;
StrList.Add(Format(DISKPART_FMT_SELECT, [DriveInfo.nDiskNum]));
StrList.Add(DISKPART_ONLINE_DISK);
StrList.SaveToFile(sScptPath, TEncoding.ANSI);
ExecuteAppWaitUntilTerminate('diskpart.exe', Format('/s "%s"', [sScptPath]), SW_HIDE, 10000);
Sleep(500);
end;
DeleteFile_wait(PChar(sScptPath), 2);
_Trace('디스크 offline 처리 끝, Drive=%s, Name=%s', [sDrive, DriveInfo.sFriendlyName], 5);
sBlkSerial := EjectDrive2(sDrive, ModePolicy.IgrUsbSerialList, true, true);
if (sBlkSerial = '') and (IsReadOnlyByWriteProbe(sDrive) = 1) then
begin
_Trace('디스크 속성 변경 Unlock, Drive=%s, Name=%s', [sDrive, DriveInfo.sFriendlyName], 5);
SetReadOnly(sDrive, DriveInfo.nDiskNum, false);
end;
end else
sBlkSerial := EjectDrive2(sDrive, ModePolicy.IgrUsbSerialList, true, true, true);
if sBlkSerial = '' then
begin
// 예외된 장치면 알약 검사 시작
if FindAlyacScanWindow = 0 then
begin
var sAyPath: String := 'C:\Program Files\ESTsoft\ALYac\AYCShell.ayc';
if FileExists(sAyPath) then
begin
if SecondsBetween(dtCreateMg_, Now) > 5 then
begin
ExecutePath(sAyPath, Format('/removable/%s:', [sDrive[1]]));
_Trace('알약 드라이브 검사 시작 : Drive=%s', [sDrive], 5);
end else
_Trace('Agent 시작 후 5초 이내, 알약 드라이브 검사 무시 : Drive=%s', [sDrive], 5);
end else
_Trace('알약 드라이브 검사 프로그램을 찾지 못함 : Path=%s', [sAyPath], 5);
end else
_Trace('알약 드라이브 검사창 확인됨. 검사 시작 무시 : Drive=%s', [sDrive], 5);
end;
end;
CUSTOMER_BLUECORNER : EjectDrive(sDrive, ModePolicy.IgrUsbSerialList, true, true);
else begin
sBlkSerial := EjectDrive2(sDrive, ModePolicy.IgrUsbSerialList, true, true);
end;
end;
//sBlkSerial := EjectDrive2(sDrive, ModePolicy.IgrUsbSerialList, true, true);
if bNoLogPop then
exit;
@ -5183,28 +5197,78 @@ begin
try
PO := GetModePolicy;
// USB 차단
case PO.UsbBlockKind of
ubkReadOnly :
begin
if ThdUsbMonRO_ = nil then
begin
ThdUsbMonRO_ := TThdUsbMon.Create(0, upkReadOnly);
ThdUsbMonRO_.StartThread;
_Trace('USB 읽기만 적용 - ON', 2);
end;
end;
else
begin
if ThdUsbMonRO_ <> nil then
begin
FreeAndNil(ThdUsbMonRO_);
_Trace('USB 읽기만 적용 - OFF', 2);
end;
// case PO.UsbBlockKind of
// ubkReadOnly :
// begin
// if ThdUsbMonRO_ = nil then
// begin
// ThdUsbMonRO_ := TThdUsbMon.Create(0, upkReadOnly);
// ThdUsbMonRO_.StartThread;
// _Trace('USB 읽기만 적용 - ON', 2);
// end;
// end;
// else
// begin
// if ThdUsbMonRO_ <> nil then
// begin
// FreeAndNil(ThdUsbMonRO_);
// _Trace('USB 읽기만 적용 - OFF', 2);
// end;
_Trace('TimerProcessDevTask : (%d)', [DWORD(PO.UsbBlockKind)]);
if PO.UsbBlockKind = ubkBlock then
DoEjectUsbDrives;
end;
end;
begin
if bFltCtrlInit_ then
begin
if not (FltCtrlPolicy_ = DWORD(dsDisable)) then
begin
FltCtrl_.SetDeviceProtect(1);
FltCtrl_.SetPolicy(DWORD(BDC_USB_DISK), DWORD(dsDisable), 1);
FltCtrl_.SetPolicy(DWORD(BDC_EXTERNALHDD), DWORD(dsDisable), 1);
FltCtrlPolicy_ := DWORD(dsDisable);
end;
if sExceptUsbDevKn_ <> PO.IgrUsbSerialsKn then
begin
sExceptUsbDevKn_ := PO.IgrUsbSerialsKn;
UpdateIgrUsbSerial4FltCtr(sExceptUsbDevKn_);
end;
end;
end
else if PO.UsbBlockKind = ubkReadOnly then
begin
if bFltCtrlInit_ then
begin
if not (FltCtrlPolicy_ = DWORD(dsReadOnly)) then
begin
FltCtrl_.SetDeviceProtect(2);
FltCtrl_.SetPolicy(DWORD(BDC_USB_DISK), DWORD(dsReadOnly), 1);
FltCtrl_.SetPolicy(DWORD(BDC_EXTERNALHDD), DWORD(dsReadOnly), 1);
FltCtrlPolicy_ := DWORD(dsReadOnly);
end;
if sExceptUsbDevKn_ <> PO.IgrUsbSerialsKn then
begin
sExceptUsbDevKn_ := PO.IgrUsbSerialsKn;
UpdateIgrUsbSerial4FltCtr(sExceptUsbDevKn_);
end;
end;
end
else begin
if not (FltCtrlPolicy_ = DWORD(dsEnable)) then
begin
sExceptUsbDevKn_ := '';
FltCtrl_.ClearUsbException;
FltCtrl_.SetDeviceProtect(0);
FltCtrl_.SetPolicy(DWORD(BDC_USB_DISK), DWORD(dsEnable), 0);
FltCtrl_.SetPolicy(DWORD(BDC_EXTERNALHDD), DWORD(dsEnable), 0);
FltCtrlPolicy_ := DWORD(dsEnable);
end;
end;
DoEjectUsbDrives;
// end;
// end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. TimerProcessDevTask()');
@ -7260,45 +7324,6 @@ begin
if FileService_ <> nil then
FileService_.DelDriveWatch(sDrive);
{
// if sEjectWbDrive_ = sDrive then
// begin
// bAccept := false;
// exit;
// end else
if IsReadOnlyByWriteProbe(sDrive) = 1 then
begin
// hEjectWbDrive_ := CreateFile(PChar(Format('\\.\%s:', [sDrive[1]])), GENERIC_READ,
// FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
// nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
// if hEjectWbDrive_ = INVALID_HANDLE_VALUE then
// hEjectWbDrive_ := 0;
//
// sEjectWbDrive_ := sDrive;
// bAccept := false;
// exit;
if ThdUsbMonRO_ <> nil then
ThdUsbMonRO_.SetRecoverWB(false);
try
var DriveInfo: TDriveInfo;
GetDriveDetail(sDrive, @DriveInfo);
SetReadOnly(sDrive, DriveInfo.nDiskNum, false);
Sleep(500);
if IsReadOnlyByWriteProbe(sDrive) <> 1 then
EjectDrive(sDrive, nil, false, true);
// else
// sEjectWbDrive_ := sDrive;
finally
if ThdUsbMonRO_ <> nil then
ThdUsbMonRO_.SetRecoverWB(true);
end;
end;
}
// if ThdUsbMonRO_ <> nil then
// ThdUsbMonRO_.DelDrive(sDrive);
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. OnUSBQueryRemove()');

Some files were not shown because too many files have changed in this diff Show More