Hi, I've patched Wine to make recordings work in "Lexia" (http://www.lexia.just.nu/, currently down). When I started out, recordings didn't work, and I was getting traces like:
trace:mci:mciSendStringW (L"open new type waveaudio alias capture", 0x7db2ebc8, 128, (nil)) fixme:mci:mciSendStringW 'new': NIY as device name trace:mci:mciSendStringW (L"set capture time format milliseconds bitspersample 16 samplespersec 22050 channels 1 bytespersec 44100 alignment 4", 0x7db92fa8, 128, (nil)) trace:mci:mciSendStringW (L"open capture wait", (nil), 0, (nil)) trace:mci:MCI_LoadMciDriver wDevID=0001 fixme:mci:MCI_LoadMciDriver Couldn't load driver for type L"CAPTURE". If you don't have a windows installation accessible from Wine, you perhaps forgot to create a [mci] section in system.ini trace:mci:mciSendStringW (L"record capture", 0x7db2ebc8, 128, (nil)) trace:mci:mciSendStringW (L"open capture wait", (nil), 0, (nil)) trace:mci:MCI_LoadMciDriver wDevID=0001 fixme:mci:MCI_LoadMciDriver Couldn't load driver for type L"CAPTURE". If you don't have a windows installation accessible from Wine, you perhaps forgot to create a [mci] section in system.ini
I created the patch below, but eventually, it turned out that it's sufficient to add this to system.ini:
[mci] CAPTURE=mciwave.dll
In other words: With this change, recordings works despite mciSendStringW returning MCIERR_MISSING_DEVICE_NAME. Strange but true.
To summarize:
1) I believe the mciwave.c patch below makes sense in any case, right? Without it freed memory is used.
2) Any ideas why "open new" works, even though MCIERR_MISSING_DEVICE_NAME is returned?
3) Most importantly: Why is it necessary to add CAPTURE to system.ini? Perhaps the "alias" argument isn't correctly handled?
The patch:
Index: dlls/winmm/mci.c =================================================================== RCS file: /home/wine/wine/dlls/winmm/mci.c,v retrieving revision 1.69 diff -u -r1.69 mci.c --- dlls/winmm/mci.c 23 May 2006 12:48:57 -0000 1.69 +++ dlls/winmm/mci.c 8 Jun 2006 12:53:43 -0000 @@ -1283,10 +1283,9 @@
/* case dev == 'new' has to be handled */ if (!strcmpW(dev, wszNew)) { - FIXME("'new': NIY as device name\n"); - dwRet = MCIERR_MISSING_DEVICE_NAME; - goto errCleanUp; - } + /* FIXME: Use temp file name. Remove after use. */ + dev = MCI_strdupAtoW("mcitemp.wav"); + }
/* otherwise, try to grab devType from open */ if (!strcmpW(verb, wszOpen)) { Index: dlls/mciwave/mciwave.c =================================================================== RCS file: /home/wine/wine/dlls/mciwave/mciwave.c,v retrieving revision 1.2 diff -u -r1.2 mciwave.c --- dlls/mciwave/mciwave.c 23 May 2006 12:48:10 -0000 1.2 +++ dlls/mciwave/mciwave.c 8 Jun 2006 12:53:43 -0000 @@ -409,18 +409,19 @@ fn = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR)); if (!fn) return MCIERR_OUT_OF_MEMORY; strcpyW(fn, filename); + /* Note: Frees filename as well */ HeapFree(GetProcessHeap(), 0, (void*)wmw->openParms.lpstrElementName); wmw->openParms.lpstrElementName = fn;
- if (strlenW(filename) > 0) { + if (strlenW(fn) > 0) { /* FIXME : what should be done if wmw->hFile is already != 0, or the driver is playin' */ - TRACE("MCI_OPEN_ELEMENT %s!\n", debugstr_w(filename)); + TRACE("MCI_OPEN_ELEMENT %s!\n", debugstr_w(fn));
- wmw->hFile = mmioOpenW((LPWSTR)filename, NULL, + wmw->hFile = mmioOpenW((LPWSTR)fn, NULL, MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READ);
if (wmw->hFile == 0) { - WARN("can't find file=%s!\n", debugstr_w(filename)); + WARN("can't find file=%s!\n", debugstr_w(fn)); dwRet = MCIERR_FILE_NOT_FOUND; } else
Regards,
1) I believe the mciwave.c patch below makes sense in any case, right?
Without it freed memory is used.
I don't see why ?
- Any ideas why "open new" works, even though MCIERR_MISSING_DEVICE_NAME is returned?
because "open new alias capture" should create a new mci session of name capture (which is application defined), and mci supports the "auto" open feature, which is when accessing a not yet created device, it opens it. so, the fix to system.ini is wrong. what's missing is the support of the new keyword, as the FIXME in mci.c suggests. A+
- I believe the mciwave.c patch below makes sense in any case, right?
Without it freed memory is used.
I don't see why ?
wmw->openParms.lpstrElementName and filename is a pointer to the same memory, due to this statement in WAVE_mciOpen:
memcpy(&wmw->openParms, lpOpenParms, sizeof(MCI_WAVE_OPEN_PARMSA));
- Any ideas why "open new" works, even though MCIERR_MISSING_DEVICE_NAME is returned?
because "open new alias capture" should create a new mci session of name capture (which is application defined), and mci supports the "auto" open feature, which is when accessing a not yet created device, it opens it. so, the fix to system.ini is wrong. what's missing is the support of the new keyword, as the FIXME in mci.c suggests.
Are you referring to FIXME("'new': NIY as device name\n")? In that case, can you roughly describe what needs to be done? Or, perhaps you have a plan for fixing this yourself? :)
Kind regards,
On Thu, 8 Jun 2006, Peter Åstrand wrote:
- Any ideas why "open new" works, even though MCIERR_MISSING_DEVICE_NAME is returned?
because "open new alias capture" should create a new mci session of name capture (which is application defined), and mci supports the "auto" open feature, which is when accessing a not yet created device, it opens it. so, the fix to system.ini is wrong. what's missing is the support of the new keyword, as the FIXME in mci.c suggests.
Are you referring to FIXME("'new': NIY as device name\n")? In that case, can
I've managed to implement this now. Will send a patch to the wine-patches mailing list.
Regards,
Peter Åstrand wrote:
- I believe the mciwave.c patch below makes sense in any case, right?
Without it freed memory is used.
I don't see why ?
wmw->openParms.lpstrElementName and filename is a pointer to the same memory, due to this statement in WAVE_mciOpen:
memcpy(&wmw->openParms, lpOpenParms, sizeof(MCI_WAVE_OPEN_PARMSA));
actually not exactly as mciOpenFile is called with lpOpenParms->lpstrElementName
but you're right that the code is wrong, as we're freeing the lpstrElementName as passed by the calling program the right fix would be to set wmw->openParms.lpstrElementName to NULL after memcpy:ing lpOpenParams in mciOpen
A+