Phil Brinkle 0 Posted October 28, 2020 Greetings! I am working with an undocumented third-party COM server via WMI interface. var ACPIObj : ISWbemObject; DataPackProp : ISWbemProperty; OutParam: ISWbemObject; PropValue : Variant; begin //... OutParam:=ACPIObj.ExecMethod_('GetObjectData', nil, 0, nil); if OutParam <> nil then begin DataPackProp:=OutParam.Properties_.Item('DataPack’,0); PropValue:=DataPackProp.Get_Value; //.. end; After executing a method called ‘GetObjectData’, PropValue is actually storing an IDispatch interface, since it has the VarType of varDispatch. Is there a way of enumerating all the properties stored in the PropValue variable? Thank you! Share this post Link to post
FPiette 385 Posted October 28, 2020 (edited) Yes, you can. Basically, you have to call GetTypeInfoCount(), GetTypeInfo(), GetTypeAttr() and other functions (All documented by Microsoft). Here is a function to list all method names including property getter/setter. Similar code can enumerate argument list, argument data types and return value data type. procedure DisplayMethodNames( const DispIntf : IDispatch; const IntfName : String; Strings : TStrings); var Count : Integer; TypeInfo : ITypeInfo; TypeAttr : PTypeAttr; FuncDesc : PFuncDesc; HR : HRESULT; I : Integer; FuncName : WideString; begin if IntfName <> '' then Strings.Add(IntfName); Count := 0; HR := DispIntf.GetTypeInfoCount(Count); if Failed(HR) or (Count = 0) then Exit; HR := DispIntf.GetTypeInfo(0, 0, TypeInfo); if Succeeded(HR) and (TypeInfo <> nil) then begin TypeAttr := nil; HR := TypeInfo.GetTypeAttr(TypeAttr); if Succeeded(HR) and (TypeAttr <> nil) then begin for I := 0 to TypeAttr.cFuncs - 1 do begin FuncDesc := nil; HR := TypeInfo.GetFuncDesc(I, FuncDesc); if Succeeded(HR) and (FuncDesc <> nil) then begin TypeInfo.GetDocumentation(FuncDesc.memid, @FuncName, nil, // DocString, nil, // HelpContext nil); // HelpFile if Length(FuncName) <> 0 then Strings.Add(Format(' %-3d %s', [I, FuncName])); TypeInfo.ReleaseFuncDesc(FuncDesc); end; end; TypeInfo.ReleaseTypeAttr(TypeAttr); end; end; end; Edited October 28, 2020 by FPiette 6 Share this post Link to post
Phil Brinkle 0 Posted October 28, 2020 Thank you for your quick reply, sir! Your code works fine and it returns 36 functions for me: 0 QueryInterface 1 AddRef 2 Release 3 GetTypeInfoCount 4 GetTypeInfo 5 GetIDsOfNames 6 Invoke 7 Put_ 8 PutAsync_ 9 Delete_ 10 DeleteAsync_ 11 Instances_ 12 InstancesAsync_ 13 Subclasses_ 14 SubclassesAsync_ 15 Associators_ 16 AssociatorsAsync_ 17 References_ 18 ReferencesAsync_ 19 ExecMethod_ 20 ExecMethodAsync_ 21 Clone_ 22 GetObjectText_ 23 SpawnDerivedClass_ 24 SpawnInstance_ 25 CompareTo_ 26 Qualifiers_ 27 Properties_ 28 Methods_ 29 Derivation_ 30 Path_ 31 Security_ 32 Refresh_ 33 SystemProperties_ 34 GetText_ 35 SetFromText_ Now I have to examine it to know how to retrieve all the properties of an IDispatch interface, since I am not familiar with COM programming. Thank you for you help! Share this post Link to post
FPiette 385 Posted October 28, 2020 (edited) Thanks. If you like my answer, please mark it as such (The heart icon on the right side of my answer). Maybe you have a type library ? If you import it into Delphi, you'll have all the information. Edited October 28, 2020 by FPiette Share this post Link to post
Guest Posted October 28, 2020 4 hours ago, FPiette said: Thanks. If you like my answer, please mark it as such (The heart icon on the right side of my answer). Mr. Piette! I now have a go-to-guy re COM/OLE 🙂 Seriously, don't worry, i avoid OLE like i do Covid. Ahem, not true, i'm more afraid of OLE than Covid. 'll give you one anyways! Hmm.. still above you 🙂 la-di-da... (not for long though, deep into deliveries for at least ½ a year on)... Share this post Link to post
Phil Brinkle 0 Posted October 30, 2020 (edited) On 10/28/2020 at 7:15 PM, FPiette said: Thanks. If you like my answer, please mark it as such (The heart icon on the right side of my answer). Maybe you have a type library ? If you import it into Delphi, you'll have all the information. I am sorry, I don't have one, since I am working with an undocumented COM server. BTW, experimentally I found out that the PropValue variable has one property of Result which is an array of bytes. So, using TempArrayBuffer:=PropValue.Result I can read the content of the array. Do you know the way of enumerating all the properties of the PropValue variant? I believe there should be other properties. Thank you! Edited October 30, 2020 by Phil Brinkle Share this post Link to post
Anders Melander 1815 Posted October 30, 2020 On 10/28/2020 at 10:02 PM, Dany Marmur said: Seriously, don't worry, i avoid OLE like i do Covid. Maybe if you learned the difference between OLE and COM you wouldn't be so scared... Hardly anyone uses OLE anymore. Share this post Link to post
FPiette 385 Posted October 30, 2020 44 minutes ago, Phil Brinkle said: I am working with an undocumented COM server. Undocumented doesn't mean it has not documentation inside the exe/dll. The proof is that my function show the list of functions. Try to import the DLL in Delphi as it is a type library (Delphi Menu Component / Import component / Import a Type Library. If it doesn't appear in the list, click the Add button and select your dll. If it doesn't work, try adding it as an ActiveX instead. Share this post Link to post
Anders Melander 1815 Posted October 30, 2020 (edited) On 10/28/2020 at 4:45 PM, Phil Brinkle said: Your code works fine and it returns 36 functions for me Those are just the WMI methods and they are all documented. https://docs.microsoft.com/en-us/windows/win32/api/wbemcli/nn-wbemcli-iwbemclassobject If you want to talk to a COM server why are you then going through WMI? Are you sure it isn't a WMI Provider you are talking about? 52 minutes ago, Phil Brinkle said: I am working with an undocumented COM server. If you install the Windows SDK (just the tools parts) there's a utility in it called OleView that you can use to examine type libraries and COM servers. The type library of your server is probably embedded in the EXE file. Edit: If it's a WMI provider then it's probably a DLL and it's probably early bound and without a type library. It depends on what kind of provider it is. Edited October 30, 2020 by Anders Melander 1 Share this post Link to post
Anders Melander 1815 Posted October 30, 2020 Instead of waiting on the back and forth I'll assume that what we have here is a classic case of the XY problem. To determine what properties a WMI object exposes you can use a tool like WMI Explorer (there are many other tools like that, this is just the first one I found). Share this post Link to post
Phil Brinkle 0 Posted October 30, 2020 It's a BIOS ACPI object which can be accessed through WMI (root/wmi namespace) only. WMI Explorer is a very good software since it lets me execute methods of objects. I have been using it for months, thanks! But it cannot pass an array of values to a WMI method, only an integer. Anyway, I much appreciate your assistance, guys! Share this post Link to post