Commit 281c9273 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- got rid of all the internal MM tweaks to load builtin MCI

drivers. They are all seen as drivers, loaded as DLLs and standard module loadorder is used to know which type to use (builtin vs native). - first full working implementation of mmThread??? functions (to support gracefully native MCI drivers). - support of mmShowMMCPLPropertySheet. - fix of some heap validate bugs (thanks to Ulrich for reporting them).
parent 4f6d7f38
......@@ -15,6 +15,7 @@ services.
1. Lowlevel layers
Following lowlevel layers are implemented:
1.1 (Waveform) Audio
The API consists of the waveIn*/waveOut* functions found in
......@@ -29,18 +30,18 @@ services.
The implementation contains all features commonly used, but has several
problems. For instance:
Writes and reads are not done asynchronously as they are supposed to
be done. This breaks some programs (soundrec.exe from the Windows applets),
but doesn't worry other programs. Some callbacks are probably done
incorrectly (there are reports of some broken multimedia applications,
but I haven't found one yet.)
Writes are not done asynchronously as they are supposed to be done.
This breaks some programs (soundrec.exe from the Windows applets),
but doesn't worry other programs.
TODO:
- add asynchronous writes and reads (must use threads)
- check the callback functions
- add asynchronous writes (must use threads)
- verify all functions for correctness
- add drivers for other soundsystems (Sun Audio, remote audio systems
(using X extensions, ...), ALSA
- WaveHdr must be sent though mmsystem.c to get the linear address
set correctly. An application calling directly (wod|wid)Message
will fail
1.2 Mixer
......@@ -77,9 +78,10 @@ services.
use existing instrument definition (from playmidi or kmid)
with a .winerc option
- have a look at OPL/3 ?
- a hack is used in mmsystem.c (setting reserved to the 32 bit linear
address of the block whatever the call is made from 16 or 32 bits
code...). this should be made in midi.c I think
- MidiHdr must be sent though mmsystem.c to get the linear address
set correctly. An application calling directly (wod|wid)Message
will fail
- implement asynchronous playback of MidiHdr
1.4 Timers
......@@ -92,7 +94,7 @@ services.
and 'Pinball! SpaceCadet' at least start up.
TODO:
- Implemented asynchronous timers (using a thread probably)
- Implemented asynchronous timers (using the service thread)
1.5 MMIO
......@@ -138,20 +140,19 @@ services.
allocation and calls.
The implementation is not complete.
There is a first shot at using native (MS provided) MCI
drivers. For this to work, there are two .winerc options to be
used:
- key 'mci' in [option] section
MCI drivers are seen as regular WINE modules, and can be loaded
(with a correct loadorder between builtin, native, elfdll, so), as
any other DLL. Please note, that MCI drivers module names must
bear the .drv extension to be correctly understood.
The list of available MCI drivers is obtained as follows:
1/ key 'mci' in [option] section from .winerc (or wineconf)
mci=CDAUDIO:SEQUENCER
gives the list of MCI drivers (names, in uppercase only) to
be used in WINE. This list, when defined, supercedes the mci
be used in WINE.
2/ This list, when defined, supercedes the mci
key in c:\windows\system.ini
- key 'mciExternal' in [option] section
mciExternal=CDAUDIO
gives the list of MCI drivers to be loaded from Windows
installation. Since, drivers are DLLs, drivers are searched
(and loaded) as DLLs are.
TODO:
- support windows MCI drivers (should be possible for they usually
......@@ -164,6 +165,7 @@ services.
- implement other stuff as yet unknown
- in mciString(), make use of hiword from mciSendMessage
return value to convert value into string...
- move mci drivers as regular DLLs (loading in wine, elfglue...)
WINE implements several MCI midlevel drivers:
......@@ -193,7 +195,12 @@ services.
It uses the lowlevel audio API (although not abstracted correctly).
FIXME: The MCI_STATUS command is broken.
TODO: - check for correctness
TODO:
- check for correctness
- better use of asynchronous playback from low level
Native MCIWAVE has been working but is currently blocked by
scheduling issues.
2.3 MIDI/SEQUENCER
......@@ -205,6 +212,9 @@ services.
- implement it correctly
- finish asynchronous commands
Native MCIMIDI has been working but is currently blocked by
scheduling issues.
2.4 MCIANIM
The implementation consists of stubs and is in multimedia/mcianim.c.
......@@ -213,6 +223,14 @@ services.
- implement it, probably using xanim or something similair. Could
also be implemented by using the Windows MCI video drivers.
2.5 MCIAVI
The implementation consists of stubs and is in multimedia/mciavi.c.
TODO:
- implement it, probably using xanim or something similair. Could
also be implemented by using the Windows MCI video drivers.
3 High-level layers
The rest (basically the MMSYSTEM and WINMM DLLs entry points.
The rest (basically the MMSYSTEM and WINMM DLLs entry points).
name mmsystem
type win16
init MMSYSTEM_LibMain
#1 pascal MMSYSTEM_WEP(word word word ptr) MMSYSTEM_WEP
2 pascal SNDPLAYSOUND(ptr word) sndPlaySoundA
......@@ -147,7 +148,7 @@ type win16
1123 pascal mmThreadIsCurrent(word) mmThreadIsCurrent16
1124 pascal mmThreadIsValid(word) mmThreadIsValid16
1125 pascal mmThreadGetTask(word) mmThreadGetTask16
1150 pascal mmShowMMCPLPropertySheet(word word word word word word word) mmShowMMCPLPropertySheet16
1150 pascal mmShowMMCPLPropertySheet(word str str str) mmShowMMCPLPropertySheet16
1210 pascal mmioOpen(str ptr long) mmioOpen16
1211 pascal mmioClose(word word) mmioClose16
......@@ -175,4 +176,4 @@ type win16
#2006 stub WINMMSL_THUNKDATA16
# this is a wine only exported function. Is there another way to do it ?
2047 pascal WINE_mmThreadingEntryPoint(long) WINE_mmThreadingEntryPoint
\ No newline at end of file
2047 pascal WINE_mmThreadEntryPoint(long) WINE_mmThreadEntryPoint
......@@ -2,9 +2,10 @@
/*****************************************************************************
* Copyright 1998, Luiz Otavio L. Zorzella
* 1999, Eric Pouech
*
* File: multimedia.h
* Purpose: multimedia declarations
* Purpose: multimedia declarations (internal to multimedia DLLs)
*
*****************************************************************************
*/
......@@ -44,7 +45,7 @@
#endif
typedef struct {
HDRVR16 hDrv;
HDRVR hDrv;
DRIVERPROC16 driverProc;
MCI_OPEN_DRIVER_PARMS16 modp;
MCI_OPEN_PARMS16 mop;
......@@ -62,41 +63,50 @@ extern WINE_MCIDRIVER mciDrv[MAXMCIDRIVERS];
typedef struct {
DWORD dwSignature; /* 00 "BSIL" when ok, 0xDEADDEAD when being deleted */
DWORD dwCounter; /* 04 */
DWORD dwCounter; /* 04 > 1 when in mmThread functions */
HANDLE hThread; /* 08 hThread */
DWORD dwThreadId; /* 0C */
FARPROC16 fpThread; /* 10 segmented address of thread proc */
DWORD dwThreadPmt; /* 14 parameter to be called upon thread creation */
DWORD dwUnknown3; /* 18 increment interlocked ? */
DWORD hEvent; /* 1C event */
DWORD dwUnknown5; /* 20 */
DWORD dwStatus; /* 24 0, 10, 20, 30 */
DWORD dwThreadID; /* 0C */
FARPROC16 fpThread; /* 10 address of thread proc (segptr or lin depending on dwFlags) */
DWORD dwThreadPmt; /* 14 parameter to be passed upon thread creation to fpThread */
DWORD dwSignalCount; /* 18 counter used for signaling */
HANDLE hEvent; /* 1C event */
HANDLE hVxD; /* 20 return from OpenVxDHandle */
DWORD dwStatus; /* 24 0x00, 0x10, 0x20, 0x30 */
DWORD dwFlags; /* 28 dwFlags upon creation */
HANDLE16 hTask; /* 2C handle to created task */
} WINE_MMTHREAD;
#define MCI_GetDrv(wDevID) (&mciDrv[MCI_DevIDToIndex(wDevID)])
#define MCI_GetOpenDrv(wDevID) (&(MCI_GetDrv(wDevID)->mop))
typedef enum {
MCI_MAP_NOMEM, /* ko, memory problem */
MCI_MAP_MSGERROR, /* ko, unknown message */
MCI_MAP_OK, /* ok, no memory allocated. to be sent to 16 bit proc. */
MCI_MAP_OKMEM, /* ok, some memory allocated, need to call MCI_UnMapMsg32ATo16. to be sent to 16 bit proc. */
MCI_MAP_PASS /* ok, no memory allocated. to be sent to 32 bit proc */
} MCI_MapType;
/* function prototypes */
extern BOOL MULTIMEDIA_Init(void);
#define MCI_GetDrv(wDevID) (&mciDrv[MCI_DevIDToIndex(wDevID)])
#define MCI_GetOpenDrv(wDevID) (&(MCI_GetDrv(wDevID)->mop))
extern int MCI_DevIDToIndex(UINT16 wDevID);
extern UINT16 MCI_FirstDevID(void);
extern UINT16 MCI_NextDevID(UINT16 wDevID);
extern BOOL MCI_DevIDValid(UINT16 wDevID);
extern int MCI_MapMsg16To32A(WORD uDevType, WORD wMsg, DWORD* lParam);
extern int MCI_UnMapMsg16To32A(WORD uDevTyp, WORD wMsg, DWORD lParam);
extern MCI_MapType MCI_MapMsg16To32A(WORD uDevType, WORD wMsg, DWORD* lParam);
extern MCI_MapType MCI_UnMapMsg16To32A(WORD uDevTyp, WORD wMsg, DWORD lParam);
extern DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSA lpParms);
extern DWORD MCI_Close(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms);
extern DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSA lpParms);
typedef LONG (*MCIPROC16)(DWORD, HDRVR16, WORD, DWORD, DWORD);
typedef LONG (*MCIPROC)(DWORD, HDRVR16, DWORD, DWORD, DWORD);
typedef LONG (*MCIPROC16)(DWORD, HDRVR16, WORD, DWORD, DWORD);
typedef LONG (*MCIPROC)(DWORD, HDRVR, DWORD, DWORD, DWORD);
extern WORD MCI_GetDevTypeFromString(LPCSTR str);
extern LPCSTR MCI_GetStringFromDevType(WORD type);
extern WORD MCI_GetDevType(LPCSTR str);
extern DWORD MCI_WriteString(LPSTR lpDstStr, DWORD dstSize, LPCSTR lpSrcStr);
extern const char* MCI_CommandToString(UINT16 wMsg);
......@@ -106,28 +116,34 @@ extern LPSTR lpmciInstallNames;
extern UINT16 WINAPI MCI_DefYieldProc(UINT16 wDevID, DWORD data);
typedef struct {
WORD uDevType;
char* lpstrName;
MCIPROC lpfnProc;
} MCI_WineDesc;
extern MCI_WineDesc MCI_InternalDescriptors[];
extern LRESULT MCI_CleanUp(LRESULT dwRet, UINT wMsg, DWORD dwParam2, BOOL bIs32);
extern DWORD MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2);
extern DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2);
extern DWORD MCI_SendCommandFrom16(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2);
extern DWORD MCI_SendCommandAsync(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2, UINT size);
LONG MCIWAVE_DriverProc(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg,
LONG MCIWAVE_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
DWORD dwParam1, DWORD dwParam2);
LONG MCIMIDI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg,
LONG MCIMIDI_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
DWORD dwParam1, DWORD dwParam2);
LONG MCICDAUDIO_DriverProc(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg,
LONG MCICDAUDIO_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
DWORD dwParam1, DWORD dwParam2);
LONG MCIANIM_DriverProc(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg,
LONG MCIANIM_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
DWORD dwParam1, DWORD dwParam2);
LONG MCIAVI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg,
LONG MCIAVI_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
DWORD dwParam1, DWORD dwParam2);
HINSTANCE16 WINAPI mmTaskCreate16(SEGPTR spProc, HINSTANCE16 *lphMmTask, DWORD dwPmt);
void WINAPI mmTaskBlock16(HINSTANCE16 hInst);
LRESULT WINAPI mmTaskSignal16(HTASK16 ht);
void WINAPI mmTaskYield16(void);
void WINAPI WINE_mmThreadEntryPoint(DWORD _pmt);
LRESULT WINAPI mmThreadCreate16(FARPROC16 fpThreadAddr, LPHANDLE lpHndl, DWORD dwPmt, DWORD dwFlags);
void WINAPI mmThreadSignal16(HANDLE16 hndl);
void WINAPI mmThreadBlock16(HANDLE16 hndl);
HANDLE16 WINAPI mmThreadGetTask16(HANDLE16 hndl);
BOOL16 WINAPI mmThreadIsValid16(HANDLE16 hndl);
BOOL16 WINAPI mmThreadIsCurrent16(HANDLE16 hndl);
#endif /* __WINE_MULTIMEDIA_H */
......@@ -17,7 +17,6 @@
#include "main.h"
#include "menu.h"
#include "message.h"
#include "multimedia.h"
#include "dialog.h"
#include "drive.h"
#include "queue.h"
......@@ -239,9 +238,6 @@ BOOL WINAPI MAIN_UserInit(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserve
/* Initialize cursor/icons */
CURSORICON_Init();
/* Initialize multimedia */
if (!MULTIMEDIA_Init()) return FALSE;
/* Initialize message spying */
if (!SPY_Init()) return FALSE;
......
......@@ -141,6 +141,9 @@ static DWORD WAVE_NotifyClient(UINT16 wDevID, WORD wMsg,
return MMSYSERR_NOERROR;
}
break;
default:
FIXME(wave, "Unknown CB message %u\n", wMsg);
break;
}
return 0;
}
......@@ -162,7 +165,7 @@ static BOOL wodPlayer_WriteFragments(WINE_WAVEOUT* wwo)
LPBYTE lpData;
int count;
audio_buf_info abinfo;
for (;;) {
/* get number of writable fragments */
if (ioctl(wwo->unixdev, SNDCTL_DSP_GETOSPACE, &abinfo) == -1) {
......@@ -223,8 +226,10 @@ static BOOL wodPlayer_WriteFragments(WINE_WAVEOUT* wwo)
} else {
count = write(wwo->unixdev, lpData + wwo->dwOffCurrHdr, wwo->dwRemain);
TRACE(wave, "write(%p[%5lu], %5lu) => %d\n", lpData, wwo->dwOffCurrHdr, wwo->dwRemain, count);
wwo->dwOffCurrHdr += count;
wwo->dwRemain = wwo->dwFragmentSize;
if (count > 0) {
wwo->dwOffCurrHdr += wwo->dwRemain;
wwo->dwRemain = wwo->dwFragmentSize;
}
}
}
}
......
......@@ -18,6 +18,7 @@
DECLARE_DEBUG_CHANNEL(mci)
DECLARE_DEBUG_CHANNEL(midi)
DECLARE_DEBUG_CHANNEL(mmsys)
#ifdef HAVE_OSS
......@@ -38,7 +39,7 @@ extern LPMIDIINCAPS16 midiInDevices [MAX_MIDIINDRV];
*
*/
#ifdef HAVE_OSS
int unixToWindowsDeviceType(int type)
static int unixToWindowsDeviceType(int type)
{
#if !defined(__NetBSD__) && !defined(__OpenBSD__)
/* MOD_MIDIPORT output port
......@@ -72,7 +73,7 @@ int unixToWindowsDeviceType(int type)
* Initializes the MIDI devices information variables
*
*/
BOOL MULTIMEDIA_MidiInit(void)
static BOOL MULTIMEDIA_MidiInit(void)
{
#if defined(HAVE_OSS) && !defined(__NetBSD__) && !defined(__OpenBSD__)
int i, status, numsynthdevs = 255, nummididevs = 255;
......@@ -256,10 +257,14 @@ BOOL MULTIMEDIA_MidiInit(void)
return TRUE;
}
BOOL MULTIMEDIA_MciInit(void)
/**************************************************************************
* MULTIMEDIA_MciInit [internal]
*
* Initializes the MCI internal variables.
*
*/static BOOL MULTIMEDIA_MciInit(void)
{
LPSTR ptr1, ptr2;
char buffer[1024];
mciInstalledCount = 0;
ptr1 = lpmciInstallNames = xmalloc(2048);
......@@ -286,25 +291,61 @@ BOOL MULTIMEDIA_MciInit(void)
}
mciInstalledListLen = ptr1 - lpmciInstallNames;
if (PROFILE_GetWineIniString("options", "mciExternal", "", buffer, sizeof(buffer)) > 0) {
int i;
for (i = 0; MCI_InternalDescriptors[i].uDevType != 0xFFFF; i++) {
if (strstr(buffer, MCI_InternalDescriptors[i].lpstrName) != NULL) {
MCI_InternalDescriptors[i].uDevType = 0; /* disable slot */
}
}
}
return TRUE;
}
HINSTANCE WINMM_hInstance = 0;
HINSTANCE MMSYSTEM_hInstance = 0;
static bInitDone = FALSE;
/**************************************************************************
* MULTIMEDIA_Init [internal]
* WINMM_LibMain [EntryPoint]
*
* Initializes the multimedia information variables
* WINMM DLL entry point
*
*/
BOOL MULTIMEDIA_Init(void)
BOOL WINAPI WINMM_LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
{
TRACE(mmsys, "0x%x 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
if (!bInitDone) {
if (MULTIMEDIA_MidiInit() && MULTIMEDIA_MciInit()) {
bInitDone = TRUE;
} else {
return FALSE;
}
}
WINMM_hInstance = hinstDLL;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
BOOL WINAPI MMSYSTEM_LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
{
return MULTIMEDIA_MidiInit() && MULTIMEDIA_MciInit();
TRACE(mmsys, "0x%x 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
if (!bInitDone) {
if (MULTIMEDIA_MidiInit() && MULTIMEDIA_MciInit()) {
bInitDone = TRUE;
} else {
return FALSE;
}
}
MMSYSTEM_hInstance = hinstDLL;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
......@@ -15,11 +15,10 @@
#include "digitalv.h"
#include "options.h"
DECLARE_DEBUG_CHANNEL(cdaudio)
DECLARE_DEBUG_CHANNEL(mciavi)
DECLARE_DEBUG_CHANNEL(mcimidi)
typedef struct {
UINT wDevID;
int nUseCount; /* Incremented for each shared open */
BOOL16 fShareable; /* TRUE if first open was shareable */
WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
......@@ -38,15 +37,64 @@ static WINE_MCIAVI MCIAviDev[MAX_MCIAVIDRV];
*======================================================================*/
/**************************************************************************
* AVI_drvGetDrv [internal]
*/
static WINE_MCIAVI* AVI_drvGetDrv(UINT16 wDevID)
{
int i;
for (i = 0; i < MAX_MCIAVIDRV; i++) {
if (MCIAviDev[i].wDevID == wDevID) {
return &MCIAviDev[i];
}
}
return 0;
}
/**************************************************************************
* AVI_drvOpen [internal]
*/
static DWORD AVI_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp)
{
int i;
for (i = 0; i < MAX_MCIAVIDRV; i++) {
if (MCIAviDev[i].wDevID == 0) {
MCIAviDev[i].wDevID = modp->wDeviceID;
modp->wCustomCommandTable = -1;
modp->wType = MCI_DEVTYPE_CD_AUDIO;
return modp->wDeviceID;
}
}
return 0;
}
/**************************************************************************
* MCIAVI_drvClose [internal]
*/
static DWORD AVI_drvClose(DWORD dwDevID)
{
WINE_MCIAVI* wma = AVI_drvGetDrv(dwDevID);
if (wma) {
wma->wDevID = 0;
return 1;
}
return 0;
}
/**************************************************************************
* AVI_mciGetOpenDev [internal]
*/
static WINE_MCIAVI* AVI_mciGetOpenDev(UINT16 wDevID)
{
if (wDevID >= MAX_MCIAVIDRV || MCIAviDev[wDevID].nUseCount == 0) {
WINE_MCIAVI* wma = AVI_drvGetDrv(wDevID);
if (wma == NULL || wma->nUseCount == 0) {
WARN(mciavi, "Invalid wDevID=%u\n", wDevID);
return 0;
}
return &MCIAviDev[wDevID];
return wma;
}
static DWORD AVI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
......@@ -56,14 +104,12 @@ static DWORD AVI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPar
*/
static DWORD AVI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSA lpParms)
{
WINE_MCIAVI* wma;
WINE_MCIAVI* wma = AVI_drvGetDrv(wDevID);
TRACE(mciavi, "(%04x, %08lX, %p) : semi-stub\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wDevID > MAX_MCIAVIDRV) return MCIERR_INVALID_DEVICE_ID;
wma = &MCIAviDev[wDevID];
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
if (wma->nUseCount > 0) {
/* The driver is already open on this channel */
......@@ -78,7 +124,7 @@ static DWORD AVI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSA lpP
wma->fShareable = dwFlags & MCI_OPEN_SHAREABLE;
}
if (dwFlags & MCI_OPEN_ELEMENT) {
TRACE(cdaudio,"MCI_OPEN_ELEMENT !\n");
TRACE(mciavi,"MCI_OPEN_ELEMENT !\n");
/* return MCIERR_NO_ELEMENT_ALLOWED; */
}
......@@ -130,7 +176,7 @@ static DWORD AVI_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
wma->wStatus = MCI_MODE_PLAY;
if (lpParms && (dwFlags & MCI_NOTIFY)) {
TRACE(mcimidi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
TRACE(mciavi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
mciDriverNotify16((HWND16)LOWORD(lpParms->dwCallback),
wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
}
......@@ -933,14 +979,14 @@ static DWORD AVI_mciRestore(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_RESTORE_PARM
/**************************************************************************
* MCIAVI_DriverProc [sample driver]
*/
LONG MCIAVI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg,
LONG MCIAVI_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
DWORD dwParam1, DWORD dwParam2)
{
switch (wMsg) {
case DRV_LOAD: return 1;
case DRV_FREE: return 1;
case DRV_OPEN: return 1;
case DRV_CLOSE: return 1;
case DRV_OPEN: return AVI_drvOpen((LPSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSA)dwParam2);
case DRV_CLOSE: return AVI_drvClose(dwDevID);
case DRV_ENABLE: return 1;
case DRV_DISABLE: return 1;
case DRV_QUERYCONFIGURE: return 1;
......
......@@ -10,12 +10,13 @@
#include "winuser.h"
#include "driver.h"
#include "multimedia.h"
#include "debug.h"
#include "cdrom.h"
#include "debug.h"
DEFAULT_DEBUG_CHANNEL(cdaudio)
typedef struct {
UINT16 wDevID;
int nUseCount; /* Incremented for each shared open */
BOOL16 fShareable; /* TRUE if first open was shareable */
WORD wNotifyDeviceID; /* MCI device ID with a pending notification */
......@@ -32,16 +33,64 @@ static WINE_MCICDAUDIO CDADev[MAX_CDAUDIODRV];
/*-----------------------------------------------------------------------*/
/**************************************************************************
* CDAUDIO_drvGetDrv [internal]
*/
static WINE_MCICDAUDIO* CDAUDIO_drvGetDrv(UINT16 wDevID)
{
int i;
for (i = 0; i < MAX_CDAUDIODRV; i++) {
if (CDADev[i].wDevID == wDevID) {
return &CDADev[i];
}
}
return 0;
}
/**************************************************************************
* CDAUDIO_drvOpen [internal]
*/
static DWORD CDAUDIO_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp)
{
int i;
for (i = 0; i < MAX_CDAUDIODRV; i++) {
if (CDADev[i].wDevID == 0) {
CDADev[i].wDevID = modp->wDeviceID;
modp->wCustomCommandTable = -1;
modp->wType = MCI_DEVTYPE_CD_AUDIO;
return modp->wDeviceID;
}
}
return 0;
}
/**************************************************************************
* CDAUDIO_drvClose [internal]
*/
static DWORD CDAUDIO_drvClose(DWORD dwDevID)
{
WINE_MCICDAUDIO* wmcda = CDAUDIO_drvGetDrv(dwDevID);
if (wmcda) {
wmcda->wDevID = 0;
return 1;
}
return 0;
}
/**************************************************************************
* CDAUDIO_mciGetOpenDrv [internal]
*/
static WINE_MCICDAUDIO* CDAUDIO_mciGetOpenDrv(UINT16 wDevID)
{
if (wDevID >= MAX_CDAUDIODRV || CDADev[wDevID].nUseCount == 0 ||
CDADev[wDevID].wcda.unixdev <= 0) {
WINE_MCICDAUDIO* wmcda = CDAUDIO_drvGetDrv(wDevID);
if (wmcda == NULL || wmcda->nUseCount == 0 || wmcda->wcda.unixdev <= 0) {
WARN(cdaudio, "Invalid wDevID=%u\n", wDevID);
return 0;
}
return &CDADev[wDevID];
return wmcda;
}
/**************************************************************************
......@@ -173,18 +222,16 @@ static DWORD CDAUDIO_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS l
static DWORD CDAUDIO_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSA lpOpenParms)
{
DWORD dwDeviceID;
WINE_MCICDAUDIO* wmcda;
WINE_MCICDAUDIO* wmcda = CDAUDIO_drvGetDrv(wDevID);
MCI_SEEK_PARMS seekParms;
TRACE(cdaudio,"(%04X, %08lX, %p);\n", wDevID, dwFlags, lpOpenParms);
if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wDevID > MAX_CDAUDIODRV) return MCIERR_INVALID_DEVICE_ID;
if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
dwDeviceID = lpOpenParms->wDeviceID;
wmcda = &CDADev[wDevID];
if (wmcda->nUseCount > 0) {
/* The driver is already open on this channel */
/* If the driver was opened shareable before and this open specifies */
......@@ -671,18 +718,18 @@ static DWORD CDAUDIO_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParm
/**************************************************************************
* MCICDAUDIO_DriverProc [sample driver]
*/
LONG MCICDAUDIO_DriverProc(DWORD dwDevID, HDRVR16 hDriv, DWORD wMsg,
LONG MCICDAUDIO_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
DWORD dwParam1, DWORD dwParam2)
{
switch(wMsg) {
case DRV_LOAD: return 1;
case DRV_FREE: return 1;
case DRV_OPEN: return 1;
case DRV_CLOSE: return 1;
case DRV_OPEN: return CDAUDIO_drvOpen((LPSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSA)dwParam2);
case DRV_CLOSE: return CDAUDIO_drvClose(dwDevID);
case DRV_ENABLE: return 1;
case DRV_DISABLE: return 1;
case DRV_QUERYCONFIGURE: return 1;
case DRV_CONFIGURE: MessageBoxA(0, "Sample Multimedia Linux Driver !", "MMLinux Driver", MB_OK); return 1;
case DRV_CONFIGURE: MessageBoxA(0, "Sample Multimedia Driver !", "Wine Driver", MB_OK); return 1;
case DRV_INSTALL: return DRVCNF_RESTART;
case DRV_REMOVE: return DRVCNF_RESTART;
......
......@@ -275,7 +275,7 @@ MCISTR_Open(_MCISTR_PROTO_)
pU->openParams.lpstrElementName = strdup(s);
dwFlags |= MCI_OPEN_ELEMENT;
}
uDevTyp = MCI_GetDevType(dev);
uDevTyp = MCI_GetDevTypeFromString(dev);
if (uDevTyp == 0) {
free(pU->openParams.lpstrElementName);
free(pU);
......
......@@ -16,6 +16,11 @@ imagehlp.c
imm32.c
kernel32.c
lz32.c
mcianim.c
mciavi.c
mcicda.c
mciseq.c
mciwave.c
mpr.c
msacm32.c
msnet32.c
......
......@@ -23,6 +23,11 @@ DLLS = \
kernel32.spec \
lz32.spec \
mpr.spec \
mcianim.spec \
mciavi.spec \
mcicda.spec \
mciseq.spec \
mciwave.spec \
msacm32.spec \
msnet32.spec \
msvfw32.spec \
......
......@@ -63,6 +63,11 @@ extern const BUILTIN32_DESCRIPTOR IMM32_Descriptor;
extern const BUILTIN32_DESCRIPTOR KERNEL32_Descriptor;
extern const BUILTIN32_DESCRIPTOR LZ32_Descriptor;
extern const BUILTIN32_DESCRIPTOR MPR_Descriptor;
extern const BUILTIN32_DESCRIPTOR MCIAVI_Descriptor;
extern const BUILTIN32_DESCRIPTOR MCIANIM_Descriptor;
extern const BUILTIN32_DESCRIPTOR MCICDA_Descriptor;
extern const BUILTIN32_DESCRIPTOR MCISEQ_Descriptor;
extern const BUILTIN32_DESCRIPTOR MCIWAVE_Descriptor;
extern const BUILTIN32_DESCRIPTOR MSACM32_Descriptor;
extern const BUILTIN32_DESCRIPTOR MSNET32_Descriptor;
extern const BUILTIN32_DESCRIPTOR MSVFW32_Descriptor;
......@@ -108,6 +113,11 @@ static BUILTIN32_DLL BuiltinDLLs[] =
{ &IMM32_Descriptor, 0, NULL },
{ &KERNEL32_Descriptor, 0, NULL },
{ &LZ32_Descriptor, 0, NULL },
{ &MCIANIM_Descriptor, 0, NULL },
{ &MCIAVI_Descriptor, 0, NULL },
{ &MCICDA_Descriptor, 0, NULL },
{ &MCISEQ_Descriptor, 0, NULL },
{ &MCIWAVE_Descriptor, 0, NULL },
{ &MPR_Descriptor, 0, NULL },
{ &MSACM32_Descriptor, 0, NULL },
{ &MSNET32_Descriptor, 0, NULL },
......
name mcianim
file mcianim.drv
type win32
1 stdcall DriverProc(long long long long long) MCIANIM_DriverProc
name mciavi
file mciavi.drv
type win32
1 stdcall DriverProc(long long long long long) MCIAVI_DriverProc
name mcicda
file mcicda.drv
type win32
1 stdcall DriverProc(long long long long long) MCICDAUDIO_DriverProc
name mciseq
file mciseq.drv
type win32
1 stdcall DriverProc(long long long long long) MCIMIDI_DriverProc
name mciwave
file mciwave.drv
type win32
1 stdcall DriverProc(long long long long long) MCIWAVE_DriverProc
name winmm
type win32
init WINMM_LibMain
1 stdcall PlaySoundA(ptr long long) PlaySoundA
2 stdcall WINMM_2(ptr long long) PlaySoundA
......
......@@ -88,6 +88,9 @@ mpr, winspool = builtin, native
ddraw, dinput, dsound = builtin, native
winmm, mmsystem = builtin
msvideo, msvfw32 = builtin, native
mcicda.drv, mciseq.drv = builtin, native
mciwave.drv = builtin, native
mciavi.drv, mcianim.drv = native, builtin
w32skrnl = builtin
wnaspi32, wow32 = builtin
system, display, wprocs = builtin
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment