381 lines
8.5 KiB
C
381 lines
8.5 KiB
C
/*++
|
||
|
||
Copyright (c) 1997 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
win32obj.c
|
||
|
||
Abstract:
|
||
|
||
This module contains helper functions for creating debug-specific
|
||
named Win32 objects. Functions are included for named events,
|
||
semaphores, and mutexes.
|
||
|
||
Object names created by these routines have the following format:
|
||
|
||
filename.ext:line_number member:address PID:pid
|
||
|
||
Where:
|
||
|
||
filename.ext = The file name where the object was created.
|
||
|
||
line_number = The line number within the file.
|
||
|
||
member = The member/global variable name where the handle is
|
||
stored. This name is provided by the caller, but is usually
|
||
of the form "g_Global" for globals and "CLASS::m_Member" for
|
||
class members.
|
||
|
||
address = An address, used to guarantee uniqueness of the objects
|
||
created. This is provided by the caller. For global variables,
|
||
this is typically the address of the global. For class members,
|
||
this is typically the address of the containing class.
|
||
|
||
pid = The current process ID. This ensures uniqueness across all
|
||
processes.
|
||
|
||
Here are a couple of examples:
|
||
|
||
main.cxx:796 g_hShutdownEvent:683a42bc PID:373
|
||
|
||
resource.cxx:136 RTL_RESOURCE::SharedSemaphore:00250970 PID:373
|
||
|
||
Author:
|
||
|
||
Keith Moore (keithmo) 23-Sep-1997
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
|
||
#include <nt.h>
|
||
#include <ntrtl.h>
|
||
#include <nturtl.h>
|
||
#include <windows.h>
|
||
#include <pudebug.h>
|
||
|
||
|
||
#define MAX_OBJECT_NAME 256 // chars
|
||
|
||
|
||
LONG g_PuDbgEventsCreated = 0;
|
||
LONG g_PuDbgSemaphoresCreated = 0;
|
||
LONG g_PuDbgMutexesCreated = 0;
|
||
|
||
|
||
|
||
LPSTR
|
||
PuDbgpBuildObjectName(
|
||
IN LPSTR ObjectNameBuffer,
|
||
IN LPSTR FileName,
|
||
IN ULONG LineNumber,
|
||
IN LPSTR MemberName,
|
||
IN PVOID Address
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Internal routine that builds an appropriate object name based on
|
||
the file name, line number, member name, address, and process ID.
|
||
|
||
Arguments:
|
||
|
||
ObjectNameBuffer - Pointer to the target buffer for the name.
|
||
|
||
FileName - The filename of the source creating the object. This
|
||
is __FILE__ of the caller.
|
||
|
||
LineNumber - The line number within the source. This is __LINE__
|
||
of the caller.
|
||
|
||
MemberName - The member/global variable name where the object handle
|
||
is to be stored.
|
||
|
||
Address - The address of the containing structure/class or of the
|
||
global itself.
|
||
|
||
Return Value:
|
||
|
||
LPSTR - Pointer to ObjectNameBuffer if successful, NULL otherwise.
|
||
|
||
N.B. This routine always returns NULL when running under Win9x.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
PLATFORM_TYPE platformType;
|
||
LPSTR fileNamePart;
|
||
LPSTR result;
|
||
|
||
//
|
||
// We have no convenient way to dump objects w/ names from
|
||
// Win9x, so we'll only enable this functionality under NT.
|
||
//
|
||
|
||
platformType = IISGetPlatformType();
|
||
result = NULL;
|
||
|
||
if( platformType == PtNtServer ||
|
||
platformType == PtNtWorkstation ) {
|
||
|
||
//
|
||
// Find the filename part of the incoming source file name.
|
||
//
|
||
|
||
fileNamePart = strrchr( FileName, '\\' );
|
||
|
||
if( fileNamePart == NULL ) {
|
||
fileNamePart = strrchr( FileName, '/' );
|
||
}
|
||
|
||
if( fileNamePart == NULL ) {
|
||
fileNamePart = strrchr( FileName, ':' );
|
||
}
|
||
|
||
if( fileNamePart == NULL ) {
|
||
fileNamePart = FileName;
|
||
} else {
|
||
fileNamePart++;
|
||
}
|
||
|
||
//
|
||
// Ensure we don't overwrite our object name buffer.
|
||
//
|
||
|
||
if( ( sizeof(":1234567890 :12345678 PID:1234567890") +
|
||
strlen( fileNamePart ) +
|
||
strlen( MemberName ) ) < MAX_OBJECT_NAME ) {
|
||
|
||
wsprintfA(
|
||
ObjectNameBuffer,
|
||
"%s:%lu %s:%08lx PID:%lu",
|
||
fileNamePart,
|
||
LineNumber,
|
||
MemberName,
|
||
Address,
|
||
GetCurrentProcessId()
|
||
);
|
||
|
||
result = ObjectNameBuffer;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
return result;
|
||
|
||
} // PuDbgpBuildObjectName
|
||
|
||
|
||
HANDLE
|
||
PuDbgCreateEvent(
|
||
IN LPSTR FileName,
|
||
IN ULONG LineNumber,
|
||
IN LPSTR MemberName,
|
||
IN PVOID Address,
|
||
IN BOOL ManualReset,
|
||
IN BOOL InitialState
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Creates a new event object.
|
||
|
||
Arguments:
|
||
|
||
FileName - The filename of the source creating the object. This
|
||
is __FILE__ of the caller.
|
||
|
||
LineNumber - The line number within the source. This is __LINE__
|
||
of the caller.
|
||
|
||
MemberName - The member/global variable name where the object handle
|
||
is to be stored.
|
||
|
||
Address - The address of the containing structure/class or of the
|
||
global itself.
|
||
|
||
ManualReset - TRUE to create a manual reset event, FALSE to create
|
||
an automatic reset event.
|
||
|
||
InitialState - The intitial state of the event object.
|
||
|
||
Return Value:
|
||
|
||
HANDLE - Handle to the object if successful, NULL otherwise.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
LPSTR objName;
|
||
HANDLE objHandle;
|
||
CHAR objNameBuffer[MAX_OBJECT_NAME];
|
||
|
||
objName = PuDbgpBuildObjectName(
|
||
objNameBuffer,
|
||
FileName,
|
||
LineNumber,
|
||
MemberName,
|
||
Address
|
||
);
|
||
|
||
objHandle = CreateEventA(
|
||
NULL, // lpEventAttributes
|
||
ManualReset, // bManualReset
|
||
InitialState, // bInitialState
|
||
objName // lpName
|
||
);
|
||
|
||
if( objHandle != NULL ) {
|
||
InterlockedIncrement( &g_PuDbgEventsCreated );
|
||
}
|
||
|
||
return objHandle;
|
||
|
||
} // PuDbgCreateEvent
|
||
|
||
|
||
HANDLE
|
||
PuDbgCreateSemaphore(
|
||
IN LPSTR FileName,
|
||
IN ULONG LineNumber,
|
||
IN LPSTR MemberName,
|
||
IN PVOID Address,
|
||
IN LONG InitialCount,
|
||
IN LONG MaximumCount
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Creates a new semaphore object.
|
||
|
||
Arguments:
|
||
|
||
FileName - The filename of the source creating the object. This
|
||
is __FILE__ of the caller.
|
||
|
||
LineNumber - The line number within the source. This is __LINE__
|
||
of the caller.
|
||
|
||
MemberName - The member/global variable name where the object handle
|
||
is to be stored.
|
||
|
||
Address - The address of the containing structure/class or of the
|
||
global itself.
|
||
|
||
InitialCount - The initial count of the semaphore.
|
||
|
||
MaximumCount - The maximum count of the semaphore.
|
||
|
||
Return Value:
|
||
|
||
HANDLE - Handle to the object if successful, NULL otherwise.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
LPSTR objName;
|
||
HANDLE objHandle;
|
||
CHAR objNameBuffer[MAX_OBJECT_NAME];
|
||
|
||
objName = PuDbgpBuildObjectName(
|
||
objNameBuffer,
|
||
FileName,
|
||
LineNumber,
|
||
MemberName,
|
||
Address
|
||
);
|
||
|
||
objHandle = CreateSemaphoreA(
|
||
NULL, // lpSemaphoreAttributes
|
||
InitialCount, // lInitialCount
|
||
MaximumCount, // lMaximumCount
|
||
objName // lpName
|
||
);
|
||
|
||
if( objHandle != NULL ) {
|
||
InterlockedIncrement( &g_PuDbgSemaphoresCreated );
|
||
}
|
||
|
||
return objHandle;
|
||
|
||
} // PuDbgCreateSemaphore
|
||
|
||
|
||
HANDLE
|
||
PuDbgCreateMutex(
|
||
IN LPSTR FileName,
|
||
IN ULONG LineNumber,
|
||
IN LPSTR MemberName,
|
||
IN PVOID Address,
|
||
IN BOOL InitialOwner
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Creates a new mutex object.
|
||
|
||
Arguments:
|
||
|
||
FileName - The filename of the source creating the object. This
|
||
is __FILE__ of the caller.
|
||
|
||
LineNumber - The line number within the source. This is __LINE__
|
||
of the caller.
|
||
|
||
MemberName - The member/global variable name where the object handle
|
||
is to be stored.
|
||
|
||
Address - The address of the containing structure/class or of the
|
||
global itself.
|
||
|
||
InitialOwner - TRUE if the mutex should be created "owned".
|
||
|
||
Return Value:
|
||
|
||
HANDLE - Handle to the object if successful, NULL otherwise.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
LPSTR objName;
|
||
HANDLE objHandle;
|
||
CHAR objNameBuffer[MAX_OBJECT_NAME];
|
||
|
||
objName = PuDbgpBuildObjectName(
|
||
objNameBuffer,
|
||
FileName,
|
||
LineNumber,
|
||
MemberName,
|
||
Address
|
||
);
|
||
|
||
objHandle = CreateMutexA(
|
||
NULL, // lpMutexAttributes
|
||
InitialOwner, // bInitialOwner,
|
||
objName // lpName
|
||
);
|
||
|
||
if( objHandle != NULL ) {
|
||
InterlockedIncrement( &g_PuDbgMutexesCreated );
|
||
}
|
||
|
||
return objHandle;
|
||
|
||
} // PuDbgCreateMutex
|
||
|