From: Aleksey Bragin Date: Tue, 20 Apr 2010 17:16:57 +0000 (+0000) Subject: - Sync localspl, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mscoree, msctf, msgsm32... X-Git-Tag: backups/header-work@57446~33^2~101 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=4a1f6e12e3faa48d51faf652b2b1f9fcf7a0a94b - Sync localspl, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mscoree, msctf, msgsm32.acm, mshtml to Wine-1.1.43. svn path=/trunk/; revision=46957 --- diff --git a/reactos/dll/win32/localspl/provider.c b/reactos/dll/win32/localspl/provider.c index b17e074b845..322418804c3 100644 --- a/reactos/dll/win32/localspl/provider.c +++ b/reactos/dll/win32/localspl/provider.c @@ -1375,7 +1375,7 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo } /* Verified with the Adobe PS Driver, that w2k does not use di.Version */ - RegSetValueExW(hdrv, versionW, 0, REG_DWORD, (LPBYTE) &env->driverversion, + RegSetValueExW(hdrv, versionW, 0, REG_DWORD, (const BYTE*) &env->driverversion, sizeof(DWORD)); RegSetValueExW(hdrv, driverW, 0, REG_SZ, (LPBYTE) di.pDriverPath, @@ -1395,7 +1395,7 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo RegSetValueExW(hdrv, help_fileW, 0, REG_SZ, (LPBYTE) di.pHelpFile, (lstrlenW(di.pHelpFile)+1)* sizeof(WCHAR)); else - RegSetValueExW(hdrv, help_fileW, 0, REG_SZ, (LPBYTE)emptyW, sizeof(emptyW)); + RegSetValueExW(hdrv, help_fileW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW)); apd_copyfile(di.pHelpFile, &apd); @@ -1404,7 +1404,7 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo RegSetValueExW(hdrv, dependent_filesW, 0, REG_MULTI_SZ, (LPBYTE) di.pDependentFiles, multi_sz_lenW(di.pDependentFiles)); else - RegSetValueExW(hdrv, dependent_filesW, 0, REG_MULTI_SZ, (LPBYTE)emptyW, sizeof(emptyW)); + RegSetValueExW(hdrv, dependent_filesW, 0, REG_MULTI_SZ, (const BYTE*)emptyW, sizeof(emptyW)); while ((ptr != NULL) && (ptr[0])) { if (apd_copyfile(ptr, &apd)) { ptr += lstrlenW(ptr) + 1; @@ -1420,20 +1420,20 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo RegSetValueExW(hdrv, monitorW, 0, REG_SZ, (LPBYTE) di.pMonitorName, (lstrlenW(di.pMonitorName)+1)* sizeof(WCHAR)); else - RegSetValueExW(hdrv, monitorW, 0, REG_SZ, (LPBYTE)emptyW, sizeof(emptyW)); + RegSetValueExW(hdrv, monitorW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW)); if (di.pDefaultDataType) RegSetValueExW(hdrv, datatypeW, 0, REG_SZ, (LPBYTE) di.pDefaultDataType, (lstrlenW(di.pDefaultDataType)+1)* sizeof(WCHAR)); else - RegSetValueExW(hdrv, datatypeW, 0, REG_SZ, (LPBYTE)emptyW, sizeof(emptyW)); + RegSetValueExW(hdrv, datatypeW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW)); /* settings for level 4 */ if (di.pszzPreviousNames) RegSetValueExW(hdrv, previous_namesW, 0, REG_MULTI_SZ, (LPBYTE) di.pszzPreviousNames, multi_sz_lenW(di.pszzPreviousNames)); else - RegSetValueExW(hdrv, previous_namesW, 0, REG_MULTI_SZ, (LPBYTE)emptyW, sizeof(emptyW)); + RegSetValueExW(hdrv, previous_namesW, 0, REG_MULTI_SZ, (const BYTE*)emptyW, sizeof(emptyW)); if (level > 5) TRACE("level %u for Driver %s is incomplete\n", level, debugstr_w(di.pName)); diff --git a/reactos/dll/win32/mciavi32/mciavi.c b/reactos/dll/win32/mciavi32/mciavi.c index d77525ca4ff..1c15dc55dbc 100644 --- a/reactos/dll/win32/mciavi32/mciavi.c +++ b/reactos/dll/win32/mciavi32/mciavi.c @@ -89,6 +89,7 @@ static DWORD MCIAVI_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp) wma->hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL); wma->wDevID = modp->wDeviceID; wma->wCommandTable = mciLoadCommandResource(MCIAVI_hInstance, mciAviWStr, 0); + wma->dwStatus = MCI_MODE_NOT_READY; modp->wCustomCommandTable = wma->wCommandTable; modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO; mciSetDriverData(wma->wDevID, (DWORD_PTR)wma); @@ -301,11 +302,11 @@ DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms) wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; + MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); + EnterCriticalSection(&wma->cs); if (wma->nUseCount == 1) { - if (wma->dwStatus != MCI_MODE_STOP) - dwRet = MCIAVI_mciStop(wDevID, MCI_WAIT, NULL); MCIAVI_CleanUp(wma); if ((dwFlags & MCI_NOTIFY) && lpParms) { @@ -836,14 +837,14 @@ static DWORD MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_P { WINE_MCIAVI *wma; - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + FIXME("(%04x, %08x, %p) Item %04x: stub\n", wDevID, dwFlags, lpParms, dwFlags & MCI_DGV_SETAUDIO_ITEM ? lpParms->dwItem : 0); + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - return MCIERR_UNSUPPORTED_FUNCTION; /* like w2k */ + return 0; } /****************************************************************************** @@ -870,14 +871,14 @@ static DWORD MCIAVI_mciSetVideo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETVIDEO_P { WINE_MCIAVI *wma; - FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms); - if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; + FIXME("(%04x, %08x, %p) Item %04x: stub\n", wDevID, dwFlags, lpParms, dwFlags & MCI_DGV_SETVIDEO_ITEM ? lpParms->dwItem : 0); + wma = MCIAVI_mciGetOpenDev(wDevID); if (wma == NULL) return MCIERR_INVALID_DEVICE_ID; - return MCIERR_UNSUPPORTED_FUNCTION; /* like w2k */ + return 0; } /****************************************************************************** diff --git a/reactos/dll/win32/mcicda/mcicda.c b/reactos/dll/win32/mcicda/mcicda.c index cf9132cdcff..6ea996a21b9 100644 --- a/reactos/dll/win32/mcicda/mcicda.c +++ b/reactos/dll/win32/mcicda/mcicda.c @@ -420,7 +420,8 @@ static DWORD MCICDA_Open(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpOpenPar if (dwFlags & MCI_OPEN_ELEMENT) { if (dwFlags & MCI_OPEN_ELEMENT_ID) { WARN("MCI_OPEN_ELEMENT_ID %p! Abort\n", lpOpenParms->lpstrElementName); - return MCIERR_NO_ELEMENT_ALLOWED; + ret = MCIERR_NO_ELEMENT_ALLOWED; + goto the_error; } TRACE("MCI_OPEN_ELEMENT element name: %s\n", debugstr_w(lpOpenParms->lpstrElementName)); if (!isalpha(lpOpenParms->lpstrElementName[0]) || lpOpenParms->lpstrElementName[1] != ':' || @@ -483,6 +484,8 @@ static DWORD MCICDA_Close(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParm if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID; + MCICDA_Stop(wDevID, MCI_WAIT, NULL); + if (--wmcda->nUseCount == 0) { CloseHandle(wmcda->handle); } diff --git a/reactos/dll/win32/mciqtz32/mciqtz.c b/reactos/dll/win32/mciqtz32/mciqtz.c index b98e163ebbc..c826de17633 100644 --- a/reactos/dll/win32/mciqtz32/mciqtz.c +++ b/reactos/dll/win32/mciqtz32/mciqtz.c @@ -153,7 +153,8 @@ static DWORD MCIQTZ_mciOpen(UINT wDevID, DWORD dwFlags, MCIQTZ_mciStop(wDevID, MCI_WAIT, NULL); - CoInitializeEx(NULL, COINIT_MULTITHREADED); + hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); + wma->uninit = SUCCEEDED(hr); hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, (LPVOID*)&wma->pgraph); if (FAILED(hr)) { @@ -197,7 +198,8 @@ err: IMediaControl_Release(wma->pmctrl); wma->pmctrl = NULL; - CoUninitialize(); + if (wma->uninit) + CoUninitialize(); return MCIERR_INTERNAL; } @@ -220,7 +222,8 @@ static DWORD MCIQTZ_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpP if (wma->opened) { IGraphBuilder_Release(wma->pgraph); IMediaControl_Release(wma->pmctrl); - CoUninitialize(); + if (wma->uninit) + CoUninitialize(); wma->opened = FALSE; } diff --git a/reactos/dll/win32/mciqtz32/mciqtz_private.h b/reactos/dll/win32/mciqtz32/mciqtz_private.h index dcfcad0eb4a..caf80de4dc9 100644 --- a/reactos/dll/win32/mciqtz32/mciqtz_private.h +++ b/reactos/dll/win32/mciqtz32/mciqtz_private.h @@ -28,6 +28,7 @@ typedef struct { MCIDEVICEID wDevID; BOOL opened; + BOOL uninit; IGraphBuilder* pgraph; IMediaControl* pmctrl; BOOL started; diff --git a/reactos/dll/win32/mciseq/mcimidi.c b/reactos/dll/win32/mciseq/mcimidi.c index 301428d517d..87753c33dde 100644 --- a/reactos/dll/win32/mciseq/mcimidi.c +++ b/reactos/dll/win32/mciseq/mcimidi.c @@ -62,6 +62,7 @@ typedef struct tagWINE_MCIMIDI { UINT wDevID; /* the MCI one */ HMIDI hMidi; int nUseCount; /* Incremented for each shared open */ + WORD wPort; /* the WINMM device unit */ WORD wNotifyDeviceID; /* MCI device ID with a pending notification */ HANDLE hCallback; /* Callback handle for pending notification */ HMMIO hFile; /* mmio file handle open as Element */ @@ -726,6 +727,7 @@ static DWORD MIDI_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpParms) wmm->hFile = 0; wmm->hMidi = 0; + wmm->wPort = MIDI_MAPPER; wmm->lpstrElementName = NULL; dwDeviceID = lpParms->wDeviceID; @@ -962,8 +964,8 @@ static DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) MIDI_mciReadNextEvent(wmm, mmt); /* FIXME == 0 */ } - dwRet = midiOutOpen((LPHMIDIOUT)&wmm->hMidi, MIDIMAPPER, 0L, 0L, CALLBACK_NULL); - /* dwRet = midiInOpen(&wmm->hMidi, MIDIMAPPER, 0L, 0L, CALLBACK_NULL);*/ + dwRet = midiOutOpen((LPHMIDIOUT)&wmm->hMidi, wmm->wPort, 0L, 0L, CALLBACK_NULL); + /* dwRet = midiInOpen(&wmm->hMidi, wmm->wPort, 0L, 0L, CALLBACK_NULL);*/ if (dwRet != MMSYSERR_NOERROR) { return dwRet; } @@ -1290,7 +1292,7 @@ static DWORD MIDI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa /************************************************************************** * MIDI_mciSet [internal] */ -static DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms) +static DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SEQ_SET_PARMS lpParms) { WINE_MCIMIDI* wmm = MIDI_mciGetOpenDev(wDevID); @@ -1359,8 +1361,15 @@ static DWORD MIDI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms) TRACE("MCI_SEQ_SET_SLAVE !\n"); if (dwFlags & MCI_SEQ_SET_OFFSET) TRACE("MCI_SEQ_SET_OFFSET !\n"); - if (dwFlags & MCI_SEQ_SET_PORT) - TRACE("MCI_SEQ_SET_PORT !\n"); + if (dwFlags & MCI_SEQ_SET_PORT) { + TRACE("MCI_SEQ_SET_PORT = %d\n", lpParms->dwPort); + if ((UINT16)lpParms->dwPort != (UINT16)MIDI_MAPPER && + (UINT16)lpParms->dwPort >= midiOutGetNumDevs()) + /* FIXME: input/output port distinction? */ + return MCIERR_SEQ_PORT_NONEXISTENT; + /* FIXME: Native manages to swap the device while playing! */ + wmm->wPort = lpParms->dwPort; + } if (dwFlags & MCI_SEQ_SET_TEMPO) TRACE("MCI_SEQ_SET_TEMPO !\n"); return 0; @@ -1459,8 +1468,13 @@ static DWORD MIDI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpPar lpParms->dwReturn = 0; break; case MCI_SEQ_STATUS_PORT: - TRACE("MCI_SEQ_STATUS_PORT (%u)!\n", wmm->wDevID); - lpParms->dwReturn = MIDI_MAPPER; + if (wmm->wPort != (UINT16)MIDI_MAPPER) + lpParms->dwReturn = wmm->wPort; + else { + lpParms->dwReturn = MAKEMCIRESOURCE(MIDI_MAPPER, MCI_SEQ_MAPPER_S); + ret = MCI_RESOURCE_RETURNED; + } + TRACE("MCI_SEQ_STATUS_PORT (%u) => %d\n", wmm->wDevID, wmm->wPort); break; case MCI_SEQ_STATUS_TEMPO: TRACE("MCI_SEQ_STATUS_TEMPO !\n"); @@ -1664,7 +1678,7 @@ LRESULT CALLBACK MCIMIDI_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, case MCI_PLAY: return MIDI_mciPlay (dwDevID, dwParam1, (LPMCI_PLAY_PARMS) dwParam2); case MCI_RECORD: return MIDI_mciRecord (dwDevID, dwParam1, (LPMCI_RECORD_PARMS) dwParam2); case MCI_STOP: return MIDI_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); - case MCI_SET: return MIDI_mciSet (dwDevID, dwParam1, (LPMCI_SET_PARMS) dwParam2); + case MCI_SET: return MIDI_mciSet (dwDevID, dwParam1, (LPMCI_SEQ_SET_PARMS) dwParam2); case MCI_PAUSE: return MIDI_mciPause (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); case MCI_RESUME: return MIDI_mciResume (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); case MCI_STATUS: return MIDI_mciStatus (dwDevID, dwParam1, (LPMCI_STATUS_PARMS) dwParam2); diff --git a/reactos/dll/win32/mciwave/mciwave.c b/reactos/dll/win32/mciwave/mciwave.c index 24e75ee9dac..87dc260207c 100644 --- a/reactos/dll/win32/mciwave/mciwave.c +++ b/reactos/dll/win32/mciwave/mciwave.c @@ -47,6 +47,8 @@ typedef struct { WAVEFORMATEX wfxRef; LPWAVEFORMATEX lpWaveFormat; /* Points to wfxRef until set by OPEN or RECORD */ BOOL fInput; /* FALSE = Output, TRUE = Input */ + WORD wInput; /* wave input device */ + WORD wOutput; /* wave output device */ volatile WORD dwStatus; /* one from MCI_MODE_xxxx */ DWORD dwMciTimeFormat;/* One of the supported MCI_FORMAT_xxxx */ DWORD dwPosition; /* position in bytes in chunk */ @@ -529,6 +531,7 @@ static LRESULT WAVE_mciOpen(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_P wmw->nUseCount++; + wmw->wInput = wmw->wOutput = WAVE_MAPPER; wmw->fInput = FALSE; wmw->hWave = 0; wmw->dwStatus = MCI_MODE_NOT_READY; @@ -831,8 +834,7 @@ static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, */ mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */ - /* FIXME: how to choose between several output channels ? here mapper is forced */ - dwRet = waveOutOpen((HWAVEOUT *)&wmw->hWave, WAVE_MAPPER, wmw->lpWaveFormat, + dwRet = waveOutOpen((HWAVEOUT *)&wmw->hWave, wmw->wOutput, wmw->lpWaveFormat, (DWORD_PTR)WAVE_mciPlayCallback, (DWORD_PTR)wmw, CALLBACK_FUNCTION); if (dwRet != 0) { @@ -1064,11 +1066,7 @@ static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt */ mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */ - /* By default the device will be opened for output, the MCI_CUE function is there to - * change from output to input and back - */ - /* FIXME: how to choose between several output channels ? here mapper is forced */ - dwRet = waveInOpen((HWAVEIN*)&wmw->hWave, WAVE_MAPPER, wmw->lpWaveFormat, + dwRet = waveInOpen((HWAVEIN*)&wmw->hWave, wmw->wInput, wmw->lpWaveFormat, (DWORD_PTR)WAVE_mciRecordCallback, (DWORD_PTR)wmw, CALLBACK_FUNCTION); if (dwRet != MMSYSERR_NOERROR) { @@ -1279,7 +1277,7 @@ static DWORD WAVE_mciSeek(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lp /************************************************************************** * WAVE_mciSet [internal] */ -static DWORD WAVE_mciSet(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms) +static DWORD WAVE_mciSet(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_SET_PARMS lpParms) { WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID); @@ -1337,44 +1335,64 @@ static DWORD WAVE_mciSet(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpPa default: WARN("Unknown audio channel %u\n", lpParms->dwAudio); break; } } - if (dwFlags & MCI_WAVE_INPUT) - TRACE("MCI_WAVE_INPUT !\n"); - if (dwFlags & MCI_WAVE_OUTPUT) - TRACE("MCI_WAVE_OUTPUT !\n"); - if (dwFlags & MCI_WAVE_SET_ANYINPUT) - TRACE("MCI_WAVE_SET_ANYINPUT !\n"); - if (dwFlags & MCI_WAVE_SET_ANYOUTPUT) - TRACE("MCI_WAVE_SET_ANYOUTPUT !\n"); + if (dwFlags & MCI_WAVE_INPUT) { + TRACE("MCI_WAVE_INPUT = %d\n", lpParms->wInput); + if (lpParms->wInput >= waveInGetNumDevs()) + return MCIERR_OUTOFRANGE; + if (wmw->wInput != (WORD)lpParms->wInput) + WAVE_mciStop(wDevID, MCI_WAIT, NULL); + wmw->wInput = lpParms->wInput; + } + if (dwFlags & MCI_WAVE_OUTPUT) { + TRACE("MCI_WAVE_OUTPUT = %d\n", lpParms->wOutput); + if (lpParms->wOutput >= waveOutGetNumDevs()) + return MCIERR_OUTOFRANGE; + if (wmw->wOutput != (WORD)lpParms->wOutput) + WAVE_mciStop(wDevID, MCI_WAIT, NULL); + wmw->wOutput = lpParms->wOutput; + } + if (dwFlags & MCI_WAVE_SET_ANYINPUT) { + TRACE("MCI_WAVE_SET_ANYINPUT\n"); + if (wmw->wInput != (WORD)lpParms->wInput) + WAVE_mciStop(wDevID, MCI_WAIT, NULL); + wmw->wInput = WAVE_MAPPER; + } + if (dwFlags & MCI_WAVE_SET_ANYOUTPUT) { + TRACE("MCI_WAVE_SET_ANYOUTPUT\n"); + if (wmw->wOutput != (WORD)lpParms->wOutput) + WAVE_mciStop(wDevID, MCI_WAIT, NULL); + wmw->wOutput = WAVE_MAPPER; + } /* Set wave format parameters is refused after Open or Record.*/ if (dwFlags & MCI_WAVE_SET_FORMATTAG) { - TRACE("MCI_WAVE_SET_FORMATTAG = %d\n", ((LPMCI_WAVE_SET_PARMS)lpParms)->wFormatTag); + TRACE("MCI_WAVE_SET_FORMATTAG = %d\n", lpParms->wFormatTag); if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION; - if (((LPMCI_WAVE_SET_PARMS)lpParms)->wFormatTag != WAVE_FORMAT_PCM) + if (lpParms->wFormatTag != WAVE_FORMAT_PCM) return MCIERR_OUTOFRANGE; } if (dwFlags & MCI_WAVE_SET_AVGBYTESPERSEC) { if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION; - wmw->wfxRef.nAvgBytesPerSec = ((LPMCI_WAVE_SET_PARMS)lpParms)->nAvgBytesPerSec; + wmw->wfxRef.nAvgBytesPerSec = lpParms->nAvgBytesPerSec; TRACE("MCI_WAVE_SET_AVGBYTESPERSEC = %d\n", wmw->wfxRef.nAvgBytesPerSec); } if (dwFlags & MCI_WAVE_SET_BITSPERSAMPLE) { if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION; - wmw->wfxRef.wBitsPerSample = ((LPMCI_WAVE_SET_PARMS)lpParms)->wBitsPerSample; + wmw->wfxRef.wBitsPerSample = lpParms->wBitsPerSample; TRACE("MCI_WAVE_SET_BITSPERSAMPLE = %d\n", wmw->wfxRef.wBitsPerSample); } if (dwFlags & MCI_WAVE_SET_BLOCKALIGN) { if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION; - wmw->wfxRef.nBlockAlign = ((LPMCI_WAVE_SET_PARMS)lpParms)->nBlockAlign; + wmw->wfxRef.nBlockAlign = lpParms->nBlockAlign; TRACE("MCI_WAVE_SET_BLOCKALIGN = %d\n", wmw->wfxRef.nBlockAlign); } if (dwFlags & MCI_WAVE_SET_CHANNELS) { if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION; - wmw->wfxRef.nChannels = ((LPMCI_WAVE_SET_PARMS)lpParms)->nChannels; + wmw->wfxRef.nChannels = lpParms->nChannels; TRACE("MCI_WAVE_SET_CHANNELS = %d\n", wmw->wfxRef.nChannels); } if (dwFlags & MCI_WAVE_SET_SAMPLESPERSEC) { if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION; - wmw->wfxRef.nSamplesPerSec = ((LPMCI_WAVE_SET_PARMS)lpParms)->nSamplesPerSec; + wmw->wfxRef.nSamplesPerSec = lpParms->nSamplesPerSec; TRACE("MCI_WAVE_SET_SAMPLESPERSEC = %d\n", wmw->wfxRef.nSamplesPerSec); } if (dwFlags & MCI_NOTIFY) @@ -1500,24 +1518,34 @@ static DWORD WAVE_mciStatus(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_STATUS_PARM ret = MCI_RESOURCE_RETURNED; break; case MCI_WAVE_INPUT: - TRACE("MCI_WAVE_INPUT !\n"); - lpParms->dwReturn = 0; - ret = MCIERR_WAVE_INPUTUNSPECIFIED; + if (wmw->wInput != (WORD)WAVE_MAPPER) + lpParms->dwReturn = wmw->wInput; + else { + lpParms->dwReturn = MAKEMCIRESOURCE(WAVE_MAPPER, WAVE_MAPPER_S); + ret = MCI_RESOURCE_RETURNED; + } + TRACE("MCI_WAVE_INPUT => %d\n", (signed)wmw->wInput); break; case MCI_WAVE_OUTPUT: - TRACE("MCI_WAVE_OUTPUT !\n"); - { - UINT id; - if (waveOutGetID(wmw->hWave, &id) == MMSYSERR_NOERROR) { - lpParms->dwReturn = id; - } else { - lpParms->dwReturn = 0; - ret = MCIERR_WAVE_OUTPUTUNSPECIFIED; - } + if (wmw->wOutput != (WORD)WAVE_MAPPER) + lpParms->dwReturn = wmw->wOutput; + else { + lpParms->dwReturn = MAKEMCIRESOURCE(WAVE_MAPPER, WAVE_MAPPER_S); + ret = MCI_RESOURCE_RETURNED; } + TRACE("MCI_WAVE_OUTPUT => %d\n", (signed)wmw->wOutput); break; /* It is always ok to query wave format parameters, * except on auto-open yield MCIERR_UNSUPPORTED_FUNCTION. */ + case MCI_WAVE_STATUS_FORMATTAG: + if (wmw->lpWaveFormat->wFormatTag != WAVE_FORMAT_PCM) + lpParms->dwReturn = wmw->lpWaveFormat->wFormatTag; + else { + lpParms->dwReturn = MAKEMCIRESOURCE(WAVE_FORMAT_PCM, WAVE_FORMAT_PCM_S); + ret = MCI_RESOURCE_RETURNED; + } + TRACE("MCI_WAVE_FORMATTAG => %lu\n", lpParms->dwReturn); + break; case MCI_WAVE_STATUS_AVGBYTESPERSEC: lpParms->dwReturn = wmw->lpWaveFormat->nAvgBytesPerSec; TRACE("MCI_WAVE_STATUS_AVGBYTESPERSEC => %lu\n", lpParms->dwReturn); @@ -1534,10 +1562,6 @@ static DWORD WAVE_mciStatus(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_STATUS_PARM lpParms->dwReturn = wmw->lpWaveFormat->nChannels; TRACE("MCI_WAVE_STATUS_CHANNELS => %lu\n", lpParms->dwReturn); break; - case MCI_WAVE_STATUS_FORMATTAG: - lpParms->dwReturn = wmw->lpWaveFormat->wFormatTag; - TRACE("MCI_WAVE_FORMATTAG => %lu\n", lpParms->dwReturn); - break; case MCI_WAVE_STATUS_SAMPLESPERSEC: lpParms->dwReturn = wmw->lpWaveFormat->nSamplesPerSec; TRACE("MCI_WAVE_STATUS_SAMPLESPERSEC => %lu\n", lpParms->dwReturn); @@ -1705,7 +1729,7 @@ LRESULT CALLBACK MCIWAVE_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, case MCI_PLAY: return WAVE_mciPlay (dwDevID, dwParam1, dwParam2, NULL); case MCI_RECORD: return WAVE_mciRecord (dwDevID, dwParam1, dwParam2, NULL); case MCI_STOP: return WAVE_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); - case MCI_SET: return WAVE_mciSet (dwDevID, dwParam1, (LPMCI_SET_PARMS) dwParam2); + case MCI_SET: return WAVE_mciSet (dwDevID, dwParam1, (LPMCI_WAVE_SET_PARMS) dwParam2); case MCI_PAUSE: return WAVE_mciPause (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); case MCI_RESUME: return WAVE_mciResume (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2); case MCI_STATUS: return WAVE_mciStatus (dwDevID, dwParam1, (LPMCI_STATUS_PARMS) dwParam2); diff --git a/reactos/dll/win32/mscoree/mscoree.rbuild b/reactos/dll/win32/mscoree/mscoree.rbuild index 2fa0743f07a..a014334a962 100644 --- a/reactos/dll/win32/mscoree/mscoree.rbuild +++ b/reactos/dll/win32/mscoree/mscoree.rbuild @@ -5,6 +5,7 @@ wine advapi32 + shell32 uuid corruntimehost.c mscoree_main.c diff --git a/reactos/dll/win32/mscoree/mscoree_main.c b/reactos/dll/win32/mscoree/mscoree_main.c index 5b20c854c2e..0e6f25204cc 100644 --- a/reactos/dll/win32/mscoree/mscoree_main.c +++ b/reactos/dll/win32/mscoree/mscoree_main.c @@ -21,11 +21,14 @@ #include +#include "wine/unicode.h" #include "windef.h" #include "winbase.h" #include "winuser.h" +#include "winnls.h" #include "winreg.h" #include "ole2.h" +#include "shellapi.h" #include "initguid.h" #include "cor.h" @@ -36,26 +39,25 @@ WINE_DEFAULT_DEBUG_CHANNEL( mscoree ); -static LPWSTR get_mono_exe(void) +static BOOL get_mono_path(LPWSTR path) { - static const WCHAR mono_exe[] = {'b','i','n','\\','m','o','n','o','.','e','x','e',' ',0}; static const WCHAR mono_key[] = {'S','o','f','t','w','a','r','e','\\','N','o','v','e','l','l','\\','M','o','n','o',0}; static const WCHAR defaul_clr[] = {'D','e','f','a','u','l','t','C','L','R',0}; static const WCHAR install_root[] = {'S','d','k','I','n','s','t','a','l','l','R','o','o','t',0}; static const WCHAR slash[] = {'\\',0}; - WCHAR version[64], version_key[MAX_PATH], root[MAX_PATH], *ret; - DWORD len, size; + WCHAR version[64], version_key[MAX_PATH]; + DWORD len; HKEY key; if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, mono_key, 0, KEY_READ, &key)) - return NULL; + return FALSE; len = sizeof(version); if (RegQueryValueExW(key, defaul_clr, 0, NULL, (LPBYTE)version, &len)) { RegCloseKey(key); - return NULL; + return FALSE; } RegCloseKey(key); @@ -64,24 +66,129 @@ static LPWSTR get_mono_exe(void) lstrcatW(version_key, version); if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, version_key, 0, KEY_READ, &key)) - return NULL; + return FALSE; - len = sizeof(root); - if (RegQueryValueExW(key, install_root, 0, NULL, (LPBYTE)root, &len)) + len = sizeof(WCHAR) * MAX_PATH; + if (RegQueryValueExW(key, install_root, 0, NULL, (LPBYTE)path, &len)) { RegCloseKey(key); - return NULL; + return FALSE; } RegCloseKey(key); - size = len + sizeof(slash) + sizeof(mono_exe); - if (!(ret = HeapAlloc(GetProcessHeap(), 0, size))) return NULL; + return TRUE; +} + +static CRITICAL_SECTION mono_lib_cs; +static CRITICAL_SECTION_DEBUG mono_lib_cs_debug = +{ + 0, 0, &mono_lib_cs, + { &mono_lib_cs_debug.ProcessLocksList, + &mono_lib_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": mono_lib_cs") } +}; +static CRITICAL_SECTION mono_lib_cs = { &mono_lib_cs_debug, -1, 0, 0, 0, 0 }; + +HMODULE mono_handle; + +void (*mono_config_parse)(const char *filename); +MonoAssembly* (*mono_domain_assembly_open) (MonoDomain *domain, const char *name); +void (*mono_jit_cleanup)(MonoDomain *domain); +int (*mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]); +MonoDomain* (*mono_jit_init)(const char *file); +int (*mono_jit_set_trace_options)(const char* options); +void (*mono_set_dirs)(const char *assembly_dir, const char *config_dir); + +static void set_environment(LPCWSTR bin_path) +{ + WCHAR path_env[MAX_PATH]; + int len; + + static const WCHAR pathW[] = {'P','A','T','H',0}; + + /* We have to modify PATH as Mono loads other DLLs from this directory. */ + GetEnvironmentVariableW(pathW, path_env, sizeof(path_env)/sizeof(WCHAR)); + len = strlenW(path_env); + path_env[len++] = ';'; + strcpyW(path_env+len, bin_path); + SetEnvironmentVariableW(pathW, path_env); +} + +static HMODULE load_mono(void) +{ + static const WCHAR mono_dll[] = {'\\','b','i','n','\\','m','o','n','o','.','d','l','l',0}; + static const WCHAR libmono_dll[] = {'\\','b','i','n','\\','l','i','b','m','o','n','o','.','d','l','l',0}; + static const WCHAR bin[] = {'\\','b','i','n',0}; + static const WCHAR lib[] = {'\\','l','i','b',0}; + static const WCHAR etc[] = {'\\','e','t','c',0}; + HMODULE result; + WCHAR mono_path[MAX_PATH], mono_dll_path[MAX_PATH+16], mono_bin_path[MAX_PATH+4]; + WCHAR mono_lib_path[MAX_PATH+4], mono_etc_path[MAX_PATH+4]; + char mono_lib_path_a[MAX_PATH], mono_etc_path_a[MAX_PATH]; + + EnterCriticalSection(&mono_lib_cs); + + if (!mono_handle) + { + if (!get_mono_path(mono_path)) goto end; + + strcpyW(mono_bin_path, mono_path); + strcatW(mono_bin_path, bin); + set_environment(mono_bin_path); + + strcpyW(mono_lib_path, mono_path); + strcatW(mono_lib_path, lib); + WideCharToMultiByte(CP_UTF8, 0, mono_lib_path, -1, mono_lib_path_a, MAX_PATH, NULL, NULL); + + strcpyW(mono_etc_path, mono_path); + strcatW(mono_etc_path, etc); + WideCharToMultiByte(CP_UTF8, 0, mono_etc_path, -1, mono_etc_path_a, MAX_PATH, NULL, NULL); + + strcpyW(mono_dll_path, mono_path); + strcatW(mono_dll_path, mono_dll); + mono_handle = LoadLibraryW(mono_dll_path); + + if (!mono_handle) + { + strcpyW(mono_dll_path, mono_path); + strcatW(mono_dll_path, libmono_dll); + mono_handle = LoadLibraryW(mono_dll_path); + } + + if (!mono_handle) goto end; + +#define LOAD_MONO_FUNCTION(x) do { \ + x = (void*)GetProcAddress(mono_handle, #x); \ + if (!x) { \ + mono_handle = NULL; \ + goto end; \ + } \ +} while (0); + + LOAD_MONO_FUNCTION(mono_config_parse); + LOAD_MONO_FUNCTION(mono_domain_assembly_open); + LOAD_MONO_FUNCTION(mono_jit_cleanup); + LOAD_MONO_FUNCTION(mono_jit_exec); + LOAD_MONO_FUNCTION(mono_jit_init); + LOAD_MONO_FUNCTION(mono_jit_set_trace_options); + LOAD_MONO_FUNCTION(mono_set_dirs); + +#undef LOAD_MONO_FUNCTION + + mono_set_dirs(mono_lib_path_a, mono_etc_path_a); + + mono_config_parse(NULL); + } + +end: + result = mono_handle; - lstrcpyW(ret, root); - lstrcatW(ret, slash); - lstrcatW(ret, mono_exe); + LeaveCriticalSection(&mono_lib_cs); + + if (!result) + MESSAGE("wine: Install the Windows version of Mono to run .NET executables\n"); - return ret; + return result; } HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, @@ -89,20 +196,16 @@ HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID *ppv) { - WCHAR *mono_exe; - FIXME("(%s, %s, %s, %p, %d, %s, %s, %p): semi-stub!\n", debugstr_w(pwszVersion), debugstr_w(pwszBuildFlavor), debugstr_w(pwszHostConfigFile), pReserved, startupFlags, debugstr_guid(rclsid), debugstr_guid(riid), ppv); - if (!(mono_exe = get_mono_exe())) + if (!get_mono_path(NULL)) { MESSAGE("wine: Install the Windows version of Mono to run .NET executables\n"); return E_FAIL; } - HeapFree(GetProcessHeap(), 0, mono_exe); - return S_OK; } @@ -138,68 +241,73 @@ BOOL WINAPI _CorDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return TRUE; } -__int32 WINAPI _CorExeMain(void) +static void get_utf8_args(int *argc, char ***argv) { - STARTUPINFOW si; - PROCESS_INFORMATION pi; - WCHAR *mono_exe, *cmd_line; - DWORD size, exit_code; - static const WCHAR WINE_MONO_TRACE[]={'W','I','N','E','_','M','O','N','O','_','T','R','A','C','E',0}; - static const WCHAR trace_switch_start[]={'"','-','-','t','r','a','c','e','=',0}; - static const WCHAR trace_switch_end[]={'"',' ',0}; - int trace_size; - WCHAR trace_setting[256]; + WCHAR **argvw; + int size=0, i; + char *current_arg; + + argvw = CommandLineToArgvW(GetCommandLineW(), argc); - if (!(mono_exe = get_mono_exe())) + for (i=0; i<*argc; i++) { - MESSAGE("install the Windows version of Mono to run .NET executables\n"); - return -1; + size += sizeof(char*); + size += WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL); } + size += sizeof(char*); - trace_size = GetEnvironmentVariableW(WINE_MONO_TRACE, trace_setting, sizeof(trace_setting)/sizeof(WCHAR)); + *argv = HeapAlloc(GetProcessHeap(), 0, size); + current_arg = (char*)(*argv + *argc + 1); - size = (lstrlenW(mono_exe) + lstrlenW(GetCommandLineW()) + 1) * sizeof(WCHAR); + for (i=0; i<*argc; i++) + { + (*argv)[i] = current_arg; + current_arg += WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, current_arg, size, NULL, NULL); + } - if (trace_size) - size += (trace_size + lstrlenW(trace_switch_start) + lstrlenW(trace_switch_end)) * sizeof(WCHAR); + (*argv)[*argc] = NULL; - if (!(cmd_line = HeapAlloc(GetProcessHeap(), 0, size))) + HeapFree(GetProcessHeap(), 0, argvw); +} + +__int32 WINAPI _CorExeMain(void) +{ + int exit_code; + int trace_size; + char trace_setting[256]; + int argc; + char **argv; + MonoDomain *domain; + MonoAssembly *assembly; + char filename[MAX_PATH]; + + if (!load_mono()) { - HeapFree(GetProcessHeap(), 0, mono_exe); return -1; } - lstrcpyW(cmd_line, mono_exe); - HeapFree(GetProcessHeap(), 0, mono_exe); + get_utf8_args(&argc, &argv); + + trace_size = GetEnvironmentVariableA("WINE_MONO_TRACE", trace_setting, sizeof(trace_setting)); if (trace_size) { - lstrcatW(cmd_line, trace_switch_start); - lstrcatW(cmd_line, trace_setting); - lstrcatW(cmd_line, trace_switch_end); + mono_jit_set_trace_options(trace_setting); } - lstrcatW(cmd_line, GetCommandLineW()); + GetModuleFileNameA(NULL, filename, MAX_PATH); - TRACE("new command line: %s\n", debugstr_w(cmd_line)); + domain = mono_jit_init(filename); - memset(&si, 0, sizeof(si)); - si.cb = sizeof(si); - if (!CreateProcessW(NULL, cmd_line, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) - { - HeapFree(GetProcessHeap(), 0, cmd_line); - return -1; - } - HeapFree(GetProcessHeap(), 0, cmd_line); + assembly = mono_domain_assembly_open(domain, filename); + + exit_code = mono_jit_exec(domain, assembly, argc, argv); - /* wait for the process to exit */ - WaitForSingleObject(pi.hProcess, INFINITE); - GetExitCodeProcess(pi.hProcess, &exit_code); + mono_jit_cleanup(domain); - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); + HeapFree(GetProcessHeap(), 0, argv); - return (int)exit_code; + return exit_code; } __int32 WINAPI _CorExeMain2(PBYTE ptrMemory, DWORD cntMemory, LPWSTR imageName, LPWSTR loaderName, LPWSTR cmdLine) diff --git a/reactos/dll/win32/mscoree/mscoree_private.h b/reactos/dll/win32/mscoree/mscoree_private.h index f329455fff1..f14da1d15cd 100644 --- a/reactos/dll/win32/mscoree/mscoree_private.h +++ b/reactos/dll/win32/mscoree/mscoree_private.h @@ -22,5 +22,18 @@ extern IUnknown* create_corruntimehost(void); +/* Mono 2.6 embedding */ +typedef struct _MonoDomain MonoDomain; +typedef struct _MonoAssembly MonoAssembly; + +extern HMODULE mono_handle; + +extern void (*mono_config_parse)(const char *filename); +extern MonoAssembly* (*mono_domain_assembly_open) (MonoDomain *domain, const char *name); +extern void (*mono_jit_cleanup)(MonoDomain *domain); +extern int (*mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]); +extern MonoDomain* (*mono_jit_init)(const char *file); +extern int (*mono_jit_set_trace_options)(const char* options); +extern void (*mono_set_dirs)(const char *assembly_dir, const char *config_dir); #endif /* __MSCOREE_PRIVATE__ */ diff --git a/reactos/dll/win32/msctf/displayattributemgr.c b/reactos/dll/win32/msctf/displayattributemgr.c new file mode 100644 index 00000000000..75248cd4393 --- /dev/null +++ b/reactos/dll/win32/msctf/displayattributemgr.c @@ -0,0 +1,139 @@ +/* + * ITfDisplayAttributeMgr implementation + * + * Copyright 2010 CodeWeavers, Aric Stewart + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "wine/debug.h" +#include "winbase.h" +#include "winreg.h" +#include "shlwapi.h" + +#include "msctf.h" +#include "msctf_internal.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msctf); + +typedef struct tagDisplayAttributeMgr { + const ITfDisplayAttributeMgrVtbl *DisplayAttributeMgrVtbl; + + LONG refCount; + +} DisplayAttributeMgr; + +static void DisplayAttributeMgr_Destructor(DisplayAttributeMgr *This) +{ + TRACE("destroying %p\n", This); + + HeapFree(GetProcessHeap(),0,This); +} + +static HRESULT WINAPI DisplayAttributeMgr_QueryInterface(ITfDisplayAttributeMgr *iface, REFIID iid, LPVOID *ppvOut) +{ + DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface; + *ppvOut = NULL; + + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfDisplayAttributeMgr)) + { + *ppvOut = This; + } + + if (*ppvOut) + { + IUnknown_AddRef(iface); + return S_OK; + } + + WARN("unsupported interface: %s\n", debugstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI DisplayAttributeMgr_AddRef(ITfDisplayAttributeMgr *iface) +{ + DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface; + return InterlockedIncrement(&This->refCount); +} + +static ULONG WINAPI DisplayAttributeMgr_Release(ITfDisplayAttributeMgr *iface) +{ + DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface; + ULONG ret; + + ret = InterlockedDecrement(&This->refCount); + if (ret == 0) + DisplayAttributeMgr_Destructor(This); + return ret; +} + +/***************************************************** + * ITfDisplayAttributeMgr functions + *****************************************************/ + +static HRESULT WINAPI DisplayAttributeMgr_OnUpdateInfo(ITfDisplayAttributeMgr *iface) +{ + DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface; + + FIXME("STUB:(%p)\n",This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DisplayAttributeMgr_EnumDisplayAttributeInfo(ITfDisplayAttributeMgr *iface, IEnumTfDisplayAttributeInfo **ppEnum) +{ + DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface; + + FIXME("STUB:(%p)\n",This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DisplayAttributeMgr_GetDisplayAttributeInfo(ITfDisplayAttributeMgr *iface, REFGUID guid, ITfDisplayAttributeInfo **ppInfo, CLSID *pclsidOwner) +{ + DisplayAttributeMgr *This = (DisplayAttributeMgr *)iface; + + FIXME("STUB:(%p)\n",This); + return E_NOTIMPL; +} + +static const ITfDisplayAttributeMgrVtbl DisplayAttributeMgr_DisplayAttributeMgrVtbl = +{ + DisplayAttributeMgr_QueryInterface, + DisplayAttributeMgr_AddRef, + DisplayAttributeMgr_Release, + + DisplayAttributeMgr_OnUpdateInfo, + DisplayAttributeMgr_EnumDisplayAttributeInfo, + DisplayAttributeMgr_GetDisplayAttributeInfo +}; + +HRESULT DisplayAttributeMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) +{ + DisplayAttributeMgr *This; + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + This = HeapAlloc(GetProcessHeap(),0,sizeof(DisplayAttributeMgr)); + if (This == NULL) + return E_OUTOFMEMORY; + + This->DisplayAttributeMgrVtbl= &DisplayAttributeMgr_DisplayAttributeMgrVtbl; + This->refCount = 1; + + TRACE("returning %p\n", This); + *ppOut = (IUnknown *)This; + return S_OK; +} diff --git a/reactos/dll/win32/msctf/inputprocessor.c b/reactos/dll/win32/msctf/inputprocessor.c index ba4a76d83b5..34e35c41cb1 100644 --- a/reactos/dll/win32/msctf/inputprocessor.c +++ b/reactos/dll/win32/msctf/inputprocessor.c @@ -279,8 +279,8 @@ static HRESULT WINAPI InputProcessorProfiles_AddLanguageProfile( if (!res) { DWORD zero = 0x0; - RegSetValueExW(fmtkey, desc, 0, REG_SZ, (LPBYTE)pchDesc, cchDesc * sizeof(WCHAR)); - RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (LPBYTE)pchIconFile, cchFile * sizeof(WCHAR)); + RegSetValueExW(fmtkey, desc, 0, REG_SZ, (const BYTE*)pchDesc, cchDesc * sizeof(WCHAR)); + RegSetValueExW(fmtkey, icnf, 0, REG_SZ, (const BYTE*)pchIconFile, cchFile * sizeof(WCHAR)); RegSetValueExW(fmtkey, icni, 0, REG_DWORD, (LPBYTE)&uIconIndex, sizeof(DWORD)); if (disposition == REG_CREATED_NEW_KEY) RegSetValueExW(fmtkey, szwEnable, 0, REG_DWORD, (LPBYTE)&zero, sizeof(DWORD)); diff --git a/reactos/dll/win32/msctf/msctf.c b/reactos/dll/win32/msctf/msctf.c index 62d1ff2abd8..759fe7ec579 100644 --- a/reactos/dll/win32/msctf/msctf.c +++ b/reactos/dll/win32/msctf/msctf.c @@ -88,6 +88,7 @@ static const struct { {&CLSID_TF_InputProcessorProfiles, InputProcessorProfiles_Constructor}, {&CLSID_TF_CategoryMgr, CategoryMgr_Constructor}, {&CLSID_TF_LangBarMgr, LangBarMgr_Constructor}, + {&CLSID_TF_DisplayAttributeMgr, DisplayAttributeMgr_Constructor}, {NULL, NULL} }; diff --git a/reactos/dll/win32/msctf/msctf.rbuild b/reactos/dll/win32/msctf/msctf.rbuild index de8f52bf64d..cb072f676e7 100644 --- a/reactos/dll/win32/msctf/msctf.rbuild +++ b/reactos/dll/win32/msctf/msctf.rbuild @@ -11,6 +11,7 @@ categorymgr.c compartmentmgr.c context.c + displayattributemgr.c documentmgr.c inputprocessor.c langbarmgr.c diff --git a/reactos/dll/win32/msctf/msctf_internal.h b/reactos/dll/win32/msctf/msctf_internal.h index 57423e996fc..9aaaad0fb1b 100644 --- a/reactos/dll/win32/msctf/msctf_internal.h +++ b/reactos/dll/win32/msctf/msctf_internal.h @@ -41,6 +41,7 @@ extern HRESULT Range_Constructor(ITfContext *context, ITextStoreACP *textstore, extern HRESULT CompartmentMgr_Constructor(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppOut); extern HRESULT CompartmentMgr_Destructor(ITfCompartmentMgr *This); extern HRESULT LangBarMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut); +extern HRESULT DisplayAttributeMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut); extern HRESULT Context_Initialize(ITfContext *cxt, ITfDocumentMgr *manager); extern HRESULT Context_Uninitialize(ITfContext *cxt); diff --git a/reactos/dll/win32/msctf/regsvr.c b/reactos/dll/win32/msctf/regsvr.c index 2af1f241154..65ebb1da122 100644 --- a/reactos/dll/win32/msctf/regsvr.c +++ b/reactos/dll/win32/msctf/regsvr.c @@ -469,6 +469,13 @@ static struct regsvr_coclass const coclass_list[] = { "msctf.dll", "Apartment" }, + { + &CLSID_TF_DisplayAttributeMgr, + "TF_DisplayAttributeMgr", + NULL, + "msctf.dll", + "Apartment" + }, { NULL } /* list terminator */ }; diff --git a/reactos/dll/win32/msgsm32.acm/msgsm32.c b/reactos/dll/win32/msgsm32.acm/msgsm32.c index e760ac3a0ed..12dfef91d3b 100644 --- a/reactos/dll/win32/msgsm32.acm/msgsm32.c +++ b/reactos/dll/win32/msgsm32.acm/msgsm32.c @@ -179,10 +179,10 @@ static DWORD GSM_FormatValidate(const WAVEFORMATEX *wfx) WARN("GSM nBlockAlign %u\n", wfx->nBlockAlign); return 0; } - if (((GSM610WAVEFORMAT*)wfx)->wSamplesPerBlock != 320) + if (((const GSM610WAVEFORMAT*)wfx)->wSamplesPerBlock != 320) { WARN("GSM wSamplesPerBlock %u\n", - ((GSM610WAVEFORMAT*)wfx)->wSamplesPerBlock); + ((const GSM610WAVEFORMAT*)wfx)->wSamplesPerBlock); return 0; } if (wfx->nAvgBytesPerSec != wfx->nSamplesPerSec * 65 / 320) diff --git a/reactos/dll/win32/mshtml/dispex.c b/reactos/dll/win32/mshtml/dispex.c index 4b1bd882e5e..de0c94871f6 100644 --- a/reactos/dll/win32/mshtml/dispex.c +++ b/reactos/dll/win32/mshtml/dispex.c @@ -52,8 +52,11 @@ struct dispex_data_t { typedef struct { VARIANT var; LPWSTR name; + DWORD flags; } dynamic_prop_t; +#define DYNPROP_DELETED 0x01 + typedef struct { DispatchEx dispex; const IUnknownVtbl *lpIUnknownVtbl; @@ -245,12 +248,12 @@ static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, const FUN static int dispid_cmp(const void *p1, const void *p2) { - return ((func_info_t*)p1)->id - ((func_info_t*)p2)->id; + return ((const func_info_t*)p1)->id - ((const func_info_t*)p2)->id; } static int func_name_cmp(const void *p1, const void *p2) { - return strcmpiW((*(func_info_t**)p1)->name, (*(func_info_t**)p2)->name); + return strcmpiW((*(func_info_t* const*)p1)->name, (*(func_info_t* const*)p2)->name); } static dispex_data_t *preprocess_dispex_data(DispatchEx *This) @@ -319,7 +322,7 @@ static dispex_data_t *preprocess_dispex_data(DispatchEx *This) static int id_cmp(const void *p1, const void *p2) { - return *(DISPID*)p1 - *(DISPID*)p2; + return *(const DISPID*)p1 - *(const DISPID*)p2; } HRESULT get_dispids(tid_t tid, DWORD *ret_size, DISPID **ret) @@ -442,7 +445,7 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags { const BOOL alloc = flags & fdexNameEnsure; dispex_dynamic_data_t *data; - unsigned i; + dynamic_prop_t *prop; data = get_dynamic_data(This, alloc); if(!data) { @@ -453,9 +456,14 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags return DISP_E_UNKNOWNNAME; } - for(i=0; i < data->prop_cnt; i++) { - if(flags & fdexNameCaseInsensitive ? !strcmpiW(data->props[i].name, name) : !strcmpW(data->props[i].name, name)) { - *ret = data->props+i; + for(prop = data->props; prop < data->props+data->prop_cnt; prop++) { + if(flags & fdexNameCaseInsensitive ? !strcmpiW(prop->name, name) : !strcmpW(prop->name, name)) { + if(prop->flags & DYNPROP_DELETED) { + if(!alloc) + return DISP_E_UNKNOWNNAME; + prop->flags &= ~DYNPROP_DELETED; + } + *ret = prop; return S_OK; } } @@ -481,10 +489,16 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags data->buf_size <<= 1; } - data->props[data->prop_cnt].name = heap_strdupW(name); - VariantInit(&data->props[data->prop_cnt].var); - *ret = data->props + data->prop_cnt++; + prop = data->props + data->prop_cnt; + prop->name = heap_strdupW(name); + if(!prop->name) + return E_OUTOFMEMORY; + + VariantInit(&prop->var); + prop->flags = 0; + data->prop_cnt++; + *ret = prop; return S_OK; } @@ -729,6 +743,109 @@ static HRESULT get_builtin_func(dispex_data_t *data, DISPID id, func_info_t **re return DISP_E_UNKNOWNNAME; } +static HRESULT get_builtin_id(DispatchEx *This, BSTR name, DWORD grfdex, DISPID *ret) +{ + dispex_data_t *data; + int min, max, n, c; + + data = get_dispex_data(This); + if(!data) + return E_FAIL; + + min = 0; + max = data->func_cnt-1; + + while(min <= max) { + n = (min+max)/2; + + c = strcmpiW(data->name_table[n]->name, name); + if(!c) { + if((grfdex & fdexNameCaseSensitive) && strcmpW(data->name_table[n]->name, name)) + break; + + *ret = data->name_table[n]->id; + return S_OK; + } + + if(c > 0) + max = n-1; + else + min = n+1; + } + + if(This->data->vtbl && This->data->vtbl->get_dispid) { + HRESULT hres; + + hres = This->data->vtbl->get_dispid(This->outer, name, grfdex, ret); + if(hres != DISP_E_UNKNOWNNAME) + return hres; + } + + return DISP_E_UNKNOWNNAME; +} + +static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + dispex_data_t *data; + func_info_t *func; + HRESULT hres; + + data = get_dispex_data(This); + if(!data) + return E_FAIL; + + hres = get_builtin_func(data, id, &func); + if(id == DISPID_VALUE && hres == DISP_E_UNKNOWNNAME) + return dispex_value(This, lcid, flags, dp, res, ei, caller); + if(FAILED(hres)) + return hres; + + if(func->func_disp_idx == -1) + hres = typeinfo_invoke(This, func, flags, dp, res, ei); + else + hres = function_invoke(This, func, flags, dp, res, ei); + + return hres; +} + +HRESULT remove_prop(DispatchEx *This, BSTR name, VARIANT_BOOL *success) +{ + dynamic_prop_t *prop; + DISPID id; + HRESULT hres; + + hres = get_builtin_id(This, name, 0, &id); + if(hres == S_OK) { + DISPID named_id = DISPID_PROPERTYPUT; + VARIANT var; + DISPPARAMS dp = {&var,&named_id,1,1}; + EXCEPINFO ei; + + V_VT(&var) = VT_EMPTY; + memset(&ei, 0, sizeof(ei)); + hres = invoke_builtin_prop(This, id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL); + if(FAILED(hres)) + return hres; + + *success = VARIANT_TRUE; + return S_OK; + } + + hres = get_dynamic_prop(This, name, 0, &prop); + if(FAILED(hres)) { + if(hres != DISP_E_UNKNOWNNAME) + return hres; + *success = VARIANT_FALSE; + return S_OK; + } + + VariantClear(&prop->var); + prop->flags |= DYNPROP_DELETED; + *success = VARIANT_TRUE; + return S_OK; +} + #define DISPATCHEX_THIS(iface) DEFINE_THIS(DispatchEx, IDispatchEx, iface) static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) @@ -815,8 +932,6 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW { DispatchEx *This = DISPATCHEX_THIS(iface); dynamic_prop_t *dprop; - dispex_data_t *data; - int min, max, n, c; HRESULT hres; TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid); @@ -824,38 +939,9 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW if(grfdex & ~(fdexNameCaseSensitive|fdexNameCaseInsensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK)) FIXME("Unsupported grfdex %x\n", grfdex); - data = get_dispex_data(This); - if(!data) - return E_FAIL; - - min = 0; - max = data->func_cnt-1; - - while(min <= max) { - n = (min+max)/2; - - c = strcmpiW(data->name_table[n]->name, bstrName); - if(!c) { - if((grfdex & fdexNameCaseSensitive) && strcmpW(data->name_table[n]->name, bstrName)) - break; - - *pid = data->name_table[n]->id; - return S_OK; - } - - if(c > 0) - max = n-1; - else - min = n+1; - } - - if(This->data->vtbl && This->data->vtbl->get_dispid) { - HRESULT hres; - - hres = This->data->vtbl->get_dispid(This->outer, bstrName, grfdex, pid); - if(hres != DISP_E_UNKNOWNNAME) - return hres; - } + hres = get_builtin_id(This, bstrName, grfdex, pid); + if(hres != DISP_E_UNKNOWNNAME) + return hres; hres = get_dynamic_prop(This, bstrName, grfdex, &dprop); if(FAILED(hres)) @@ -869,8 +955,6 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { DispatchEx *This = DISPATCHEX_THIS(iface); - dispex_data_t *data; - func_info_t *func; HRESULT hres; TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); @@ -893,12 +977,12 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc if(is_dynamic_dispid(id)) { DWORD idx = id - DISPID_DYNPROP_0; - VARIANT *var; + dynamic_prop_t *prop; if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx) return DISP_E_UNKNOWNNAME; - var = &This->dynamic_data->props[idx].var; + prop = This->dynamic_data->props+idx; switch(wFlags) { case DISPATCH_METHOD|DISPATCH_PROPERTYGET: @@ -909,8 +993,8 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc DISPPARAMS dp = {NULL, &named_arg, 0, 1}; IDispatchEx *dispex; - if(V_VT(var) != VT_DISPATCH) { - FIXME("invoke vt %d\n", V_VT(var)); + if(V_VT(&prop->var) != VT_DISPATCH) { + FIXME("invoke %s\n", debugstr_variant(&prop->var)); return E_NOTIMPL; } @@ -929,14 +1013,14 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc V_VT(dp.rgvarg) = VT_DISPATCH; V_DISPATCH(dp.rgvarg) = (IDispatch*)DISPATCHEX(This); - hres = IDispatch_QueryInterface(V_DISPATCH(var), &IID_IDispatchEx, (void**)&dispex); + hres = IDispatch_QueryInterface(V_DISPATCH(&prop->var), &IID_IDispatchEx, (void**)&dispex); TRACE("%s call\n", debugstr_w(This->dynamic_data->props[idx].name)); if(SUCCEEDED(hres)) { hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, lcid, wFlags, &dp, pvarRes, pei, pspCaller); IDispatchEx_Release(dispex); }else { ULONG err = 0; - hres = IDispatch_Invoke(V_DISPATCH(var), DISPID_VALUE, &IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &err); + hres = IDispatch_Invoke(V_DISPATCH(&prop->var), DISPID_VALUE, &IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &err); } TRACE("%s ret %08x\n", debugstr_w(This->dynamic_data->props[idx].name), hres); @@ -944,7 +1028,9 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc return hres; } case DISPATCH_PROPERTYGET: - return VariantCopy(pvarRes, var); + if(prop->flags & DYNPROP_DELETED) + return DISP_E_UNKNOWNNAME; + return VariantCopy(pvarRes, &prop->var); case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: case DISPATCH_PROPERTYPUT: if(pdp->cArgs != 1 || (pdp->cNamedArgs == 1 && *pdp->rgdispidNamedArgs != DISPID_PROPERTYPUT) @@ -954,30 +1040,20 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc } TRACE("put %s\n", debugstr_variant(pdp->rgvarg)); - VariantClear(var); - return VariantCopy(var, pdp->rgvarg); + VariantClear(&prop->var); + hres = VariantCopy(&prop->var, pdp->rgvarg); + if(FAILED(hres)) + return hres; + + prop->flags &= ~DYNPROP_DELETED; + return S_OK; default: FIXME("unhandled wFlags %x\n", wFlags); return E_NOTIMPL; } } - data = get_dispex_data(This); - if(!data) - return E_FAIL; - - hres = get_builtin_func(data, id, &func); - if(id == DISPID_VALUE && hres == DISP_E_UNKNOWNNAME) - return dispex_value(This, lcid, wFlags, pdp, pvarRes, pei, pspCaller); - if(FAILED(hres)) - return hres; - - if(func->func_disp_idx == -1) - hres = typeinfo_invoke(This, func, wFlags, pdp, pvarRes, pei); - else - hres = function_invoke(This, func, wFlags, pdp, pvarRes, pei); - - return hres; + return invoke_builtin_prop(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); } static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex) @@ -1055,12 +1131,14 @@ static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx) return DISP_E_UNKNOWNNAME; - if(idx+1 == This->dynamic_data->prop_cnt) { + while(++idx < This->dynamic_data->prop_cnt && This->dynamic_data->props[idx].flags & DYNPROP_DELETED); + + if(idx == This->dynamic_data->prop_cnt) { *pid = DISPID_STARTENUM; return S_FALSE; } - *pid = id+1; + *pid = DISPID_DYNPROP_0+idx; return S_OK; } diff --git a/reactos/dll/win32/mshtml/editor.c b/reactos/dll/win32/mshtml/editor.c index 961bb916370..14e7ebb6f64 100644 --- a/reactos/dll/win32/mshtml/editor.c +++ b/reactos/dll/win32/mshtml/editor.c @@ -508,7 +508,6 @@ void handle_edit_event(HTMLDocument *This, nsIDOMEvent *event) void handle_edit_load(HTMLDocument *This) { - This->doc_obj->nscontainer->reset_focus = GetFocus(); get_editor_controller(This->doc_obj->nscontainer); } diff --git a/reactos/dll/win32/mshtml/htmlelem.c b/reactos/dll/win32/mshtml/htmlelem.c index e77c1dc4c42..b0cb791a1e8 100644 --- a/reactos/dll/win32/mshtml/htmlelem.c +++ b/reactos/dll/win32/mshtml/htmlelem.c @@ -198,8 +198,10 @@ static HRESULT WINAPI HTMLElement_removeAttribute(IHTMLElement *iface, BSTR strA LONG lFlags, VARIANT_BOOL *pfSuccess) { HTMLElement *This = HTMLELEM_THIS(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; + + TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(strAttributeName), lFlags, pfSuccess); + + return remove_prop(&This->node.dispex, strAttributeName, pfSuccess); } static HRESULT WINAPI HTMLElement_put_className(IHTMLElement *iface, BSTR v) diff --git a/reactos/dll/win32/mshtml/htmlwindow.c b/reactos/dll/win32/mshtml/htmlwindow.c index 2aafaa3e4b4..5dbea55905c 100644 --- a/reactos/dll/win32/mshtml/htmlwindow.c +++ b/reactos/dll/win32/mshtml/htmlwindow.c @@ -57,6 +57,26 @@ static void window_set_docnode(HTMLWindow *window, HTMLDocumentNode *doc_node) if(doc_node) htmldoc_addref(&doc_node->basedoc); } + + if(doc_node && window->doc_obj->usermode == EDITMODE) { + nsIDOMNSHTMLDocument *nshtmldoc; + nsAString mode_str; + nsresult nsres; + + static const PRUnichar onW[] = {'o','n',0}; + + nsres = nsIDOMHTMLDocument_QueryInterface(doc_node->nsdoc, &IID_nsIDOMNSHTMLDocument, (void**)&nshtmldoc); + if(NS_SUCCEEDED(nsres)) { + nsAString_Init(&mode_str, onW); + nsres = nsIDOMNSHTMLDocument_SetDesignMode(nshtmldoc, &mode_str); + nsAString_Finish(&mode_str); + nsIDOMNSHTMLDocument_Release(nshtmldoc); + if(NS_FAILED(nsres)) + ERR("SetDesignMode failed: %08x\n", nsres); + }else { + ERR("Could not get nsIDOMNSHTMLDocument interface: %08x\n", nsres); + } + } } nsIDOMWindow *get_nsdoc_window(nsIDOMDocument *nsdoc) diff --git a/reactos/dll/win32/mshtml/install.c b/reactos/dll/win32/mshtml/install.c index e47c28423d0..4122194a7cc 100644 --- a/reactos/dll/win32/mshtml/install.c +++ b/reactos/dll/win32/mshtml/install.c @@ -60,11 +60,6 @@ static const WCHAR mshtml_keyW[] = '\\','W','i','n','e', '\\','M','S','H','T','M','L',0}; -static const CHAR mshtml_keyA[] = - {'S','o','f','t','w','a','r','e', - '\\','W','i','n','e', - '\\','M','S','H','T','M','L',0}; - static HWND install_dialog = NULL; static LPWSTR tmp_file_name = NULL; static HANDLE tmp_file = INVALID_HANDLE_VALUE; @@ -230,18 +225,23 @@ static BOOL install_from_unix_file(const char *file_name) static BOOL install_from_registered_dir(void) { char *file_name; + HKEY hkey; DWORD res, type, size = MAX_PATH; BOOL ret; - file_name = heap_alloc(size+sizeof(GECKO_FILE_NAME)); /* @@ Wine registry key: HKCU\Software\Wine\MSHTML */ - res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size); + res = RegOpenKeyW(HKEY_CURRENT_USER, mshtml_keyW, &hkey); + if(res != ERROR_SUCCESS) + return FALSE; + + file_name = heap_alloc(size+sizeof(GECKO_FILE_NAME)); + res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size); if(res == ERROR_MORE_DATA) { file_name = heap_realloc(file_name, size+sizeof(GECKO_FILE_NAME)); - res = RegGetValueA(HKEY_CURRENT_USER, mshtml_keyA, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size); + res = RegQueryValueExA(hkey, "GeckoCabDir", NULL, &type, (PBYTE)file_name, &size); } - - if(res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) { + RegCloseKey(hkey); + if(res != ERROR_SUCCESS || type != REG_SZ) { heap_free(file_name); return FALSE; } diff --git a/reactos/dll/win32/mshtml/mshtml_private.h b/reactos/dll/win32/mshtml/mshtml_private.h index 228be35864e..3db8d791e48 100644 --- a/reactos/dll/win32/mshtml/mshtml_private.h +++ b/reactos/dll/win32/mshtml/mshtml_private.h @@ -38,6 +38,7 @@ #define NS_ERROR_FAILURE ((nsresult)0x80004005L) #define NS_NOINTERFACE ((nsresult)0x80004002L) #define NS_ERROR_NOT_IMPLEMENTED ((nsresult)0x80004001L) +#define NS_ERROR_NOT_AVAILABLE ((nsresult)0x80040111L) #define NS_ERROR_INVALID_ARG ((nsresult)0x80070057L) #define NS_ERROR_UNEXPECTED ((nsresult)0x8000ffffL) #define NS_ERROR_UNKNOWN_PROTOCOL ((nsresult)0x804b0012L) @@ -171,6 +172,7 @@ void release_dispex(DispatchEx*); BOOL dispex_query_interface(DispatchEx*,REFIID,void**); HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**); HRESULT get_dispids(tid_t,DWORD*,DISPID**); +HRESULT remove_prop(DispatchEx*,BSTR,VARIANT_BOOL*); typedef struct HTMLWindow HTMLWindow; typedef struct HTMLDocumentNode HTMLDocumentNode; @@ -435,8 +437,6 @@ struct NSContainer { nsIURIContentListener *content_listener; HWND hwnd; - - HWND reset_focus; /* hack */ }; typedef struct nsWineURI nsWineURI; @@ -461,9 +461,16 @@ typedef struct { char *content_type; char *charset; PRUint32 response_status; + struct list response_headers; UINT url_scheme; } nsChannel; +struct ResponseHeader { + struct list entry; + WCHAR *header; + WCHAR *data; +}; + typedef struct { HRESULT (*qi)(HTMLDOMNode*,REFIID,void**); void (*destructor)(HTMLDOMNode*); @@ -836,7 +843,6 @@ void update_title(HTMLDocumentObj*); /* editor */ void init_editor(HTMLDocument*); -void set_ns_editmode(NSContainer*); void handle_edit_event(HTMLDocument*,nsIDOMEvent*); HRESULT editor_exec_copy(HTMLDocument*,DWORD,VARIANT*,VARIANT*); HRESULT editor_exec_cut(HTMLDocument*,DWORD,VARIANT*,VARIANT*); diff --git a/reactos/dll/win32/mshtml/navigate.c b/reactos/dll/win32/mshtml/navigate.c index cc2aeb3f6c2..7a777957ce1 100644 --- a/reactos/dll/win32/mshtml/navigate.c +++ b/reactos/dll/win32/mshtml/navigate.c @@ -62,7 +62,7 @@ typedef struct { HRESULT (*stop_binding)(BSCallback*,HRESULT); HRESULT (*read_data)(BSCallback*,IStream*); HRESULT (*on_progress)(BSCallback*,ULONG,LPCWSTR); - HRESULT (*on_response)(BSCallback*,DWORD); + HRESULT (*on_response)(BSCallback*,DWORD,LPCWSTR); } BSCallbackVtbl; struct BSCallback { @@ -493,7 +493,7 @@ static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwR TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders), debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders); - return This->vtbl->on_response(This, dwResponseCode); + return This->vtbl->on_response(This, dwResponseCode, szResponseHeaders); } static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface, @@ -825,7 +825,8 @@ static HRESULT BufferBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCWSTR return S_OK; } -static HRESULT BufferBSC_on_response(BSCallback *bsc, DWORD response_code) +static HRESULT BufferBSC_on_response(BSCallback *bsc, DWORD response_code, + LPCWSTR response_headers) { return S_OK; } @@ -1099,11 +1100,72 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCW return S_OK; } -static HRESULT nsChannelBSC_on_response(BSCallback *bsc, DWORD response_code) +static HRESULT nsChannelBSC_on_response(BSCallback *bsc, DWORD response_code, + LPCWSTR response_headers) { nsChannelBSC *This = NSCHANNELBSC_THIS(bsc); This->nschannel->response_status = response_code; + + if(response_headers) { + const WCHAR *hdr_start, *hdr_end; + + hdr_start = strchrW(response_headers, '\r'); + while(hdr_start) { + const WCHAR *colon; + struct ResponseHeader *new_header; + int len; + + hdr_start += 2; + hdr_end = strchrW(hdr_start, '\r'); + if(!hdr_end) { + WARN("Header doesn't end with CRLF: %s\n", wine_dbgstr_w(hdr_start)); + break; + } + if(hdr_end == hdr_start) + break; + + for(colon = hdr_start; *colon != ':' && colon != hdr_end; ++colon); + if(*colon != ':') { + WARN("Header missing colon: %s\n", wine_dbgstr_w(hdr_start)); + hdr_start = strchrW(hdr_start, '\r'); + continue; + } + + new_header = heap_alloc(sizeof(struct ResponseHeader)); + if(!new_header) + return E_OUTOFMEMORY; + + len = colon - hdr_start; + new_header->header = heap_alloc((len + 1) * sizeof(WCHAR)); + if(!new_header->header) { + heap_free(new_header); + return E_OUTOFMEMORY; + } + memcpy(new_header->header, hdr_start, len * sizeof(WCHAR)); + new_header->header[len] = 0; + + colon++; + while(*colon == ' ') + colon++; + + len = hdr_end - colon; + new_header->data = heap_alloc((len + 1) * sizeof(WCHAR)); + if(!new_header->data) { + heap_free(new_header->header); + heap_free(new_header); + return E_OUTOFMEMORY; + } + memcpy(new_header->data, colon, len * sizeof(WCHAR)); + new_header->data[len] = 0; + + list_add_head(&This->nschannel->response_headers, &new_header->entry); + TRACE("Adding header to list: (%s):(%s)\n", wine_dbgstr_w(new_header->header), wine_dbgstr_w(new_header->data)); + + hdr_start = strchrW(hdr_start, '\r'); + } + } + return S_OK; } diff --git a/reactos/dll/win32/mshtml/nsembed.c b/reactos/dll/win32/mshtml/nsembed.c index fa8aa41fedf..8a590079278 100644 --- a/reactos/dll/win32/mshtml/nsembed.c +++ b/reactos/dll/win32/mshtml/nsembed.c @@ -80,8 +80,6 @@ static const WCHAR wszNsContainer[] = {'N','s','C','o','n','t','a','i','n','e',' static ATOM nscontainer_class; -#define WM_RESETFOCUS_HACK WM_USER+600 - static LRESULT WINAPI nsembed_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { NSContainer *This; @@ -106,20 +104,13 @@ static LRESULT WINAPI nsembed_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP WARN("SetSize failed: %08x\n", nsres); break; - case WM_RESETFOCUS_HACK: - /* - * FIXME - * Gecko grabs focus in edit mode and some apps don't like it. - * We should somehow prevent grabbing focus. - */ - - TRACE("WM_RESETFOCUS_HACK\n"); + case WM_PARENTNOTIFY: + TRACE("WM_PARENTNOTIFY %x\n", (unsigned)wParam); - if(This->reset_focus) { - SetFocus(This->reset_focus); - This->reset_focus = NULL; - if(This->doc) - This->doc->focus = FALSE; + switch(wParam) { + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + nsIWebBrowserFocus_Activate(This->focus); } } @@ -776,46 +767,6 @@ void get_editor_controller(NSContainer *This) } } -void set_ns_editmode(NSContainer *This) -{ - nsIEditingSession *editing_session = NULL; - nsIURIContentListener *listener = NULL; - nsIDOMWindow *dom_window = NULL; - nsresult nsres; - - nsres = get_nsinterface((nsISupports*)This->webbrowser, &IID_nsIEditingSession, - (void**)&editing_session); - if(NS_FAILED(nsres)) { - ERR("Could not get nsIEditingSession: %08x\n", nsres); - return; - } - - nsres = nsIWebBrowser_GetContentDOMWindow(This->webbrowser, &dom_window); - if(NS_FAILED(nsres)) { - ERR("Could not get content DOM window: %08x\n", nsres); - nsIEditingSession_Release(editing_session); - return; - } - - nsres = nsIEditingSession_MakeWindowEditable(editing_session, dom_window, - NULL, FALSE, TRUE, TRUE); - nsIEditingSession_Release(editing_session); - nsIDOMWindow_Release(dom_window); - if(NS_FAILED(nsres)) { - ERR("MakeWindowEditable failed: %08x\n", nsres); - return; - } - - /* MakeWindowEditable changes WebBrowser's parent URI content listener. - * It seams to be a bug in Gecko. To workaround it we set our content - * listener again and Gecko's one as its parent. - */ - nsIWebBrowser_GetParentURIContentListener(This->webbrowser, &listener); - nsIURIContentListener_SetParentContentListener(NSURICL(This), listener); - nsIURIContentListener_Release(listener); - nsIWebBrowser_SetParentURIContentListener(This->webbrowser, NSURICL(This)); -} - void close_gecko(void) { TRACE("()\n"); @@ -1316,9 +1267,6 @@ static nsresult NSAPI nsEmbeddingSiteWindow_SetFocus(nsIEmbeddingSiteWindow *ifa TRACE("(%p)\n", This); - if(This->reset_focus) - PostMessageW(This->hwnd, WM_RESETFOCUS_HACK, 0, 0); - return nsIBaseWindow_SetFocus(This->window); } diff --git a/reactos/dll/win32/mshtml/nsevents.c b/reactos/dll/win32/mshtml/nsevents.c index c491424fdd4..3e0314966db 100644 --- a/reactos/dll/win32/mshtml/nsevents.c +++ b/reactos/dll/win32/mshtml/nsevents.c @@ -109,11 +109,11 @@ static nsrefcnt NSAPI nsDOMEventListener_Release(nsIDOMEventListener *iface) return release_listener(This); } -static BOOL is_doc_child_focus(HTMLDocumentObj *doc) +static BOOL is_doc_child_focus(NSContainer *nscontainer) { HWND hwnd; - for(hwnd = GetFocus(); hwnd && hwnd != doc->hwnd; hwnd = GetParent(hwnd)); + for(hwnd = GetFocus(); hwnd && hwnd != nscontainer->hwnd; hwnd = GetParent(hwnd)); return hwnd != NULL; } @@ -129,7 +129,7 @@ static nsresult NSAPI handle_blur(nsIDOMEventListener *iface, nsIDOMEvent *event return NS_ERROR_FAILURE; doc_obj = doc->basedoc.doc_obj; - if(!doc_obj->nscontainer->reset_focus && doc_obj->focus && !is_doc_child_focus(doc_obj)) { + if(doc_obj->focus && !is_doc_child_focus(doc_obj->nscontainer)) { doc_obj->focus = FALSE; notif_focus(doc_obj); } @@ -148,7 +148,7 @@ static nsresult NSAPI handle_focus(nsIDOMEventListener *iface, nsIDOMEvent *even return NS_ERROR_FAILURE; doc_obj = doc->basedoc.doc_obj; - if(!doc_obj->nscontainer->reset_focus && !doc_obj->focus) { + if(!doc_obj->focus) { doc_obj->focus = TRUE; notif_focus(doc_obj); } diff --git a/reactos/dll/win32/mshtml/nsio.c b/reactos/dll/win32/mshtml/nsio.c index 88a4e55254b..0c8e45704d7 100644 --- a/reactos/dll/win32/mshtml/nsio.c +++ b/reactos/dll/win32/mshtml/nsio.c @@ -307,7 +307,7 @@ static void set_uri_window(nsWineURI *This, HTMLWindow *window) static inline BOOL is_http_channel(nsChannel *This) { - return This->url_scheme == URL_SCHEME_HTTP || This->url_scheme == URL_SCHEME_HTTP; + return This->url_scheme == URL_SCHEME_HTTP || This->url_scheme == URL_SCHEME_HTTPS; } #define NSCHANNEL_THIS(iface) DEFINE_THIS(nsChannel, HttpChannel, iface) @@ -363,6 +363,8 @@ static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface) LONG ref = InterlockedDecrement(&This->ref); if(!ref) { + struct ResponseHeader *header, *next_hdr; + nsIURI_Release(NSURI(This->uri)); if(This->owner) nsISupports_Release(This->owner); @@ -376,6 +378,14 @@ static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface) nsIURI_Release(This->original_uri); heap_free(This->content_type); heap_free(This->charset); + + LIST_FOR_EACH_ENTRY_SAFE(header, next_hdr, &This->response_headers, struct ResponseHeader, entry) { + list_remove(&header->entry); + heap_free(header->header); + heap_free(header->data); + heap_free(header); + } + heap_free(This); } @@ -933,9 +943,9 @@ static nsresult NSAPI nsChannel_SetRequestMethod(nsIHttpChannel *iface, { nsChannel *This = NSCHANNEL_THIS(iface); - FIXME("(%p)->(%p)\n", This, aRequestMethod); + TRACE("(%p)->(%p): Returning NS_OK\n", This, aRequestMethod); - return NS_ERROR_NOT_IMPLEMENTED; + return NS_OK; } static nsresult NSAPI nsChannel_GetReferrer(nsIHttpChannel *iface, nsIURI **aReferrer) @@ -1052,19 +1062,48 @@ static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface, { nsChannel *This = NSCHANNEL_THIS(iface); - FIXME("(%p)->(%p)\n", This, aRequestSucceeded); + TRACE("(%p)->(%p)\n", This, aRequestSucceeded); - return NS_ERROR_NOT_IMPLEMENTED; + if(!This->response_status) + return NS_ERROR_NOT_AVAILABLE; + + *aRequestSucceeded = This->response_status/100 == 2; + + return NS_OK; } static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface, const nsACString *header, nsACString *_retval) { nsChannel *This = NSCHANNEL_THIS(iface); + const char *header_str; + WCHAR *header_wstr; + struct ResponseHeader *this_header; - FIXME("(%p)->(%p %p)\n", This, header, _retval); + nsACString_GetData(header, &header_str); + TRACE("(%p)->(%p(%s) %p)\n", This, header, header_str, _retval); - return NS_ERROR_NOT_IMPLEMENTED; + header_wstr = heap_strdupAtoW(header_str); + if(!header_wstr) + return NS_ERROR_UNEXPECTED; + + LIST_FOR_EACH_ENTRY(this_header, &This->response_headers, struct ResponseHeader, entry) { + if(!strcmpW(this_header->header, header_wstr)) { + char *data = heap_strdupWtoA(this_header->data); + if(!data) { + heap_free(header_wstr); + return NS_ERROR_UNEXPECTED; + } + nsACString_SetData(_retval, data); + heap_free(data); + heap_free(header_wstr); + return NS_OK; + } + } + + heap_free(header_wstr); + + return NS_ERROR_NOT_AVAILABLE; } static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface, @@ -2414,7 +2453,6 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString * HTMLWindow *window = NULL; nsIURI *uri = NULL; LPCWSTR base_wine_url = NULL; - BOOL is_wine_uri = FALSE; nsresult nsres; nsACString_GetData(aSpec, &spec); @@ -2425,10 +2463,8 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString * if(is_gecko_special_uri(spec)) return nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, _retval); - if(!strncmp(spec, "wine:", 5)) { + if(!strncmp(spec, "wine:", 5)) spec += 5; - is_wine_uri = TRUE; - } if(aBaseURI) { PARSEDURLA parsed_url = {sizeof(PARSEDURLA)}; @@ -2473,7 +2509,7 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString * set_wine_url(wine_uri, url); else WARN("CoCombineUrl failed: %08x\n", hres); - }else if(is_wine_uri) { + }else { WCHAR url[INTERNET_MAX_URL_LENGTH]; MultiByteToWideChar(CP_ACP, 0, spec, -1, url, sizeof(url)/sizeof(WCHAR)); @@ -2516,6 +2552,7 @@ static nsresult NSAPI nsIOService_NewChannelFromURI(nsIIOService *iface, nsIURI ret->lpIHttpChannelInternalVtbl = &nsHttpChannelInternalVtbl; ret->ref = 1; ret->uri = wine_uri; + list_init(&ret->response_headers); nsIURI_AddRef(aURI); ret->original_uri = aURI; diff --git a/reactos/dll/win32/mshtml/olecmd.c b/reactos/dll/win32/mshtml/olecmd.c index b54f06420fb..4d5967a923f 100644 --- a/reactos/dll/win32/mshtml/olecmd.c +++ b/reactos/dll/win32/mshtml/olecmd.c @@ -616,9 +616,6 @@ static HRESULT exec_editmode(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, IDocHostUIHandler_HideUI(This->doc_obj->hostui); } - if(This->doc_obj->nscontainer) - set_ns_editmode(This->doc_obj->nscontainer); - if(This->doc_obj->ui_active) { RECT rcBorderWidths; diff --git a/reactos/dll/win32/mshtml/view.c b/reactos/dll/win32/mshtml/view.c index 261e959b0ad..5c096ed9928 100644 --- a/reactos/dll/win32/mshtml/view.c +++ b/reactos/dll/win32/mshtml/view.c @@ -92,7 +92,6 @@ static void activate_gecko(NSContainer *This) nsIBaseWindow_SetVisibility(This->window, TRUE); nsIBaseWindow_SetEnabled(This->window, TRUE); - nsIWebBrowserFocus_Activate(This->focus); } void update_doc(HTMLDocument *This, DWORD flags) @@ -216,6 +215,10 @@ static LRESULT WINAPI serverwnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM break; case WM_TIMER: return on_timer(This); + case WM_SETFOCUS: + TRACE("(%p) WM_SETFOCUS\n", This); + nsIWebBrowserFocus_Activate(This->nscontainer->focus); + break; case WM_MOUSEACTIVATE: return MA_ACTIVATE; } @@ -664,6 +667,8 @@ static HRESULT WINAPI OleDocumentView_UIActivate(IOleDocumentView *iface, BOOL f This->doc_obj->ui_active = TRUE; }else { + This->doc_obj->focus = FALSE; + nsIWebBrowserFocus_Deactivate(This->doc_obj->nscontainer->focus); if(This->doc_obj->ui_active) { This->doc_obj->ui_active = FALSE; if(This->doc_obj->ip_window) @@ -811,7 +816,7 @@ static HRESULT WINAPI ViewObject_SetAdvise(IViewObjectEx *iface, DWORD aspects, TRACE("(%p)->(%d %d %p)\n", This, aspects, advf, pAdvSink); if(aspects != DVASPECT_CONTENT || advf != ADVF_PRIMEFIRST) - FIXME("unsuported arguments\n"); + FIXME("unsupported arguments\n"); if(This->doc_obj->view_sink) IAdviseSink_Release(This->doc_obj->view_sink);