BSOne.SFC/Tocsg.Module/WscProduct/Tocsg.WscApi.pas

185 lines
5.7 KiB
Plaintext

{*******************************************************}
{ }
{ Tocsg.WscApi }
{ }
{ Copyright (C) 2022 kku }
{ }
{*******************************************************}
unit Tocsg.WscApi;
interface
uses
WinApi.Windows, Vcl.OleServer, System.Generics.Collections;
const
strIID_IWscProduct = '{8C38232E-3A45-4A27-92B0-1A16A975F669}';
strIID_IWSCProductList = '{722A338C-6E8E-4E72-AC27-1417FB0C81C2}';
strCLASS_WSCProductList = '{17072F7B-9ABE-4A74-A261-1EB76B55107A}';
IID_IWscProduct: TGUID = strIID_IWscProduct;
IID_IWSCProductList: TGUID = strIID_IWSCProductList;
CLASS_WSCProductList: TGUID = strCLASS_WSCProductList;
WSC_SECURITY_PRODUCT_STATE_ON = 0;
WSC_SECURITY_PRODUCT_STATE_OFF = 1;
WSC_SECURITY_PRODUCT_STATE_SNOOZED = 2;
WSC_SECURITY_PRODUCT_STATE_EXPIRED = 3;
WSC_SECURITY_PRODUCT_OUT_OF_DATE = 0;
WSC_SECURITY_PRODUCT_UP_TO_DATE = 1;
WSC_SECURITY_PROVIDER_NONE = 0;
WSC_SECURITY_PROVIDER_FIREWALL = $1;
WSC_SECURITY_PROVIDER_AUTOUPDATE_SETTINGS = $2;
WSC_SECURITY_PROVIDER_ANTIVIRUS = $4;
WSC_SECURITY_PROVIDER_ANTISPYWARE = $8;
WSC_SECURITY_PROVIDER_INTERNET_SETTINGS = $10;
WSC_SECURITY_PROVIDER_USER_ACCOUNT_CONTROL = $20;
WSC_SECURITY_PROVIDER_SERVICE = $40;
WSC_SECURITY_PROVIDER_ALL = WSC_SECURITY_PROVIDER_FIREWALL or
WSC_SECURITY_PROVIDER_AUTOUPDATE_SETTINGS or
WSC_SECURITY_PROVIDER_ANTIVIRUS or
WSC_SECURITY_PROVIDER_ANTISPYWARE or
WSC_SECURITY_PROVIDER_INTERNET_SETTINGS or
WSC_SECURITY_PROVIDER_USER_ACCOUNT_CONTROL or
WSC_SECURITY_PROVIDER_SERVICE;
type
IWscProduct = interface(IDispatch)
[strIID_IWscProduct]
function get_ProductName(var sVal: PChar): Integer; stdcall;
function get_ProductState(var nVal: Integer): Integer; stdcall;
function get_SignatureStatus(var nVal: Integer): Integer; stdcall;
function get_RemediationPath(var sVal: PChar): Integer; stdcall;
function get_ProductStateTimestamp(var sVal: PChar): Integer; stdcall;
function get_ProductGuid(var sVal: PChar): Integer; stdcall;
function get_ProductIsDefault(var bVal: Boolean): Integer; stdcall;
end;
IWSCProductList = interface(IDispatch)
[strIID_IWSCProductList]
function Initialize(dwProvider: DWORD): Integer; stdcall;
function get_Count(var nVal: Integer): Integer; stdcall;
function get_Item(nIdx: Integer; var pVal: IWscProduct): Integer; stdcall;
end;
PWSCProductEnt = ^TWSCProductEnt;
TWSCProductEnt = record
sName,
sGuid,
sStateTimestamp,
sRemediationPath: String;
bIsDefault: Boolean;
nState,
nStatus: Integer;
end;
TWSCProductEntList = class(TList<PWSCProductEnt>)
protected
nProvider_: Integer;
procedure Notify(const Item: PWSCProductEnt; Action: TCollectionNotification); override;
public
property Provider: Integer read nProvider_;
end;
function GetWscSecurityInfo(nProvider: Integer; aList: TWSCProductEntList): Integer;
implementation
uses
Tocsg.Exception, Winapi.ActiveX, System.SysUtils;
{ TWSCProductEntList }
procedure TWSCProductEntList.Notify(const Item: PWSCProductEnt; Action: TCollectionNotification);
begin
if Action = cnRemoved then
Dispose(Item);
end;
function GetWscSecurityInfo(nProvider: Integer; aList: TWSCProductEntList): Integer;
var
ProductList: IWSCProductList;
Product: IWscProduct;
nProductCnt: Integer;
i, nVal: Integer;
sData: PChar;
bVal: Boolean;
pEnt: PWSCProductEnt;
PdEnt: TWSCProductEnt;
begin
Result := 0;
aList.Clear;
aList.nProvider_ := nProvider;
try
ProductList := nil;
if FAILED(CoCreateInstance(CLASS_WSCProductList, nil, CLSCTX_INPROC_SERVER, IID_IWSCProductList, ProductList)) then
exit;
if ProductList = nil then
exit;
if FAILED(ProductList.Initialize(nProvider)) then
exit;
if FAILED(ProductList.get_Count(nProductCnt)) then
exit;
// 구버전 윈도우 10에서 SysFreeString() 하면 프로그램이 크러쉬 된다.... 22_0620 17:16:55 kku
for i := 0 to nProductCnt - 1 do
begin
ZeroMemory(@PdEnt, SizeOf(PdEnt));
if not FAILED(ProductList.get_Item(i, Product)) then
begin
if not FAILED(Product.get_ProductName(sData)) then
begin
PdEnt.sName := String(sData);
// SysFreeString(sData);
end else
continue;
if not FAILED(Product.get_ProductGuid(sData)) then
begin
PdEnt.sGuid := String(sData);
// SysFreeString(sData);
end;
if not FAILED(Product.get_ProductStateTimestamp(sData)) then
begin
PdEnt.sStateTimestamp := String(sData);
// SysFreeString(sData);
end;
if not FAILED(Product.get_RemediationPath(sData)) then
begin
PdEnt.sRemediationPath := String(sData);
// SysFreeString(sData);
end;
if not FAILED(Product.get_ProductIsDefault(bVal)) then
PdEnt.bIsDefault := bVal;
if not FAILED(Product.get_ProductState(nVal)) then
PdEnt.nState := nVal;
if not FAILED(Product.get_SignatureStatus(nVal)) then
PdEnt.nStatus := nVal;
New(pEnt);
pEnt^ := PdEnt;
aList.Add(pEnt);
Finalize(PdEnt);
Inc(Result);
end;
end;
except
on E: Exception do
ETgException.TraceException(E, 'Fail .. GetWscSecurityInfo()');
end;
end;
end.