BSOne.SFC/Tocsg.Lib/VCL/Tocsg.MTP.pas

189 lines
5.3 KiB
Plaintext

{*******************************************************}
{ }
{ Tocsg.MTP }
{ }
{ Copyright (C) 2022 kku }
{ }
{*******************************************************}
unit Tocsg.MTP;
interface
uses
System.SysUtils, System.Classes, Tocsg.Obj, Winapi.Windows,
System.Generics.Collections;
type
PMtpEnt = ^TMtpEnt;
TMtpEnt = record
sName,
sDesc,
sMfg,
sDevId: String;
end;
TMtpEntList = TList<PMtpEnt>;
TManagerMtpDev = class(TTgObject)
private
MtpEntList_: TMtpEntList;
procedure OnMptEntNotify(Sender: TObject; const Item: PMtpEnt; Action: TCollectionNotification);
public
Constructor Create;
Destructor Destroy; override;
procedure RefreshMptDev;
function GetMtpEntByDevId(sDevId: String): PMtpEnt;
property MtpEntList: TMtpEntList read MtpEntList_;
end;
implementation
uses
Tocsg.Driver, Tocsg.Exception, Tocsg.Safe;
Constructor TManagerMtpDev.Create;
begin
Inherited Create;
MtpEntList_ := TMtpEntList.Create;
MtpEntList_.OnNotify := OnMptEntNotify;
end;
Destructor TManagerMtpDev.Destroy;
begin
FreeAndNil(MtpEntList_);
Inherited;
end;
procedure TManagerMtpDev.OnMptEntNotify(Sender: TObject; const Item: PMtpEnt; Action: TCollectionNotification);
begin
if Action = cnRemoved then
Dispose(Item);
end;
procedure TManagerMtpDev.RefreshMptDev;
var
hDev: HDEVINFO;
sdd: TSPDevInfoData;
i, c: Integer;
dwBufSize,
dwStatus, dwProblem,
dwPropertyRegDataType: DWORD;
pBuf: Pointer;
sInfo1, sInfo2: String;
InfoList: TStringList;
pEnt: PMtpEnt;
function GetPropStr(dwProp: DWORD): String;
begin
Result := '';
dwBufSize := 0;
if pBuf <> nil then
begin
FreeMem(pBuf);
pBuf := nil;
end;
while not SetupDiGetDeviceRegistryProperty(hDev, sdd,
dwProp, dwPropertyRegDataType, pBuf, dwBufSize, dwBufSize) do
begin
if GetLastError = ERROR_INSUFFICIENT_BUFFER then
begin
if pBuf <> nil then
FreeMem(pBuf);
pBuf := AllocMem(dwBufSize);
end else break;
end;
if pBuf <> nil then
Result := PChar(pBuf); // 값 여러줄 있는거 무시하고 첫번째만 가져옴
end;
begin
try
hDev := SetupDiGetClassDevs(@GUID_DEVCLASS_WPD, nil, 0, DIGCF_PRESENT);
if hDev = INVALID_HANDLE_VALUE then
exit;
pBuf := nil;
try
ZeroMemory(@sdd, SizeOf(sdd));
sdd.cbSize := SizeOf(sdd);
Guard(InfoList, TStringList.Create);
i := 0;
while SetupDiEnumDeviceInfo(hDev, i, sdd) do
begin
sInfo1 := UpperCase(Trim(GetPropStr(SPDRP_COMPATIBLEIDS)));
sInfo2 := UpperCase(Trim(GetPropStr(SPDRP_SERVICE)));
// if GetPropStr(SPDRP_DEVTYPE) = 'MTP' then // todo : "버스에서 보고된 장치 설명" 값을 가져오는 방법을 모름.. 22_0630 15:18:12 kku
if (sInfo1 = 'USB\MS_COMP_MTP') or (sInfo2 = 'WUDFWPDMTP') then
begin
New(pEnt);
// _Trace(GetPropStr(SPDRP_COMPATIBLEIDS)); // USB\MS_COMP_MTP
// _Trace(GetPropStr(SPDRP_SERVICE)); // WUDFWpdMtp
// _Trace(GetPropStr(SPDRP_CLASS));
// _Trace(GetPropStr(SPDRP_CLASSGUID));
// _Trace(GetPropStr(SPDRP_DRIVER));
// _Trace(GetPropStr(SPDRP_CONFIGFLAGS));
// _Trace(GetPropStr(SPDRP_LOCATION_INFORMATION));
// _Trace(GetPropStr(SPDRP_PHYSICAL_DEVICE_OBJECT_NAME));
// _Trace(GetPropStr(SPDRP_CAPABILITIES));
// _Trace(GetPropStr(SPDRP_UI_NUMBER));
// _Trace(GetPropStr(SPDRP_UPPERFILTERS));
// _Trace(GetPropStr(SPDRP_LOWERFILTERS));
// _Trace(GetPropStr(SPDRP_BUSTYPEGUID));
// _Trace(GetPropStr(SPDRP_LEGACYBUSTYPE));
// _Trace(GetPropStr(SPDRP_BUSNUMBER));
// _Trace(GetPropStr(SPDRP_UI_NUMBER));
// _Trace(GetPropStr(SPDRP_ENUMERATOR_NAME));
// _Trace(GetPropStr(SPDRP_SECURITY));
// _Trace(GetPropStr(SPDRP_SECURITY_SDS));
// _Trace(GetPropStr(SPDRP_DEVTYPE));
// _Trace(GetPropStr(SPDRP_EXCLUSIVE));
// _Trace(GetPropStr(SPDRP_CHARACTERISTICS));
// _Trace(GetPropStr(SPDRP_ADDRESS));
// _Trace(GetPropStr(SPDRP_UI_NUMBER_DESC_FORMAT));
// _Trace(GetPropStr(SPDRP_DEVICE_POWER_DATA));
// _Trace(GetPropStr(SPDRP_REMOVAL_POLICY));
// _Trace(GetPropStr(SPDRP_LOCATION_PATHS));
pEnt.sName := GetPropStr(SPDRP_FRIENDLYNAME);
pEnt.sDesc := GetPropStr(SPDRP_DEVICEDESC);
pEnt.sMfg := GetPropStr(SPDRP_MFG);
pEnt.sDevId := GetPropStr(SPDRP_HARDWAREID);
MtpEntList_.Add(pEnt);
end;
Inc(i);
end;
finally
SetupDiDestroyDeviceInfoList(hDev);
if pBuf <> nil then
FreeMem(pBuf);
end;
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. RefreshMptDev()');
end;
end;
function TManagerMtpDev.GetMtpEntByDevId(sDevId: String): PMtpEnt;
var
i: Integer;
begin
Result := nil;
for i := 0 to MtpEntList_.Count - 1 do
if MtpEntList_[i].sDevId = sDevId then
begin
Result := MtpEntList_[i];
exit;
end;
end;
end.