Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

452 lines
11 KiB

//--------------------------------------------------------------------------;
//
// File: Init.c
//
// Copyright (c) 1995 Microsoft Corporation. All Rights Reserved.
//
// Abstract:
//
//
// Contents:
// initDSOUNDInfo()
// endDSOUNDInfo()
// DllMain()
//
// History:
// 02/01/95 Fwong
//
//--------------------------------------------------------------------------;
#include "dsoundpr.h"
// Our module handle.
HANDLE hModule;
// ini strings for setting WAVE emulation
char szIniSection[] = "DSOUND";
char szNumBuffers[] = "Buffers";
char szSizeBuffer[] = "BufferSize";
char szDupEnumWaveDevs[] = "DupEnumWaveDevs";
#if defined(RDEBUG) || defined(DEBUG)
char szEnumOnlyWaveDevs[]= "EnumOnlyWaveDevs";
#endif
WAVEFORMATEX gwfxUserDefault = {
WAVE_FORMAT_PCM, // wFormatTag
2, // nChannels
22050, // nSamplesPerSec
44100, // nAvgBytesPerSec
2, // nBlockAlign
8, // wBitsPerSample
0 // cbSize
};
#ifndef DSBLD_NOCRITSECTS
// Multi thread protection
HANDLE hDllMutex;
static BOOL bFirstTime = TRUE;
#define TMPDLLEVENT "__DSOUNDDLL_EVENT__"
#define HELPINITEVENT "__DSOUNDDLL_HELPINIT_EVENT__"
int iDLLCSCnt;
#endif
//--------------------------------------------------------------------------;
//
// BOOL initDSOUNDInfo
//
// Description:
// Initializes the global data for wave devices.
//
// Arguments:
// None.
//
// Return (BOOL):
// TRUE if successful, FALSE otherwise.
//
// History:
// 01/18/95 Fwong
//
//--------------------------------------------------------------------------;
BOOL FNLOCAL initDSOUNDInfo
(
void
)
{
UINT ii;
DPF(3,"initDSOUNDInfo");
ii = waveOutGetNumDevs();
if( ii >= LIMIT_WAVE_DEVICES ) {
DPF(0,"Too many WAVE devices installed in system");
gpdsinfo = NULL;
return FALSE;
}
// We will track and alloc our own memory
MemInit();
gpdsinfo = (LPDSOUNDINFO)MemAlloc( sizeof(DSOUNDINFO) );
if(NULL == gpdsinfo)
{
DPF(0,"Could not allocate memory for SOUNDOBJI");
MemFini();
gpdsinfo = NULL;
return FALSE;
}
// Init layer to Emulation VxD
gpdsinfo->hHel = DSVXD_Open("DSOUND.VXD");
if (NULL != gpdsinfo->hHel) DSVXD_Initialize( gpdsinfo->hHel );
DPF(3,"Finished Open DSVXD layer %X", gpdsinfo->hHel );
gpdsinfo->uRefCount = 1;
gpdsinfo->pDSoundObj = NULL;
ii = sizeof(DSOUNDCALLBACKS) +
sizeof(DSOUND3DCALLBACKS) +
sizeof(DSOUNDBUFFERCALLBACKS) +
sizeof(DSOUNDBUFFER3DCALLBACKS);
gpdsinfo->lpVtblDS = (LPDSOUNDCALLBACKS)MemAlloc(ii);
if(NULL == gpdsinfo->lpVtblDS) {
MemFree( gpdsinfo );
MemFini();
gpdsinfo = NULL;
return FALSE;
}
gpdsinfo->lpVtblDS3D =
(LPDSOUND3DCALLBACKS)(((LPBYTE)(gpdsinfo->lpVtblDS)) +
sizeof(DSOUNDCALLBACKS));
gpdsinfo->lpVtblDSb =
(LPDSOUNDBUFFERCALLBACKS)(((LPBYTE)(gpdsinfo->lpVtblDS3D)) +
sizeof(DSOUND3DCALLBACKS));
gpdsinfo->lpVtblDSb3D =
(LPDSOUNDBUFFER3DCALLBACKS)(((LPBYTE)(gpdsinfo->lpVtblDSb)) +
sizeof(DSOUNDBUFFERCALLBACKS));
DSHWCreateTable(gpdsinfo->lpVtblDS);
// DS3DCreateTable(gpdsinfo->lpVtblDS3D);
DSHWBufferCreateTable(gpdsinfo->lpVtblDSb);
// DS3DBufferCreateTable(gpdsinfo->lpVtblDSb3D);
//
// Set the user default. Someday this may come from the registry
// and/or control panel, but for now it is hard-coded.
//
gpdsinfo->pwfxUserDefault = &gwfxUserDefault;
//
//
//
gpdsinfo->nBuffers = GetProfileInt(szIniSection,szNumBuffers,4);
gpdsinfo->cbBuffer = GetProfileInt(szIniSection,szSizeBuffer,1024);
gpdsinfo->fDupEnumWaveDevs = GetProfileInt(szIniSection, szDupEnumWaveDevs, 0);
#if defined(RDEBUG) || defined(DEBUG)
gpdsinfo->fEnumOnlyWaveDevs= GetProfileInt(szIniSection, szEnumOnlyWaveDevs, 0);
#endif
gpdsinfo->aguidWave[0] = DS_WAVE0_IID;
gpdsinfo->aguidWave[1] = DS_WAVE1_IID;
gpdsinfo->aguidWave[2] = DS_WAVE2_IID;
gpdsinfo->aguidWave[3] = DS_WAVE3_IID;
gpdsinfo->aguidWave[4] = DS_WAVE4_IID;
gpdsinfo->aguidWave[5] = DS_WAVE5_IID;
gpdsinfo->aguidWave[6] = DS_WAVE6_IID;
gpdsinfo->aguidWave[7] = DS_WAVE7_IID;
gpdsinfo->aguidWave[8] = DS_WAVE8_IID;
gpdsinfo->aguidWave[9] = DS_WAVE9_IID;
gpdsinfo->aguidWave[10] = DS_WAVE10_IID;
gpdsinfo->aguidWave[11] = DS_WAVE11_IID;
gpdsinfo->aguidWave[12] = DS_WAVE12_IID;
gpdsinfo->aguidWave[13] = DS_WAVE13_IID;
gpdsinfo->aguidWave[14] = DS_WAVE14_IID;
gpdsinfo->aguidWave[15] = DS_WAVE15_IID;
gpdsinfo->aguidWave[16] = DS_WAVE16_IID;
gpdsinfo->aguidWave[17] = DS_WAVE17_IID;
gpdsinfo->aguidWave[18] = DS_WAVE18_IID;
gpdsinfo->aguidWave[19] = DS_WAVE19_IID;
gpdsinfo->aguidWave[20] = DS_WAVE20_IID;
gpdsinfo->aguidWave[21] = DS_WAVE21_IID;
gpdsinfo->aguidWave[22] = DS_WAVE22_IID;
gpdsinfo->aguidWave[23] = DS_WAVE23_IID;
gpdsinfo->aguidWave[24] = DS_WAVE24_IID;
gpdsinfo->aguidWave[25] = DS_WAVE25_IID;
gpdsinfo->aguidWave[26] = DS_WAVE26_IID;
gpdsinfo->aguidWave[27] = DS_WAVE27_IID;
gpdsinfo->aguidWave[28] = DS_WAVE28_IID;
gpdsinfo->aguidWave[29] = DS_WAVE29_IID;
gpdsinfo->aguidWave[30] = DS_WAVE30_IID;
gpdsinfo->aguidWave[31] = DS_WAVE31_IID;
return TRUE;
} // initDSOUNDInfo()
//--------------------------------------------------------------------------;
//
// BOOL endDSOUNDInfo
//
// Description:
//
//
// Arguments:
// None.
//
// Return (BOOL):
//
// History:
// 01/18/95 Fwong
//
//--------------------------------------------------------------------------;
BOOL FNLOCAL endDSOUNDInfo
(
void
)
{
DPF(4,"endDSOUNDInfo");
if(NULL == gpdsinfo)
{
return TRUE;
}
// If DS Objects still exist then get rid of them
if( gpdsinfo->pDSoundObj ) {
// We still have objects left
DPF(0,"ERROR: ******* Not cleaned up all DS Objects ******* " );
}
if( gpdsinfo->hHel ) {
DPF(3,"Close HEL layer %X", gpdsinfo->hHel );
DSVXD_Shutdown( gpdsinfo->hHel );
DSVXD_Close( gpdsinfo->hHel );
gpdsinfo->hHel = NULL;
DPF(3,"Finished Close HEL layer" );
}
// Free mem from VTbl
MemFree( gpdsinfo->lpVtblDS );
MemFree( gpdsinfo );
gpdsinfo = NULL;
MemFini();
return TRUE;
} // endDSOUNDInfo()
BOOL CALLBACK DllMain
(
HINSTANCE hinst,
DWORD dwReason,
LPVOID lpReserved
)
{
HANDLE hhelpinitevent;
#ifdef WIN95
BOOL didhelp;
#endif
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
DbgInitialize(TRUE);
DPF(1, "DllMain(hinst=%.08lXh, DLL_PROCESS_ATTACH)",hinst);
#ifndef DSBLD_NOCRITSECTS
{
HANDLE hevent;
hevent = CreateEvent( NULL, TRUE, FALSE, TMPDLLEVENT );
DPF( 2, "CreatedEvent: %08lx", hevent );
hhelpinitevent = CreateEvent( NULL, TRUE, FALSE, HELPINITEVENT );
DPF( 4, "CreatedEvent: help init %08lx", hhelpinitevent );
/*
* is this the first time?
*/
if( InterlockedExchange( &bFirstTime, FALSE ) ) {
DPF( 3, "INIT_DLL_CSECT" );
INIT_DLL_CSECT();
DPF( 5, "ENTER_DLL_CSECT" );
ENTER_DLL_CSECT();
if( hevent != NULL )
{
SetEvent( hevent );
}
hModule = hinst;
} else {
/*
* second or later time through, wait for first time to
* finish and then take the csect
*/
if( hevent != NULL )
{
DPF( 5, "WaitForSingleObject" );
WaitForSingleObject( hevent, INFINITE );
}
DPF( 5, "ENTER_DLL_CSECT" );
ENTER_DLL_CSECT();
}
}
DPF( 5, "DONE ENTER_DLL_CSECT" );
#else
hModule = hinst;
#endif
if( gpdsinfo == NULL ) {
ASSERT( hModule == hinst );
if(!initDSOUNDInfo()) {
DPF(3, "Init Failed");
LEAVE_DLL_CSECT();
return FALSE;
}
} else {
gpdsinfo->uRefCount++;
}
#ifdef WIN95
{
/*
* get the helper process started
*/
DPF(2, "CreateHelperProcess" );
didhelp = CreateHelperProcess( &gpdsinfo->pidHelper );
if( gpdsinfo->pidHelper == 0 )
{
DPF(0, "Could not start helper; exiting" );
LEAVE_DLL_CSECT();
return FALSE;
}
#ifndef DSBLD_NOCRITSECTS
{
if( !didhelp && ( GetCurrentProcessId() != gpdsinfo->pidHelper ) )
{
/*
* this thread is not the first thread into process attach (!didhelp)
* and not the DDHELP thread which is loading DSOUND.DLL in response
* to HelperLoadDLL(). Therefore, this thread must wait until DDHELP
* had initialized to prevent a deadlock.
*/
if( NULL != hhelpinitevent )
{
LEAVE_DLL_CSECT();
WaitForSingleObject( hhelpinitevent, INFINITE );
ENTER_DLL_CSECT();
}
}
}
#endif
}
#else
gpdsinfo->pidHelper = GetCurrentProcessId();
#endif
#ifdef WIN95
/*
* signal the new process being added
*/
if( didhelp )
{
DPF(2, "Waiting for DDHELP startup" );
LEAVE_DLL_CSECT();
if( !WaitForHelperStartup() )
{
DPF(0, "LEAVING, WaitForHelperStartup FAILED" );
return FALSE;
}
HelperLoadDLL( DS_APP_DLLNAME, NULL, 0 );
DPF(2, "DDHELP starting, notifying of new process" );
ENTER_DLL_CSECT();
#ifndef DSBLD_NOCRITSECTS
/*
* DDHELP initialization is complete. Signal the
* event to unblock any other pending app. threads.
*/
if( NULL != hhelpinitevent )
SetEvent( hhelpinitevent );
#endif
}
SignalNewProcess( GetCurrentProcessId(), DSNotify );
#endif
DPF(5, "!*** break for debugging ***");
LEAVE_DLL_CSECT();
return (TRUE);
case DLL_PROCESS_DETACH:
{
DPF(1, "DllMain(hinst=%.08lXh, DLL_PROCESS_DETACH)",hinst);
if( gpdsinfo == NULL ) {
DPF(0, "*****************Detach on NULL gpdsinfo");
} else {
// Release all objects owned by this process
CurrentProcessCleanup( (DWORD)HackGetCurrentProcessId(),
FALSE );
ENTER_DLL_CSECT();
gpdsinfo->uRefCount--;
DPF(2, "DLL RefCnt = %lu", gpdsinfo->uRefCount );
if( gpdsinfo->uRefCount == 0 ) {
endDSOUNDInfo();
LEAVE_DLL_CSECT();
FINI_DLL_CSECT();
} else if ( gpdsinfo->uRefCount == 1 ) {
/*
* see if it is time to clean up...
* we clean up on a reference
* count of 1 instead of 0,
* because DDHELP has a count on us as
* well...
*/
#ifdef DEBUG
MemState();
#endif
DPF(2, "On last refcnt, safe to ditch DDHELP.EXE" );
LEAVE_DLL_CSECT();
#ifdef WIN95
DoneWithHelperProcess();
#endif
} else {
LEAVE_DLL_CSECT();
}
}
return TRUE;
}
}
}