1043 lines
25 KiB
C
1043 lines
25 KiB
C
//==========================================================================;
|
|
//
|
|
// init.c
|
|
//
|
|
// Copyright (c) 1991-1999 Microsoft Corporation
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// History:
|
|
// 11/15/92 cjp [curtisp]
|
|
//
|
|
//==========================================================================;
|
|
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <mmsystem.h>
|
|
#include <mmddkp.h>
|
|
#include <mmreg.h>
|
|
#include <msacm.h>
|
|
#include <msacmdrv.h>
|
|
|
|
#ifdef USE_ACMTHUNK
|
|
#include "acmthunk.h"
|
|
#endif
|
|
#include "msacmmap.h"
|
|
#include "profile.h"
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
|
|
ACMGLOBALINFO acmglobalinfo;
|
|
ACMGARB acmgarb;
|
|
PACMGARB gpag;
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// LRESULT mapWaveGetDevCaps
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// BOOL fInput: TRUE if input.
|
|
//
|
|
// LPWAVEOUTCAPS pwc: Pointer to a WAVEOUTCAPS structure to receive
|
|
// the information. Used for both input and output. Output structure
|
|
// contains input structure plus extras....
|
|
//
|
|
// UINT cbSize: Size of the WAVEOUTCAPS structure.
|
|
//
|
|
// Return (MMRESULT):
|
|
//
|
|
// History:
|
|
// 06/14/93 cjp [curtisp]
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
MMRESULT FNGLOBAL mapWaveGetDevCaps
|
|
(
|
|
BOOL fInput,
|
|
LPWAVEOUTCAPS pwc,
|
|
UINT cbSize
|
|
)
|
|
{
|
|
MMRESULT mmr;
|
|
WAVEOUTCAPS woc;
|
|
UINT cWaveDevs;
|
|
BOOL fFoundOnlyOneMappableDeviceID;
|
|
UINT uMappableDeviceID;
|
|
UINT i;
|
|
|
|
if (fInput)
|
|
{
|
|
cbSize = min(sizeof(WAVEINCAPS), cbSize);
|
|
cWaveDevs = gpag->cWaveInDevs;
|
|
}
|
|
else
|
|
{
|
|
cbSize = min(sizeof(WAVEOUTCAPS), cbSize);
|
|
cWaveDevs = gpag->cWaveOutDevs;
|
|
}
|
|
|
|
//
|
|
// Determine if there is only one mappable device ID. If there is only
|
|
// one, then set fFoundOnlyOneMappableID=TRUE and put the device ID
|
|
// in uMappableDeviceID.
|
|
//
|
|
fFoundOnlyOneMappableDeviceID = FALSE;
|
|
for (i=0; i < cWaveDevs; i++)
|
|
{
|
|
if (fInput)
|
|
{
|
|
mmr = (MMRESULT)waveInMessage((HWAVEIN)LongToHandle(i), DRV_QUERYMAPPABLE, 0L, 0L);
|
|
}
|
|
else
|
|
{
|
|
mmr = (MMRESULT)waveOutMessage((HWAVEOUT)LongToHandle(i), DRV_QUERYMAPPABLE, 0L, 0L);
|
|
}
|
|
|
|
if (MMSYSERR_NOERROR == mmr)
|
|
{
|
|
if (fFoundOnlyOneMappableDeviceID)
|
|
{
|
|
fFoundOnlyOneMappableDeviceID = FALSE;
|
|
break;
|
|
}
|
|
uMappableDeviceID = i;
|
|
fFoundOnlyOneMappableDeviceID = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// If there is only one mappable device ID, then get the caps from it to
|
|
// fill in the dwSupport fields. Otherwise, let's hardcode the dwSupport
|
|
// field.
|
|
//
|
|
if (fFoundOnlyOneMappableDeviceID)
|
|
{
|
|
if (fInput)
|
|
{
|
|
mmr = waveInGetDevCaps(uMappableDeviceID, (LPWAVEINCAPS)&woc, cbSize);
|
|
}
|
|
else
|
|
{
|
|
mmr = waveOutGetDevCaps(uMappableDeviceID, &woc, cbSize);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
woc.dwSupport = WAVECAPS_VOLUME | WAVECAPS_LRVOLUME;
|
|
mmr = MMSYSERR_NOERROR;
|
|
}
|
|
|
|
//
|
|
// Bail on error
|
|
//
|
|
if (MMSYSERR_NOERROR != mmr)
|
|
{
|
|
return (mmr);
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
woc.wMid = MM_MICROSOFT;
|
|
woc.wPid = MM_WAVE_MAPPER;
|
|
woc.vDriverVersion = VERSION_MSACMMAP;
|
|
woc.wChannels = 2;
|
|
|
|
LoadString(gpag->hinst, IDS_ACM_CAPS_DESCRIPTION, woc.szPname, SIZEOF(woc.szPname));
|
|
|
|
//
|
|
//
|
|
//
|
|
woc.dwFormats = WAVE_FORMAT_1M08 |
|
|
WAVE_FORMAT_1S08 |
|
|
WAVE_FORMAT_1M16 |
|
|
WAVE_FORMAT_1S16 |
|
|
WAVE_FORMAT_2M08 |
|
|
WAVE_FORMAT_2S08 |
|
|
WAVE_FORMAT_2M16 |
|
|
WAVE_FORMAT_2S16 |
|
|
WAVE_FORMAT_4M08 |
|
|
WAVE_FORMAT_4S08 |
|
|
WAVE_FORMAT_4M16 |
|
|
WAVE_FORMAT_4S16;
|
|
|
|
_fmemcpy(pwc, &woc, cbSize);
|
|
|
|
return (MMSYSERR_NOERROR);
|
|
} // waveGetDevCaps()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// UINT GetPCMSupportFlags
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// PZYZPCMFORMATS pzpf
|
|
// UINT iaPCMFormats:
|
|
//
|
|
// Return (VOID):
|
|
//
|
|
// History:
|
|
// 06/14/93 cjp [curtisp]
|
|
// 03/13/94 fdy [frankye]
|
|
// Modifed the interface to take pzpf and an index into it.
|
|
// Modifed the function to set flags to indicate which wave
|
|
// devices support the format in question.
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
VOID FNLOCAL GetPCMSupportFlags
|
|
(
|
|
PZYZPCMFORMAT pzpf,
|
|
UINT iaPCMFormats
|
|
)
|
|
{
|
|
PCMWAVEFORMAT wfPCM;
|
|
UINT uSamplesPerSec;
|
|
UINT u, n, i;
|
|
|
|
#define WFQFLAGS (WAVE_FORMAT_QUERY | WAVE_ALLOWSYNC)
|
|
|
|
WAIT_FOR_MUTEX(gpag->hMutexSettings);
|
|
|
|
//
|
|
// set all supported formats to 'not supported'
|
|
//
|
|
for (i = gpag->cWaveInDevs; i; i--)
|
|
pzpf[iaPCMFormats].uFlagsInput[i-1] = 0;
|
|
for (i = gpag->cWaveOutDevs; i; i--)
|
|
pzpf[iaPCMFormats].uFlagsOutput[i-1] = 0;
|
|
|
|
//
|
|
// we need to try 4 different format types:
|
|
// Mono 8 Bit
|
|
// Stereo 8 Bit
|
|
// Mono 16 Bit
|
|
// Stereo 16 Bit
|
|
//
|
|
for (u = 0; u < 4; u++)
|
|
{
|
|
//
|
|
// set the stuff that is constant for all 4 formats
|
|
//
|
|
uSamplesPerSec = pzpf[iaPCMFormats].uSamplesPerSec;
|
|
|
|
wfPCM.wf.wFormatTag = WAVE_FORMAT_PCM;
|
|
wfPCM.wf.nSamplesPerSec = uSamplesPerSec;
|
|
|
|
switch (u)
|
|
{
|
|
case 0:
|
|
wfPCM.wf.nChannels = 1;
|
|
wfPCM.wf.nAvgBytesPerSec= uSamplesPerSec;
|
|
wfPCM.wf.nBlockAlign = 1;
|
|
wfPCM.wBitsPerSample = 8;
|
|
break;
|
|
|
|
case 1:
|
|
wfPCM.wf.nChannels = 2;
|
|
wfPCM.wf.nAvgBytesPerSec= uSamplesPerSec * 2;
|
|
wfPCM.wf.nBlockAlign = 2;
|
|
wfPCM.wBitsPerSample = 8;
|
|
break;
|
|
|
|
case 2:
|
|
wfPCM.wf.nChannels = 1;
|
|
wfPCM.wf.nAvgBytesPerSec= uSamplesPerSec * 2;
|
|
wfPCM.wf.nBlockAlign = 2;
|
|
wfPCM.wBitsPerSample = 16;
|
|
break;
|
|
|
|
case 3:
|
|
wfPCM.wf.nChannels = 2;
|
|
wfPCM.wf.nAvgBytesPerSec= uSamplesPerSec * 4;
|
|
wfPCM.wf.nBlockAlign = 4;
|
|
wfPCM.wBitsPerSample = 16;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// first query ALL ENABLED INPUT devices for the wfPCM format
|
|
//
|
|
if (gpag->pSettings->fPreferredOnly &&
|
|
(gpag->pSettings->uIdPreferredIn != -1))
|
|
{
|
|
i = gpag->pSettings->uIdPreferredIn;
|
|
n = gpag->pSettings->uIdPreferredIn + 1;
|
|
}
|
|
else
|
|
{
|
|
i = 0;
|
|
n = gpag->cWaveInDevs;
|
|
}
|
|
|
|
for (; i < n; i++)
|
|
{
|
|
#ifndef _WIN32
|
|
if (!waveInOpen(NULL, i, (LPWAVEFORMAT)&wfPCM, 0L, 0L, WFQFLAGS))
|
|
#else
|
|
if (!waveInOpen(NULL, i, (LPWAVEFORMATEX)&wfPCM, 0L, 0L, WFQFLAGS))
|
|
#endif
|
|
{
|
|
pzpf[iaPCMFormats].uFlagsInput[i] |= (ZYZPCMF_IN_M08 << u);
|
|
}
|
|
}
|
|
|
|
//
|
|
// now query ALL ENABLED OUTPUT devices for the wfPCM format
|
|
//
|
|
if (gpag->pSettings->fPreferredOnly &&
|
|
(gpag->pSettings->uIdPreferredOut != -1))
|
|
{
|
|
i = gpag->pSettings->uIdPreferredOut;
|
|
n = gpag->pSettings->uIdPreferredOut + 1;
|
|
}
|
|
else
|
|
{
|
|
i = 0;
|
|
n = gpag->cWaveOutDevs;
|
|
}
|
|
|
|
for (; i < n; i++)
|
|
{
|
|
#ifndef _WIN32
|
|
if (!waveOutOpen(NULL, i, (LPWAVEFORMAT)&wfPCM, 0L, 0L, WFQFLAGS))
|
|
#else
|
|
if (!waveOutOpen(NULL, i, (LPWAVEFORMATEX)&wfPCM, 0L, 0L, WFQFLAGS))
|
|
#endif
|
|
{
|
|
pzpf[iaPCMFormats].uFlagsOutput[i] |= (ZYZPCMF_OUT_M08 << u);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// finally return
|
|
//
|
|
#if 0 // def DEBUG
|
|
DPF(3, "PCM Support: %uHz, In[%d]=%04xh, Out[%d]=%04xh",
|
|
pzpf[iaPCMFormats].uSamplesPerSec,
|
|
iaPCMFormats,
|
|
*pzpf[iaPCMFormats].uFlagsInput,
|
|
iaPCMFormats,
|
|
*pzpf[iaPCMFormats].uFlagsOutput);
|
|
#endif
|
|
|
|
RELEASE_MUTEX(gpag->hMutexSettings);
|
|
|
|
return;
|
|
} // GetPCMSupportFlags()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL GetWaveFormats
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// PZYZPCMFORMAT pzpf:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
// History:
|
|
// 06/14/93 cjp [curtisp]
|
|
// 03/13/94 fdy [frankye]
|
|
// Expanded the ZYZPCMFORMAT structure to include flags which
|
|
// indicate which wave device supports a given format. This
|
|
// function will now set these flags. Note that
|
|
// the code that is #if 0'd WILL NOT WORK given these changes, so
|
|
// if anybody ever resuscitates that code, you better modify it!
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNGLOBAL GetWaveFormats
|
|
(
|
|
PZYZPCMFORMAT pzpf
|
|
)
|
|
{
|
|
UINT u;
|
|
|
|
#if 0
|
|
WAVEOUTCAPS woc;
|
|
WAVEINCAPS wic;
|
|
UINT n;
|
|
DWORD dwInFormats;
|
|
DWORD dwOutFormats;
|
|
|
|
//
|
|
// first things first: get all 'standard' supported formats from the
|
|
// current selected devices for input and output...
|
|
//
|
|
dwInFormats = 0L;
|
|
if (gpag->fPreferredOnly && (gpag->uIdPreferredIn != -1))
|
|
{
|
|
if (!waveInGetDevCaps(gpag->uIdPreferredIn, &wic, sizeof(wic)))
|
|
dwInFormats = wic.dwFormats;
|
|
}
|
|
else
|
|
{
|
|
n = gpag->cWaveInDevs;
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
if (!waveInGetDevCaps(i, &wic, sizeof(wic)))
|
|
dwInFormats |= wic.dwFormats;
|
|
}
|
|
}
|
|
|
|
dwOutFormats = 0L;
|
|
if (gpag->fPreferredOnly && (gpag->uIdPreferredOut != -1))
|
|
{
|
|
if (!waveOutGetDevCaps(gpag->uIdPreferredOut, &woc, sizeof(woc)))
|
|
dwOutFormats = woc.dwFormats;
|
|
}
|
|
else
|
|
{
|
|
n = gpag->cWaveOutDevs;
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
if (!waveOutGetDevCaps(i, &woc, sizeof(woc)))
|
|
dwOutFormats |= woc.dwFormats;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//
|
|
// now step through each sample rate in the pzpf structure and set all
|
|
// the appropriate bits for whether it is supported, etc..
|
|
//
|
|
for (u = 0; pzpf[u].uSamplesPerSec; u++)
|
|
{
|
|
//
|
|
// we need to special case a few of the sample rates, etc to get
|
|
// this whole thing working--once the grunt work is done here
|
|
// (and only once during initialization), then the data is easily
|
|
// accessible/used...
|
|
//
|
|
|
|
switch (pzpf[u].uSamplesPerSec)
|
|
{
|
|
//
|
|
// NOTE! it would be nice if we could rely on the caps
|
|
// structure being correct on drivers.... but alas, Media Vision
|
|
// found a way to mess that up also (on some of their hundreds
|
|
// of releases of their drivers). so ALWAYS query for the
|
|
// format support.
|
|
//
|
|
// by the way, the reason they ship their drivers with this
|
|
// bug (and possibly other OEM's) is due to Sound Recorder
|
|
// (apparently their only test app?!?) only doing queries
|
|
// and never looking at the caps bits.
|
|
//
|
|
#if 0
|
|
case 11025:
|
|
pzpf[u].uFlags = (WORD)(dwInFormats & WAVE_FORMAT_11k) << 8;
|
|
pzpf[u].uFlags |= (WORD)(dwOutFormats & WAVE_FORMAT_11k);
|
|
break;
|
|
|
|
case 22050:
|
|
pzpf[u].uFlags =
|
|
(WORD)(dwInFormats & WAVE_FORMAT_22k) >> 4 << 8;
|
|
pzpf[u].uFlags |= (WORD)(dwOutFormats & WAVE_FORMAT_22k) >> 4;
|
|
break;
|
|
|
|
case 44100:
|
|
pzpf[u].uFlags =
|
|
(WORD)(dwInFormats & WAVE_FORMAT_44k) >> 8 << 8;
|
|
pzpf[u].uFlags |= (WORD)(dwOutFormats & WAVE_FORMAT_44k) >> 8;
|
|
break;
|
|
#else
|
|
case 11025:
|
|
case 22050:
|
|
case 44100:
|
|
#endif
|
|
case 5510:
|
|
case 6620:
|
|
case 8000:
|
|
case 9600:
|
|
case 16000:
|
|
case 18900:
|
|
case 27420:
|
|
case 32000:
|
|
case 33075:
|
|
case 37800:
|
|
case 48000:
|
|
GetPCMSupportFlags(pzpf, u);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// reset these--they are auto determined while the mapper is being
|
|
// used...
|
|
//
|
|
|
|
WAIT_FOR_MUTEX(gpag->hMutexSettings);
|
|
|
|
gpag->pSettings->fSyncOnlyOut = FALSE;
|
|
gpag->pSettings->fSyncOnlyIn = FALSE;
|
|
|
|
RELEASE_MUTEX(gpag->hMutexSettings);
|
|
|
|
return (TRUE);
|
|
} // GetWaveFormats()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL mapSettingsRestore
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
// History:
|
|
// 06/14/93 cjp [curtisp]
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNGLOBAL mapSettingsRestore
|
|
(
|
|
void
|
|
)
|
|
{
|
|
DWORD dwFlags;
|
|
UINT ii;
|
|
DWORD cbSize;
|
|
PUINT pFlags;
|
|
|
|
DPF(1, "mapSettingsRestore:");
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
gpag->cWaveOutDevs = waveOutGetNumDevs();
|
|
gpag->cWaveInDevs = waveInGetNumDevs();
|
|
|
|
// Number of devices per sampling rate...
|
|
cbSize = gpag->cWaveOutDevs + gpag->cWaveInDevs;
|
|
|
|
// Number of total flags...
|
|
// cbSize *= (sizeof(gaPCMFormats)/sizeof(gaPCMFormats[0]));
|
|
cbSize *= 15; // It's fifteen; Trust Me - Fwong.
|
|
|
|
// Size in bytes...
|
|
cbSize *= sizeof(UINT);
|
|
|
|
pFlags = (PUINT)GlobalAllocPtr(GHND, cbSize);
|
|
|
|
if (NULL == pFlags)
|
|
{
|
|
//
|
|
// Hmm... How do we cope.
|
|
//
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
ZeroMemory(pFlags, cbSize);
|
|
|
|
if (NULL != gaPCMFormats[0].uFlagsInput)
|
|
{
|
|
GlobalFreePtr(gaPCMFormats[0].uFlagsInput);
|
|
}
|
|
|
|
for (ii = 0; ;ii++)
|
|
{
|
|
if (0 == gaPCMFormats[ii].uSamplesPerSec)
|
|
{
|
|
break;
|
|
}
|
|
|
|
gaPCMFormats[ii].uFlagsInput = pFlags;
|
|
pFlags += gpag->cWaveInDevs;
|
|
|
|
gaPCMFormats[ii].uFlagsOutput = pFlags;
|
|
pFlags += gpag->cWaveOutDevs;
|
|
}
|
|
|
|
WAIT_FOR_MUTEX(gpag->hMutexSettings);
|
|
|
|
// gpag->fPrestoSyncAsync = (BOOL)IRegReadDwordDefault( hkeyMapper, gszKeyPrestoSyncAsync, 0 );
|
|
gpag->fPrestoSyncAsync = FALSE;
|
|
|
|
|
|
//
|
|
// find the waveOut device that is selected as preferred
|
|
//
|
|
if (!waveOutMessage((HWAVEOUT)LongToHandle(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&gpag->pSettings->uIdPreferredOut, (DWORD_PTR)&dwFlags)) {
|
|
gpag->pSettings->fPreferredOnly = (0 != (DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY));
|
|
} else {
|
|
gpag->pSettings->uIdPreferredOut = (UINT)(-1);
|
|
gpag->pSettings->fPreferredOnly = TRUE;
|
|
}
|
|
|
|
//
|
|
// find the waveIn device that is selected as preferred
|
|
//
|
|
if (!waveInMessage((HWAVEIN)LongToHandle(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&gpag->pSettings->uIdPreferredIn, (DWORD_PTR)&dwFlags)) {
|
|
gpag->pSettings->fPreferredOnly = (0 != (DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY));
|
|
} else {
|
|
gpag->pSettings->uIdPreferredOut = (UINT)(-1);
|
|
gpag->pSettings->fPreferredOnly = TRUE;
|
|
}
|
|
|
|
//
|
|
// reread/cache all the PCM format info from the devices selected, etc.
|
|
//
|
|
GetWaveFormats(gaPCMFormats);
|
|
|
|
RELEASE_MUTEX(gpag->hMutexSettings);
|
|
|
|
return (TRUE);
|
|
} // mapSettingsRestore()
|
|
|
|
|
|
//==========================================================================;
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//==========================================================================;
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// LRESULT mapDriverEnable
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HDRVR hdrvr:
|
|
//
|
|
// Return (LRESULT):
|
|
//
|
|
// History:
|
|
// 09/18/93 cjp [curtisp]
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
LRESULT FNGLOBAL mapDriverEnable
|
|
(
|
|
HDRVR hdrvr
|
|
)
|
|
{
|
|
#ifdef USE_ACMTHUNK
|
|
BOOL f;
|
|
#endif
|
|
DWORD dw;
|
|
|
|
DPF(1, "mapDriverEnable(hdrvr=%.04Xh)", hdrvr);
|
|
|
|
|
|
#ifdef USE_ACMTHUNK
|
|
f = acmThunkInitialize();
|
|
if (!f)
|
|
{
|
|
DPF(0, "!ACM thunk cannot be initialized!");
|
|
return (0L);
|
|
}
|
|
#endif
|
|
|
|
dw = acmGetVersion();
|
|
if (VERSION_MSACMMAP > HIWORD(dw))
|
|
{
|
|
DPF(0, "!requires version %u.%.02u of the ACM!",
|
|
VERSION_MSACMMAP_MAJOR, VERSION_MSACMMAP_MINOR);
|
|
|
|
#ifdef USE_ACMTHUNK
|
|
acmThunkTerminate();
|
|
#endif
|
|
|
|
return (0L);
|
|
}
|
|
|
|
mapSettingsRestore();
|
|
gpag->fEnabled = TRUE;
|
|
|
|
//
|
|
// the return value is ignored, but return non-zero anyway
|
|
//
|
|
return (1L);
|
|
} // mapDriverEnable()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// LRESULT mapDriverDisable
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HDRVR hdrvr:
|
|
//
|
|
// Return (LRESULT):
|
|
//
|
|
// History:
|
|
// 09/18/93 cjp [curtisp]
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
LRESULT FNGLOBAL mapDriverDisable
|
|
(
|
|
HDRVR hdrvr
|
|
)
|
|
{
|
|
DPF(1, "mapDriverDisable(hdrvr=%.04Xh)", hdrvr);
|
|
|
|
if (gpag->fEnabled)
|
|
{
|
|
gpag->fEnabled = FALSE;
|
|
}
|
|
|
|
#ifdef USE_ACMTHUNK
|
|
acmThunkTerminate();
|
|
#endif
|
|
|
|
//
|
|
// the return value is ignored, but return non-zero anyway
|
|
//
|
|
return (1L);
|
|
} // mapDriverDisable()
|
|
|
|
|
|
//==========================================================================;
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//==========================================================================;
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// LRESULT mapDriverInstall
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HDRVR hdrvr:
|
|
//
|
|
// Return (LRESULT):
|
|
//
|
|
// History:
|
|
// 09/25/93 cjp [curtisp]
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
LRESULT FNGLOBAL mapDriverInstall
|
|
(
|
|
HDRVR hdrvr
|
|
)
|
|
{
|
|
DPF(1, "mapDriverInstall(hdrvr=%.04Xh)", hdrvr);
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
return (DRVCNF_RESTART);
|
|
} // mapDriverInstall()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// LRESULT mapDriverRemove
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HDRVR hdrvr:
|
|
//
|
|
// Return (LRESULT):
|
|
//
|
|
// History:
|
|
// 09/25/93 cjp [curtisp]
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
LRESULT FNGLOBAL mapDriverRemove
|
|
(
|
|
HDRVR hdrvr
|
|
)
|
|
{
|
|
DPF(1, "mapDriverRemove(hdrvr=%.04Xh)", hdrvr);
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
return (DRVCNF_RESTART);
|
|
} // mapDriverRemove()
|
|
|
|
|
|
//==========================================================================;
|
|
//
|
|
// WIN 16 SPECIFIC SUPPORT
|
|
//
|
|
//==========================================================================;
|
|
|
|
#ifndef WIN32
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// int WEP
|
|
//
|
|
// Description:
|
|
// The infamous useless WEP(). Note that this procedure needs to be
|
|
// in a FIXED segment under Windows 3.0. Under Windows 3.1 this is
|
|
// not necessary.
|
|
//
|
|
// Arguments:
|
|
// WORD wUseless: Should tell whether Windows is exiting or not.
|
|
//
|
|
// Return (int):
|
|
// Always return non-zero.
|
|
//
|
|
// History:
|
|
// 04/29/93 cjp [curtisp]
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
EXTERN_C int FNEXPORT WEP
|
|
(
|
|
WORD wUseless
|
|
)
|
|
{
|
|
DPF(1, "WEP(wUseless=%u)", wUseless);
|
|
|
|
//
|
|
// always return non-zero
|
|
//
|
|
return (1);
|
|
} // WEP()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// int LibMain
|
|
//
|
|
// Description:
|
|
// Library initialization code.
|
|
//
|
|
// This routine must guarantee the following things so CODEC's don't
|
|
// have to special case code everywhere:
|
|
//
|
|
// o will only run in Windows 3.10 or greater (our exehdr is
|
|
// marked appropriately).
|
|
//
|
|
// o will only run on >= 386 processor. only need to check
|
|
// on Win 3.1.
|
|
//
|
|
// Arguments:
|
|
// HINSTANCE hinst: Our module instance handle.
|
|
//
|
|
// WORD wDataSeg: Our data segment selector.
|
|
//
|
|
// WORD cbHeapSize: The heap size from the .def file.
|
|
//
|
|
// LPSTR pszCmdLine: The command line.
|
|
//
|
|
// Return (int):
|
|
// Returns non-zero if the initialization was successful and 0 otherwise.
|
|
//
|
|
// History:
|
|
// 11/15/92 cjp [curtisp]
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
int FNGLOBAL LibMain
|
|
(
|
|
HINSTANCE hinst,
|
|
WORD wDataSeg,
|
|
WORD cbHeapSize,
|
|
LPSTR pszCmdLine
|
|
)
|
|
{
|
|
//
|
|
// we ONLY work on >= 386. if we are on a wimpy processor, scream in
|
|
// pain and die a horrible death!
|
|
//
|
|
// NOTE! do this check first thing and get out if on a 286. we are
|
|
// compiling with -G3 and C8's libentry garbage does not check for
|
|
// >= 386 processor. the following code does not execute any 386
|
|
// instructions (not complex enough)..
|
|
//
|
|
#if (WINVER < 0x0400)
|
|
if (GetWinFlags() & WF_CPU286)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
#endif
|
|
|
|
DbgInitialize(TRUE);
|
|
|
|
DPF(1, "LibMain(hinst=%.4Xh, wDataSeg=%.4Xh, cbHeapSize=%u, pszCmdLine=%.8lXh)",
|
|
hinst, wDataSeg, cbHeapSize, pszCmdLine);
|
|
|
|
DPF(5, "!*** break for debugging ***");
|
|
|
|
|
|
//
|
|
// everything looks good to go in Win 16 land.
|
|
//
|
|
gpag = &acmgarb;
|
|
gpag->hinst = hinst;
|
|
|
|
// Note: in Win16 there's only one instance of the mapper
|
|
gpag->pSettings = &(acmglobalinfo);
|
|
|
|
return (TRUE);
|
|
} // LibMain()
|
|
|
|
#else // WIN32
|
|
|
|
//==========================================================================;
|
|
//
|
|
// WIN 32 SPECIFIC SUPPORT
|
|
//
|
|
//==========================================================================;
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// PACMGLOBALINFO mapAllocateGlobalInfo
|
|
//
|
|
// Description:
|
|
// Either creates the common buffer among all instances of the mapper
|
|
// or it finds the common buffer.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return (PACMGLOBALINFO):
|
|
// Returns a pointer to global info structure.
|
|
//
|
|
// History:
|
|
// 01/21/98 Fwong Adding multi-instance support.
|
|
// 01/24/99 FrankYe Back to simple single process support, since
|
|
// since winmm has been modified to hold the
|
|
// preferred device settings.
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
PACMGLOBALINFO mapAllocateGlobalInfo
|
|
(
|
|
void
|
|
)
|
|
{
|
|
// We could actually use a critical section instead of a mutex here.
|
|
gpag->hMutexSettings = CreateMutex(NULL, FALSE, NULL);
|
|
return &(acmglobalinfo);
|
|
} // mapAllocateGlobalInfo()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// void mapFreeGlobalInfo
|
|
//
|
|
// Description:
|
|
// Cleans up the objects associated with the global memory buffer.
|
|
//
|
|
// Arguments:
|
|
// PACMGLOBALINFO pagi: Base buffer for global info.
|
|
//
|
|
// Return (void):
|
|
//
|
|
// History:
|
|
// 01/21/98 Fwong Adding multi-instance support.
|
|
// 01/24/99 FrankYe Back to simple single process support, since
|
|
// since winmm has been modified to hold the
|
|
// preferred device settings.
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
void mapFreeGlobalInfo
|
|
(
|
|
PACMGLOBALINFO pagi
|
|
)
|
|
{
|
|
if(NULL != gpag->hMutexSettings) CloseHandle(gpag->hMutexSettings);
|
|
} // mapFreeGlobalInfo()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL DllEntryPoint
|
|
//
|
|
// Description:
|
|
// This is the standard DLL entry point for Win 32.
|
|
//
|
|
// Arguments:
|
|
// HINSTANCE hinst: Our instance handle.
|
|
//
|
|
// DWORD dwReason: The reason we've been called--process/thread attach
|
|
// and detach.
|
|
//
|
|
// LPVOID lpReserved: Reserved. Should be NULL--so ignore it.
|
|
//
|
|
// Return (BOOL):
|
|
// Returns non-zero if the initialization was successful and 0 otherwise.
|
|
//
|
|
// History:
|
|
// 11/15/92 cjp [curtisp]
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNEXPORT DllEntryPoint
|
|
(
|
|
HINSTANCE hinst,
|
|
DWORD dwReason,
|
|
LPVOID lpReserved
|
|
)
|
|
{
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
DbgInitialize(TRUE);
|
|
|
|
gpag = &acmgarb;
|
|
gpag->hinst = hinst;
|
|
gpag->pSettings = mapAllocateGlobalInfo();
|
|
|
|
DisableThreadLibraryCalls(hinst);
|
|
|
|
DPF(1, "DllEntryPoint(hinst=%.08lXh, DLL_PROCESS_ATTACH)", hinst);
|
|
return (TRUE);
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
mapFreeGlobalInfo(gpag->pSettings);
|
|
|
|
DPF(1, "DllEntryPoint(hinst=%.08lXh, DLL_PROCESS_DETACH)", hinst);
|
|
return (TRUE);
|
|
}
|
|
|
|
return (TRUE);
|
|
} // DllEntryPoint()
|
|
|
|
#endif
|