📄 mixdrv.cpp
字号:
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
mixdrv.cpp
Abstract:
Implements the WinCE audio mixer device driver entry points
Both the mixer device and the wave audio device use the same hardware
Therefore the two logical devices were combined
into a single module that exposes both the mixer device interface (proprietary
at this moment) and the wave interface (fairly well documented and public on MSDN)
Environment:
Win CE 2.11
Revision History:
4/20/1999 Initial Version
3/22/2000 Inclusion in this driver, some small changes
--*/
#include "includes.h"
#include <mmsystem.h>
#include <mmddk.h>
#include <wavedev.h>
#include "mixdrv.h"
#include "globals.h"
#include "mixfunc.h"
PDRIVER_CONTEXT g_pDriverContext = NULL;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
MIX_Init
Description:
Arguments:
DWORD regKeyPath :
Return Value: DWORD
-------------------------------------------------------------------*/
DWORD MIX_Init( DWORD regKeyPath )
{
MIXMSG1("+MIX_Init: '%s'", (TCHAR*)regKeyPath);
if (!g_pDriverContext)
{ // we did not yet initialize anything;
g_pDriverContext = (PDRIVER_CONTEXT)LocalAlloc(0, sizeof(DRIVER_CONTEXT));
if (!g_pDriverContext)
{
MIXERRMSG("Error allocating g_pDriverContext");
return ERROR_NOT_ENOUGH_MEMORY;
}
g_pDriverContext->bMixerInitialized = FALSE;
}
if (g_pDriverContext->bMixerInitialized)
{
// somebody tries to INIT us again! That shouldn't happen, so
// we ASSERT (to help debugging), but accept anyway
MIXERRMSG("-MIX_Init: Already initialized");
ASSERT(FALSE);
return (DWORD)g_pDriverContext;
}
g_pDriverContext->bMixerInitialized = TRUE;
g_pDriverContext->pMixerContextList = NULL; // init to zero, gets another value on open
InitializeCriticalSection( &g_pDriverContext->mixCritSec );
mix_InitMixer(g_pDriverContext);
MIXMSG1("-MIX_Init: success 0x%8.8X", (DWORD)g_pDriverContext);
return (DWORD)g_pDriverContext; // success at this point;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
MIX_Deinit
Description:
Arguments:
DWORD devctx :
Return Value: BOOL
-------------------------------------------------------------------*/
BOOL MIX_Deinit( DWORD devctx )
{
BOOL result;
MIXMSG1("+MIX_Deinit: 0x%08x", devctx);
if (devctx == 0) // initialization failed; get out
return TRUE;
if( devctx == (DWORD)g_pDriverContext)
{
result = TRUE; // success = TRUE
DeleteCriticalSection( &g_pDriverContext->mixCritSec );
if( g_pDriverContext )
{
PMIXER_CONTEXT pNext, pMix = g_pDriverContext->pMixerContextList;
g_pDriverContext->bMixerInitialized = FALSE;
ASSERT(NULL == pMix); // all devices should have been closed before here
while (pMix)
{
pNext = pMix->pNext;
LocalFree(pMix);
pMix = pNext;
}
LocalFree(g_pDriverContext);
g_pDriverContext = NULL;
}
}
else
{
result = FALSE;
SetLastError( ERROR_INVALID_HANDLE );
MIXERRMSG1("Invalid Open Handle: 0x%08x", devctx);
}
MIXMSG1("-MIX_Deinit: %d", result);
return result;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
MIX_PowerDown
Description:
Arguments:
DWORD devctx :
Return Value: void
-------------------------------------------------------------------*/
void MIX_PowerDown( DWORD devctx )
{
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
MIX_PowerUp
Description:
Arguments:
DWORD devctx :
Return Value: void
-------------------------------------------------------------------*/
void MIX_PowerUp( DWORD devctx )
{
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
MIX_Open
Description:
Arguments:
DWORD devctx :
DWORD access :
DWORD share :
Return Value: DWORD
-------------------------------------------------------------------*/
DWORD MIX_Open( DWORD devctx, DWORD access, DWORD share )
{
PMIXER_CONTEXT pNewMixer;
MIXMSG1("+MIX_Open: 0x%08x", devctx);
if (devctx == 0) // opening the device failed; return failure to DEVICE.EXE
return 0;
EnterCriticalSection( &g_pDriverContext->mixCritSec );
if( devctx == (DWORD)g_pDriverContext )
{
pNewMixer = (PMIXER_CONTEXT)LocalAlloc(LPTR, sizeof(MIXER_CONTEXT));
if (!pNewMixer)
{
SetLastError( ERROR_OUTOFMEMORY );
}
else
{ // add new mixer to the driver list
pNewMixer->pNext = g_pDriverContext->pMixerContextList;
g_pDriverContext->pMixerContextList = pNewMixer;
}
}
else
{
MIXERRMSG1("MIX_Open: bad Device Handle 0x%08x", devctx) ;
SetLastError( ERROR_INVALID_HANDLE );
pNewMixer = NULL;
}
LeaveCriticalSection( &g_pDriverContext->mixCritSec );
MIXMSG1("-MIX_Open: 0x%08x", pNewMixer) ;
return (DWORD)pNewMixer;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
MIX_Close
Description:
Arguments:
DWORD openctx :
Return Value: BOOL
-------------------------------------------------------------------*/
BOOL MIX_Close( DWORD openctx )
{
BOOL retval;
MIXMSG1("+MIX_Close: 0x%08x", openctx);
retval = mix_FreeMixer((PMIXER_CONTEXT)openctx);
MIXMSG1("-MIX_Close: %d", retval);
return retval;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
MIX_Read
Description:
Arguments:
DWORD openctx :
void *pBuf :
DWORD len :
Return Value: DWORD
-------------------------------------------------------------------*/
DWORD MIX_Read( DWORD openctx, void *pBuf, DWORD len )
{
MIXMSG3("+MIX_Read: 0x%08x, 0x%08x, %d", openctx, pBuf, len);
return (DWORD)-1;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
MIX_Seek
Description:
Arguments:
DWORD openctx :
long int pos :
DWORD type :
Return Value: DWORD
-------------------------------------------------------------------*/
DWORD MIX_Seek( DWORD openctx, long int pos, DWORD type )
{
MIXERRMSG1("MIX does not seek: 0x%08x", openctx);
return (DWORD)-1; // not implemented, -1 indicates error
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
MIX_Write
Description:
Arguments:
DWORD openctx :
void *pBuf :
DWORD len :
Return Value: DWORD
-------------------------------------------------------------------*/
DWORD MIX_Write( DWORD openctx, void *pBuf, DWORD len )
{
MIXERRMSG1("MIX_Write: MIXTS is read-only: 0x%08x", openctx);
return (DWORD)-1; // read-only driver, -1 indicates error
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:
MIX_IOControl
Description:
Handles the calls sent through DevicerIoControl. That's the function that
communicates with mixapi.lib and does the actual work
Arguments:
DWORD dwOpenData : the pointer to the mixer context that the driver returned in MIX_Open
DWORD dwCode : must be IOCTL_MIX_MESSAGE
BYTE *pBufIn : pointer to a PMMDRV_MESSAGE_PARAMS that stores the description of the desired action
DWORD dwLenIn : must be sizeof(MMDRV_MESSAGE_PARAMS)
BYTE *pBufOut : stores the return code (DWORD)
DWORD dwLenOut : if pBufOut is not NULL, that should be at least sizeof(DWORD)
DWORD *pdwActualOut : if pBufOut is not NULL and pdwActualOut is not NULL,
that will return sizeof(DWORD)
Return Value: BOOL
-------------------------------------------------------------------*/
BOOL MIX_IOControl(
DWORD dwOpenData,
DWORD dwCode,
BYTE *pBufIn,
DWORD dwLenIn,
BYTE *pBufOut,
DWORD dwLenOut,
DWORD *pdwActualOut )
{
DWORD dwRet;
PMMDRV_MESSAGE_PARAMS pParams = (PMMDRV_MESSAGE_PARAMS) pBufIn;
PDRIVER_CONTEXT pDriverContext = g_pDriverContext;
PMIXER_CONTEXT pMixer = (PMIXER_CONTEXT)dwOpenData;
MIXMSG("+MIX_IOControl");
#if 0
HEXPARAM(dwOpenData);
HEXPARAM(dwCode);
HEXPARAM(pBufIn);
HEXPARAM(dwLenIn);
HEXPARAM(pBufOut);
HEXPARAM(dwLenOut);
HEXPARAM(pdwActualOut);
#endif
ASSERT(pDriverContext);
// set the error code to be no error first
SetLastError(ERROR_SUCCESS);
if( pdwActualOut != NULL )
*pdwActualOut = 0L;
if(NULL == pMixer)
{
MIXERRMSG("MIX_IOControl bad hOpen");
SetLastError( ERROR_INVALID_HANDLE );
dwRet = MMSYSERR_INVALHANDLE;
goto end;
}
if (dwCode != IOCTL_MIX_MESSAGE)
{
MIXERRMSG("Bad parameters in MIX_IOControl()");
SetLastError(ERROR_INVALID_PARAMETER);
dwRet = MMSYSERR_INVALPARAM;
goto end;
}
if(pParams->uDeviceId >= MAX_SUPPORTED_INSTANCES)
{
MIXERRMSG("Bad device ID in MIX_IOControl()");
SetLastError(ERROR_BAD_DEVICE);
dwRet = MMSYSERR_BADDEVICEID;
goto end;
}
if (pBufOut != NULL && dwLenOut < sizeof(DWORD))
{
MIXERRMSG("Bad return buffer in MIX_IOControl()");
SetLastError(ERROR_INSUFFICIENT_BUFFER);
dwRet = MMSYSERR_INVALPARAM;
goto end;
}
LockMixerList();
__try
{
switch (pParams->uMsg)
{
case MXDM_GETNUMDEVS:
MIXMSG("MXDM_GETNUMDEVS");
dwRet = mix_handle_GETNUMDEVS(pMixer, pParams->dwUser, pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_GETDEVCAPS:
MIXMSG("MXDM_GETDEVCAPS");
dwRet = mix_handle_GETDEVCAPS(pMixer, pParams->dwUser, pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_OPEN:
MIXMSG("MXDM_OPEN");
dwRet = mix_handle_OPEN(pMixer, &(pParams->dwUser), pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_CLOSE:
MIXMSG("MXDM_CLOSE");
dwRet = mix_handle_CLOSE(pMixer, pParams->dwUser, pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_GETLINEINFO:
MIXMSG("MXDM_GETLINEINFO");
dwRet = mix_handle_GETLINEINFO(pMixer, pParams->dwUser, pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_GETLINECONTROLS:
MIXMSG("MXDM_GETLINECONTROLS");
dwRet = mix_handle_GETLINECONTROLS(pMixer, pParams->dwUser, pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_GETCONTROLDETAILS:
MIXMSG("MXDM_GETCONTROLDETAILS");
dwRet = mix_handle_GETCONTROLDETAILS(pMixer, pParams->dwUser, pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_SETCONTROLDETAILS:
MIXMSG("MXDM_SETCONTROLDETAILS");
dwRet = mix_handle_SETCONTROLDETAILS(pMixer, pParams->dwUser, pParams->dwParam1, pParams->dwParam2);
break;
case MXDM_INIT:
MIXMSG("MXDM_INIT");
dwRet = MMSYSERR_NOERROR;
break;
default:
MIXERRMSG1("Bad code in MIX_IOControl %d", pParams->uMsg);
dwRet = MMSYSERR_NOTSUPPORTED;
break;
}
}
__except (GetExceptionCode() == STATUS_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
MIXERRMSG("EXCEPTION IN MIX_IOControl!!!!");
SetLastError(ERROR_GEN_FAILURE);
dwRet = MMSYSERR_ERROR;
}
UnlockMixerList();
end:
//
// Pass the return code back via pBufOut
//
if (pBufOut != NULL)
{
*((DWORD*) pBufOut) = dwRet;
if (pdwActualOut)
*pdwActualOut = sizeof(dwRet);
}
MIXMSG1("-MIX_IOControl, dwRet = 0x%8.8x", dwRet);
return MMSYSERR_NOERROR == dwRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -