diff --git a/OleViewDotNet.Main/COMUtilities.cs b/OleViewDotNet.Main/COMUtilities.cs index 07c2fbff..3bb810e5 100644 --- a/OleViewDotNet.Main/COMUtilities.cs +++ b/OleViewDotNet.Main/COMUtilities.cs @@ -2214,7 +2214,7 @@ private static bool QueryAllInterfaces(IEnumerable clsids, IProgr try { query_progress.Report(); - clsid.LoadSupportedInterfaces(false, null); + clsid.LoadSupportedInterfaces(false, null, COMServerType.UnknownServer); } catch { diff --git a/OleViewDotNet.Main/Database/COMCLSIDEntry.cs b/OleViewDotNet.Main/Database/COMCLSIDEntry.cs index fbffd389..46c175fc 100644 --- a/OleViewDotNet.Main/Database/COMCLSIDEntry.cs +++ b/OleViewDotNet.Main/Database/COMCLSIDEntry.cs @@ -457,18 +457,20 @@ public interface ICOMClassEntry /// /// Force the supported interface list to refresh /// Token to use when querying for the interfaces. + /// Server type to use when creating the object. /// Returns true if supported interfaces were refreshed. /// Thrown on error. - Task LoadSupportedInterfacesAsync(bool refresh, NtToken token); + Task LoadSupportedInterfacesAsync(bool refresh, NtToken token, COMServerType serverType); /// /// Get list of supported Interface IIDs Synchronously /// /// Force the supported interface list to refresh /// Token to use when querying for the interfaces. + /// Server type to use when creating the object. /// Returns true if supported interfaces were refreshed. /// Thrown on error. - bool LoadSupportedInterfaces(bool refresh, NtToken token); + bool LoadSupportedInterfaces(bool refresh, NtToken token, COMServerType serverType); /// /// Indicates that the class' interface list has been loaded. @@ -1030,11 +1032,11 @@ public override int GetHashCode() ^ Source.GetHashCode() ^ PackageId.GetSafeHashCode(); } - private async Task GetSupportedInterfacesInternal(NtToken token) + private async Task GetSupportedInterfacesInternal(NtToken token, COMServerType serverType) { try { - return await COMEnumerateInterfaces.GetInterfacesOOP(this, Database, token); + return await COMEnumerateInterfaces.GetInterfacesOOP(this, Database, token, serverType); } catch (Win32Exception) { @@ -1073,9 +1075,10 @@ private COMCLSIDServerEntry GetDefaultServer() /// /// Force the supported interface list to refresh /// Token to use when checking for the interfaces. + /// Server type to use when creating the object. /// Returns true if supported interfaces were refreshed. /// Thrown on error. - public async Task LoadSupportedInterfacesAsync(bool refresh, NtToken token) + public async Task LoadSupportedInterfacesAsync(bool refresh, NtToken token, COMServerType serverType) { if (Clsid == Guid.Empty) { @@ -1084,7 +1087,7 @@ public async Task LoadSupportedInterfacesAsync(bool refresh, NtToken token if (refresh || !InterfacesLoaded) { - COMEnumerateInterfaces enum_int = await GetSupportedInterfacesInternal(token); + COMEnumerateInterfaces enum_int = await GetSupportedInterfacesInternal(token, serverType); m_interfaces = new List(enum_int.Interfaces); m_factory_interfaces = new List(enum_int.FactoryInterfaces); InterfacesLoaded = true; @@ -1098,11 +1101,12 @@ public async Task LoadSupportedInterfacesAsync(bool refresh, NtToken token /// /// Force the supported interface list to refresh /// Token to use when querying for the interfaces. + /// Server type to use when creating the object. /// Returns true if supported interfaces were refreshed. /// Thrown on error. - public bool LoadSupportedInterfaces(bool refresh, NtToken token) + public bool LoadSupportedInterfaces(bool refresh, NtToken token, COMServerType serverType) { - Task result = LoadSupportedInterfacesAsync(refresh, token); + Task result = LoadSupportedInterfacesAsync(refresh, token, serverType); try { result.Wait(); @@ -1169,23 +1173,28 @@ public CLSCTX CreateContext { get { - CLSCTX dwContext = CLSCTX.ALL; + return ServerTypeToClsCtx(DefaultServerType); + } + } - if (DefaultServerType == COMServerType.InProcServer32) - { - dwContext = CLSCTX.INPROC_SERVER; - } - else if (DefaultServerType == COMServerType.LocalServer32) - { - dwContext = CLSCTX.LOCAL_SERVER; - } - else if (DefaultServerType == COMServerType.InProcHandler32) - { - dwContext = CLSCTX.INPROC_HANDLER; - } + public static CLSCTX ServerTypeToClsCtx(COMServerType serverType) + { + CLSCTX dwContext = CLSCTX.ALL; - return dwContext; + if (serverType == COMServerType.InProcServer32) + { + dwContext = CLSCTX.INPROC_SERVER; } + else if (serverType == COMServerType.LocalServer32) + { + dwContext = CLSCTX.LOCAL_SERVER; + } + else if (serverType == COMServerType.InProcHandler32) + { + dwContext = CLSCTX.INPROC_HANDLER; + } + + return dwContext; } public IntPtr CreateInstance(CLSCTX dwContext, string server) diff --git a/OleViewDotNet.Main/Database/COMEnumerateInterfaces.cs b/OleViewDotNet.Main/Database/COMEnumerateInterfaces.cs index 1c5aa3a7..065b18cb 100644 --- a/OleViewDotNet.Main/Database/COMEnumerateInterfaces.cs +++ b/OleViewDotNet.Main/Database/COMEnumerateInterfaces.cs @@ -352,7 +352,7 @@ private COMEnumerateInterfaces(Guid clsid, CLSCTX clsctx, string activatable_cla _winrt_component = !string.IsNullOrWhiteSpace(_activatable_classid); } - public async static Task GetInterfacesOOP(COMRuntimeClassEntry ent, COMRegistry registry, NtToken token) + public async static Task GetInterfacesOOP(COMRuntimeClassEntry ent, COMRegistry registry, NtToken token, COMServerType serverType) { string apartment = "s"; if (ent.Threading == ThreadingType.Both @@ -500,7 +500,7 @@ private async static Task GetInterfacesOOP(string command_line, } } - public async static Task GetInterfacesOOP(COMCLSIDEntry ent, COMRegistry registry, NtToken token) + public async static Task GetInterfacesOOP(COMCLSIDEntry ent, COMRegistry registry, NtToken token, COMServerType serverType) { string apartment = "s"; if (ent.DefaultThreadingModel == COMThreadingModel.Both @@ -509,9 +509,15 @@ public async static Task GetInterfacesOOP(COMCLSIDEntry apartment = "m"; } - string command_line = string.Format("{0} {1} \"{2}\"", ent.Clsid.ToString("B"), apartment, ent.CreateContext); + CLSCTX createCtx; + if (serverType == COMServerType.UnknownServer) + createCtx = ent.CreateContext; + else + createCtx = COMCLSIDEntry.ServerTypeToClsCtx(serverType); + + string command_line = string.Format("{0} {1} \"{2}\"", ent.Clsid.ToString("B"), apartment, createCtx); var interfaces = await GetInterfacesOOP(command_line, false, registry, token); - return new COMEnumerateInterfaces(ent.Clsid, ent.CreateContext, string.Empty, interfaces.Interfaces, interfaces.FactoryInterfaces); + return new COMEnumerateInterfaces(ent.Clsid, createCtx, string.Empty, interfaces.Interfaces, interfaces.FactoryInterfaces); } } } diff --git a/OleViewDotNet.Main/Database/COMRuntimeClassEntry.cs b/OleViewDotNet.Main/Database/COMRuntimeClassEntry.cs index 92972662..27a9e8d7 100644 --- a/OleViewDotNet.Main/Database/COMRuntimeClassEntry.cs +++ b/OleViewDotNet.Main/Database/COMRuntimeClassEntry.cs @@ -259,11 +259,11 @@ int IComparable.CompareTo(COMRuntimeClassEntry other) return Server.CompareTo(other.Server); } - private async Task GetSupportedInterfacesInternal(NtToken token) + private async Task GetSupportedInterfacesInternal(NtToken token, COMServerType serverType) { try { - return await COMEnumerateInterfaces.GetInterfacesOOP(this, m_registry, token); + return await COMEnumerateInterfaces.GetInterfacesOOP(this, m_registry, token, serverType); } catch (Win32Exception) { @@ -271,11 +271,11 @@ private async Task GetSupportedInterfacesInternal(NtToke } } - public async Task LoadSupportedInterfacesAsync(bool refresh, NtToken token) + public async Task LoadSupportedInterfacesAsync(bool refresh, NtToken token, COMServerType serverType) { if (refresh || !InterfacesLoaded) { - COMEnumerateInterfaces enum_int = await GetSupportedInterfacesInternal(token); + COMEnumerateInterfaces enum_int = await GetSupportedInterfacesInternal(token, serverType); m_interfaces = new List(enum_int.Interfaces); m_factory_interfaces = new List(enum_int.FactoryInterfaces); InterfacesLoaded = true; @@ -290,9 +290,9 @@ public async Task LoadSupportedInterfacesAsync(bool refresh, NtToken token /// Force the supported interface list to refresh /// Returns true if supported interfaces were refreshed. /// Thrown on error. - public bool LoadSupportedInterfaces(bool refresh, NtToken token) + public bool LoadSupportedInterfaces(bool refresh, NtToken token, COMServerType serverType) { - Task result = LoadSupportedInterfacesAsync(refresh, token); + Task result = LoadSupportedInterfacesAsync(refresh, token, serverType); result.Wait(); if (result.IsFaulted) { diff --git a/OleViewDotNet.Main/Forms/COMRegistryViewer.cs b/OleViewDotNet.Main/Forms/COMRegistryViewer.cs index ddbe1b38..3461a596 100644 --- a/OleViewDotNet.Main/Forms/COMRegistryViewer.cs +++ b/OleViewDotNet.Main/Forms/COMRegistryViewer.cs @@ -1047,7 +1047,7 @@ private async Task SetupCLSIDNodeTree(TreeNode node, bool bRefresh) node.Nodes.Add(wait_node); try { - await clsid.LoadSupportedInterfacesAsync(bRefresh, null); + await clsid.LoadSupportedInterfacesAsync(bRefresh, null, COMServerType.UnknownServer); int interface_count = clsid.Interfaces.Count(); int factory_count = clsid.FactoryInterfaces.Count(); if (interface_count == 0 && factory_count == 0) diff --git a/OleViewDotNet.Main/Forms/MainForm.cs b/OleViewDotNet.Main/Forms/MainForm.cs index b97a993c..a89def59 100644 --- a/OleViewDotNet.Main/Forms/MainForm.cs +++ b/OleViewDotNet.Main/Forms/MainForm.cs @@ -141,7 +141,7 @@ public async Task HostObject(ICOMClassEntry ent, object obj, bool factory) if (!ent.InterfacesLoaded) { - await ent.LoadSupportedInterfacesAsync(false, null); + await ent.LoadSupportedInterfacesAsync(false, null, COMServerType.UnknownServer); } IEnumerable intfs = factory ? ent.FactoryInterfaces : ent.Interfaces; @@ -226,7 +226,7 @@ public async Task CreateInstanceFromCLSID(Guid clsid, CLSCTX clsctx, bool class_ props.Add("CLSID", ent.Clsid.FormatGuid()); props.Add("Name", ent.Name); props.Add("Server", ent.DefaultServer); - await ent.LoadSupportedInterfacesAsync(false, null); + await ent.LoadSupportedInterfacesAsync(false, null, COMServerType.UnknownServer); if (class_factory) { @@ -357,7 +357,7 @@ public async Task OpenObjectInformation(object comObj, string defaultName) props.Add("CLSID", ent.Clsid.FormatGuid()); props.Add("Name", ent.Name); props.Add("Server", ent.DefaultServer); - await ent.LoadSupportedInterfacesAsync(false, null); + await ent.LoadSupportedInterfacesAsync(false, null, COMServerType.UnknownServer); ints = ent.Interfaces.Select(i => m_registry.MapIidToInterface(i.Iid)); } else diff --git a/OleViewDotNet.Main/Forms/PropertiesControl.cs b/OleViewDotNet.Main/Forms/PropertiesControl.cs index f5abf5c5..c72cb8b1 100644 --- a/OleViewDotNet.Main/Forms/PropertiesControl.cs +++ b/OleViewDotNet.Main/Forms/PropertiesControl.cs @@ -445,7 +445,7 @@ private async void btnRefreshInterfaces_Click(object sender, EventArgs e) try { ICOMClassEntry entry = (ICOMClassEntry)tabPageSupportedInterfaces.Tag; - await entry.LoadSupportedInterfacesAsync(true, null); + await entry.LoadSupportedInterfacesAsync(true, null, COMServerType.UnknownServer); LoadInterfaceList(entry.Interfaces, listViewInterfaces); LoadInterfaceList(entry.FactoryInterfaces, listViewFactoryInterfaces); } diff --git a/OleViewDotNet.PowerShell/OleViewDotNet.psm1 b/OleViewDotNet.PowerShell/OleViewDotNet.psm1 index 1c2f31db..84193812 100644 --- a/OleViewDotNet.PowerShell/OleViewDotNet.psm1 +++ b/OleViewDotNet.PowerShell/OleViewDotNet.psm1 @@ -907,6 +907,8 @@ Get a COM class or Runtime class instance interfaces. This cmdlet enumerates the supported interfaces for a COM class or Runtime class and returns them. .PARAMETER ClassEntry The COM or Runtime classes to enumerate. +.PARAMETER ServerType +Specify a type of server to match against. If specified as UnknownServer will search DefaultServerType. .PARAMETER Refresh Specify to force the interfaces to be refreshed. .PARAMETER Factory @@ -936,6 +938,7 @@ function Get-ComClassInterface { Param( [Parameter(Mandatory, Position = 0, ValueFromPipeline)] [OleViewDotNet.Database.ICOMClassEntry[]]$ClassEntry, + [OleViewDotNet.Database.COMServerType]$ServerType = "UnknownServer", [switch]$Refresh, [switch]$Factory, [switch]$NoQuery, @@ -954,7 +957,7 @@ function Get-ComClassInterface { $i++ } } - $class.LoadSupportedInterfaces($Refresh, $Token) | Out-Null + $class.LoadSupportedInterfaces($Refresh, $Token, $ServerType) | Out-Null } if ($Factory) { $class.FactoryInterfaces | Write-Output