I recently downloaded a Japanese RPG game (http://download.sama.jp:8080/archives/shinkiro_pre.zip) and tried to run it under Wine. However, it crashed with the following fatal trace:
[alex@karlalex shinkiro_pre]$ pwd /home/alex/.wine/drive_c/shinkiro_pre [alex@karlalex shinkiro_pre]$ LANG=ja WINEDEBUG=msacm,winmm wine game.exe trace:winmm:DllMain 0x7f620000 0x1 0x1 trace:winmm:WINMM_CreateIData Initialized IData (0x7f67fba0) trace:winmm:MMDRV_Init () trace:winmm:MMDRV_Install ('winealsa.drv', 'winealsa.drv', mapper=N); ALSA lib control.c:654:(snd_ctl_open_noupdate) Invalid CTL plug:hw:0 ALSA lib pcm_hw.c:1056:(snd_pcm_hw_open) open /dev/snd/pcmC1D0p failed: Device or resource busy ALSA lib pcm_hw.c:1056:(snd_pcm_hw_open) open /dev/snd/pcmC1D0c failed: Device or resource busy trace:winmm:MMDRV_Install Got 32 bit func 'midMessage' trace:winmm:MMDRV_Install Got 32 bit func 'modMessage' trace:winmm:MMDRV_Install Got 32 bit func 'widMessage' trace:winmm:MMDRV_Install Got 32 bit func 'wodMessage' trace:winmm:MMDRV_GetDescription32 (0x7fa9fc54, 0x7fa9f998, 128) trace:winmm:MMDRV_GetDescription32 Can't find file winealsa.drv trace:winmm:MMDRV_Install winealsa.drv => No description trace:winmm:MMDRV_InitPerType (0x7f67f600, 0000, 0003) trace:winmm:MMDRV_InitPerType (0x7f67f600, 0001, 0001) trace:winmm:MMDRV_InitPerType (0x7f67f600, 0002, 0035) trace:winmm:MMDRV_InitPerType DRVM_INIT => MMSYSERR_NOERROR trace:winmm:MMDRV_InitPerType Got 1 dev for (winealsa.drv:MidiIn) trace:winmm:MMDRV_InitPerType Setting min=0 max=1 (ttop=1) for (winealsa.drv:MidiIn) trace:winmm:MMDRV_InitPerType MidiIn:Trans[0] -> winealsa.drv trace:winmm:MMDRV_InitPerType (0x7f67f600, 0003, 0001) trace:winmm:MMDRV_InitPerType DRVM_INIT => MMSYSERR_NOERROR trace:winmm:MMDRV_InitPerType Got 5 dev for (winealsa.drv:MidiOut) trace:winmm:MMDRV_InitPerType Setting min=0 max=5 (ttop=5) for (winealsa.drv:MidiOut) trace:winmm:MMDRV_InitPerType MidiOut:Trans[0] -> winealsa.drv trace:winmm:MMDRV_InitPerType MidiOut:Trans[1] -> winealsa.drv trace:winmm:MMDRV_InitPerType MidiOut:Trans[2] -> winealsa.drv trace:winmm:MMDRV_InitPerType MidiOut:Trans[3] -> winealsa.drv trace:winmm:MMDRV_InitPerType MidiOut:Trans[4] -> winealsa.drv trace:winmm:MMDRV_InitPerType (0x7f67f600, 0004, 0032) trace:winmm:MMDRV_InitPerType DRVM_INIT => MMSYSERR_NOERROR trace:winmm:MMDRV_InitPerType Got 1 dev for (winealsa.drv:WaveIn) trace:winmm:MMDRV_InitPerType Setting min=0 max=1 (ttop=1) for (winealsa.drv:WaveIn) trace:winmm:MMDRV_InitPerType WaveIn:Trans[0] -> winealsa.drv trace:winmm:MMDRV_InitPerType (0x7f67f600, 0005, 0003) trace:winmm:MMDRV_InitPerType DRVM_INIT => MMSYSERR_NOERROR trace:winmm:MMDRV_InitPerType Got 1 dev for (winealsa.drv:WaveOut) trace:winmm:MMDRV_InitPerType Setting min=0 max=1 (ttop=1) for (winealsa.drv:WaveOut) trace:winmm:MMDRV_InitPerType WaveOut:Trans[0] -> winealsa.drv trace:winmm:MMDRV_Install ('wavemapper', 'msacm.drv', mapper=Y); trace:msacm:DllMain 0x7f5f0000 0x1 (nil) trace:msacm:MSACM_RegisterDriver (L"MSACM.imaadpcm", L"imaadp32.acm", (nil)) trace:msacm:MSACM_RegisterDriver (L"MSACM.msadpcm", L"msadp32.acm", (nil)) trace:msacm:MSACM_RegisterDriver (L"MSACM.msg711", L"msg711.acm", (nil)) trace:msacm:MSACM_RegisterDriver (L"MSACM.winemp3", L"winemp3.acm", (nil)) trace:msacm:MSACM_RegisterDriver (L"msacm32.dll", L"msacm32.dll", (nil)) trace:winmm:MMDRV_Install Got 32 bit func 'widMessage' trace:winmm:MMDRV_Install Got 32 bit func 'wodMessage' trace:winmm:MMDRV_GetDescription32 (0x7fa9fb54, 0x7fa9f998, 128) trace:winmm:MMDRV_GetDescription32 Can't find file msacm.drv trace:winmm:MMDRV_Install msacm.drv => No description trace:winmm:MMDRV_InitPerType (0x7f67f654, 0000, 0003) trace:winmm:MMDRV_InitPerType (0x7f67f654, 0001, 0001) trace:winmm:MMDRV_InitPerType (0x7f67f654, 0002, 0035) trace:winmm:MMDRV_InitPerType (0x7f67f654, 0003, 0001) trace:winmm:MMDRV_InitPerType (0x7f67f654, 0004, 0032) trace:winmm:MMDRV_InitPerType DRVM_INIT => MMSYSERR_NOERROR trace:winmm:MMDRV_InitPerType Got 1 dev for (wavemapper:WaveIn) trace:winmm:MMDRV_InitPerType Setting min=0 max=0 (ttop=1) for (wavemapper:WaveIn) trace:winmm:MMDRV_InitPerType WaveIn:Trans[-1] -> wavemapper trace:winmm:MMDRV_InitPerType WaveIn:Trans[0] -> winealsa.drv trace:winmm:MMDRV_InitPerType (0x7f67f654, 0005, 0003) trace:winmm:MMDRV_InitPerType DRVM_INIT => MMSYSERR_NOERROR trace:winmm:MMDRV_InitPerType Got 1 dev for (wavemapper:WaveOut) trace:winmm:MMDRV_InitPerType Setting min=0 max=0 (ttop=1) for (wavemapper:WaveOut) trace:winmm:MMDRV_InitPerType WaveOut:Trans[-1] -> wavemapper trace:winmm:MMDRV_InitPerType WaveOut:Trans[0] -> winealsa.drv trace:winmm:MMDRV_Install ('midimapper', 'midimap.drv', mapper=Y); trace:winmm:MMDRV_GetNum (0003) trace:winmm:midiOutGetDevCapsW (0, 0x7fa9f720, 84); trace:winmm:MMDRV_Get ((nil), 0003, Y) trace:winmm:MMDRV_GetByID (0000, 0003) trace:winmm:MMDRV_Message (MidiOut 0 2 0x00000000 0x7fa9f720 0x00000054 Y) trace:winmm:MMDRV_Message Calling message(dev=0 msg=2 usr=0x00000000 p1=0x7fa9f720 p2=0x00000054) trace:winmm:MMDRV_Message => MMSYSERR_NOERROR trace:winmm:midiOutGetDevCapsW (1, 0x7fa9f720, 84); trace:winmm:MMDRV_Get (0x1, 0003, Y) trace:winmm:MMDRV_GetByID (0001, 0003) trace:winmm:MMDRV_Message (MidiOut 1 2 0x00000000 0x7fa9f720 0x00000054 Y) trace:winmm:MMDRV_Message Calling message(dev=1 msg=2 usr=0x00000000 p1=0x7fa9f720 p2=0x00000054) trace:winmm:MMDRV_Message => MMSYSERR_NOERROR trace:winmm:midiOutGetDevCapsW (2, 0x7fa9f720, 84); trace:winmm:MMDRV_Get (0x2, 0003, Y) trace:winmm:MMDRV_GetByID (0002, 0003) trace:winmm:MMDRV_Message (MidiOut 2 2 0x00000000 0x7fa9f720 0x00000054 Y) trace:winmm:MMDRV_Message Calling message(dev=2 msg=2 usr=0x00000000 p1=0x7fa9f720 p2=0x00000054) trace:winmm:MMDRV_Message => MMSYSERR_NOERROR trace:winmm:midiOutGetDevCapsW (3, 0x7fa9f720, 84); trace:winmm:MMDRV_Get (0x3, 0003, Y) trace:winmm:MMDRV_GetByID (0003, 0003) trace:winmm:MMDRV_Message (MidiOut 3 2 0x00000000 0x7fa9f720 0x00000054 Y) trace:winmm:MMDRV_Message Calling message(dev=3 msg=2 usr=0x00000000 p1=0x7fa9f720 p2=0x00000054) trace:winmm:MMDRV_Message => MMSYSERR_NOERROR trace:winmm:midiOutGetDevCapsW (4, 0x7fa9f720, 84); trace:winmm:MMDRV_Get (0x4, 0003, Y) trace:winmm:MMDRV_GetByID (0004, 0003) trace:winmm:MMDRV_Message (MidiOut 4 2 0x00000000 0x7fa9f720 0x00000054 Y) trace:winmm:MMDRV_Message Calling message(dev=4 msg=2 usr=0x00000000 p1=0x7fa9f720 p2=0x00000054) trace:winmm:MMDRV_Message => MMSYSERR_NOERROR trace:winmm:MMDRV_Install Got 32 bit func 'modMessage' trace:winmm:MMDRV_GetDescription32 (0x7fa9fa54, 0x7fa9f98c, 128) trace:winmm:MMDRV_GetDescription32 Can't find file midimap.drv trace:winmm:MMDRV_Install midimap.drv => No description trace:winmm:MMDRV_InitPerType (0x7f67f6a8, 0000, 0003) trace:winmm:MMDRV_InitPerType (0x7f67f6a8, 0001, 0001) trace:winmm:MMDRV_InitPerType (0x7f67f6a8, 0002, 0035) trace:winmm:MMDRV_InitPerType (0x7f67f6a8, 0003, 0001) trace:msacm:MIDIMAP_modMessage (0, 0064, 00000000, 00000000, 00000000); trace:winmm:MMDRV_InitPerType DRVM_INIT => MMSYSERR_NOERROR trace:msacm:MIDIMAP_modMessage (0, 0001, 00000000, 00000000, 00000000); trace:winmm:MMDRV_InitPerType Got 1 dev for (midimapper:MidiOut) trace:winmm:MMDRV_InitPerType Setting min=0 max=0 (ttop=5) for (midimapper:MidiOut) trace:winmm:MMDRV_InitPerType MidiOut:Trans[-1] -> midimapper trace:winmm:MMDRV_InitPerType MidiOut:Trans[0] -> winealsa.drv trace:winmm:MMDRV_InitPerType MidiOut:Trans[1] -> winealsa.drv trace:winmm:MMDRV_InitPerType MidiOut:Trans[2] -> winealsa.drv trace:winmm:MMDRV_InitPerType MidiOut:Trans[3] -> winealsa.drv trace:winmm:MMDRV_InitPerType MidiOut:Trans[4] -> winealsa.drv trace:winmm:MMDRV_InitPerType (0x7f67f6a8, 0004, 0032) trace:winmm:MMDRV_InitPerType (0x7f67f6a8, 0005, 0003) trace:winmm:joyGetPos (0, 0x7fa9f2b8); trace:winmm:MMDRV_GetNum (0005) trace:winmm:waveOutMessage ((nil), 2068, 2141844160, 0) trace:winmm:MMDRV_Get ((nil), 0005, N) trace:winmm:MMDRV_Get ((nil), 0005, Y) trace:winmm:MMDRV_GetByID (0000, 0005) trace:winmm:MMDRV_PhysicalFeatures (0x7fe01b8c, 0814, 7fa9f2c0, 00000000) trace:winmm:MMDRV_Message (WaveOut 0 2068 0x00000000 0x7fa9f2c0 0x00000000 Y) trace:winmm:MMDRV_Message Calling message(dev=0 msg=2068 usr=0x00000000 p1=0x7fa9f2c0 p2=0x00000000) trace:winmm:MMDRV_Message => MMSYSERR_NOERROR trace:winmm:WAVE_Open (0x7fe19304, 0, Out, 0x7fe163a0, 7D70B324, 7FE19068, 00030080, 32); trace:winmm:WAVE_Open wFormatTag=1, nChannels=2, nSamplesPerSec=22050, nAvgBytesPerSec=44100, nBlockAlign=2, wBitsPerSample=8 trace:winmm:MMDRV_Alloc (28, 0005, 0x7fa9f298, 0x7fa9f2e8, 0x7fa9f2e0, 0x7fa9f2e4, Y) trace:winmm:MMDRV_GetNum (0005) trace:winmm:WAVE_Open cb=7d70b324 trace:winmm:MMDRV_Open (0x7fe18dd8, 0005, 0x7fa9f29c, 0x00030080) trace:winmm:MMDRV_Open Setting mmdIndex to 0 trace:winmm:MMDRV_Message (WaveOut 0 5 0x7fa9f268 0x7fa9f29c 0x00030080 Y) trace:winmm:MMDRV_Message Calling message(dev=0 msg=5 usr=0x7fa9f268 p1=0x7fa9f29c p2=0x00030080) trace:winmm:MMDRV_Message => MMSYSERR_NOERROR trace:winmm:WAVE_Open dwRet = MMSYSERR_NOERROR trace:winmm:WAVE_Open => MMSYSERR_NOERROR hWave=0x8000 trace:msacm:acmDriverAddA (0x7fa9f3d4, 0x10000000, 10001040, 00000000, 00000003) trace:msacm:MSACM_RegisterDriver ((null), (null), 0x10000000) err:msacm:MSACM_GetRegistryKey No alias needed for registry entry trace:msacm:acmDriverOpen (0x7fa9ebc0, 0x7d7d03f8, 00000000) trace:msacm:acmDriverOpen '(null)' => 7d7d0430 wine: Unhandled exception (thread 0009), starting debugger... WineDbg starting on pid 0x8 Unhandled exception: page fault on write access to 0x7b480000 in 32-bit code (0x47415b47). In 32 bit mode. Register dump: CS:0073 SS:007b DS:007b ES:007b FS:003b GS:0033 EIP:47415b47 ESP:7fa9eb60 EBP:7fa9eb80 EFLAGS:00210246( - 00 -RIZP1) EAX:00000000 EBX:77ef5f14 ECX:3fffc006 EDX:00000000 ESI:fffffff8 EDI:7b480000 Stack dump: 0x7fa9eb60: 7b470020 77eca05e 7b470020 00000000 0x7fa9eb70: fffffff8 77ef5f14 7b470020 fffffff8 0x7fa9eb80: 7fa9eba8 77ec93b8 7b470020 fffffff8 0x7fa9eb90: 00000000 7d7d0000 7b470000 7f60798c 0x7fa9eba0: 7d7d03f8 7d7d03f8 7fa9f360 7f60069f 0x7fa9ebb0: 7d7d0000 0000000a fffffff8 77eea224 Backtrace: =>1 0x47415b47 __GI_memset in libc.so.6 (0x7fa9eb80) 2 0x77ec93b8 RtlAllocateHeap(heap=0x7d7d0000, flags=0xa, size=0xfffffff8) [/home/alex/install/wine/wine-20050524-patch/dlls/ntdll/heap.c:1179] in ntdll (0x7fa9eba8) 3 0x7f60069f MSACM_FillCache+0x197(padid=0x7d7d03f8) [/home/alex/install/wine/wine-20050524-patch/dlls/msacm/internal.c:106] in msacm32 (0x7fa9f360) 4 0x7f600b1c MSACM_RegisterDriver(pszDriverAlias=0x0, pszFileName=0x0, hinstModule=0x10000000) [/home/alex/install/wine/wine-20050524-patch/dlls/msacm/internal.c:279] in msacm32 (0x7fa9f37c) 5 0x7f5fd580 acmDriverAddA+0x4c(phadid=0x7fa9f3d4, hinstModule=0x10000000, lParam=0x10001040, dwPriority=0x0, fdwAdd=0x3) [driver.c:79] in msacm32 (0x7fa9f39c) 6 0x0045bb45 in game (+0x5bb45) (0x7fa9ff2c) 7 0x7fd2105b start_process+0xc3(arg=0x0) [/home/alex/install/wine/wine-20050524-patch/dlls/kernel/process.c:1044] in kernel32 (0x7fa9fff4) 8 0xb7f5b70d wine_switch_to_stack+0x11 in libwine.so.1 (0x00000000) 0x47415b47 __GI_memset+0x37 in libc.so.6: repe stosl %es:(%edi) Modules: Module Address Debug info Name (81 modules) ELF 0x001d5000-0027e000 Deferred libasound.so.2 ELF 0x001d5000-0027e000 Deferred libasound.so.2 ELF 0x002a1000-002b2000 Deferred libz.so.1 ELF 0x002b4000-00319000 Deferred libfreetype.so.6 ELF 0x0031b000-00342000 Deferred libfontconfig.so.1 ELF 0x003b2000-0047a000 Deferred libx11.so.6 PE 0x00400000-008d7000 Export game ELF 0x00cba000-00cc8000 Deferred libxext.so.6 ELF 0x00cca000-00ce1000 Deferred libice.so.6 ELF 0x00cdb000-00ce1000 Deferred libxxf86dga.so.1 ELF 0x00ce3000-00ceb000 Deferred libsm.so.6 ELF 0x00d01000-00d09000 Deferred libxrender.so.1 ELF 0x00d0b000-00d0e000 Deferred libxrandr.so.2 ELF 0x00d3b000-00d40000 Deferred libxxf86vm.so.1 ELF 0x00dbf000-00dc8000 Deferred libxcursor.so.1 PE 0x10000000-10138000 Deferred vorbis.acm ELF 0x47395000-473ac000 Deferred ld-linux.so.2 ELF 0x473ae000-474ca000 Export libc.so.6 ELF 0x474cc000-474ef000 Deferred libm.so.6 ELF 0x474f1000-474f5000 Deferred libdl.so.2 ELF 0x475e4000-475f6000 Deferred libpthread.so.0 ELF 0x476ba000-476d9000 Deferred libexpat.so.0 ELF 0x77e90000-77f00000 Stabs ntdll<elf> -PE 0x77eb0000-77f00000 \ ntdll ELF 0x77f00000-77f03000 Deferred <wine-loader> ELF 0x7b8c0000-7b8d4000 Deferred joystick.drv<elf> -PE 0x7b8d0000-7b8d4000 \ joystick.drv ELF 0x7d4b6000-7d4c0000 Deferred xomgeneric.so.2 ELF 0x7d6dd000-7d722000 Deferred dsound<elf> -PE 0x7d6f0000-7d722000 \ dsound ELF 0x7d722000-7d790000 Deferred ddraw<elf> -PE 0x7d740000-7d790000 \ ddraw ELF 0x7d98c000-7d9b6000 Deferred winealsa.drv<elf> -PE 0x7d9a0000-7d9b6000 \ winealsa.drv ELF 0x7f0ec000-7f109000 Deferred ximcp.so.2 ELF 0x7f110000-7f128000 Deferred msacm.drv<elf> -PE 0x7f120000-7f128000 \ msacm.drv ELF 0x7f29d000-7f311000 Deferred winex11.drv<elf> -PE 0x7f2b0000-7f311000 \ winex11.drv ELF 0x7f3b2000-7f3c7000 Deferred midimap.drv<elf> -PE 0x7f3c0000-7f3c7000 \ midimap.drv ELF 0x7f3c7000-7f3ca000 Deferred xlcdef.so.2 ELF 0x7f3ca000-7f41d000 Deferred shlwapi<elf> -PE 0x7f3e0000-7f41d000 \ shlwapi ELF 0x7f41d000-7f4d1000 Deferred shell32<elf> -PE 0x7f440000-7f4d1000 \ shell32 ELF 0x7f4d1000-7f56e000 Deferred comctl32<elf> -PE 0x7f4e0000-7f56e000 \ comctl32 ELF 0x7f56e000-7f591000 Deferred msvfw32<elf> -PE 0x7f580000-7f591000 \ msvfw32 ELF 0x7f591000-7f5cb000 Deferred avifil32<elf> -PE 0x7f5a0000-7f5cb000 \ avifil32 ELF 0x7f5cb000-7f5e8000 Deferred imm32<elf> -PE 0x7f5d0000-7f5e8000 \ imm32 ELF 0x7f5e8000-7f609000 Stabs msacm32<elf> -PE 0x7f5f0000-7f609000 \ msacm32 ELF 0x7f609000-7f680000 Deferred winmm<elf> -PE 0x7f620000-7f680000 \ winmm ELF 0x7f680000-7f705000 Deferred oleaut32<elf> -PE 0x7f6a0000-7f705000 \ oleaut32 ELF 0x7f705000-7f723000 Deferred iphlpapi<elf> -PE 0x7f710000-7f723000 \ iphlpapi ELF 0x7f723000-7f768000 Deferred rpcrt4<elf> -PE 0x7f740000-7f768000 \ rpcrt4 ELF 0x7f768000-7f7e2000 Deferred ole32<elf> -PE 0x7f780000-7f7e2000 \ ole32 ELF 0x7f7e2000-7f81b000 Deferred advapi32<elf> -PE 0x7f7f0000-7f81b000 \ advapi32 ELF 0x7f81b000-7f898000 Deferred gdi32<elf> -PE 0x7f830000-7f898000 \ gdi32 ELF 0x7f898000-7f9a0000 Deferred user32<elf> -PE 0x7f8c0000-7f9a0000 \ user32 ELF 0x7fcb3000-7fdb0000 Stabs kernel32<elf> -PE 0x7fce0000-7fdb0000 \ kernel32 ELF 0x7fec8000-7fed4000 Deferred libnss_files.so.2 ELF 0x7feda000-7fef0000 Deferred lz32<elf> -PE 0x7fee0000-7fef0000 \ lz32 ELF 0x7fef0000-7ffe4000 Deferred libwine_unicode.so.1 ELF 0x7ffe5000-7fffe000 Deferred version<elf> -PE 0x7fff0000-7fffe000 \ version ELF 0xb7f57000-b7f6f000 DIA libwine.so.1 Threads: process tid prio (all id:s are in hex) 00000008 (D) C:\shinkiro_pre\game.exe 0000000a 15 00000009 0 <== WineDbg terminated on pid 0x8 [alex@karlalex shinkiro_pre]$
I believe the following sequence of events is taking place:
- The function acmDriverAdd is called by the executable with these parameters: trace:msacm:acmDriverAddA (0x7fa9f3d4, 0x10000000, 10001040, 00000000, 00000003)
That is: hinstModule == 0x10000000, fdwAdd == ACM_DRIVERADDF_FUNCTION, lParam (acmDriverProc) == 0x10001040 - After verifying that the parameters are valid, the function calls: *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule);
Note that lParam is ignored (it even says so in a comment within the same file)
- The MSACM_RegisterDriver() function, in turn, calls MSACM_FillCache(). - MSACM_FillCache() calls MSACM_Message() in order to initialize a ACMDRIVERDETAILSW structure. However, this function eventually requires that hinstModule be a valid LPWINE_DRIVER reference, which it is not - it is not even a valid pointer (as reported by HeapValidate(GetProcessHeap(), 0, ptr)). Presumably hinstModule is a reference to the executable itself, and lParam(acmDriverProc) was expected to be enough to build a complete driver reference. The net result is that the ACMDRIVERDETAILSW structure remains uninitialized. - A HeapAlloc() is attempted based on the fields of the uninitialized structure. - (Segmentation fault)
I tried the following change in acmDriverAddA() at dlls/msacm/driver.c:
if (!hinstModule) { return MMSYSERR_INVALHANDLE; } else { #define WINE_DI_MAGIC 0x900F1B01 unsigned int * d = (unsigned int *)hinstModule; if (HeapValidate(GetProcessHeap(), 0, d) && *d == WINE_DI_MAGIC) { *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule); } else { return MMSYSERR_INVALHANDLE; } }
This essentially checks for the preconditions required for the remainder of the code. However, I believe this to be incomplete. So, the obvious solution should be to build a LPWINE_DRIVER function and add its reference to the chain maintained by winmm.dll. However, I am not sure of how to proceed from here. Since dlls/msacm/driver.c and dlls/winmm/driver.c end up in different DLLs, I don't think writing a function to manipulate the chain at dlls/winmm/driver.c could be called from dlls/msacm/driver.c without exporting it in the spec file. No obvious documented function in the spec file of winmm suggests itself as appropriate for the task of building a driver reference from outside winmm.dll, given only the driverProc.
How is this solved in other cases (that is, in a way that does not prevent the resulting patch from being accepted)?
Alex Villacís Lasso
------------------------------------------------------------------------ Mail enviado desde PortalMail 1.4.2 Web based email system. PaloSanto Solutions, Sunnyvale CA. http://www.palosanto.com
How is this solved in other cases (that is, in a way that does not prevent the resulting patch from being accepted)?
the way to go would be to no longer rely on winmm.SendDriverMessage, but to directly store in ACM structures the address of the DriverProc. In the case of acmDriverAdd, you would just store the function address, in the other cases you would grab the DriverProc address from the DLL. If you change this, you would be able to no longer export the driverProc from msacm and simply call acmDriverAdd for the internal msacm PCM handling driver.
A+
a_villacis@palosanto.com wrote:
I tried the following change in acmDriverAddA() at dlls/msacm/driver.c:
if (!hinstModule) { return MMSYSERR_INVALHANDLE; } else { #define WINE_DI_MAGIC 0x900F1B01 unsigned int * d = (unsigned int *)hinstModule; if (HeapValidate(GetProcessHeap(), 0, d) && *d == WINE_DI_MAGIC) { *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule); } else { return MMSYSERR_INVALHANDLE; } }
I saw a mail in wine-devel mentioning the approach of abandoning the dependency on DriverSendMessage(). I will try to implement it. Meanwhile, this patch prevents the game from crashing, although it does not add any functionality. However, it will try to report the unsupported configuration as a guide for later implementation.
Alex Villacís Lasso