Copyright © Microsoft Corporation. This document is an archived reproduction of a version originally published by Microsoft. It may have slight formatting modifications for consistency and to improve readability.
Figure 2 CriticalSectionHelper.cpp
//======================================================================
// Russ Osterlund / Matt Pietrek
// MSDN Magazine, 2003
//======================================================================
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "CriticalSectionHelper.h"

typedef void (__stdcall *PFNINITIALIZECRITICALSECTION)( 
    LPCRITICAL_SECTION );

static PFNINITIALIZECRITICALSECTION s_pfnInitializeCriticalSection = 0;

#pragma optimize( "y", on ) // Ensure that we get standard stack frames
#pragma warning(disable :4273) // We're overloading a function 
                               // from WinBase.H. The compiler 
                               // will be unhappy, so quiet it.
extern "C"
void
__stdcall
InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection )
{
    if ( !s_pfnInitializeCriticalSection )
    {
        HMODULE hModuleKERNEL32 = 
            GetModuleHandle( "KERNEL32.DLL" );

        s_pfnInitializeCriticalSection = 
            (PFNINITIALIZECRITICALSECTION)
            GetProcAddress( hModuleKERNEL32, 
            "InitializeCriticalSection" );
    }

    s_pfnInitializeCriticalSection( lpCriticalSection );

    DWORD   pReturnAddress;
    __asm   mov     eax, dword ptr [ebp+4]
    __asm   mov     [pReturnAddress], eax

    // Set one of the "spare" fields in the critical section to 
    // the return address.  We subtract 6, since the return 
    // address is after the "CALL" instruction, which is 
    // typically 6 bytes.  Being off by 6 bytes is usually 
    // enough for the line # lookup to pick the wrong line of 
    // code.
    lpCriticalSection->DebugInfo->Spare[0] = pReturnAddress 6;
    lpCriticalSection->DebugInfo->Spare[1] = 
        MYCRITSECT_SIGNATURE;
}

#if 0
extern "C" __stdcall
BOOL
InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION 
    lpCriticalSection, DWORD dwSpinCount );
#endif

Figure 3 MyCriticalSections Output
Initializing symbol engine
Symbol engine initialized OK
-------------------------------------------------------------------------
Critical Section 70
Address: 0x00437B38 !csMain
Initialized in function DEMO!main+00000025
Initialized at c:\projects\mycriticalsections\demo\demo.cpp, line 19
    LockCount: 0
    Recursion: 1
    Held by:   2348 (92C)
    DebugInfo:
        Entry Count:      0
-------------------------------------------------------------------------
Critical Section 71
Address: 0x00437B20 DEMO!yetAnotherCriticalSection
Initialized in function DEMO!main+0000004D
Initialized at c:\projects\mycriticalsections\demo\demo.cpp, line 22
    LockCount: 3
    Recursion: 3
    Held by:   2348 (92C)
    Threads Waiting: 1
    DebugInfo:
        Entry Count:      1

125 Critical Sections examined, 2 initialized with signature