https://bugs.winehq.org/show_bug.cgi?id=56260
--- Comment #7 from Fabian Maurer dark.shadow4@web.de --- Comment on attachment 75991 --> https://bugs.winehq.org/attachment.cgi?id=75991 Second Testprogram to reproduce the issue
/* WATCOM=/opt/watcom PATH=$WATCOM/binl:$PATH INCLUDE=$WATCOM/h:$WATCOM/h/win LIB=$WATCOM/lib286:$WATCOM/lib286/dos wcl -bcl=windows main.c -q mmsystem.lib -zu */
#include <windows.h> #include <stddef.h> #include <stdlib.h> #include <stdio.h> #include <mmsystem.h> #include <i86.h>
/* Error handling */
void error(const char* str) { MessageBox((HWND)0, str, "", 0); exit(1); }
void errori(const char* str, DWORD i) { static char t[20]; sprintf(t, "%s %lx", str, i); error(t); }
void mesi(const char* str, DWORD i) { static char t[20]; sprintf(t, "%s %lx", str, i); MessageBox((HWND)0, t, "", 0); }
void mes(const char* str) { MessageBox((HWND)0, str, "", 0); }
/* HOOK Stuff */
typedef struct { BYTE code_original[5]; BYTE code_hooked[5]; BOOL hooked; LPBYTE address; UINT selector; FARPROC callback; HGLOBAL hhook; } _hook_info; typedef _hook_info FAR* hook_info;
typedef UINT (WINAPI* tAllocCsToDsAlias)(UINT);
hook_info hook_init(HINSTANCE instance, const char* name_lib, const char* name_func, FARPROC hook_func) { HMODULE mod_kernel, mod_lib; FARPROC func; tAllocCsToDsAlias pAllocCsToDsAlias; int i; HGLOBAL hhook; hook_info hook;
hhook = GlobalAlloc(GMEM_MOVEABLE, sizeof(_hook_info)); hook = (hook_info)GlobalLock(hhook); hook->hhook = hhook; mod_kernel = GetModuleHandle("KERNEL"); mod_lib = GetModuleHandle(name_lib);
pAllocCsToDsAlias = (tAllocCsToDsAlias)GetProcAddress(mod_kernel,"AllocCsToDsAlias"); if (!pAllocCsToDsAlias) { error("AllocCsToDsAlias missing"); }
func = GetProcAddress(mod_lib, name_func); if (!func) { error("Can't get original func"); }
hook->callback = MakeProcInstance((FARPROC)hook_func, instance); if (hook->callback == NULL || hook->callback == hook_func) { error("MakeProcInstance failed"); }
hook->hooked = FALSE; hook->selector = pAllocCsToDsAlias(FP_SEG(func)); hook->address = (LPBYTE)MK_FP(hook->selector, FP_OFF(func)); if (hook->address[0] == 0xEA) { error("Already hooked, something went terribly wrong!"); } hook->code_hooked[0] = 0xEA; *(LPDWORD)(&hook->code_hooked[1]) = (DWORD)hook->callback;
for (i = 0; i< 5; i++) hook->code_original[i] = hook->address[i];
return hook; }
void hook_enable(hook_info hook) { int i; if (hook->hooked) return;
for (i = 0; i < 5; i++) hook->address[i] = hook->code_hooked[i]; hook->hooked = TRUE; }
void hook_disable(hook_info hook) { int i; if (!hook->hooked) return;
for (i = 0; i < 5; i++) hook->address[i] = hook->code_original[i]; hook->hooked = FALSE; }
void hook_free(hook_info hook) { HGLOBAL hhook; hook_disable(hook); FreeSelector(hook->selector); FreeProcInstance(hook->callback); hhook = hook->hhook; GlobalUnlock(hhook); GlobalFree(hhook); }
/* Main code */
static hook_info hook;
static int done = 0;
void CALLBACK _export waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { if (uMsg == WOM_DONE) { done = 1; } }
int WINAPI _export HookGetCodeInfoFunc(FARPROC proc, SEGINFO FAR* seginfo) { hook_disable(hook); GetCodeInfo(proc, seginfo); hook_enable(hook);
seginfo->flags &= ~(0x10); return 1; }
BOOL IsWine(void) { HMODULE kernel = GetModuleHandle("KERNEL"); FARPROC proc = GetProcAddress(kernel, "__wine_call_int_handler"); return proc != NULL; }
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWAVEOUT hout; PCMWAVEFORMAT format; WAVEHDR NEAR* block; int result; FARPROC callback; char NEAR* buffer; OFSTRUCT ofstruct; HFILE file;
if (!IsWine()) { hook = hook_init(hInstance, "KERNEL", "GetCodeInfo", (FARPROC)HookGetCodeInfoFunc); hook_enable(hook); }
if ((file = OpenFile("test.wav", &ofstruct, OF_READ)) == HFILE_ERROR) { error("CreateFile failed"); }
block = (WAVEHDR NEAR*)LocalAlloc(0, 8000 + sizeof(WAVEHDR));
buffer = (char NEAR*)block + sizeof(WAVEHDR); block->dwBufferLength = 8000; block->lpData = buffer;
if (_lread(file, buffer, 8000) == HFILE_ERROR) { error("ReadFile failed"); }
format.wf.wFormatTag = WAVE_FORMAT_PCM; format.wf.nChannels = 1; format.wf.nSamplesPerSec = 11025; format.wf.nBlockAlign = 1; format.wf.nAvgBytesPerSec = 11025; format.wBitsPerSample = 8;
callback = MakeProcInstance((FARPROC)waveOutProc, hInstance); if (callback == NULL) { error("MakeProcInstance failed"); }
if ((result = waveOutOpen(&hout, WAVE_MAPPER, (LPWAVEFORMAT)&format, (DWORD)callback, 0, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) { errori("waveOutOpen failed", result); } if (!IsWine()) { hook_free(hook); } waveOutPrepareHeader(hout, block, sizeof(WAVEHDR)); waveOutWrite(hout, block, sizeof(WAVEHDR)); while(!done) { } error("success!"); return 0; }