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

📄 mmsystem.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- tab-width: 8; c-basic-offset: 4 -*- */

/*
 * MMSYTEM functions
 *
 * Copyright 1993      Martin Ayotte
 *           1998-2003 Eric Pouech
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * Eric POUECH :
 *  	99/4	added mmTask and mmThread functions support
 */

#include <stdarg.h>
#include <string.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "mmsystem.h"
#include "winreg.h"
#include "ntstatus.h"
#include "winternl.h"
#include "wownt32.h"
#include "winnls.h"

#include "wine/winuser16.h"
#include "winemm16.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(mmsys);

static WINE_MMTHREAD*   WINMM_GetmmThread(HANDLE16);
static LPWINE_DRIVER    DRIVER_OpenDriver16(LPCWSTR, LPCWSTR, LPARAM);
static LRESULT          DRIVER_CloseDriver16(HDRVR16, LPARAM, LPARAM);
static LRESULT          DRIVER_SendMessage16(HDRVR16, UINT, LPARAM, LPARAM);
static LRESULT          MMIO_Callback16(SEGPTR, LPMMIOINFO, UINT, LPARAM, LPARAM);

/* ###################################################
 * #                  LIBRARY                        #
 * ###################################################
 */

/**************************************************************************
 * 			DllEntryPoint (MMSYSTEM.4)
 *
 * MMSYSTEM DLL entry point
 *
 */
BOOL WINAPI MMSYSTEM_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
			     WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
{
    TRACE("%p 0x%lx\n", hinstDLL, fdwReason);

    switch (fdwReason) {
    case DLL_PROCESS_ATTACH:
	/* need to load WinMM in order to:
	 * - initiate correctly shared variables (WINMM_Init())
	 */
        if (!GetModuleHandleA("WINMM.DLL"))
        {
            ERR("Could not load sibling WinMM.dll\n");
            return FALSE;
	}
	WINMM_IData.hWinMM16Instance = hinstDLL;
        /* hook in our 16 bit function pointers */
        pFnGetMMThread16    = WINMM_GetmmThread;
        pFnOpenDriver16     = DRIVER_OpenDriver16;
        pFnCloseDriver16    = DRIVER_CloseDriver16;
        pFnSendMessage16    = DRIVER_SendMessage16;
        pFnMmioCallback16   = MMIO_Callback16;
        pFnReleaseThunkLock = ReleaseThunkLock;
        pFnRestoreThunkLock = RestoreThunkLock;
        MMDRV_Init16();
	break;
    case DLL_PROCESS_DETACH:
	WINMM_IData.hWinMM16Instance = 0;
        pFnGetMMThread16    = NULL;
        pFnOpenDriver16     = NULL;
        pFnCloseDriver16    = NULL;
        pFnSendMessage16    = NULL;
        pFnMmioCallback16   = NULL;
        pFnReleaseThunkLock = NULL;
        pFnRestoreThunkLock = NULL;
        /* FIXME: add equivalent for MMDRV_Init16() */
	break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
	break;
    }
    return TRUE;
}

/**************************************************************************
 * 				WEP			[MMSYSTEM.1]
 */
int WINAPI MMSYSTEM_WEP(HINSTANCE16 hInstance, WORD wDataSeg,
                        WORD cbHeapSize, LPSTR lpCmdLine)
{
    TRACE("STUB: Unloading MMSystem DLL ... hInst=%04X \n", hInstance);
    return TRUE;
}

/* ###################################################
 * #                  PlaySound                      #
 * ###################################################
 */

/**************************************************************************
 * 				PlaySound		[MMSYSTEM.3]
 */
BOOL16 WINAPI PlaySound16(LPCSTR pszSound, HMODULE16 hmod, DWORD fdwSound)
{
    BOOL16	retv;
    DWORD	lc;

    if ((fdwSound & SND_RESOURCE) == SND_RESOURCE)
    {
        HGLOBAL16 handle;
        HRSRC16 res;

        if (!(res = FindResource16( hmod, pszSound, "WAVE" ))) return FALSE;
        if (!(handle = LoadResource16( hmod, res ))) return FALSE;
        pszSound = LockResource16(handle);
        fdwSound = (fdwSound & ~SND_RESOURCE) | SND_MEMORY;
        /* FIXME: FreeResource16 */
    }

    ReleaseThunkLock(&lc);
    retv = PlaySoundA(pszSound, 0, fdwSound);
    RestoreThunkLock(lc);

    return retv;
}

/**************************************************************************
 * 				sndPlaySound		[MMSYSTEM.2]
 */
BOOL16 WINAPI sndPlaySound16(LPCSTR lpszSoundName, UINT16 uFlags)
{
    BOOL16	retv;
    DWORD	lc;

    ReleaseThunkLock(&lc);
    retv = sndPlaySoundA(lpszSoundName, uFlags);
    RestoreThunkLock(lc);

    return retv;
}

/* ###################################################
 * #                    MISC                         #
 * ###################################################
 */

/**************************************************************************
 * 				mmsystemGetVersion	[MMSYSTEM.5]
 *
 */
UINT16 WINAPI mmsystemGetVersion16(void)
{
    return mmsystemGetVersion();
}

/**************************************************************************
 * 				DriverCallback			[MMSYSTEM.31]
 */
BOOL16 WINAPI DriverCallback16(DWORD dwCallBack, UINT16 uFlags, HDRVR16 hDev,
			       WORD wMsg, DWORD dwUser, DWORD dwParam1,
			       DWORD dwParam2)
{
    return DriverCallback(dwCallBack, uFlags, HDRVR_32(hDev), wMsg, dwUser, dwParam1, dwParam2);
}

/**************************************************************************
 * 			OutputDebugStr	 	[MMSYSTEM.30]
 */
void WINAPI OutputDebugStr16(LPCSTR str)
{
    OutputDebugStringA( str );
}


/* ###################################################
 * #                    MIXER                        #
 * ###################################################
 */

/**************************************************************************
 * 	Mixer devices. New to Win95
 */

/**************************************************************************
 * 				mixerGetNumDevs			[MMSYSTEM.800]
 */
UINT16 WINAPI mixerGetNumDevs16(void)
{
    return MMDRV_GetNum(MMDRV_MIXER);
}

/**************************************************************************
 * 				mixerGetDevCaps			[MMSYSTEM.801]
 */
UINT16 WINAPI mixerGetDevCaps16(UINT16 uDeviceID, LPMIXERCAPS16 lpCaps,
				UINT16 uSize)
{
    MIXERCAPSA  micA;
    UINT        ret;

    if (lpCaps == NULL)	return MMSYSERR_INVALPARAM;

    ret = mixerGetDevCapsA(uDeviceID, &micA, sizeof(micA));
    if (ret == MMSYSERR_NOERROR) {
	MIXERCAPS16 mic16;
        mic16.wMid           = micA.wMid;
        mic16.wPid           = micA.wPid;
        mic16.vDriverVersion = micA.vDriverVersion;
        strcpy(mic16.szPname, micA.szPname);
        mic16.fdwSupport     = micA.fdwSupport;
        mic16.cDestinations  = micA.cDestinations;
	memcpy(lpCaps, &mic16, min(uSize, sizeof(mic16)));
    }
    return ret;
}

/**************************************************************************
 * 				mixerOpen			[MMSYSTEM.802]
 */
UINT16 WINAPI mixerOpen16(LPHMIXER16 lphmix, UINT16 uDeviceID, DWORD dwCallback,
			  DWORD dwInstance, DWORD fdwOpen)
{
    HMIXER	hmix;
    UINT	ret;

    ret = MIXER_Open(&hmix, uDeviceID, dwCallback, dwInstance, fdwOpen, FALSE);
    if (lphmix) *lphmix = HMIXER_16(hmix);
    return ret;
}

/**************************************************************************
 * 				mixerClose			[MMSYSTEM.803]
 */
UINT16 WINAPI mixerClose16(HMIXER16 hMix)
{
    return mixerClose(HMIXER_32(hMix));
}

/**************************************************************************
 * 				mixerGetID (MMSYSTEM.806)
 */
UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix, LPUINT16 lpid, DWORD fdwID)
{
    UINT	xid;
    UINT	ret = mixerGetID(HMIXEROBJ_32(hmix), &xid, fdwID);

    if (lpid)
	*lpid = xid;
    return ret;
}

/**************************************************************************
 * 				mixerGetControlDetails	[MMSYSTEM.808]
 */
UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix,
				       LPMIXERCONTROLDETAILS16 lpmcd,
				       DWORD fdwDetails)
{
    DWORD	ret = MMSYSERR_NOTENABLED;
    SEGPTR	sppaDetails;

    TRACE("(%04x, %p, %08lx)\n", hmix, lpmcd, fdwDetails);

    if (lpmcd == NULL || lpmcd->cbStruct != sizeof(*lpmcd))
	return MMSYSERR_INVALPARAM;

    sppaDetails = (SEGPTR)lpmcd->paDetails;
    lpmcd->paDetails = MapSL(sppaDetails);
    ret = mixerGetControlDetailsA(HMIXEROBJ_32(hmix),
			         (LPMIXERCONTROLDETAILS)lpmcd, fdwDetails);
    lpmcd->paDetails = (LPVOID)sppaDetails;

    return ret;
}

/**************************************************************************
 * 				mixerGetLineControls		[MMSYSTEM.807]
 */
UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,
				     LPMIXERLINECONTROLS16 lpmlc16,
				     DWORD fdwControls)
{
    MIXERLINECONTROLSA	mlcA;
    DWORD		ret;
    unsigned int	i;
    LPMIXERCONTROL16	lpmc16;

    TRACE("(%04x, %p, %08lx)\n", hmix, lpmlc16, fdwControls);

    if (lpmlc16 == NULL || lpmlc16->cbStruct != sizeof(*lpmlc16) ||
	lpmlc16->cbmxctrl != sizeof(MIXERCONTROL16))
	return MMSYSERR_INVALPARAM;

    mlcA.cbStruct = sizeof(mlcA);
    mlcA.dwLineID = lpmlc16->dwLineID;
    mlcA.u.dwControlID = lpmlc16->u.dwControlID;
    mlcA.u.dwControlType = lpmlc16->u.dwControlType;
    mlcA.cControls = lpmlc16->cControls;
    mlcA.cbmxctrl = sizeof(MIXERCONTROLA);
    mlcA.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
			      mlcA.cControls * mlcA.cbmxctrl);

    ret = mixerGetLineControlsA(HMIXEROBJ_32(hmix), &mlcA, fdwControls);

    if (ret == MMSYSERR_NOERROR) {
	lpmlc16->dwLineID = mlcA.dwLineID;
	lpmlc16->u.dwControlID = mlcA.u.dwControlID;
	lpmlc16->u.dwControlType = mlcA.u.dwControlType;
	lpmlc16->cControls = mlcA.cControls;

	lpmc16 = MapSL(lpmlc16->pamxctrl);

	for (i = 0; i < mlcA.cControls; i++) {
	    lpmc16[i].cbStruct = sizeof(MIXERCONTROL16);
	    lpmc16[i].dwControlID = mlcA.pamxctrl[i].dwControlID;
	    lpmc16[i].dwControlType = mlcA.pamxctrl[i].dwControlType;
	    lpmc16[i].fdwControl = mlcA.pamxctrl[i].fdwControl;
	    lpmc16[i].cMultipleItems = mlcA.pamxctrl[i].cMultipleItems;
	    strcpy(lpmc16[i].szShortName, mlcA.pamxctrl[i].szShortName);
	    strcpy(lpmc16[i].szName, mlcA.pamxctrl[i].szName);
	    /* sizeof(lpmc16[i].Bounds) == sizeof(mlcA.pamxctrl[i].Bounds) */
	    memcpy(&lpmc16[i].Bounds, &mlcA.pamxctrl[i].Bounds,
		   sizeof(mlcA.pamxctrl[i].Bounds));
	    /* sizeof(lpmc16[i].Metrics) == sizeof(mlcA.pamxctrl[i].Metrics) */
	    memcpy(&lpmc16[i].Metrics, &mlcA.pamxctrl[i].Metrics,
		   sizeof(mlcA.pamxctrl[i].Metrics));
	}
    }

    HeapFree(GetProcessHeap(), 0, mlcA.pamxctrl);

    return ret;
}

/**************************************************************************
 * 				mixerGetLineInfo	[MMSYSTEM.805]
 */
UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix, LPMIXERLINE16 lpmli16,
				 DWORD fdwInfo)
{
    MIXERLINEA		mliA;
    UINT		ret;

    TRACE("(%04x, %p, %08lx)\n", hmix, lpmli16, fdwInfo);

    if (lpmli16 == NULL || lpmli16->cbStruct != sizeof(*lpmli16))
	return MMSYSERR_INVALPARAM;

    mliA.cbStruct = sizeof(mliA);
    switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
    case MIXER_GETLINEINFOF_COMPONENTTYPE:
	mliA.dwComponentType = lpmli16->dwComponentType;
	break;
    case MIXER_GETLINEINFOF_DESTINATION:
	mliA.dwDestination = lpmli16->dwDestination;
	break;
    case MIXER_GETLINEINFOF_LINEID:
	mliA.dwLineID = lpmli16->dwLineID;
	break;
    case MIXER_GETLINEINFOF_SOURCE:
	mliA.dwDestination = lpmli16->dwDestination;
	mliA.dwSource = lpmli16->dwSource;
	break;
    case MIXER_GETLINEINFOF_TARGETTYPE:
	mliA.Target.dwType = lpmli16->Target.dwType;
	mliA.Target.wMid = lpmli16->Target.wMid;
	mliA.Target.wPid = lpmli16->Target.wPid;
	mliA.Target.vDriverVersion = lpmli16->Target.vDriverVersion;
	strcpy(mliA.Target.szPname, lpmli16->Target.szPname);
	break;
    default:
	FIXME("Unsupported fdwControls=0x%08lx\n", fdwInfo);
    }

    ret = mixerGetLineInfoA(HMIXEROBJ_32(hmix), &mliA, fdwInfo);

    lpmli16->dwDestination     	= mliA.dwDestination;
    lpmli16->dwSource          	= mliA.dwSource;
    lpmli16->dwLineID          	= mliA.dwLineID;
    lpmli16->fdwLine           	= mliA.fdwLine;
    lpmli16->dwUser            	= mliA.dwUser;
    lpmli16->dwComponentType   	= mliA.dwComponentType;
    lpmli16->cChannels         	= mliA.cChannels;
    lpmli16->cConnections      	= mliA.cConnections;
    lpmli16->cControls         	= mliA.cControls;
    strcpy(lpmli16->szShortName, mliA.szShortName);
    strcpy(lpmli16->szName, mliA.szName);
    lpmli16->Target.dwType     	= mliA.Target.dwType;
    lpmli16->Target.dwDeviceID 	= mliA.Target.dwDeviceID;
    lpmli16->Target.wMid       	= mliA.Target.wMid;
    lpmli16->Target.wPid        = mliA.Target.wPid;
    lpmli16->Target.vDriverVersion = mliA.Target.vDriverVersion;
    strcpy(lpmli16->Target.szPname, mliA.Target.szPname);

    return ret;
}

/**************************************************************************
 * 				mixerSetControlDetails	[MMSYSTEM.809]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -