⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mixdrv.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 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 + -