Question

Enumerating the ROT in VB using APIs Help please !!

Asked by: RAFAAJ

I found this code on the web but it's witten in C. Can anyone translate this into VB please.


int _tmain(
    int argc,
    _TCHAR * argv[]
    )
{
    HRESULT hRes;
   
    hRes = OleInitialize(NULL);
    if (FAILED(hRes))
    {
        _tprintf("OleInitialize failed (0x%08X)\n", hRes);
        return -1;
    }

    IRunningObjectTable * pROT = NULL;
    IEnumMoniker * pEnum = NULL;
    IMoniker * pMoniker = NULL;
    IBindCtx * pBindCtx = NULL;
    PWSTR pszName = NULL;
    ULONG cElt;

    for (;;)
    {
        // get interface pointer of the running object table
        hRes = GetRunningObjectTable(NULL, &pROT);
        if (FAILED(hRes))
        {
            _tprintf("GetRunningObjectTable failed (0x%08X)\n", hRes);
            break;
        }

        // create binding context object
        hRes = CreateBindCtx(0, &pBindCtx);
        if (FAILED(hRes))
        {
            _tprintf("CreateBindCtx failed (0x%08X)\n", hRes);
            break;
        }

        // enumerate running objects
        hRes = pROT->EnumRunning(&pEnum);
        if (FAILED(hRes))
        {
            _tprintf("IRunningObjectTable::EnumRunning failed (0x%08X)\n",
                     hRes);
            break;
        }

        // go through all monikers in the table and display moniker name
        while (pEnum->Next(1, &pMoniker, &cElt) == S_OK)
        {
            hRes = pMoniker->GetDisplayName(pBindCtx, NULL, &pszName);
            if (FAILED(hRes))
            {
                _tprintf("IMoniker::GetDisplayName failed (0x%08X)\n", hRes);
                break;
            }

            _tprintf("%ls\n", pszName);

            CoTaskMemFree(pszName);
            pMoniker->Release();

            pszName = NULL;
            pMoniker = NULL;
        }

        break;
    }

    if (pszName != NULL)
        CoTaskMemFree(pszName);
    if (pMoniker != NULL)
        pMoniker->Release();
    if (pEnum != NULL)
        pEnum->Release();
    if (pBindCtx != NULL)
        pBindCtx->Release();
    if (pROT != NULL)
        pROT->Release();

    OleUninitialize();
    return 0;
}


I'll increase the points if I get a working VB example.

Thank you.

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2006-10-04 at 04:07:04ID22012313
Tags

getrunningobjecttable

,

vb

Topic

Visual Basic Programming

Participating Experts
4
Points
500
Comments
24

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. TCHAR cFileName[MAX_PATH]
    I am trying to find a file named "a.exe", the following code does not work. What's wrong? How to fix it? Thanks. WIN32_FIND_DATA foundFile; ....... FindFirstFile("a.exe", &foundFile); TCHAR* fName=foundFile.cFileName; printf(" filePath= %s\n&q...
  2. Using int _tmain(int argc, _TCHAR* argv[])
    I thought I knew how to use such a Start/Run command line input, but I'm having problems. What is the proper input line for this; I've tried this: "C:\Documents and Settings\My Documents\Visual Studio Projects\C++\DLList.exe Readme.txt" and others, but nothing ...
  3. Argv[] , argc Quesstion
    I am trying to access argv[], argc in a function i am using but it wont compile, it keeps giving me error, 'argv, argc undeclared' int processRows(int i) { int rowNumber; while (i < argc) { if (*argv == '-') { /* the next arguement, so return */ ...
  4. Unicode and argv[] problem
    I have a Simple console project that I'm trying to prove out getting UNICODE input from the command line. I ultimately need to get UNICODE input from the command line and pass it to other subroutines, but I can't get this to work. The output works with a single character, b...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: EDDYKTPosted on 2006-10-04 at 04:24:03ID: 17658418

 

by: RAFAAJPosted on 2006-10-04 at 06:40:14ID: 17659260

EDDYKT

As I mentioned, I need this to be done via APIs only.

I don't want to use any third party DLLS for this.

I can't believe I can't find any VB code to Enumerate the ROT or use other related COM APIs !! I searched endlessly on the internet but coudn't find a single example  :(

Any chance anyone ?

 

by: cpkilekofpPosted on 2006-10-04 at 07:17:40ID: 17659565

Truth, I could do it, I've done such translations before and this is not that different, but it's a significant programming effort that I won't perform for the 125 points you're offering.  

I offer the following link

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon98/html/vbconaccessingdllswindowsapi.asp

so you can do the job yourself.  It should be straightforward, but you will need to access the MSDN Library many times to get the sizes of the relevant structures.  If you need assistance with specific pieces of your effort, please let me know.

 

by: AzraSoundPosted on 2006-10-04 at 08:02:02ID: 17659895

It's not a third party dll...its a type library giving you access to certain API calls that are otherwise more complex to work with, or unattainable from VB.  You also don't need to distribute this type library with your VB application...it is compiled into the program.

(this is w/ respect to EDDYKT's post)

 

by: RAFAAJPosted on 2006-10-04 at 08:07:23ID: 17659934

cpkilekofp ,

I have increased the points to 500 so I hope someone can offer a solution.

What I am really after is : "How to enumerate the ROT and get a pointer to the Documents and applications registered in it  "

So let's say there are three Excel Applications running at the same time. I want to get a pointer to each and every one of these 3 applications and their respective Workbooks  by enumerating the ROT.This is so I can automate each all the 3 apps in my Client code.

Note that If I use the VB ' GetObject '  Function,  I will only get a pointer to the first Excel app only !

The C code I initially  posted was just so that I could show that it CAN BE DONE via API calls only ie: without having to use a third party dll.

Surely , this can't be that difficult !! isn't it ?

I hope I have explained this clearly. ...





 

by: RAFAAJPosted on 2006-10-04 at 08:13:36ID: 17659990

AzraSound,

I really don't want to use any non built-in dlls.

The OLELIB.TLB  lib is ,as you said,  just a wrapper for what can be achieved from scrach via plain COM related APIs like EnumerateRot , GetRunningObjectTable , RegisterActiveObject.....etc

For educational reasons and for portability reasons, I would love to see how this can be done in VB from scrach without having to resort to any dll wrappers.

Thanks.

 

by: AzraSoundPosted on 2006-10-04 at 08:21:19ID: 17660061

I've never worked with those APIs, but some APIs simply arent accessible from VB b/c of the data types involved (e.g., certain callback function pointers), and a type library is our only outlet to gain access to them.  It may be such is the case with the COM related API.

Also, it is no surprise you cannot find such code in VB.  VB is a very high level language...most all VB developers are not concerned about lower level details.  Most even avoid any API when possible.  Microsoft knows this and that is why all the intrinsic behavior of COM was hidden from the VB developer.  I mention this only to explain why an example such as what you are seeking is not being easily found in VB code.

 

by: RAFAAJPosted on 2006-10-04 at 08:26:11ID: 17660104

Ah,  I forgot . I am using VBA not VB so the OLELIB.TLB lib CAN'T BE COMPILED into the exe . That's another reason why  I must use the built-in "ole32" lib alone !

Anybody ?

 

by: cpkilekofpPosted on 2006-10-04 at 08:31:51ID: 17660154

LOL give me some time, it's a busy work day.  The task is fairly straightforward, but I have to do some research on the structures that you want to access.

 

by: RAFAAJPosted on 2006-10-04 at 08:43:32ID: 17660270

Thanks AzraSound,

I recently bought myself an advanced VB6 book titled : "Advanced Visual Basic 6 " by 'Matthew Curland' which does deal with this ROT business and goes deeper into the hidden inner workings of VB. This proves that Yes, VB can indeed do this as well ! ...maybe it's more difficult but it CAN be done.

Unfortunately, the way this subject is explained in the book  is so shallow and vague.... And to make things worse, the codes are annoyingly wrapped in overwhelmingly complex and lenghthy Classes.  So really, I haven't benefited from the book at all and I am very disappointed.

I still haven't given up hope completely on this . I am sure someone knows how to do this.

 

by: cpkilekofpPosted on 2006-10-04 at 12:18:58ID: 17662205

References to COM objects and type libraries is not necessarily compiled into Visual Basic, either (look up the topic of Late Binding).  OLELIB.TLB can be easily linked in to a VBA app associated with Excel (which still uses the word 'macro' to describe such) by opening the Visual Basic Editor, going to Tools/References, and (if it is registered) looking it up in the list, or (if it is unregistered) browsing for it (note the Browse button) which will register it on selection.

The problem is, normally you can't call the member functions of a C++ object (which is what most of the code is doing, something I should have observed but didn't the first time I replied).  I've usually seen that written as "it's impossible" but I've done a few impossible things before (and busted my head against some REALLY impossible things).  I've had time to think about attempting it in straight VB, and I believe it to be at least a midterm project, and possibly a senior research project, and highly likely to end in failure...and I'd simply wind up duplicating in a very ugly fashion the functionality that OLELIB.TLB seems to offer (and it does seem popular based on a quick Web search).

Why not try downloading it either from the author's page?  The link given didn't work for me, but a Web search will give you multiple places to get it from.  It definitely has the functionality you need.  Remember, the reason C++ is still around is that there are some things it can do much easier than in VB; after all, Windows and its various components are written in C++, so they can often be directly accessed from that language.

For this piece of advice, I don't expect any points ;-)

 

by: AzraSoundPosted on 2006-10-04 at 12:57:43ID: 17662673

>>References to COM objects and type libraries is not necessarily compiled into Visual Basic, either (look up the topic of Late Binding).

COM objects, no, but type libraries, I thought, were compiled with the exe.  How does late binding tie into this?  Just curious...don't mean to take this off topic.

 

by: cpkilekofpPosted on 2006-10-04 at 13:23:15ID: 17663054

A type library is simply a wrapper for a set of COM objects.  Information from the type library IS compiled into your executable IF you choose early binding.  If not, the type library (once registered) can be used just as if it was a DLL for the purpose of referencing COM objects.  (Anyone please feel free to correct me if I've inadvertently misstated something here).

 

by: AzraSoundPosted on 2006-10-04 at 14:49:08ID: 17663841

In terms of late vs. early binding, even if you have the type library referenced in your project, this is still late binding:

Dim obj As Object
Set obj = New SomeObject.SomeClass


So, if you implement that in code, the type library info is not compiled into the exe, or do type libraries not allow this type of late binding, or does this still work fine w/o requiring distribution of the type library?

 

by: RAFAAJPosted on 2006-10-04 at 17:05:21ID: 17664725

cpkilekofp ,

I knew how to register OLELIB.TLB and set a reference to it in VBA via Tools\References...I fact, I dowloaded this lib in the past and worked just fine as expected.

However, as I said earlier , I wanted to see how this could be done in VB from scratch just by using the numerous "ole32" COM related APIs. I tend to learn better from seeing , testing and analysing code examples rather than reading  through endless theorical concepts.

I still wander how and why the "ole32" library and all its related COM  API functions are exposed and accessible to VB if they can't (or shouldn't) be used !!

forgive me if I come accross as being repetitive and stubborn but I have this gut feeling someone out there must have done this before .......  Am I going to be lucky :)

Regards.


 

by: cpkilekofpPosted on 2006-10-05 at 09:57:55ID: 17670299

Well, one,

I still wander how and why the "ole32" library and all its related COM  API functions are exposed and accessible to VB if they can't (or shouldn't) be used !!

contains an erroneous assumption:  The ole32 library is not exposed to and cannot be loaded as a reference in Visual Basic.  

These functions ARE exposed in VB.NET because Microsoft chose to expose them in the Common Language Runtime.

Someone built OLELIB.TLB to expose these functions in Visual Basic and other COM applications.

That someone built OLELIB.TLB in Visual C++.

Let's take an example:  one of the things you have to do is load an enumerator with an interface IEnumMoniker.  In order to be able to use the DLL functions called when you invoke methods on the IEnumMoniker interface, you have to know exactly what object is being represented by that interface.  And so on for every interface you are using.  It can be done, but it will take forever, and I suspect you may violate your Microsoft license to do it.  

If you are having trouble processing the Advanced Visual Basic 6 book, you wouldn't understand the code that implements it in any case, I suspect; I doubt I could explain the techniques better than the author of that book does, particularly since I don't know them yet.

Finally, I'm going to give you a quote older than the Christian Era, delivered by Euclid the geometer to Ptolemy, Pharoah of Egypt, when asked to explain his subject to his sovereign:

"Sire, there is no royal road to geometry."

In this case, there seems to be no easily generated Visual Basic source code that will emulate the C code you have described.  If such does exist, those who know how to do it may very well be forbidden to do it by non-disclosure agreements concerning the OLE runtime code (as this is what you have to hack in order to meet your demands).

If this does not answer your query, good luck, as I am done here.

 

by: ArkPosted on 2006-10-09 at 01:17:00ID: 17689268

Hello Azra!
>>...most all VB developers are not concerned about lower level details.  Most even avoid any API when possible. <<
Not me :)
IMHO, it even can be done with plain VB (using hidden IUnknown + ObjPtr/VarPtr + CopyMemory(RULEZ!)), but, unfortunatelly, VBA have no XxxPtr hack :(, so you and EDDYKT are right - *.tlb is the only way

 

by: AzraSoundPosted on 2006-10-09 at 06:58:21ID: 17690601

>>Not me :)

Haha!  Hi Ark...yes, you are definitely the exception to the rule.   :)

 

by: ArkPosted on 2006-10-09 at 16:11:07ID: 17694561

>>*.tlb is the only way<<
I was wrong! VB can everything :)
Here is the code (tested with VB, but IMHO, it'll work in VBA - I added VarPtr declaration from msvbvm and remove all calls to StrPtr)

'======== bas module code===========
Option Explicit

Public Declare Sub OleInitialize Lib "ole32.dll" (pvReserved As Any)
Public Declare Sub OleUninitialize Lib "ole32.dll" ()

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)

Private Declare Function PutMem2 Lib "msvbvm60" (ByVal pWORDDst As Long, ByVal NewValue As Long) As Long
Private Declare Function PutMem4 Lib "msvbvm60" (ByVal pDWORDDst As Long, ByVal NewValue As Long) As Long
Private Declare Function GetMem4 Lib "msvbvm60" (ByVal pDWORDSrc As Long, ByVal pDWORDDst As Long) As Long
Public Declare Function VarPtr Lib "msvbvm60" (var As Any) As Long

Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long

Private Declare Function CopyStringA Lib "kernel32" Alias "lstrcpyA" (ByVal NewString As String, ByVal OldString As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function WideCharToMultiByte Lib "kernel32" _
    (ByVal codepage As Long, ByVal dwFlags As Long, _
    lpWideCharStr As Any, ByVal cchWideChar As Long, _
    lpMultiByteStr As Any, ByVal cchMultiByte As Long, _
    ByVal lpDefaultChar As String, _
    ByVal lpUsedDefaultChar As Long) As Long

Private Const GMEM_FIXED As Long = &H0
Private Const asmPUSH_imm32 As Byte = &H68
Private Const asmRET_imm16 As Byte = &HC2
Private Const asmRET_16 As Long = &H10C2&
Private Const asmCALL_rel32 As Byte = &HE8

'IUnknown vTable ordinals
Public Const unk_QueryInterface As Long = 0
Public Const unk_AddRef As Long = 1
Public Const unk_Release As Long = 2

'Function to call Interface members by ordinal in VTable
Public Function CallInterface(ByVal pInterface As Long, ByVal FuncOrdinal As Long, ByVal ParamsCount As Long, Optional ByVal p1 As Long = 0, Optional ByVal p2 As Long = 0, Optional ByVal p3 As Long = 0, Optional ByVal p4 As Long = 0, Optional ByVal p5 As Long = 0, Optional ByVal p6 As Long = 0, Optional ByVal p7 As Long = 0, Optional ByVal p8 As Long = 0, Optional ByVal p9 As Long = 0, Optional ByVal p10 As Long = 0) As Long
  Dim i As Long, t As Long
  Dim hGlobal As Long, hGlobalOffset As Long
 
  If ParamsCount < 0 Then Err.Raise 5 'invalid call
  If pInterface = 0 Then Err.Raise 5
 
  '5 bytes for each parameter
  '5 bytes - PUSH this
  '5 bytes - call member function
  '3 bytes - ret 0x0010, pop CallWindowProc
  '1 byte - dword align.
   
  hGlobal = GlobalAlloc(GMEM_FIXED, 5 * ParamsCount + 5 + 5 + 3 + 1)
  If hGlobal = 0 Then Err.Raise 7 'insuff. memory
  hGlobalOffset = hGlobal
 
  If ParamsCount > 0 Then
    t = VarPtr(p1)
    For i = ParamsCount - 1 To 0 Step -1
      PutMem2 hGlobalOffset, asmPUSH_imm32
      hGlobalOffset = hGlobalOffset + 1
      GetMem4 t + i * 4, hGlobalOffset
      hGlobalOffset = hGlobalOffset + 4
    Next
  End If
 
 'First member of any interface - this. Assign...
  PutMem2 hGlobalOffset, asmPUSH_imm32
  hGlobalOffset = hGlobalOffset + 1
  PutMem4 hGlobalOffset, pInterface
  hGlobalOffset = hGlobalOffset + 4
 
  'Call IFace Function by its ordinal
  PutMem2 hGlobalOffset, asmCALL_rel32
  hGlobalOffset = hGlobalOffset + 1
  GetMem4 pInterface, VarPtr(t)     'dereference: find vTable
  GetMem4 t + FuncOrdinal * 4, VarPtr(t) 'Function offset in vTable, dereference
  PutMem4 hGlobalOffset, t - hGlobalOffset - 4
  hGlobalOffset = hGlobalOffset + 4

  'all interfaces are stdcall, so forget about stack clearing
  PutMem4 hGlobalOffset, asmRET_16        'ret 0x0010
 
  CallInterface = CallWindowProc(hGlobal, 0, 0, 0, 0)
 
  GlobalFree hGlobal

End Function

Public Function StrFromPtrA(ByVal lpszA As Long, Optional nSize As Long = 0) As String
   Dim s As String, bTrim As Boolean
   If nSize = 0 Then
      nSize = lstrlenA(lpszA)
      bTrim = True
   End If
   s = String(nSize, Chr$(0))
   CopyStringA s, ByVal lpszA
   If bTrim Then s = TrimNULL(s)
   StrFromPtrA = s
End Function

Public Function StrFromPtrW(ByVal lpszW As Long, Optional nSize As Long = 0) As String
   Dim s As String, bTrim As Boolean
   If nSize = 0 Then
      nSize = lstrlenW(lpszW) * 2
      bTrim = True
   End If
   s = String(nSize, Chr$(0))
'   CopyMemory ByVal StrPtr(s), ByVal lpszW, nSize ' VBA doesn't support StrPtr :(
   WideCharToMultiByte 0, &H0, ByVal lpszW, -1, ByVal s, Len(s), &H0, &H0
   If bTrim Then s = TrimNULL(s)
   StrFromPtrW = s
End Function

Public Function TrimNULL(ByVal str As String) As String
    If InStr(str, Chr$(0)) > 0& Then
        TrimNULL = Left$(str, InStr(str, Chr$(0)) - 1&)
    Else
        TrimNULL = str
    End If
End Function

'============Form code===========
Private Declare Function GetRunningObjectTable Lib "ole32.dll" (ByVal dwReserved As Long, pROT As Long) As Long
Private Declare Function CreateBindCtx Lib "ole32.dll" (ByVal dwReserved As Long, pBindCtx As Long) As Long
Private Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long)

'Interface members ordinals
Private Const vtbl_ROT_EnumRunning = 9
Private Const vtbl_EnumMoniker_Next = 3
Private Const vtbl_Moniker_GetDisplayName = 20

Private Sub Command1_Click()
   EnumRot
End Sub

Private Sub EnumRot()
   Dim pROT As Long, pEnumMoniker As Long, pMoniker As Long, pBindCtx As Long
   Dim ret As Long, nCount As Long
   Dim pName As Long
   ret = GetRunningObjectTable(0, pROT)
   ret = CreateBindCtx(0, pBindCtx)
   CallInterface pROT, vtbl_ROT_EnumRunning, 1, VarPtr(pEnumMoniker)
   While CallInterface(pEnumMoniker, vtbl_EnumMoniker_Next, 3, 1, VarPtr(pMoniker), VarPtr(nCount)) = 0
        CallInterface pMoniker, vtbl_Moniker_GetDisplayName, 3, pBindCtx, 0, VarPtr(pName)
'For win9x you'll need StrFromPtrA
        Debug.Print StrFromPtrW(pName)
        CallInterface pMoniker, unk_Release, 0
        CoTaskMemFree pName
   Wend
   CallInterface pEnumMoniker, unk_Release, 0
   CallInterface pBindCtx, unk_Release, 0
   CallInterface pROT, unk_Release, 0
End Sub

Regards
Ark

 

by: cpkilekofpPosted on 2006-10-10 at 06:49:40ID: 17698740

LOL Very cool stuff...I've tested this code in Excel 2002 and it works just fine (though you'll have to do some filtration, on my system a GUID showed up as the last entry, also showed objects for event handlers in macros).

Thank you very much, Ark.  The techiniques here are going to help me eliminate a Visual C++ object from my distribution and replace its functionality with pure VB code.  And congratulations (in advance) on 500 points very well earned.

 

by: cpkilekofpPosted on 2006-11-28 at 05:30:57ID: 18027539

Ark clearly deserves the points, as his solution was exactly what was requested.

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...