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