none
RunningObjectTable method signature discovery RRS feed

  • Question

  • Hi,

    I'm using the RunningObjectTable to interface with a program. I have the signature of the first 9 methods and they work great, I know there are 14 methods according to the registry, but I do not have documentation for the last 5  methods and I don't know the method signature for these.

    Are there any way to extract the method signatures for the remaining 5 methods? I know this is very low level and I've tried, but can't seem to get anywhere.

    I've tried to guess the methods, but then I get memory access violation errors.

    Thanks,

    John

    Saturday, July 24, 2010 8:17 PM

Answers

  • Thanks,

    I found this with the help of COM NDR Inspector by Vito. Not sire what the first three proc's are.

    interface methods:
    ------------------
      [proc#0] = IUnknown::QueryInterface
      [proc#1] = IUnknown::AddRef
      [proc#2] = IUnknown::Release
      OUT LONG [#16] [proc#3] ( IN LONG [#4], IN LONG [#8], IN MS IID{IStream} [#12] )
      OUT LONG [#12] [proc#4] ( IN MS FC_USER_MARSHAL [#4], IN MS IID{IStream} [#8] )
      OUT LONG [#8] [proc#5] ( IN MS IID{IStream} [#4] )
      OUT LONG [#12] [proc#6] ( IN LONG [#4], IN LONG [#8] )
      OUT LONG [#8] [proc#7] ( IN MS FC_USER_MARSHAL [#4] )
      OUT LONG [#8] [proc#8] ( OUT MS FC_USER_MARSHAL [#4] )
      OUT LONG [#8] [proc#9] ( OUT MS FC_USER_MARSHAL [#4] )
      OUT LONG [#8] [proc#10] ( OUT SIMPLE_PTR{ENUM16} [#4] )
      OUT LONG [#8] [proc#11] ( OUT MS FC_USER_MARSHAL [#4] )
      OUT LONG [#8] [proc#12] ( OUT MS FC_USER_MARSHAL [#4] )
      OUT LONG [#8] [proc#13] ( OUT MS FC_USER_MARSHAL [#4] )

    Saturday, July 24, 2010 10:56 PM

All replies

  • Are you talking about the IRunningObjectTable COM interface?  That has the standard three methods from IUnknown plus 7 more documented here: http://msdn.microsoft.com/en-us/library/ms695276(VS.85).aspx#methods

    In other words, doesn't add up to the numers you stated.

    Saturday, July 24, 2010 9:45 PM
  • No, let me post the code.

    This is the interface. I have the 11 methods, I need the last 3.

      [ComImport, Guid("50000004-0000-1000-0001-0000836BD2D2"),
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      internal interface IObjectDesigner
      {
        [PreserveSig, DispId(1)]
        int ReadObject([In] int objectType, [In] int objectId, [In] IStream destination);
        [PreserveSig, DispId(2)]
        int ReadObjects([In] string filter, [In] IStream destination);
        [PreserveSig, DispId(3)]
        int WriteObjects([In] IStream source);
        [PreserveSig, DispId(4)]
        int CompileObject([In] int objectType, [In] int objectId);
        [PreserveSig, DispId(5)]
        int CompileObjects([In] string filter);
        [PreserveSig, DispId(6)]
        int GetServerName(out string serverName);
        [PreserveSig, DispId(7)]
        int GetDatabaseName(out string databaseName);
        [PreserveSig, DispId(8)]
        int GetServerType(out int serverType);
        [PreserveSig, DispId(9)]
        int GetCSIDEVersion(out string csideVersion);
        [PreserveSig, DispId(10)]
        int GetApplicationVersion(out string applicationVersion);
        [PreserveSig, DispId(11)]
        int GetCompanyName(out string companyName);
      }
    

    This is the Class:

      public class ObjectDesigner
      {
        private IObjectDesigner _objectDesigner;
        private const string DefaultMonikerName = "!C/SIDE";
        private const string ObjectDesignerGuid = "50000004-0000-1000-0001-0000836BD2D2";
    
        public ObjectDesigner()
        {
          Guid guid = new Guid("50000004-0000-1000-0001-0000836BD2D2");
    
          Hashtable runningObjects = GetActiveObjectList(DefaultMonikerName);
    
          foreach (DictionaryEntry de in runningObjects)
          {
            string progId = de.Key.ToString();
            if (progId.IndexOf("{") != -1)
            {
              // Convert a class id into a friendly prog Id
              progId = ConvertClassIdToProgId(de.Key.ToString());
            }
            object getObj = GetActiveObject(progId);
            if (getObj != null)
            {
    
              this._objectDesigner = getObj as IObjectDesigner;
              if (this._objectDesigner == null)
              {
                throw new Exception("Could not connect to program");
              }
            }
            }
          }
    
          public void CompileObject(NavObjectType navObjectType, int objectId)
          {
            int result = this._objectDesigner.CompileObject((int) navObjectType,
              objectId);
            this.ProcessResult(result);
          }
    
          public void CompileObjects(string filter)
          {
            int result = this._objectDesigner.CompileObjects(filter);
            this.ProcessResult(result);
          }
    
          [DllImport("ole32.dll")]
          public static extern void CreateBindCtx(int reserved, out IBindCtx ppbc);
          [DllImport("OLE32.DLL")]
          public static extern int CreateStreamOnHGlobal(int hGlobalMemHandle,
            bool fDeleteOnRelease, out IStream pOutStm);
          public string GetCompanyName()
          {
            string companyName;
            int num = this._objectDesigner.GetCompanyName(out companyName);
            return companyName;
          }
    
          public string GetDatabaseName()
          {
            string databaseName;
            int num = this._objectDesigner.GetDatabaseName(out databaseName);
            return databaseName;
          }
    
          public static Hashtable GetActiveObjectList(string filter)
          {
            Hashtable result = new Hashtable();
    
            IntPtr numFetched = IntPtr.Zero;
            IRunningObjectTable runningObjectTable;
            IEnumMoniker monikerEnumerator;
            IMoniker[] monikers = new IMoniker[1];
    
            GetRunningObjectTable(0, out runningObjectTable);
            runningObjectTable.EnumRunning(out monikerEnumerator);
            monikerEnumerator.Reset();
            Console.WriteLine("Select client:");
            int clientNo = 0;
            while (monikerEnumerator.Next(1, monikers, numFetched) == 0)
            {
              IBindCtx ctx;
              CreateBindCtx(0, out ctx);
    
              string runningObjectName;
              monikers[0].GetDisplayName(ctx, null, out runningObjectName);
              System.Guid classId;
              monikers[0].GetClassID(out classId);
              object runningObjectVal;
              runningObjectTable.GetObject(monikers[0], out runningObjectVal);
    
              if (runningObjectName.IndexOf(filter) != -1 &&
                runningObjectName.IndexOf("company") != -1)
              {
                clientNo += 1;
                result[runningObjectName] = runningObjectVal;
              }
            }
    
            return result;
          }
    
          [DllImport("oleaut32.dll", CharSet=CharSet.Unicode)]
          internal static extern int GetErrorInfo(int dwReserved,
            [MarshalAs(UnmanagedType.Interface)] out IErrorInfo ppIErrorInfo);
          public static object GetObjectFromRot(string monikerName, Guid guid)
          {
            IRunningObjectTable prot;
            IEnumMoniker ppenumMoniker;
            IntPtr pceltFetched = IntPtr.Zero;
            IMoniker[] rgelt = new IMoniker[1];
            object ppvResult = null;
            GetRunningObjectTable(0, out prot);
            prot.EnumRunning(out ppenumMoniker);
            ppenumMoniker.Reset();
            while (ppenumMoniker.Next(1, rgelt, pceltFetched) == 0)
            {
              IBindCtx ppbc;
              string ppszDisplayName;
              CreateBindCtx(0, out ppbc);
              rgelt[0].GetDisplayName(ppbc, null, out ppszDisplayName);
              if (!(!ppszDisplayName.StartsWith(monikerName) || 
                ppszDisplayName.Equals(monikerName)))
              {
                rgelt[0].BindToObject(ppbc, null, ref guid, out ppvResult);
                return ppvResult;
              }
            }
            return ppvResult;
          }
          public static object GetActiveObject(string progId)
          {
            // Convert the prog id into a class id
            string classId = ConvertProgIdToClassId(progId);
    
            IRunningObjectTable prot = null;
            IEnumMoniker pMonkEnum = null;
            try
            {
              IntPtr Fetched = IntPtr.Zero;
              // Open the running objects table.
              GetRunningObjectTable(0, out prot);
              prot.EnumRunning(out pMonkEnum);
              pMonkEnum.Reset();
              IMoniker[] pmon = new IMoniker[1];
    
              // Iterate through the results
              while (pMonkEnum.Next(1, pmon, Fetched) == 0)
              {
                IBindCtx pCtx;
                CreateBindCtx(0, out pCtx);
                string displayName;
                pmon[0].GetDisplayName(pCtx, null, out displayName);
                Marshal.ReleaseComObject(pCtx);
                if (displayName.IndexOf(classId) != -1)
                {
                  // Return the matching object
                  object objReturnObject;
                  prot.GetObject(pmon[0], out objReturnObject);
                  return objReturnObject;
                }
              }
              return null;
            }
            finally
            {
              // Free resources
              if (prot != null)
                Marshal.ReleaseComObject(prot);
              if (pMonkEnum != null)
                Marshal.ReleaseComObject(pMonkEnum);
            }
          }
          public static Hashtable GetRunningObjectTable()
          {
            IRunningObjectTable prot;
            IEnumMoniker ppenumMoniker;
            IntPtr pceltFetched = IntPtr.Zero;
            Hashtable hashtable = new Hashtable();
            IMoniker[] rgelt = new IMoniker[1];
            GetRunningObjectTable(0, out prot);
            prot.EnumRunning(out ppenumMoniker);
            ppenumMoniker.Reset();
            while (ppenumMoniker.Next(1, rgelt, pceltFetched) == 0)
            {
              IBindCtx ppbc;
              string ppszDisplayName;
              object ppunkObject;
              CreateBindCtx(0, out ppbc);
              rgelt[0].GetDisplayName(ppbc, null, out ppszDisplayName);
              prot.GetObject(rgelt[0], out ppunkObject);
              hashtable[ppszDisplayName] = ppunkObject;
            }
            return hashtable;
          }
          [DllImport("ole32.dll", PreserveSig = false)]
          private static extern void CLSIDFromProgIDEx(
            [MarshalAs(UnmanagedType.LPWStr)] string progId, out Guid clsid);
    
          [DllImport("ole32.dll", PreserveSig = false)]
          private static extern void CLSIDFromProgID(
            [MarshalAs(UnmanagedType.LPWStr)] string progId, out Guid clsid);
          public static string ConvertProgIdToClassId(string progID)
          {
            Guid testGuid;
            try
            {
              CLSIDFromProgIDEx(progID, out testGuid);
            }
            catch
            {
              try
              {
                CLSIDFromProgID(progID, out testGuid);
              }
              catch
              {
                return progID;
              }
            }
            return testGuid.ToString().ToUpper();
          }
    
          [DllImport("ole32.dll")]
          private static extern int ProgIDFromCLSID([In()]ref Guid clsid,
            [MarshalAs(UnmanagedType.LPWStr)]out string lplpszProgID);
          public static string ConvertClassIdToProgId(string classID)
          {
            Guid testGuid = new Guid(classID.Replace("!", ""));
            string progId = null;
            try
            {
              ProgIDFromCLSID(ref testGuid, out progId);
            }
            catch (Exception)
            {
              return null;
            }
            return progId;
          }
          [DllImport("ole32.dll")]
          public static extern void GetRunningObjectTable(int reserved,
            out IRunningObjectTable prot);
        }
    
    Saturday, July 24, 2010 10:34 PM
  • I really don't know anything about IObjectDesigner.  However, a search turned up this page http://www.codeproject.com/KB/library/AutoupateNAV.aspx that looks like it used the same methods as you.

    > I have the signature of the first 9 methods and they work great

    If documentation is not available, calling these methods is unlikely to be supported anyways, so why bother with them?

     

    Saturday, July 24, 2010 10:42 PM
  • Thanks,

    I found this with the help of COM NDR Inspector by Vito. Not sire what the first three proc's are.

    interface methods:
    ------------------
      [proc#0] = IUnknown::QueryInterface
      [proc#1] = IUnknown::AddRef
      [proc#2] = IUnknown::Release
      OUT LONG [#16] [proc#3] ( IN LONG [#4], IN LONG [#8], IN MS IID{IStream} [#12] )
      OUT LONG [#12] [proc#4] ( IN MS FC_USER_MARSHAL [#4], IN MS IID{IStream} [#8] )
      OUT LONG [#8] [proc#5] ( IN MS IID{IStream} [#4] )
      OUT LONG [#12] [proc#6] ( IN LONG [#4], IN LONG [#8] )
      OUT LONG [#8] [proc#7] ( IN MS FC_USER_MARSHAL [#4] )
      OUT LONG [#8] [proc#8] ( OUT MS FC_USER_MARSHAL [#4] )
      OUT LONG [#8] [proc#9] ( OUT MS FC_USER_MARSHAL [#4] )
      OUT LONG [#8] [proc#10] ( OUT SIMPLE_PTR{ENUM16} [#4] )
      OUT LONG [#8] [proc#11] ( OUT MS FC_USER_MARSHAL [#4] )
      OUT LONG [#8] [proc#12] ( OUT MS FC_USER_MARSHAL [#4] )
      OUT LONG [#8] [proc#13] ( OUT MS FC_USER_MARSHAL [#4] )

    Saturday, July 24, 2010 10:56 PM