Link to home
Start Free TrialLog in
Avatar of grava_cd
grava_cd

asked on

Mutex Enumerator

Hi.
I need a source code for Enumerate all Mutex -
CreateMutex() and OpenMutex().

Thanks
Avatar of jkr
jkr
Flag of Germany image

What do you mean - you want to know the names and states of all mutexes?
Avatar of nietod
nietod

Windows has no mechanism for doing this..   You could create a mechanism to enumerate the mutexes you create/open, but you won't be able to learn of mutexes that are created by other programs--unless you know their names.)
>>but you won't be able to learn of mutexes that are
>>created by other programs

Tend to object - at least on NT/W2k it's possible ;-)
Do you need this because you're trying to port some code?

If you explain your requirements, we might be able to give you a better solution.
>> Tend to object - at least on NT/W2k it's possible ;-)
Opps.  How?  (And why didn't you answer?   I guess only for NT and later?)
>>And why didn't you answer?  

Because I'm not sure if grava_cd wants a 'NT-only' solution and assembling a sample is quite a lot of work...
>> possible for NTW2K
See www.sysinternals.com

Anyway, I'd agree: rather explain your problem.

Cheers
Peter
Avatar of grava_cd

ASKER

Thanks for all !
I need get only the Mutex name.
Do you can send to me the NT/2K sample ?

Thanks
unhappily, sysinternals does not offer sources for the HandleEx tool - Iposted the link just to proof it's possible. (BTW. the new version runs on Win98/ME, too!)

grava_cd: The sysinternal tools rely heavily on digging into undocumented features of windows. It would be better you describe your problem, and what you want to accomplish, so perhaps we find a "legal" way to do this.

Peter
>>just to proof it's possible

That's what I already stated ;-)

>>The sysinternal tools rely heavily on digging into
>>undocumented features of windows

The key is/are using 'ZwOpenDirectoryObject()' / 'ZwQueryDirectoryObject()'. Both are 'undocumented' (i.e. not even mentioned in the DDK) and are used by the Object Manager to read what is called the 'Kernel Namespace'.

I'll see if I can assemble a sample...
>> Windows has no mechanism for doing this.
>> Both are 'undocumented'
I don;t feel completely stupid.
OK, here we go ;-)

#include <ntdll.h>
#include <tchar.h>
#include <stdio.h>


/*

    These macros are to be used like this:


    CREATE_DYNFUNC_5    (   <function pointer variable name>,
                            <function name>,
                            <dll name>,
                            <return type>,
                            <calling convention>,
                            <1st parameter's type>,
                            <2nd parameter's type>,
                            <3rd parameter's type>,
                            <4th parameter's type>,
                            <5th parameter's type>
                        );

    e.g.:

    CREATE_DYNFUNC_5    (   NtQueryInformationProcess,
                            NtQueryInformationProcess,
                            ntdll,
                            NTSTATUS,
                            __stdcall,
                            HANDLE,
                            PROCESSINFOCLASS,
                            PVOID,
                            ULONG,
                            PULONG
                        );

    which will create a variable

    FPTR_NtQueryInformationProcess  NtQueryInformationProcess;

    that is initialized with the function address of
    'NtQueryInformationProcess' from 'ntdll.dll'
*/

#define DYNLOADED_FPTR( ptrname, procname, dllname)\
FPTR_##procname ptrname = \
( FPTR_##procname ) GetProcAddress ( GetModuleHandle (  _TEXT( #dllname)), #procname);

#define CREATE_DYNFUNC_3( ptrname, procname, dllname, rettype, callconv, a1, a2, a3)\
typedef  rettype (callconv *FPTR_##procname) ( a1, a2, a3);\
DYNLOADED_FPTR( ptrname, procname, dllname);

#define CREATE_DYNFUNC_7( ptrname, procname, dllname, rettype, callconv, a1, a2, a3, a4, a5, a6, a7)\
typedef  rettype (callconv *FPTR_##procname) ( a1, a2, a3, a4, a5, a6, a7);\
DYNLOADED_FPTR( ptrname, procname, dllname);


CREATE_DYNFUNC_3    (   ZwOpenDirectoryObject,
                        ZwOpenDirectoryObject,
                        ntdll,
                        NTSTATUS,
                        __stdcall,
                        PHANDLE,
                        ACCESS_MASK,
                        NT::POBJECT_ATTRIBUTES
                    );

CREATE_DYNFUNC_7    (   ZwQueryDirectoryObject,
                        ZwQueryDirectoryObject,
                        ntdll,
                        NTSTATUS,
                        __stdcall,
                        HANDLE,
                        PVOID,
                        ULONG,
                        BOOLEAN,
                        BOOLEAN,
                        PULONG,
                        PULONG
                    );

typedef struct _DIRECTORY_BASIC_INFORMATION
{
  UNICODE_STRING    ObjectName;
  UNICODE_STRING    ObjectTypeName;

} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;

void    QueryDirectoryContents  (   HANDLE  hDir)
{
    PDIRECTORY_BASIC_INFORMATION    pdbi;
    ULONG                           nCtx    =   0;
    ULONG                           nSize   =   0;
    NTSTATUS                        ntStatus;
    char*                           acBuffer    [   1024];

    pdbi    =   ( PDIRECTORY_BASIC_INFORMATION) acBuffer;

    do  {
            ntStatus    =   ZwQueryDirectoryObject  (   hDir,
                                                        pdbi,
                                                        sizeof  (   acBuffer),
                                                        TRUE,
                                                        FALSE,
                                                        &nCtx,
                                                        NULL
                                                    );

            if  (   pdbi->ObjectTypeName.Buffer)
                    wprintf (   L"%s\t%s\n",    
                                pdbi->ObjectTypeName.Buffer,    
                                pdbi->ObjectName.Buffer
                            );
   
        }   while   (   ntStatus    ==  STATUS_SUCCESS);
}

int main    ()
{
    NTSTATUS                ntStatus;
    HANDLE                  hDirectory;

    ACCESS_MASK             amDir   =   DIRECTORY_QUERY | DIRECTORY_TRAVERSE;
    OBJECT_ATTRIBUTES       oaDir;
    UNICODE_STRING          usDirectoryName;

    NT::RtlInitUnicodeString    (   &usDirectoryName,   L"\\BaseNamedObjects");

    InitializeObjectAttributes  (   &oaDir,
                                    &usDirectoryName,
                                    OBJ_PERMANENT,
                                    NULL,
                                    NULL
                                );

    ntStatus    =   ZwOpenDirectoryObject   (   &hDirectory,
                                                amDir,
                                                &oaDir
                                            );

    if  (   STATUS_SUCCESS  !=  ntStatus)
            return  (   -1);

    QueryDirectoryContents  (   hDirectory);

    NT::ZwClose (   hDirectory);

    return  (   0);
}

The 'ntdll.h' header will follow in the next post...
Phew, it took the post - so, here's the header:

#ifndef __NTDLL_H
#define __NTDLL_H

#include <windows.h>

namespace NT
{
extern "C"
     {
#pragma warning     (     disable:     4005)
          #include <basetsd.h>
          #include <ntddk.h>
#pragma warning     (     default:     4005)
     }
}

using NT::NTSTATUS;
using NT::UNICODE_STRING;
using NT::PUNICODE_STRING;
using NT::OBJECT_ATTRIBUTES;

#endif

You'll have to use the DDK to compile & link it (available for free at http://www.microsoft.com/ddk/).
Ooops, sorry, the sample I posted lists the whole directory - use

void    QueryDirectoryContents  (   HANDLE  hDir)
{
    PDIRECTORY_BASIC_INFORMATION    pdbi;
    ULONG                           nCtx    =   0;
    ULONG                           nSize   =   0;
    NTSTATUS                        ntStatus;
    char*                           acBuffer    [   1024];

    pdbi    =   ( PDIRECTORY_BASIC_INFORMATION) acBuffer;

    do  {
            ntStatus    =   ZwQueryDirectoryObject  (   hDir,
                                                        pdbi,
                                                        sizeof  (   acBuffer),
                                                        TRUE,
                                                        FALSE,
                                                        &nCtx,
                                                        NULL
                                                    );

            if  (   pdbi->ObjectTypeName.Buffer &&  wcscmp  (   pdbi->ObjectTypeName.Buffer,    L"Mutant"))
                    wprintf (   L"%s\t%s\n",    
                                pdbi->ObjectTypeName.Buffer,    
                                pdbi->ObjectName.Buffer
                            );
   
        }   while   (   ntStatus    ==  STATUS_SUCCESS);
}

instead...
Thanks for the answer, but have many compilers errors in Visual C++ 6...
Do you dont have a ready project ?

Thanks
Yes, I do - but as the nature of the things is, I cannot post a project file here. You do have the DDK, do you?
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi.
I have DDK installed.
Do you can send the source to my email ?
marcos.prog@bol.com.br

thanks
Sure I can - the only problem is that I'm in the US right now & my notebook is not as equipped as my office PC - I'll see if I have the source code here; if not, you'll receiveit by next Tuesday when I'm back to Europe.
Ok...
thanks
OK, you should receive it any minute - note that you'll have to adapt it, unless you have the DDK on f:\w2kddk ;-)
Anything else you need to know?
grava_cd, are you still with us?
This question was LOCKED with a PROPOSED ANSWER and awaits your decision today.  Once a question is LOCKED with a Proposed Answer, few new experts will step in to help on that question, since the assumption is, you've been helped.  If the Proposed Answer helped you, please accept it and award that expert.  If it did not help you, please reject it and add comments as to status and what else is needed.

If you wish to award multiple experts, just comment here with detail, I'll respond as soon as possible.  As it stands today, you asked the question, got help and not one expert was awarded for the contribution(s) made.  Your response is needed.  I'll monitor through month end, and if you've not returned to complete this, we'll need to decide.  Expert input is welcome (as always) to determine the outcome here if the Asker does not respond.

Your response in finalizing this (and ALL) your question(s) is appreciated.

Site-related HELP:  https://www.experts-exchange.com/jsp/cmtyHelpDesk.jsp
Moondancer
Community Support Moderator @ Experts Exchange
>>This question was LOCKED with a PROPOSED ANSWER

And I would like to add that creating this solution was *VERY* time consuming, and it works.
I am sorry to see that Asker has not returned to update and finalize this question.  I am, therefore, force accepting this question.  In the event the Asker returns with additional needs related to this question, please respond and continue the collaboration process.
Thank you,
Moondancer
Community Support Moderator @ Experts Exchange
Thank you a lot, Moondancer. This one was really on my mind, as I put a lot of work in it.
Thank you as well, sorry to see these old questions overlooked and happy to be able to help resolve the backlog and add value to these items as they move to the PAQ.

Moondancer
Community Support Moderator @ Experts Exchange
I'm glad this one got closed!