From 251bf82dccf0828b0ef82770b9ed24198ce5f1d2 Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Wed, 10 Sep 2008 21:11:08 +0200 Subject: [PATCH] push ab8f8bd6525a0f7af95fd0a2a63931cd3569f61f --- configure | 1 + configure.ac | 3 +- dlls/appwiz.cpl/Fr.rc | 10 +- dlls/cabinet/fdi.c | 141 ++-- dlls/comctl32/monthcal.c | 12 +- dlls/comctl32/tests/header.c | 24 +- dlls/crypt32/cert.c | 5 + dlls/crypt32/chain.c | 2 +- dlls/crypt32/context.c | 1 + dlls/crypt32/crypt32.spec | 4 +- dlls/crypt32/decode.c | 8 +- dlls/crypt32/message.c | 166 +++-- dlls/crypt32/msg.c | 19 +- dlls/crypt32/tests/message.c | 222 +++++- dlls/crypt32/tests/msg.c | 31 + dlls/d3d8/device.c | 22 +- dlls/d3d8/tests/device.c | 71 ++ dlls/d3d9/device.c | 13 +- dlls/d3d9/tests/device.c | 29 +- dlls/dplayx/dplay.c | 2 +- dlls/dplayx/dplayx_global.c | 3 +- dlls/dplayx/tests/dplayx.c | 2 +- dlls/dsound/tests/dsound.c | 25 +- dlls/dsound/tests/dsound8.c | 27 +- dlls/jscript/Makefile.in | 11 +- dlls/jscript/array.c | 253 +++++++ dlls/jscript/bool.c | 147 ++++ dlls/jscript/dispex.c | 543 +++++++++++++- dlls/jscript/engine.c | 805 ++++++++++++++++++++- dlls/jscript/engine.h | 39 +- dlls/jscript/function.c | 244 +++++++ dlls/jscript/global.c | 352 +++++++++ dlls/jscript/jscript.c | 52 +- dlls/jscript/jscript.h | 59 +- dlls/jscript/jscript_main.c | 2 + dlls/jscript/jsutils.c | 69 ++ dlls/jscript/math.c | 275 +++++++ dlls/jscript/number.c | 167 +++++ dlls/jscript/object.c | 125 ++++ dlls/jscript/regexp.c | 143 ++++ dlls/jscript/string.c | 421 +++++++++++ dlls/jscript/tests/Makefile.in | 2 + dlls/jscript/tests/lang.js | 72 ++ .../regproc.h => dlls/jscript/tests/rsrc.rc | 14 +- dlls/jscript/tests/run.c | 188 ++++- dlls/mlang/mlang.c | 4 +- dlls/mshtml/htmldoc3.c | 30 +- dlls/mshtml/htmldoc5.c | 15 +- dlls/mshtml/htmlgeneric.c | 15 +- dlls/mshtml/htmlimg.c | 15 +- dlls/mshtml/htmlinput.c | 15 +- dlls/mshtml/htmloption.c | 15 +- dlls/mshtml/htmlscript.c | 15 +- dlls/mshtml/htmltable.c | 15 +- dlls/mshtml/htmltextarea.c | 15 +- dlls/mshtml/htmltextcont.c | 15 +- dlls/mshtml/htmltextnode.c | 15 +- dlls/msi/action.c | 24 +- dlls/msi/tests/install.c | 4 + dlls/msi/tests/package.c | 98 +-- dlls/msxml3/saxreader.c | 149 ++-- dlls/ntoskrnl.exe/ntoskrnl.c | 12 + dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- dlls/ole32/tests/storage32.c | 98 +-- dlls/oleaut32/hash.c | 3 + dlls/qmgr/job.c | 4 +- dlls/quartz/tests/avisplitter.c | 17 +- dlls/quartz/tests/filtergraph.c | 7 +- dlls/riched20/tests/editor.c | 4 +- dlls/shdocvw/events.c | 2 +- dlls/shdocvw/factory.c | 2 +- dlls/shlwapi/ordinal.c | 19 + dlls/shlwapi/shlwapi.spec | 2 +- dlls/urlmon/tests/protocol.c | 3 +- dlls/urlmon/tests/url.c | 10 +- dlls/user32/winpos.c | 7 +- dlls/winealsa.drv/dscapture.c | 2 +- dlls/wined3d/device.c | 11 +- dlls/wined3d/glsl_shader.c | 2 +- dlls/wined3d/state.c | 32 +- dlls/winex11.drv/dib.c | 18 +- dlls/winex11.drv/event.c | 23 - dlls/winex11.drv/window.c | 62 +- dlls/winex11.drv/x11drv.h | 2 +- dlls/winhttp/Makefile.in | 3 + dlls/winhttp/net.c | 6 +- dlls/winhttp/request.c | 242 ++++--- dlls/winhttp/session.c | 2 +- dlls/winhttp/tests/notification.c | 71 +- dlls/winhttp/tests/winhttp.c | 12 +- .../regedit/regproc.h => dlls/winhttp/version.rc | 18 +- dlls/ws2_32/socket.c | 6 + dlls/ws2_32/tests/sock.c | 37 +- include/amstream.idl | 16 +- include/bits1_5.idl | 2 +- include/ddk/ntddk.h | 15 + include/ddstream.idl | 18 +- include/msinkaut.idl | 4 +- include/msxml2.idl | 28 +- include/rpcndr.h | 14 +- include/shobjidl.idl | 9 +- include/vmr9.idl | 4 +- include/wincrypt.h | 2 +- include/wine/pthread.h | 5 + include/xmldom.idl | 14 + include/xmldomdid.h | 4 + programs/notepad/main.c | 3 +- programs/regedit/framewnd.c | 6 +- programs/regedit/regedit.c | 10 +- programs/regedit/regproc.c | 211 +++--- programs/regedit/regproc.h | 2 +- programs/wordpad/wordpad.c | 24 +- tools/widl/typelib.c | 4 +- tools/widl/write_msft.c | 27 +- 114 files changed, 5436 insertions(+), 1012 deletions(-) create mode 100644 dlls/jscript/array.c create mode 100644 dlls/jscript/bool.c create mode 100644 dlls/jscript/function.c create mode 100644 dlls/jscript/global.c create mode 100644 dlls/jscript/math.c create mode 100644 dlls/jscript/number.c create mode 100644 dlls/jscript/object.c create mode 100644 dlls/jscript/regexp.c create mode 100644 dlls/jscript/string.c create mode 100644 dlls/jscript/tests/lang.js copy programs/regedit/regproc.h => dlls/jscript/tests/rsrc.rc (66%) copy programs/regedit/regproc.h => dlls/winhttp/version.rc (66%) diff --git a/configure b/configure index d8c126343b6..2b60181c21d 100755 --- a/configure +++ b/configure @@ -18745,6 +18745,7 @@ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +#include #include typedef sigset_t ac__type_new_; diff --git a/configure.ac b/configure.ac index 920308143d8..8a883ef4363 100644 --- a/configure.ac +++ b/configure.ac @@ -1496,7 +1496,8 @@ dnl **** Check for types **** AC_C_CONST AC_C_INLINE AC_CHECK_TYPES([mode_t, off_t, pid_t, size_t, ssize_t, long long, fsblkcnt_t, fsfilcnt_t]) -AC_CHECK_TYPES([sigset_t],,,[#include ]) +AC_CHECK_TYPES([sigset_t],,,[#include +#include ]) AC_CHECK_TYPES([request_sense],,,[#include ]) AC_CHECK_MEMBERS([struct ff_effect.direction],,, diff --git a/dlls/appwiz.cpl/Fr.rc b/dlls/appwiz.cpl/Fr.rc index 15b4af45a6f..18c6f09d3d8 100644 --- a/dlls/appwiz.cpl/Fr.rc +++ b/dlls/appwiz.cpl/Fr.rc @@ -42,14 +42,14 @@ STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "Installation/Désinstallation" FONT 8, "MS Sans Serif" { -CONTROL "Pour installer un nouveau programme à partir d'une disquette, d'un cdrom ou de votre disque dur, cliquer sur Installation.", 1000, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 40, 7, 270, 20 - CONTROL "&Installer...", IDC_INSTALL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 246, 26, 64, 14 +CONTROL "Pour installer un nouveau programme à partir d'une disquette, d'un cdrom ou de votre disque dur, cliquer sur Installer.", 1000, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 40, 7, 270, 20 + CONTROL "&Installer", IDC_INSTALL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 246, 26, 64, 14 CONTROL "", -1, "STATIC", SS_LEFT | SS_SUNKEN | WS_CHILD | WS_VISIBLE, 7, 46, 303, 1 CONTROL 2, 1001, "STATIC", SS_ICON | WS_CHILD | WS_VISIBLE, 7, 7, 21, 20 - CONTROL "Ce logiciel peut être automatiquement désinstaller. Pour supprimer un programme ou modifier ses composants, sélectionner le dans la liste, et cliquer sur Ajouter/Supprimer.", 1002, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 40, 57, 270, 30 + CONTROL "Les logiciels suivants peuvent être automatiquement désinstallés. Pour supprimer un programme ou modifier ses composants, le sélectionner dans la liste, et cliquer sur Ajouter/Supprimer.", 1002, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 40, 57, 270, 30 CONTROL "", IDL_PROGRAMS, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SORTASCENDING | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 7, 90, 303, 100 - CONTROL "Ajouter/&Supprimer...", IDC_ADDREMOVE, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 246, 198, 64, 14 - CONTROL "&Info. support..", IDC_SUPPORT_INFO, "button", BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 176, 198, 64, 14 + CONTROL "Ajouter/&Supprimer", IDC_ADDREMOVE, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 246, 198, 64, 14 + CONTROL "&Info. support", IDC_SUPPORT_INFO, "button", BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 176, 198, 64, 14 CONTROL 3, 1003, "STATIC", SS_ICON | WS_CHILD | WS_VISIBLE, 7, 57, 21, 20 } diff --git a/dlls/cabinet/fdi.c b/dlls/cabinet/fdi.c index 454776afe68..4c499dd2935 100644 --- a/dlls/cabinet/fdi.c +++ b/dlls/cabinet/fdi.c @@ -2258,6 +2258,58 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state return DECR_OK; } +static void free_decompression_temps(HFDI hfdi, struct fdi_folder *fol, + fdi_decomp_state *decomp_state) +{ + switch (fol->comp_type & cffoldCOMPTYPE_MASK) { + case cffoldCOMPTYPE_LZX: + if (LZX(window)) { + PFDI_FREE(hfdi, LZX(window)); + LZX(window) = NULL; + } + break; + case cffoldCOMPTYPE_QUANTUM: + if (QTM(window)) { + PFDI_FREE(hfdi, QTM(window)); + QTM(window) = NULL; + } + break; + } +} + +static void free_decompression_mem(HFDI hfdi, struct fdi_folder *fol, + fdi_decomp_state *decomp_state, fdi_decomp_state *sentinel_decomp_state, + struct fdi_file *file) +{ + while (decomp_state) { + fdi_decomp_state *prev_fds; + + PFDI_CLOSE(hfdi, CAB(cabhf)); + + /* free the storage remembered by mii */ + if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname); + if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo); + if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname); + if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo); + + while (CAB(firstfol)) { + fol = CAB(firstfol); + CAB(firstfol) = CAB(firstfol)->next; + PFDI_FREE(hfdi, fol); + } + while (CAB(firstfile)) { + file = CAB(firstfile); + if (file->filename) PFDI_FREE(hfdi, (void *)file->filename); + CAB(firstfile) = CAB(firstfile)->next; + PFDI_FREE(hfdi, file); + } + prev_fds = decomp_state; + decomp_state = CAB(next); + if (prev_fds != sentinel_decomp_state) + PFDI_FREE(hfdi, prev_fds); + } +} + /*********************************************************************** * FDICopy (CABINET.22) * @@ -2839,99 +2891,18 @@ BOOL __cdecl FDICopy( } } - /* free decompression temps */ - switch (fol->comp_type & cffoldCOMPTYPE_MASK) { - case cffoldCOMPTYPE_LZX: - if (LZX(window)) { - PFDI_FREE(hfdi, LZX(window)); - LZX(window) = NULL; - } - break; - case cffoldCOMPTYPE_QUANTUM: - if (QTM(window)) { - PFDI_FREE(hfdi, QTM(window)); - QTM(window) = NULL; - } - break; - } - - while (decomp_state) { - fdi_decomp_state *prev_fds; - - PFDI_CLOSE(hfdi, CAB(cabhf)); - - /* free the storage remembered by mii */ - if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname); - if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo); - if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname); - if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo); - - while (CAB(firstfol)) { - fol = CAB(firstfol); - CAB(firstfol) = CAB(firstfol)->next; - PFDI_FREE(hfdi, fol); - } - while (CAB(firstfile)) { - file = CAB(firstfile); - if (file->filename) PFDI_FREE(hfdi, (void *)file->filename); - CAB(firstfile) = CAB(firstfile)->next; - PFDI_FREE(hfdi, file); - } - prev_fds = decomp_state; - decomp_state = CAB(next); - if (prev_fds != &_decomp_state) - PFDI_FREE(hfdi, prev_fds); - } + free_decompression_temps(hfdi, fol, decomp_state); + free_decompression_mem(hfdi, fol, decomp_state, &_decomp_state, file); return TRUE; bail_and_fail: /* here we free ram before error returns */ - /* free decompression temps */ - switch (fol->comp_type & cffoldCOMPTYPE_MASK) { - case cffoldCOMPTYPE_LZX: - if (LZX(window)) { - PFDI_FREE(hfdi, LZX(window)); - LZX(window) = NULL; - } - break; - case cffoldCOMPTYPE_QUANTUM: - if (QTM(window)) { - PFDI_FREE(hfdi, QTM(window)); - QTM(window) = NULL; - } - break; - } + free_decompression_temps(hfdi, fol, decomp_state); if (filehf) PFDI_CLOSE(hfdi, filehf); - while (decomp_state) { - fdi_decomp_state *prev_fds; - - PFDI_CLOSE(hfdi, CAB(cabhf)); - - /* free the storage remembered by mii */ - if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname); - if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo); - if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname); - if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo); - - while (CAB(firstfol)) { - fol = CAB(firstfol); - CAB(firstfol) = CAB(firstfol)->next; - PFDI_FREE(hfdi, fol); - } - while (CAB(firstfile)) { - file = CAB(firstfile); - if (file->filename) PFDI_FREE(hfdi, (void *)file->filename); - CAB(firstfile) = CAB(firstfile)->next; - PFDI_FREE(hfdi, file); - } - prev_fds = decomp_state; - decomp_state = CAB(next); - if (prev_fds != &_decomp_state) - PFDI_FREE(hfdi, prev_fds); - } + free_decompression_mem(hfdi, fol, decomp_state, &_decomp_state, file); return FALSE; } diff --git a/dlls/comctl32/monthcal.c b/dlls/comctl32/monthcal.c index 0c0a45c0692..a3f96580a10 100644 --- a/dlls/comctl32/monthcal.c +++ b/dlls/comctl32/monthcal.c @@ -994,7 +994,7 @@ MONTHCAL_SetRange(MONTHCAL_INFO *infoPtr, WPARAM wParam, LPARAM lParam) static LRESULT -MONTHCAL_GetRange(HWND hwnd, WPARAM wParam, LPARAM lParam) +MONTHCAL_GetRange(HWND hwnd, LPARAM lParam) { MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd); SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *)lParam; @@ -1631,7 +1631,7 @@ MONTHCAL_Timer(MONTHCAL_INFO *infoPtr, WPARAM wParam) static LRESULT -MONTHCAL_MouseMove(MONTHCAL_INFO *infoPtr, WPARAM wParam, LPARAM lParam) +MONTHCAL_MouseMove(MONTHCAL_INFO *infoPtr, LPARAM lParam) { MCHITTESTINFO ht; int oldselday, selday, hit; @@ -1891,7 +1891,7 @@ static LRESULT theme_changed (const MONTHCAL_INFO* infoPtr) /* FIXME: check whether dateMin/dateMax need to be adjusted. */ static LRESULT -MONTHCAL_Create(HWND hwnd, WPARAM wParam, LPARAM lParam) +MONTHCAL_Create(HWND hwnd, LPARAM lParam) { MONTHCAL_INFO *infoPtr; @@ -2021,7 +2021,7 @@ MONTHCAL_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return MONTHCAL_SetFirstDayOfWeek(infoPtr, lParam); case MCM_GETRANGE: - return MONTHCAL_GetRange(hwnd, wParam, lParam); + return MONTHCAL_GetRange(hwnd, lParam); case MCM_SETRANGE: return MONTHCAL_SetRange(infoPtr, wParam, lParam); @@ -2048,7 +2048,7 @@ MONTHCAL_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return MONTHCAL_LButtonDown(infoPtr, lParam); case WM_MOUSEMOVE: - return MONTHCAL_MouseMove(infoPtr, wParam, lParam); + return MONTHCAL_MouseMove(infoPtr, lParam); case WM_LBUTTONUP: return MONTHCAL_LButtonUp(infoPtr, lParam); @@ -2064,7 +2064,7 @@ MONTHCAL_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return MONTHCAL_Size(infoPtr, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam)); case WM_CREATE: - return MONTHCAL_Create(hwnd, wParam, lParam); + return MONTHCAL_Create(hwnd, lParam); case WM_SETFONT: return MONTHCAL_SetFont(infoPtr, (HFONT)wParam, (BOOL)lParam); diff --git a/dlls/comctl32/tests/header.c b/dlls/comctl32/tests/header.c index 536d0d152f0..4a6c54a49d8 100644 --- a/dlls/comctl32/tests/header.c +++ b/dlls/comctl32/tests/header.c @@ -999,7 +999,7 @@ static void test_hdm_imageMessages(HWND hParent) static void test_hdm_filterMessages(HWND hParent) { HWND hChild; - int retVal; + int retVal, timeout; flush_sequences(sequences, NUM_MSG_SEQUENCES); hChild = create_custom_header_control(hParent, TRUE); @@ -1007,21 +1007,27 @@ static void test_hdm_filterMessages(HWND hParent) ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq, "adder header control to parent", FALSE); + timeout = SendMessage(hChild, HDM_SETFILTERCHANGETIMEOUT, 1, 100); + SendMessage(hChild, HDM_SETFILTERCHANGETIMEOUT, 1, timeout); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + /* msdn incorrectly states that return value + * is the index of the filter control being + * modified. The sendMessage here should + * return previous filter timeout value + */ + + retVal = SendMessage(hChild, HDM_SETFILTERCHANGETIMEOUT, 1, 100); + expect(timeout, retVal); + todo_wine { - /* msdn incorrectly states that return value - * is the index of the filter control being - * modified. The sendMessage here should - * return previous filter timeout value - */ - retVal = SendMessage(hChild, HDM_SETFILTERCHANGETIMEOUT, 1, 100); - expect(1000, retVal); retVal = SendMessage(hChild, HDM_CLEARFILTER, 0, 1); expect(1, retVal); retVal = SendMessage(hChild, HDM_EDITFILTER, 1, 0); expect(1, retVal); - } + } if (winetest_interactive) ok_sequence(sequences, HEADER_SEQ_INDEX, filterMessages_seq_interactive, "filterMessages sequence testing", TRUE); diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index d9ab22985fe..8de96c8c764 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -607,6 +607,11 @@ static BOOL CRYPT_AcquirePrivateKeyFromProvInfo(PCCERT_CONTEXT pCert, CERT_KEY_PROV_INFO_PROP_ID, info, &size); allocated = TRUE; } + else + { + SetLastError(ERROR_OUTOFMEMORY); + ret = FALSE; + } } else SetLastError(CRYPT_E_NO_KEY_PROPERTY); diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c index 77032ac2d44..534d6ae3d66 100644 --- a/dlls/crypt32/chain.c +++ b/dlls/crypt32/chain.c @@ -1795,7 +1795,7 @@ BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID, set = CryptInitOIDFunctionSet( CRYPT_OID_VERIFY_CERTIFICATE_CHAIN_POLICY_FUNC, 0); CryptGetOIDFunctionAddress(set, X509_ASN_ENCODING, szPolicyOID, 0, - (void **)&verifyPolicy, hFunc); + (void **)&verifyPolicy, &hFunc); } if (verifyPolicy) ret = verifyPolicy(szPolicyOID, pChainContext, pPolicyPara, diff --git a/dlls/crypt32/context.c b/dlls/crypt32/context.c index a5b749f86af..959d0c9d8dd 100644 --- a/dlls/crypt32/context.c +++ b/dlls/crypt32/context.c @@ -173,6 +173,7 @@ void Context_CopyProperties(const void *to, const void *from, toProperties = Context_GetProperties((void *)to, contextSize); fromProperties = Context_GetProperties((void *)from, contextSize); + assert(toProperties && fromProperties); ContextPropertyList_Copy(toProperties, fromProperties); } diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec index 8476345cb71..c820612d2a7 100644 --- a/dlls/crypt32/crypt32.spec +++ b/dlls/crypt32/crypt32.spec @@ -186,8 +186,8 @@ @ stdcall CryptVerifyCertificateSignature(long long ptr long ptr) @ stdcall CryptVerifyCertificateSignatureEx(long long long ptr long ptr long ptr) @ stdcall CryptVerifyDetachedMessageHash(ptr ptr long long ptr ptr ptr ptr) -@ stub CryptVerifyDetachedMessageSignature -@ stub CryptVerifyMessageHash +@ stdcall CryptVerifyDetachedMessageSignature(ptr long ptr long long ptr ptr ptr) +@ stdcall CryptVerifyMessageHash(ptr ptr long ptr ptr ptr ptr) @ stdcall CryptVerifyMessageSignature(ptr long ptr long ptr ptr ptr) @ stub CryptVerifyMessageSignatureWithKey @ stub CryptVerifySignatureU diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c index eb782d3e018..4ed2abe9d81 100644 --- a/dlls/crypt32/decode.c +++ b/dlls/crypt32/decode.c @@ -475,6 +475,11 @@ static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[], cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo, startingPointer); + if (!cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + return FALSE; + } if (pbEncoded[0] == ASN_SEQUENCE) { DWORD dataLen; @@ -2581,7 +2586,7 @@ static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded, { *pcbStructInfo = bytesNeeded; /* MS used values one greater than the asn1 ones.. sigh */ - entry->dwAltNameChoice = (pbEncoded[0] & 0x7f) + 1; + entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1; switch (pbEncoded[0] & ASN_TYPE_MASK) { case 1: /* rfc822Name */ @@ -2599,7 +2604,6 @@ static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded, break; } case 4: /* directoryName */ - entry->dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; /* The data are memory-equivalent with the IPAddress case, * fall-through */ diff --git a/dlls/crypt32/message.c b/dlls/crypt32/message.c index 9413dd6f2ed..7551cceeac1 100644 --- a/dlls/crypt32/message.c +++ b/dlls/crypt32/message.c @@ -60,27 +60,6 @@ LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType, return count; } -static BOOL CRYPT_CopyParam(void *pvData, DWORD *pcbData, const void *src, - DWORD len) -{ - BOOL ret = TRUE; - - if (!pvData) - *pcbData = len; - else if (*pcbData < len) - { - *pcbData = len; - SetLastError(ERROR_MORE_DATA); - ret = FALSE; - } - else - { - *pcbData = len; - memcpy(pvData, src, len); - } - return ret; -} - static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg, DWORD dwSignerIndex) { @@ -101,6 +80,8 @@ static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg, } } } + else + SetLastError(CRYPT_E_UNEXPECTED_MSG_TYPE); return certInfo; } @@ -124,13 +105,87 @@ static inline PCCERT_CONTEXT CRYPT_GetSignerCertificate(HCRYPTMSG msg, pVerifyPara->dwMsgAndCertEncodingType, certInfo, store); } +BOOL WINAPI CryptVerifyDetachedMessageSignature( + PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, + const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned, + const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[], + PCCERT_CONTEXT *ppSignerCert) +{ + BOOL ret = FALSE; + HCRYPTMSG msg; + + TRACE("(%p, %d, %p, %d, %d, %p, %p, %p)\n", pVerifyPara, dwSignerIndex, + pbDetachedSignBlob, cbDetachedSignBlob, cToBeSigned, rgpbToBeSigned, + rgcbToBeSigned, ppSignerCert); + + if (ppSignerCert) + *ppSignerCert = NULL; + if (!pVerifyPara || + pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) || + GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) != + PKCS_7_ASN_ENCODING) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + + msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, + CMSG_DETACHED_FLAG, 0, pVerifyPara->hCryptProv, NULL, NULL); + if (msg) + { + ret = CryptMsgUpdate(msg, pbDetachedSignBlob, cbDetachedSignBlob, TRUE); + if (ret) + { + DWORD i; + + for (i = 0; ret && i < cToBeSigned; i++) + ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i], + i == cToBeSigned - 1 ? TRUE : FALSE); + } + if (ret) + { + CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg, + dwSignerIndex); + + ret = FALSE; + if (certInfo) + { + HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG, + pVerifyPara->dwMsgAndCertEncodingType, + pVerifyPara->hCryptProv, 0, msg); + + if (store) + { + PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate( + msg, pVerifyPara, certInfo, store); + + if (cert) + { + ret = CryptMsgControl(msg, 0, + CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo); + if (ret && ppSignerCert) + *ppSignerCert = cert; + else + CertFreeCertificateContext(cert); + } + else + SetLastError(CRYPT_E_NOT_FOUND); + CertCloseStore(store, 0); + } + CryptMemFree(certInfo); + } + } + CryptMsgClose(msg); + } + TRACE("returning %d\n", ret); + return ret; +} + BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob, BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert) { BOOL ret = FALSE; - DWORD size; - CRYPT_CONTENT_INFO *contentInfo; HCRYPTMSG msg; TRACE("(%p, %d, %p, %d, %p, %p, %p)\n", @@ -150,26 +205,14 @@ BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, return FALSE; } - if (!CryptDecodeObjectEx(pVerifyPara->dwMsgAndCertEncodingType, - PKCS_CONTENT_INFO, pbSignedBlob, cbSignedBlob, - CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL, - (LPBYTE)&contentInfo, &size)) - return FALSE; - if (strcmp(contentInfo->pszObjId, szOID_RSA_signedData)) - { - LocalFree(contentInfo); - SetLastError(CRYPT_E_UNEXPECTED_MSG_TYPE); - return FALSE; - } - msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, 0, - CMSG_SIGNED, pVerifyPara->hCryptProv, NULL, NULL); + msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, 0, 0, + pVerifyPara->hCryptProv, NULL, NULL); if (msg) { - ret = CryptMsgUpdate(msg, contentInfo->Content.pbData, - contentInfo->Content.cbData, TRUE); + ret = CryptMsgUpdate(msg, pbSignedBlob, cbSignedBlob, TRUE); if (ret && pcbDecoded) - ret = CRYPT_CopyParam(pbDecoded, pcbDecoded, - contentInfo->Content.pbData, contentInfo->Content.cbData); + ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbDecoded, + pcbDecoded); if (ret) { CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg, @@ -203,7 +246,6 @@ BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, } CryptMsgClose(msg); } - LocalFree(contentInfo); TRACE("returning %d\n", ret); return ret; } @@ -318,3 +360,45 @@ BOOL WINAPI CryptVerifyDetachedMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, } return ret; } + +BOOL WINAPI CryptVerifyMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, + BYTE *pbHashedBlob, DWORD cbHashedBlob, BYTE *pbToBeHashed, + DWORD *pcbToBeHashed, BYTE *pbComputedHash, DWORD *pcbComputedHash) +{ + HCRYPTMSG msg; + BOOL ret = FALSE; + + TRACE("(%p, %p, %d, %p, %p, %p, %p)\n", pHashPara, pbHashedBlob, + cbHashedBlob, pbToBeHashed, pcbToBeHashed, pbComputedHash, + pcbComputedHash); + + if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA)) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) != + PKCS_7_ASN_ENCODING) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + msg = CryptMsgOpenToDecode(pHashPara->dwMsgEncodingType, 0, 0, + pHashPara->hCryptProv, NULL, NULL); + if (msg) + { + ret = CryptMsgUpdate(msg, pbHashedBlob, cbHashedBlob, TRUE); + if (ret) + { + ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); + if (ret && pcbToBeHashed) + ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, + pbToBeHashed, pcbToBeHashed); + if (ret && pcbComputedHash) + ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, + pbComputedHash, pcbComputedHash); + } + CryptMsgClose(msg); + } + return ret; +} diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c index 1c07e05cd1f..8312ff97ede 100644 --- a/dlls/crypt32/msg.c +++ b/dlls/crypt32/msg.c @@ -1723,15 +1723,13 @@ static BOOL CDecodeMsg_FinalizeHashedContent(CDecodeMsg *msg, { /* Unlike for non-detached messages, the data were never stored as * the content param, but were saved in msg->detached_data instead. - * Set the content property with the detached data so the data may - * be hashed. */ - ContextPropertyList_SetProperty(msg->properties, - CMSG_CONTENT_PARAM, msg->detached_data.pbData, - msg->detached_data.cbData); + content.pbData = msg->detached_data.pbData; + content.cbData = msg->detached_data.cbData; } - ret = ContextPropertyList_FindProperty(msg->properties, - CMSG_CONTENT_PARAM, &content); + else + ret = ContextPropertyList_FindProperty(msg->properties, + CMSG_CONTENT_PARAM, &content); if (ret) ret = CryptHashData(msg->u.hash, content.pbData, content.cbData, 0); } @@ -2556,6 +2554,11 @@ static BOOL CDecodeSignedMsg_VerifySignature(CDecodeMsg *msg, PCERT_INFO info) BOOL ret = FALSE; DWORD i; + if (!msg->u.signed_data.signerHandles) + { + SetLastError(NTE_BAD_SIGNATURE); + return FALSE; + } for (i = 0; !ret && i < msg->u.signed_data.info->cSignerInfo; i++) { PCMSG_CMS_SIGNER_INFO signerInfo = @@ -2598,6 +2601,8 @@ static BOOL CDecodeSignedMsg_VerifySignatureEx(CDecodeMsg *msg, SetLastError(ERROR_INVALID_PARAMETER); else if (para->dwSignerIndex >= msg->u.signed_data.info->cSignerInfo) SetLastError(CRYPT_E_SIGNER_NOT_FOUND); + else if (!msg->u.signed_data.signerHandles) + SetLastError(NTE_BAD_SIGNATURE); else { switch (para->dwSignerType) diff --git a/dlls/crypt32/tests/message.c b/dlls/crypt32/tests/message.c index d515d9b4049..28f9a4eb8ec 100644 --- a/dlls/crypt32/tests/message.c +++ b/dlls/crypt32/tests/message.c @@ -190,6 +190,90 @@ static void test_verify_detached_message_hash(void) ok(ret, "CryptVerifyDetachedMessageHash failed: %08x\n", GetLastError()); } +static BYTE hashContent[] = { +0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a, +0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d, +0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0, +0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f }; + +static void test_verify_message_hash(void) +{ + BOOL ret; + CRYPT_HASH_MESSAGE_PARA para; + DWORD size; + BYTE *buf = NULL; + + memset(¶, 0, sizeof(para)); + /* Crash */ + if (0) + ret = CryptVerifyMessageHash(NULL, NULL, 0, NULL, NULL, NULL, NULL); + SetLastError(0xdeadbeef); + ret = CryptVerifyMessageHash(¶, NULL, 0, NULL, NULL, NULL, NULL); + ok(!ret && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + para.cbSize = sizeof(para); + SetLastError(0xdeadbeef); + ret = CryptVerifyMessageHash(¶, NULL, 0, NULL, NULL, NULL, NULL); + ok(!ret && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + para.dwMsgEncodingType = PKCS_7_ASN_ENCODING; + SetLastError(0xdeadbeef); + ret = CryptVerifyMessageHash(¶, NULL, 0, NULL, NULL, NULL, NULL); + ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD, + "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); + /* Verifying the hash of a detached message succeeds? */ + ret = CryptVerifyMessageHash(¶, detachedHashContent, + sizeof(detachedHashContent), NULL, NULL, NULL, NULL); + todo_wine + ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError()); + /* As does verifying the hash of a regular message. */ + ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent), + NULL, NULL, NULL, NULL); + ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError()); + ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent), + NULL, &size, NULL, NULL); + ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError()); + if (ret) + buf = CryptMemAlloc(size); + if (buf) + { + size = 1; + ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent), + buf, &size, NULL, NULL); + ok(!ret && GetLastError() == ERROR_MORE_DATA, + "expected ERROR_MORE_DATA, got %08x\n", GetLastError()); + ret = CryptVerifyMessageHash(¶, hashContent, sizeof(hashContent), + buf, &size, NULL, NULL); + ok(ret, "CryptVerifyMessageHash failed: %08x\n", GetLastError()); + ok(size == sizeof(msgData), "unexpected size %d\n", size); + ok(!memcmp(buf, msgData, size), "unexpected value\n"); + CryptMemFree(buf); + } +} + +static const BYTE signedWithCertContent[] = { +0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, +0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c, +0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01, +0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30, +0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, +0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31, +0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36, +0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15, +0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, +0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00, +0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04, +0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01, +0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13, +0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30, +0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04, +0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1, +0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9, +0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11, +0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19, +0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; static const BYTE signedContent[] = { 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, @@ -204,6 +288,120 @@ static const BYTE signedContent[] = { 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29, 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8, 0x0d }; +static const BYTE detachedSignedContent[] = { +0x30,0x81,0xaa,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, +0x81,0x9c,0x30,0x81,0x99,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30, +0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a, +0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06, +0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00, +0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0, +0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0, +0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23, +0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51, +0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; +static const BYTE v1CertWithValidPubKey[] = { +0x30,0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, +0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, +0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, +0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, +0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, +0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, +0x67,0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a, +0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1, +0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde, +0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f, +0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10, +0x79,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55, +0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 }; + +static PCCERT_CONTEXT WINAPI msg_get_signer_callback(void *pvArg, + DWORD certEncodingType, PCERT_INFO signerId, HCERTSTORE store) +{ + return CertCreateCertificateContext(X509_ASN_ENCODING, + v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey)); +} + +static void test_verify_detached_message_signature(void) +{ + CRYPT_VERIFY_MESSAGE_PARA para; + BOOL ret; + const BYTE *pContent; + DWORD cbContent; + + memset(¶, 0, sizeof(para)); + SetLastError(0xdeadbeef); + ret = CryptVerifyDetachedMessageSignature(NULL, 0, NULL, 0, 0, NULL, + NULL, NULL); + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, + NULL, NULL); + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + para.cbSize = sizeof(para); + SetLastError(0xdeadbeef); + ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, + NULL, NULL); + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + para.dwMsgAndCertEncodingType = X509_ASN_ENCODING; + SetLastError(0xdeadbeef); + ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, + NULL, NULL); + ok(!ret && GetLastError() == E_INVALIDARG, + "Expected E_INVALIDARG, got %08x\n", GetLastError()); + para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING; + SetLastError(0xdeadbeef); + ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, + NULL, NULL); + ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD, + "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); + /* None of these messages contains a cert in the message itself, so the + * default callback isn't able to verify their signature. + */ + SetLastError(0xdeadbeef); + ret = CryptVerifyDetachedMessageSignature(¶, 0, signedWithCertContent, + sizeof(signedWithCertContent), 0, NULL, NULL, NULL); + todo_wine + ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, + "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptVerifyDetachedMessageSignature(¶, 0, signedContent, + sizeof(signedContent), 0, NULL, NULL, NULL); + ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, + "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, + sizeof(detachedSignedContent), 0, NULL, NULL, NULL); + ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, + "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); + SetLastError(0xdeadbeef); + pContent = msgData; + cbContent = sizeof(msgData); + ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, + sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL); + ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, + "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); + /* Passing the correct callback results in success */ + para.pfnGetSignerCertificate = msg_get_signer_callback; + ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, + sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL); + ok(ret, "CryptVerifyDetachedMessageSignature failed: %08x\n", + GetLastError()); + /* Not passing the correct data to be signed results in the signature not + * matching. + */ + SetLastError(0xdeadbeef); + ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, + sizeof(detachedSignedContent), 0, NULL, NULL, NULL); + ok(!ret && GetLastError() == NTE_BAD_SIGNATURE, + "expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError()); +} + static const BYTE signedWithCertEmptyContent[] = { 0x30,0x81,0xdf,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 0x81,0xd1,0x30,0x81,0xce,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, @@ -221,28 +419,6 @@ static const BYTE signedWithCertEmptyContent[] = { 0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86, 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04, 0x00 }; -static const BYTE signedWithCertContent[] = { -0x30,0x82,0x01,0x32,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02, -0xa0,0x82,0x01,0x23,0x30,0x82,0x01,0x1f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c, -0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06, -0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01, -0x02,0x03,0x04,0xa0,0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30, -0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, -0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31, -0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36, -0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15, -0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, -0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00, -0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04, -0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,0x77,0x30,0x75,0x02,0x01, -0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13, -0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30, -0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04, -0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1, -0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9, -0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11, -0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19, -0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d }; static const BYTE signedWithCertWithPubKeyContent[] = { 0x30,0x81,0xfc,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0, 0x81,0xee,0x30,0x81,0xeb,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a, @@ -522,6 +698,8 @@ START_TEST(message) { test_msg_get_signer_count(); test_verify_detached_message_hash(); + test_verify_message_hash(); + test_verify_detached_message_signature(); test_verify_message_signature(); test_hash_message(); } diff --git a/dlls/crypt32/tests/msg.c b/dlls/crypt32/tests/msg.c index 2783815fdb6..b03f5a41891 100644 --- a/dlls/crypt32/tests/msg.c +++ b/dlls/crypt32/tests/msg.c @@ -2841,6 +2841,37 @@ static void test_msg_control(void) ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); ok(ret, "CryptMsgControl failed: %08x\n", GetLastError()); CryptMsgClose(msg); + + /* Test verifying signature of a detached signed message */ + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, + NULL, NULL); + ret = CryptMsgUpdate(msg, detachedSignedContent, + sizeof(detachedSignedContent), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + /* Can't verify the sig without having updated the data */ + SetLastError(0xdeadbeef); + ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); + ok(!ret && GetLastError() == NTE_BAD_SIGNATURE, + "expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError()); + /* Now that the signature's been checked, can't do the final update */ + ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); + todo_wine + ok(!ret && GetLastError() == NTE_BAD_HASH_STATE, + "expected NTE_BAD_HASH_STATE, got %08x\n", GetLastError()); + CryptMsgClose(msg); + /* Updating with the detached portion of the message and the data of the + * the message allows the sig to be verified. + */ + msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, CMSG_DETACHED_FLAG, 0, 0, + NULL, NULL); + ret = CryptMsgUpdate(msg, detachedSignedContent, + sizeof(detachedSignedContent), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE); + ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError()); + ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, &certInfo); + ok(ret, "CryptMsgControl failed: %08x\n", GetLastError()); + CryptMsgClose(msg); } /* win9x has much less parameter checks and will crash on many tests diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index a81bf784495..976d7dd31c5 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -805,13 +805,22 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 ifa IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; IDirect3DSurface8Impl *pSurface = (IDirect3DSurface8Impl *)pRenderTarget; IDirect3DSurface8Impl *pZSurface = (IDirect3DSurface8Impl *)pNewZStencil; + IWineD3DSurface *original_ds = NULL; HRESULT hr; TRACE("(%p) Relay\n" , This); - IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, NULL == pZSurface ? NULL : pZSurface->wineD3DSurface); - EnterCriticalSection(&d3d8_cs); - hr = IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, 0, pSurface ? pSurface->wineD3DSurface : NULL); + + hr = IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice, &original_ds); + if (hr == WINED3D_OK || hr == WINED3DERR_NOTFOUND) + { + hr = IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, pZSurface ? pZSurface->wineD3DSurface : NULL); + if (SUCCEEDED(hr) && pSurface) + hr = IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, 0, pSurface->wineD3DSurface); + if (FAILED(hr)) IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, original_ds); + } + if (original_ds) IWineD3DSurface_Release(original_ds); + LeaveCriticalSection(&d3d8_cs); return hr; } @@ -853,16 +862,17 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDepthStencilSurface(LPDIRECT3DDE EnterCriticalSection(&d3d8_cs); hr=IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface); - if(hr == D3D_OK && pZStencilSurface != NULL){ + if (hr == WINED3D_OK) { IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface); IWineD3DSurface_Release(pZStencilSurface); }else{ - FIXME("Call to IWineD3DDevice_GetDepthStencilSurface failed\n"); + if (hr != WINED3DERR_NOTFOUND) + FIXME("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr); *ppZStencilSurface = NULL; } LeaveCriticalSection(&d3d8_cs); - return D3D_OK; + return hr; } static HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) { diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index c3aa5911655..190903815bc 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -1283,6 +1283,76 @@ static void test_render_zero_triangles(void) if(d3d8) IDirect3D8_Release(d3d8); } +static void test_depth_stencil_reset(void) +{ + D3DPRESENT_PARAMETERS present_parameters; + D3DDISPLAYMODE display_mode; + IDirect3DSurface8 *surface; + IDirect3DDevice8 *device; + IDirect3D8 *d3d8; + HRESULT hr; + HWND hwnd; + + d3d8 = pDirect3DCreate8(D3D_SDK_VERSION); + ok(d3d8 != NULL, "Failed to create IDirect3D8 object\n"); + hwnd = CreateWindow("static", "d3d8_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "Failed to create window\n"); + if (!d3d8 || !hwnd) goto cleanup; + + IDirect3D8_GetAdapterDisplayMode(d3d8, D3DADAPTER_DEFAULT, &display_mode); + memset(&present_parameters, 0, sizeof(present_parameters)); + present_parameters.Windowed = TRUE; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.BackBufferFormat = display_mode.Format; + present_parameters.EnableAutoDepthStencil = TRUE; + present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8; + + hr = IDirect3D8_CreateDevice(d3d8, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device); + if(FAILED(hr)) + { + skip("could not create device, IDirect3D8_CreateDevice returned %#x\n", hr); + goto cleanup; + } + + hr = IDirect3DDevice8_TestCooperativeLevel(device); + ok(SUCCEEDED(hr), "TestCooperativeLevel failed with %#x\n", hr); + + hr = IDirect3DDevice8_SetRenderTarget(device, NULL, NULL); + ok(hr == D3D_OK, "SetRenderTarget failed with 0x%08x\n", hr); + + hr = IDirect3DDevice8_GetRenderTarget(device, &surface); + ok(hr == D3D_OK, "GetRenderTarget failed with 0x%08x\n", hr); + ok(surface != NULL, "Render target should not be NULL\n"); + if (surface) IDirect3DSurface8_Release(surface); + + hr = IDirect3DDevice8_GetDepthStencilSurface(device, &surface); + ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr); + ok(surface == NULL, "Depth stencil should be NULL\n"); + + present_parameters.EnableAutoDepthStencil = TRUE; + present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8; + hr = IDirect3DDevice8_Reset(device, &present_parameters); + ok(hr == D3D_OK, "Reset failed with 0x%08x\n", hr); + + hr = IDirect3DDevice8_GetDepthStencilSurface(device, &surface); + ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr); + ok(surface != NULL, "Depth stencil should not be NULL\n"); + if (surface) IDirect3DSurface8_Release(surface); + + present_parameters.EnableAutoDepthStencil = FALSE; + hr = IDirect3DDevice8_Reset(device, &present_parameters); + ok(hr == D3D_OK, "Reset failed with 0x%08x\n", hr); + + hr = IDirect3DDevice8_GetDepthStencilSurface(device, &surface); + ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr); + ok(surface == NULL, "Depth stencil should be NULL\n"); + +cleanup: + if(d3d8) IDirect3D8_Release(d3d8); + if(device) IDirect3D8_Release(device); +} + START_TEST(device) { HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" ); @@ -1308,5 +1378,6 @@ START_TEST(device) test_limits(); test_lights(); test_render_zero_triangles(); + test_depth_stencil_reset(); } } diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index ddeaca30370..b12e562235b 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -737,15 +737,12 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDE EnterCriticalSection(&d3d9_cs); hr = IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface); - if(hr == D3D_OK) { - if(pZStencilSurface != NULL){ - IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface); - IWineD3DSurface_Release(pZStencilSurface); - } else { - *ppZStencilSurface = NULL; - } + if (hr == WINED3D_OK) { + IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface); + IWineD3DSurface_Release(pZStencilSurface); } else { - WARN("Call to IWineD3DDevice_GetDepthStencilSurface failed\n"); + if (hr != WINED3DERR_NOTFOUND) + WARN("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr); *ppZStencilSurface = NULL; } LeaveCriticalSection(&d3d9_cs); diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 41dcafb7c20..d28da880dbf 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -744,6 +744,8 @@ static void test_reset(void) d3dpp.BackBufferWidth = 800; d3dpp.BackBufferHeight = 600; d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.EnableAutoDepthStencil = TRUE; + d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; for(i = 0; i < IDirect3D9_GetAdapterModeCount(pD3d, D3DADAPTER_DEFAULT, d3ddm.Format); i++) { ZeroMemory( &d3ddm2, sizeof(d3ddm2) ); @@ -924,6 +926,32 @@ static void test_reset(void) ok(hr == D3D_OK, "IDirect3DDevice9_TestCooperativeLevel after a successful reset returned %#x\n", hr); IDirect3DSurface9_Release(surface); + /* The depth stencil should get reset to the auto depth stencil when present. */ + hr = IDirect3DDevice9_SetDepthStencilSurface(pDevice, NULL); + ok(hr == D3D_OK, "SetDepthStencilSurface failed with 0x%08x\n", hr); + + hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &surface); + ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr); + ok(surface == NULL, "Depth stencil should be NULL\n"); + + d3dpp.EnableAutoDepthStencil = TRUE; + d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; + hr = IDirect3DDevice9_Reset(pDevice, &d3dpp); + ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr); + + hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &surface); + ok(hr == D3D_OK, "GetDepthStencilSurface failed with 0x%08x\n", hr); + ok(surface != NULL, "Depth stencil should not be NULL\n"); + if (surface) IDirect3DSurface9_Release(surface); + + d3dpp.EnableAutoDepthStencil = FALSE; + hr = IDirect3DDevice9_Reset(pDevice, &d3dpp); + ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with 0x%08x\n", hr); + + hr = IDirect3DDevice9_GetDepthStencilSurface(pDevice, &surface); + ok(hr == D3DERR_NOTFOUND, "GetDepthStencilSurface returned 0x%08x, expected D3DERR_NOTFOUND\n", hr); + ok(surface == NULL, "Depth stencil should be NULL\n"); + /* Will a sysmem or scratch survive while locked */ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(pDevice, 16, 16, D3DFMT_R5G6B5, D3DPOOL_SYSTEMMEM, &surface, NULL); ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned %08x\n", hr); @@ -2131,7 +2159,6 @@ START_TEST(device) test_mipmap_levels(); test_cursor(); test_reset(); - test_reset(); test_scene(); test_limits(); test_depthstenciltest(); diff --git a/dlls/dplayx/dplay.c b/dlls/dplayx/dplay.c index ce9cdb6434f..b3494621632 100644 --- a/dlls/dplayx/dplay.c +++ b/dlls/dplayx/dplay.c @@ -3032,7 +3032,7 @@ static HRESULT WINAPI DP_IF_Receive } /* Copy into the provided buffer */ - CopyMemory( lpData, lpMsg->msg, *lpdwDataSize ); + if (lpData) CopyMemory( lpData, lpMsg->msg, *lpdwDataSize ); return DP_OK; } diff --git a/dlls/dplayx/dplayx_global.c b/dlls/dplayx/dplayx_global.c index f70335bd569..fc72dce9140 100644 --- a/dlls/dplayx/dplayx_global.c +++ b/dlls/dplayx/dplayx_global.c @@ -889,7 +889,8 @@ HRESULT DPLAYX_SetConnectionSettingsA { DPLAYX_ReleaseSemaphore(); - ERR("DPSESSIONDESC passed in? Size=%u\n", lpConn->lpSessionDesc->dwSize ); + ERR("DPSESSIONDESC passed in? Size=%u\n", + lpConn->lpSessionDesc?lpConn->lpSessionDesc->dwSize:0 ); return DPERR_INVALIDPARAMS; } diff --git a/dlls/dplayx/tests/dplayx.c b/dlls/dplayx/tests/dplayx.c index 0f6d9799aae..d084c9bb74a 100644 --- a/dlls/dplayx/tests/dplayx.c +++ b/dlls/dplayx/tests/dplayx.c @@ -4282,7 +4282,7 @@ static void test_EnumGroupsInGroup(void) /* - Open session */ callbackData.pDP = pDP[1]; hr = IDirectPlayX_EnumSessions( pDP[1], &dpsd[0], 0, EnumSessions_cb_join, - (LPVOID) pDP[2], 0 ); + (LPVOID) &callbackData, 0 ); checkHR( DP_OK, hr ); diff --git a/dlls/dsound/tests/dsound.c b/dlls/dsound/tests/dsound.c index d6c0f29f211..9dc8f21c3e5 100644 --- a/dlls/dsound/tests/dsound.c +++ b/dlls/dsound/tests/dsound.c @@ -716,8 +716,9 @@ static HRESULT test_secondary(LPGUID lpGuid) if (gotdx8 || wfx.wBitsPerSample <= 16) { if (wfx.wBitsPerSample > 16) - ok((rc == DSERR_CONTROLUNAVAIL || rc == DSERR_INVALIDCALL) && - !secondary, "IDirectSound_CreateSoundBuffer() " + ok(((rc == DSERR_CONTROLUNAVAIL || rc == DSERR_INVALIDCALL || rc == DSERR_INVALIDPARAM /* 2003 */) && !secondary) + || rc == DS_OK, /* driver dependent? */ + "IDirectSound_CreateSoundBuffer() " "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) " "and NULL, returned: %08x %p\n", rc, secondary); else @@ -750,20 +751,27 @@ static HRESULT test_secondary(LPGUID lpGuid) wfxe.dwChannelMask = (wfx.nChannels == 1 ? KSAUDIO_SPEAKER_MONO : KSAUDIO_SPEAKER_STEREO); rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); - ok(rc==DSERR_INVALIDPARAM && !secondary, + ok((rc==DSERR_INVALIDPARAM || rc==DSERR_INVALIDCALL /* 2003 */) && !secondary, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) + { IDirectSoundBuffer_Release(secondary); + secondary=NULL; + } wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx) + 1; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); - ok(rc==DSERR_CONTROLUNAVAIL && !secondary, + ok(((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL) && !secondary) + || rc==DS_OK, /* 2003 / 2008 */ "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) + { IDirectSoundBuffer_Release(secondary); + secondary=NULL; + } wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx); wfxe.SubFormat = GUID_NULL; @@ -772,7 +780,10 @@ static HRESULT test_secondary(LPGUID lpGuid) "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) + { IDirectSoundBuffer_Release(secondary); + secondary=NULL; + } wfxe.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; ++wfxe.Samples.wValidBitsPerSample; @@ -781,7 +792,10 @@ static HRESULT test_secondary(LPGUID lpGuid) "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) + { IDirectSoundBuffer_Release(secondary); + secondary=NULL; + } --wfxe.Samples.wValidBitsPerSample; wfxe.Samples.wValidBitsPerSample = 0; @@ -790,7 +804,10 @@ static HRESULT test_secondary(LPGUID lpGuid) "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) + { IDirectSoundBuffer_Release(secondary); + secondary=NULL; + } wfxe.Samples.wValidBitsPerSample = wfxe.Format.wBitsPerSample; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); diff --git a/dlls/dsound/tests/dsound8.c b/dlls/dsound/tests/dsound8.c index 8edb9b482d4..2e02a92eb36 100644 --- a/dlls/dsound/tests/dsound8.c +++ b/dlls/dsound/tests/dsound8.c @@ -574,7 +574,9 @@ static HRESULT test_primary_secondary8(LPGUID lpGuid) formats[f][2]); wfx2=wfx; rc=IDirectSoundBuffer_SetFormat(primary,&wfx); - ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat(%s) failed: %08x\n", + ok(rc==DS_OK + || rc==DSERR_INVALIDPARAM, /* 2003 */ + "IDirectSoundBuffer_SetFormat(%s) failed: %08x\n", format_string(&wfx), rc); /* There is no guarantee that SetFormat will actually change the @@ -723,8 +725,9 @@ static HRESULT test_secondary8(LPGUID lpGuid) bufdesc.lpwfxFormat=&wfx; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); if (wfx.wBitsPerSample != 8 && wfx.wBitsPerSample != 16) - ok((rc == DSERR_CONTROLUNAVAIL || rc == DSERR_INVALIDCALL) && - !secondary, "IDirectSound_CreateSoundBuffer() " + ok(((rc == DSERR_CONTROLUNAVAIL || rc == DSERR_INVALIDCALL || rc == DSERR_INVALIDPARAM /* 2003 */) && !secondary) + || rc == DS_OK, /* driver dependent? */ + "IDirectSound_CreateSoundBuffer() " "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) " "and NULL, returned: %08x %p\n", rc, secondary); else @@ -748,16 +751,23 @@ static HRESULT test_secondary8(LPGUID lpGuid) "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) + { IDirectSoundBuffer_Release(secondary); + secondary=NULL; + } wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx) + 1; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); - ok(rc==DSERR_CONTROLUNAVAIL && !secondary, + ok(((rc==DSERR_CONTROLUNAVAIL || DSERR_INVALIDCALL /* 2003 */) && !secondary) + || rc==DS_OK /* driver dependent? */, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) + { IDirectSoundBuffer_Release(secondary); + secondary=NULL; + } wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx); wfxe.SubFormat = GUID_NULL; @@ -766,7 +776,10 @@ static HRESULT test_secondary8(LPGUID lpGuid) "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) + { IDirectSoundBuffer_Release(secondary); + secondary=NULL; + } wfxe.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; ++wfxe.Samples.wValidBitsPerSample; @@ -775,7 +788,10 @@ static HRESULT test_secondary8(LPGUID lpGuid) "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) + { IDirectSoundBuffer_Release(secondary); + secondary=NULL; + } --wfxe.Samples.wValidBitsPerSample; wfxe.Samples.wValidBitsPerSample = 0; @@ -784,7 +800,10 @@ static HRESULT test_secondary8(LPGUID lpGuid) "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) + { IDirectSoundBuffer_Release(secondary); + secondary=NULL; + } wfxe.Samples.wValidBitsPerSample = wfxe.Format.wBitsPerSample; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); diff --git a/dlls/jscript/Makefile.in b/dlls/jscript/Makefile.in index 095659b7176..ee3f7e56ed4 100644 --- a/dlls/jscript/Makefile.in +++ b/dlls/jscript/Makefile.in @@ -8,12 +8,21 @@ IMPORTS = oleaut32 kernel32 RC_SRCS = rsrc.rc C_SRCS = \ + array.c \ + bool.c \ dispex.c \ engine.c \ + function.c \ + global.c \ jscript.c \ jscript_main.c \ jsutils.c \ - lex.c + lex.c \ + math.c \ + number.c \ + object.c \ + regexp.c \ + string.c IDL_TLB_SRCS = jsglobal.idl diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c new file mode 100644 index 00000000000..31249f093e1 --- /dev/null +++ b/dlls/jscript/array.c @@ -0,0 +1,253 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * 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 + */ + +#include "jscript.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(jscript); + +typedef struct { + DispatchEx dispex; +} ArrayInstance; + +static const WCHAR lengthW[] = {'l','e','n','g','t','h',0}; +static const WCHAR concatW[] = {'c','o','n','c','a','t',0}; +static const WCHAR joinW[] = {'j','o','i','n',0}; +static const WCHAR popW[] = {'p','o','p',0}; +static const WCHAR pushW[] = {'p','u','s','h',0}; +static const WCHAR reverseW[] = {'r','e','v','e','r','s','e',0}; +static const WCHAR shiftW[] = {'s','h','i','f','t',0}; +static const WCHAR sliceW[] = {'s','l','i','c','e',0}; +static const WCHAR sortW[] = {'s','o','r','t',0}; +static const WCHAR spliceW[] = {'s','p','l','i','c','e',0}; +static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; +static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0}; +static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0}; +static const WCHAR unshiftW[] = {'u','n','s','h','i','f','t',0}; +static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0}; +static const WCHAR propertyIsEnumerableW[] = + {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; +static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0}; + + +static HRESULT Array_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_concat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_join(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_pop(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_push(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_reverse(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_shift(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_sort(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_splice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_unshift(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_propertyIsEnumerable(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Array_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static void Array_destructor(DispatchEx *dispex) +{ + heap_free(dispex); +} + +static void Array_on_put(DispatchEx *dispex, const WCHAR *name) +{ + FIXME("\n"); +} + +static const builtin_prop_t Array_props[] = { + {concatW, Array_concat, PROPF_METHOD}, + {hasOwnPropertyW, Array_hasOwnProperty, PROPF_METHOD}, + {isPrototypeOfW, Array_isPrototypeOf, PROPF_METHOD}, + {joinW, Array_join, PROPF_METHOD}, + {lengthW, Array_length, 0}, + {popW, Array_pop, PROPF_METHOD}, + {propertyIsEnumerableW, Array_propertyIsEnumerable, PROPF_METHOD}, + {pushW, Array_push, PROPF_METHOD}, + {reverseW, Array_reverse, PROPF_METHOD}, + {shiftW, Array_shift, PROPF_METHOD}, + {sliceW, Array_slice, PROPF_METHOD}, + {sortW, Array_sort, PROPF_METHOD}, + {spliceW, Array_splice, PROPF_METHOD}, + {toLocaleStringW, Array_toLocaleString, PROPF_METHOD}, + {toStringW, Array_toString, PROPF_METHOD}, + {unshiftW, Array_unshift, PROPF_METHOD}, + {valueOfW, Array_valueOf, PROPF_METHOD} +}; + +static const builtin_info_t Array_info = { + JSCLASS_ARRAY, + {NULL, Array_value, 0}, + sizeof(Array_props)/sizeof(*Array_props), + Array_props, + Array_destructor, + Array_on_put +}; + +static HRESULT ArrayConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT alloc_array(script_ctx_t *ctx, BOOL use_constr, ArrayInstance **ret) +{ + ArrayInstance *array = heap_alloc_zero(sizeof(ArrayInstance)); + HRESULT hres; + + if(use_constr) + hres = init_dispex_from_constr(&array->dispex, ctx, &Array_info, ctx->array_constr); + else + hres = init_dispex(&array->dispex, ctx, &Array_info, NULL); + + if(FAILED(hres)) { + heap_free(array); + return hres; + } + + *ret = array; + return S_OK; +} + +HRESULT create_array_constr(script_ctx_t *ctx, DispatchEx **ret) +{ + ArrayInstance *array; + HRESULT hres; + + hres = alloc_array(ctx, FALSE, &array); + if(FAILED(hres)) + return hres; + + hres = create_builtin_function(ctx, ArrayConstr_value, PROPF_CONSTR, &array->dispex, ret); + + IDispatchEx_Release(_IDispatchEx_(&array->dispex)); + return hres; +} diff --git a/dlls/jscript/bool.c b/dlls/jscript/bool.c new file mode 100644 index 00000000000..a98a4ff7554 --- /dev/null +++ b/dlls/jscript/bool.c @@ -0,0 +1,147 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * 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 + */ + +#include "jscript.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(jscript); + +typedef struct { + DispatchEx dispex; +} BoolInstance; + +static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; +static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0}; +static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0}; +static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0}; +static const WCHAR propertyIsEnumerableW[] = + {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; +static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0}; + +static HRESULT Bool_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Bool_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Bool_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Bool_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Bool_propertyIsEnumerable(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Bool_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Bool_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static const builtin_prop_t Bool_props[] = { + {hasOwnPropertyW, Bool_hasOwnProperty, PROPF_METHOD}, + {isPrototypeOfW, Bool_isPrototypeOf, PROPF_METHOD}, + {propertyIsEnumerableW, Bool_propertyIsEnumerable, PROPF_METHOD}, + {toLocaleStringW, Bool_toLocaleString, PROPF_METHOD}, + {toStringW, Bool_toString, PROPF_METHOD}, + {valueOfW, Bool_valueOf, PROPF_METHOD} +}; + +static const builtin_info_t Bool_info = { + JSCLASS_BOOLEAN, + {NULL, Bool_value, 0}, + sizeof(Bool_props)/sizeof(*Bool_props), + Bool_props, + NULL, + NULL +}; + +static HRESULT BoolConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT alloc_bool(script_ctx_t *ctx, BOOL use_constr, BoolInstance **ret) +{ + BoolInstance *bool; + HRESULT hres; + + bool = heap_alloc_zero(sizeof(BoolInstance)); + if(!bool) + return E_OUTOFMEMORY; + + if(use_constr) + hres = init_dispex_from_constr(&bool->dispex, ctx, &Bool_info, ctx->bool_constr); + else + hres = init_dispex(&bool->dispex, ctx, &Bool_info, NULL); + + if(FAILED(hres)) { + heap_free(bool); + return hres; + } + + *ret = bool; + return S_OK; +} + +HRESULT create_bool_constr(script_ctx_t *ctx, DispatchEx **ret) +{ + BoolInstance *bool; + HRESULT hres; + + hres = alloc_bool(ctx, FALSE, &bool); + if(FAILED(hres)) + return hres; + + hres = create_builtin_function(ctx, BoolConstr_value, PROPF_CONSTR, &bool->dispex, ret); + + jsdisp_release(&bool->dispex); + return hres; +} diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index d2af5f82149..ad7b988109a 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -23,6 +23,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript); +/* + * This IID is used to get DispatchEx objecto from interface. + * We might consider using private insteface instead. + */ +static const IID IID_IDispatchJS = + {0x719c3050,0xf9d3,0x11cf,{0xa4,0x93,0x00,0x40,0x05,0x23,0xa8,0xa6}}; + typedef enum { PROP_VARIANT, PROP_BUILTIN, @@ -47,6 +54,29 @@ static inline DISPID prop_to_id(DispatchEx *This, dispex_prop_t *prop) return prop - This->props; } +static inline dispex_prop_t *get_prop(DispatchEx *This, DISPID id) +{ + if(id < 0 || id >= This->prop_cnt || This->props[id].type == PROP_DELETED) + return NULL; + + return This->props+id; +} + +static DWORD get_flags(DispatchEx *This, dispex_prop_t *prop) +{ + if(prop->type == PROP_PROTREF) { + dispex_prop_t *parent = get_prop(This->prototype, prop->u.ref); + if(!parent) { + prop->type = PROP_DELETED; + return 0; + } + + return get_flags(This->prototype, parent); + } + + return prop->flags; +} + static const builtin_prop_t *find_builtin_prop(DispatchEx *This, const WCHAR *name) { int min = 0, max, i, r; @@ -167,6 +197,203 @@ static HRESULT find_prop_name_prot(DispatchEx *This, const WCHAR *name, BOOL all return S_OK; } +static HRESULT set_this(DISPPARAMS *dp, DISPPARAMS *olddp, IDispatch *jsthis) +{ + VARIANTARG *oldargs; + int i; + + static DISPID this_id = DISPID_THIS; + + *dp = *olddp; + + for(i = 0; i < dp->cNamedArgs; i++) { + if(dp->rgdispidNamedArgs[i] == DISPID_THIS) + return S_OK; + } + + oldargs = dp->rgvarg; + dp->rgvarg = heap_alloc((dp->cArgs+1) * sizeof(VARIANTARG)); + if(!dp->rgvarg) + return E_OUTOFMEMORY; + memcpy(dp->rgvarg+1, oldargs, dp->cArgs*sizeof(VARIANTARG)); + V_VT(dp->rgvarg) = VT_DISPATCH; + V_DISPATCH(dp->rgvarg) = jsthis; + dp->cArgs++; + + if(dp->cNamedArgs) { + DISPID *old = dp->rgdispidNamedArgs; + dp->rgdispidNamedArgs = heap_alloc((dp->cNamedArgs+1)*sizeof(DISPID)); + if(!dp->rgdispidNamedArgs) { + heap_free(dp->rgvarg); + return E_OUTOFMEMORY; + } + + memcpy(dp->rgdispidNamedArgs+1, old, dp->cNamedArgs*sizeof(DISPID)); + dp->rgdispidNamedArgs[0] = DISPID_THIS; + dp->cNamedArgs++; + }else { + dp->rgdispidNamedArgs = &this_id; + dp->cNamedArgs = 1; + } + + return S_OK; +} + +static HRESULT invoke_prop_func(DispatchEx *This, DispatchEx *jsthis, dispex_prop_t *prop, LCID lcid, WORD flags, + DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) +{ + HRESULT hres; + + switch(prop->type) { + case PROP_BUILTIN: + if(flags == DISPATCH_CONSTRUCT && (prop->flags & DISPATCH_METHOD)) { + WARN("%s is not a constructor\n", debugstr_w(prop->name)); + return E_INVALIDARG; + } + return prop->u.p->invoke(jsthis, lcid, flags, dp, retv, ei, caller); + case PROP_PROTREF: + return invoke_prop_func(This->prototype, jsthis, This->prototype->props+prop->u.ref, lcid, flags, dp, retv, ei, caller); + case PROP_VARIANT: { + DISPPARAMS new_dp; + + if(V_VT(&prop->u.var) != VT_DISPATCH) { + FIXME("invoke vt %d\n", V_VT(&prop->u.var)); + return E_FAIL; + } + + TRACE("call %s %p\n", debugstr_w(prop->name), V_DISPATCH(&prop->u.var)); + + hres = set_this(&new_dp, dp, (IDispatch*)_IDispatchEx_(jsthis)); + if(FAILED(hres)) + return hres; + + hres = disp_call(V_DISPATCH(&prop->u.var), DISPID_VALUE, lcid, flags, &new_dp, retv, ei, caller); + + if(new_dp.rgvarg != dp->rgvarg) { + heap_free(new_dp.rgvarg); + if(new_dp.cNamedArgs > 1) + heap_free(new_dp.rgdispidNamedArgs); + } + + return hres; + } + default: + ERR("type %d\n", prop->type); + } + + return E_FAIL; +} + +static HRESULT prop_get(DispatchEx *This, dispex_prop_t *prop, LCID lcid, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) +{ + HRESULT hres; + + switch(prop->type) { + case PROP_BUILTIN: + if(prop->u.p->flags & PROPF_METHOD) { + DispatchEx *obj; + hres = create_builtin_function(This->ctx, prop->u.p->invoke, prop->u.p->flags, NULL, &obj); + if(FAILED(hres)) + break; + + prop->type = PROP_VARIANT; + V_VT(&prop->u.var) = VT_DISPATCH; + V_DISPATCH(&prop->u.var) = (IDispatch*)_IDispatchEx_(obj); + + hres = VariantCopy(retv, &prop->u.var); + }else { + hres = prop->u.p->invoke(This, lcid, DISPATCH_PROPERTYGET, dp, retv, ei, caller); + } + break; + case PROP_PROTREF: + hres = prop_get(This->prototype, This->prototype->props+prop->u.ref, lcid, dp, retv, ei, caller); + break; + case PROP_VARIANT: + hres = VariantCopy(retv, &prop->u.var); + break; + default: + ERR("type %d\n", prop->type); + return E_FAIL; + } + + if(FAILED(hres)) { + TRACE("fail %08x\n", hres); + return hres; + } + + TRACE("%s ret %s\n", debugstr_w(prop->name), debugstr_variant(retv)); + return hres; +} + +static HRESULT prop_put(DispatchEx *This, dispex_prop_t *prop, LCID lcid, DISPPARAMS *dp, + jsexcept_t *ei, IServiceProvider *caller) +{ + DWORD i; + HRESULT hres; + + switch(prop->type) { + case PROP_BUILTIN: + if(!(prop->flags & PROPF_METHOD)) + return prop->u.p->invoke(This, lcid, DISPATCH_PROPERTYPUT, dp, NULL, ei, caller); + case PROP_PROTREF: + prop->type = PROP_VARIANT; + prop->flags = PROPF_ENUM; + V_VT(&prop->u.var) = VT_EMPTY; + break; + case PROP_VARIANT: + VariantClear(&prop->u.var); + break; + default: + ERR("type %d\n", prop->type); + return E_FAIL; + } + + for(i=0; i < dp->cNamedArgs; i++) { + if(dp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT) + break; + } + + if(i == dp->cNamedArgs) { + TRACE("no value to set\n"); + return DISP_E_PARAMNOTOPTIONAL; + } + + hres = VariantCopy(&prop->u.var, dp->rgvarg+i); + if(FAILED(hres)) + return hres; + + if(This->builtin_info->on_put) + This->builtin_info->on_put(This, prop->name); + + TRACE("%s = %s\n", debugstr_w(prop->name), debugstr_variant(dp->rgvarg+i)); + return S_OK; +} + +static HRESULT fill_protrefs(DispatchEx *This) +{ + dispex_prop_t *iter, *prop; + HRESULT hres; + + if(!This->prototype) + return S_OK; + + fill_protrefs(This->prototype); + + for(iter = This->prototype->props; iter < This->prototype->props+This->prototype->prop_cnt; iter++) { + hres = find_prop_name(This, iter->name, &prop); + if(FAILED(hres)) + return hres; + if(!prop) { + prop = alloc_protref(This, iter->name, iter - This->prototype->props); + if(!prop) + return E_OUTOFMEMORY; + } + } + + return S_OK; +} + #define DISPATCHEX_THIS(iface) DEFINE_THIS(DispatchEx, IDispatchEx, iface) static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) @@ -182,6 +409,11 @@ static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, }else if(IsEqualGUID(&IID_IDispatchEx, riid)) { TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv); *ppv = _IDispatchEx_(This); + }else if(IsEqualGUID(&IID_IDispatchJS, riid)) { + TRACE("(%p)->(IID_IDispatchJS %p)\n", This, ppv); + IUnknown_AddRef(_IDispatchEx_(This)); + *ppv = This; + return S_OK; }else { WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); *ppv = NULL; @@ -309,15 +541,68 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { DispatchEx *This = DISPATCHEX_THIS(iface); - FIXME("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); - return E_NOTIMPL; + dispex_prop_t *prop; + jsexcept_t jsexcept; + HRESULT hres; + + TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); + + if(pvarRes) + V_VT(pvarRes) = VT_EMPTY; + + prop = get_prop(This, id); + if(!prop || prop->type == PROP_DELETED) { + TRACE("invalid id\n"); + return DISP_E_MEMBERNOTFOUND; + } + + memset(&jsexcept, 0, sizeof(jsexcept)); + + switch(wFlags) { + case DISPATCH_METHOD: + case DISPATCH_CONSTRUCT: + hres = invoke_prop_func(This, This, prop, lcid, wFlags, pdp, pvarRes, &jsexcept, pspCaller); + break; + case DISPATCH_PROPERTYGET: + hres = prop_get(This, prop, lcid, pdp, pvarRes, &jsexcept, pspCaller); + break; + case DISPATCH_PROPERTYPUT: + hres = prop_put(This, prop, lcid, pdp, &jsexcept, pspCaller); + break; + default: + FIXME("Unimplemented flags %x\n", wFlags); + return E_INVALIDARG; + } + + if(pei) + *pei = jsexcept.ei; + + return hres; } static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex) { DispatchEx *This = DISPATCHEX_THIS(iface); - FIXME("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex); - return E_NOTIMPL; + dispex_prop_t *prop; + HRESULT hres; + + TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex); + + if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit)) + FIXME("Unsupported grfdex %x\n", grfdex); + + hres = find_prop_name(This, bstrName, &prop); + if(FAILED(hres)) + return hres; + if(!prop) { + TRACE("not found\n"); + return S_OK; + } + + heap_free(prop->name); + prop->name = NULL; + prop->type = PROP_DELETED; + return S_OK; } static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id) @@ -337,15 +622,51 @@ static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName) { DispatchEx *This = DISPATCHEX_THIS(iface); - FIXME("(%p)->(%x %p)\n", This, id, pbstrName); - return E_NOTIMPL; + dispex_prop_t *prop; + + TRACE("(%p)->(%x %p)\n", This, id, pbstrName); + + prop = get_prop(This, id); + if(!prop || !prop->name || prop->type == PROP_DELETED) + return DISP_E_MEMBERNOTFOUND; + + *pbstrName = SysAllocString(prop->name); + if(!*pbstrName) + return E_OUTOFMEMORY; + + return S_OK; } static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid) { DispatchEx *This = DISPATCHEX_THIS(iface); - FIXME("(%p)->(%x %x %p)\n", This, grfdex, id, pid); - return E_NOTIMPL; + dispex_prop_t *iter; + HRESULT hres; + + TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid); + + if(id == DISPID_STARTENUM) { + hres = fill_protrefs(This); + if(FAILED(hres)) + return hres; + } + + iter = get_prop(This, id+1); + if(!iter) { + *pid = DISPID_STARTENUM; + return S_FALSE; + } + + while(iter < This->props + This->prop_cnt) { + if(iter->name && (get_flags(This, iter) & PROPF_ENUM)) { + *pid = prop_to_id(This, iter); + return S_OK; + } + iter++; + } + + *pid = DISPID_STARTENUM; + return S_FALSE; } static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk) @@ -375,7 +696,7 @@ static IDispatchExVtbl DispatchExVtbl = { DispatchEx_GetNameSpaceParent }; -static HRESULT jsdisp_set_prot_prop(DispatchEx *dispex, DispatchEx *prototype) +HRESULT jsdisp_set_prototype(DispatchEx *dispex, DispatchEx *prototype) { VARIANT *var; @@ -392,10 +713,8 @@ static HRESULT jsdisp_set_prot_prop(DispatchEx *dispex, DispatchEx *prototype) return S_OK; } -static HRESULT init_dispex(DispatchEx *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, DispatchEx *prototype) +HRESULT init_dispex(DispatchEx *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, DispatchEx *prototype) { - static const WCHAR prototypeW[] = {'p','r','o','t','o','t','y','p','e',0}; - TRACE("%p (%p)\n", dispex, prototype); dispex->lpIDispatchExVtbl = &DispatchExVtbl; @@ -410,7 +729,7 @@ static HRESULT init_dispex(DispatchEx *dispex, script_ctx_t *ctx, const builtin_ if(prototype) IDispatchEx_AddRef(_IDispatchEx_(prototype)); - dispex->prop_cnt = 2; + dispex->prop_cnt = 1; dispex->props[0].name = NULL; dispex->props[0].flags = 0; if(builtin_info->value_prop.invoke) { @@ -420,20 +739,6 @@ static HRESULT init_dispex(DispatchEx *dispex, script_ctx_t *ctx, const builtin_ dispex->props[0].type = PROP_DELETED; } - dispex->props[1].type = PROP_DELETED; - dispex->props[1].name = SysAllocString(prototypeW); - dispex->props[1].flags = 0; - - if(prototype) { - HRESULT hres; - - hres = jsdisp_set_prot_prop(dispex, prototype); - if(FAILED(hres)) { - IDispatchEx_Release(_IDispatchEx_(dispex)); - return hres; - } - } - script_addref(ctx); dispex->ctx = ctx; @@ -464,3 +769,187 @@ HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, Dis *dispex = ret; return S_OK; } + +HRESULT init_dispex_from_constr(DispatchEx *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, DispatchEx *constr) +{ + DispatchEx *prot = NULL; + dispex_prop_t *prop; + HRESULT hres; + + static const WCHAR prototypeW[] = {'p','r','o','t','o','t','y','p','e',0}; + + hres = find_prop_name_prot(constr, prototypeW, FALSE, &prop); + if(SUCCEEDED(hres) && prop) { + jsexcept_t jsexcept; + VARIANT var; + + V_VT(&var) = VT_EMPTY; + memset(&jsexcept, 0, sizeof(jsexcept)); + hres = prop_get(constr, prop, ctx->lcid, NULL, &var, &jsexcept, NULL/*FIXME*/); + if(FAILED(hres)) { + ERR("Could not get prototype\n"); + return hres; + } + + if(V_VT(&var) == VT_DISPATCH) + prot = iface_to_jsdisp((IUnknown*)V_DISPATCH(&var)); + VariantClear(&var); + } + + hres = init_dispex(dispex, ctx, builtin_info, prot); + + if(prot) + IDispatchEx_Release(_IDispatchEx_(prot)); + return hres; +} + +DispatchEx *iface_to_jsdisp(IUnknown *iface) +{ + DispatchEx *ret; + HRESULT hres; + + hres = IUnknown_QueryInterface(iface, &IID_IDispatchJS, (void**)&ret); + if(FAILED(hres)) + return NULL; + + return ret; +} + +HRESULT jsdisp_call_value(DispatchEx *disp, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, + jsexcept_t *ei, IServiceProvider *caller) +{ + return disp->builtin_info->value_prop.invoke(disp, lcid, flags, dp, retv, ei, caller); +} + +HRESULT jsdisp_call(DispatchEx *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, + jsexcept_t *ei, IServiceProvider *caller) +{ + dispex_prop_t *prop; + + memset(ei, 0, sizeof(*ei)); + if(retv) + V_VT(retv) = VT_EMPTY; + + prop = get_prop(disp, id); + if(!prop) + return DISP_E_MEMBERNOTFOUND; + + return invoke_prop_func(disp, disp, prop, lcid, flags, dp, retv, ei, caller); +} + +HRESULT disp_call(IDispatch *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, + jsexcept_t *ei, IServiceProvider *caller) +{ + DispatchEx *jsdisp; + IDispatchEx *dispex; + HRESULT hres; + + jsdisp = iface_to_jsdisp((IUnknown*)disp); + if(jsdisp) { + hres = jsdisp_call(jsdisp, id, lcid, flags, dp, retv, ei, caller); + IDispatchEx_Release(_IDispatchEx_(jsdisp)); + return hres; + } + + memset(ei, 0, sizeof(*ei)); + + if(retv) + V_VT(retv) = VT_EMPTY; + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(FAILED(hres)) { + UINT err = 0; + + TRACE("using IDispatch\n"); + return IDispatch_Invoke(disp, id, &IID_NULL, lcid, flags, dp, retv, &ei->ei, &err); + } + + hres = IDispatchEx_InvokeEx(dispex, id, lcid, flags, dp, retv, &ei->ei, caller); + IDispatchEx_Release(dispex); + + return hres; +} + +HRESULT jsdisp_propput_name(DispatchEx *obj, const WCHAR *name, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller) +{ + DISPID named_arg = DISPID_PROPERTYPUT; + DISPPARAMS dp = {val, &named_arg, 1, 1}; + dispex_prop_t *prop; + HRESULT hres; + + hres = find_prop_name_prot(obj, name, TRUE, &prop); + if(FAILED(hres)) + return hres; + + return prop_put(obj, prop, lcid, &dp, ei, caller); +} + +HRESULT disp_propput(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller) +{ + DISPID dispid = DISPID_PROPERTYPUT; + DISPPARAMS dp = {val, &dispid, 1, 1}; + IDispatchEx *dispex; + DispatchEx *jsdisp; + HRESULT hres; + + jsdisp = iface_to_jsdisp((IUnknown*)disp); + if(jsdisp) { + dispex_prop_t *prop; + + prop = get_prop(jsdisp, id); + if(prop) + hres = prop_put(jsdisp, prop, lcid, &dp, ei, caller); + else + hres = DISP_E_MEMBERNOTFOUND; + + IDispatchEx_Release(_IDispatchEx_(jsdisp)); + return hres; + } + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(FAILED(hres)) { + ULONG err = 0; + + TRACE("using IDispatch\n"); + return IDispatch_Invoke(disp, id, &IID_NULL, DISPATCH_PROPERTYPUT, lcid, &dp, NULL, &ei->ei, &err); + } + + hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, caller); + + IDispatchEx_Release(dispex); + return hres; +} + +HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller) +{ + DISPPARAMS dp = {NULL,NULL,0,0}; + IDispatchEx *dispex; + DispatchEx *jsdisp; + HRESULT hres; + + jsdisp = iface_to_jsdisp((IUnknown*)disp); + if(jsdisp) { + dispex_prop_t *prop; + + prop = get_prop(jsdisp, id); + if(prop) + hres = prop_get(jsdisp, prop, lcid, &dp, val, ei, caller); + else + hres = DISP_E_MEMBERNOTFOUND; + + IDispatchEx_Release(_IDispatchEx_(jsdisp)); + return hres; + } + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(FAILED(hres)) { + ULONG err = 0; + + TRACE("uding IDispatch\n"); + return IDispatchEx_Invoke(dispex, id, &IID_NULL, lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, &err); + } + + hres = IDispatchEx_InvokeEx(dispex, id, lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, caller); + IDispatchEx_Release(dispex); + + return hres; +} diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index ef66c9767a1..c15b05b1e3e 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -23,12 +23,116 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript); +#define EXPR_NOVAL 0x0001 +#define EXPR_NEWREF 0x0002 +#define EXPR_STRREF 0x0004 + static inline HRESULT stat_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret) { return stat->eval(ctx, stat, rt, ret); } -HRESULT create_exec_ctx(exec_ctx_t **ret) +static inline HRESULT expr_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +{ + return _expr->eval(ctx, _expr, flags, ei, ret); +} + +static void exprval_release(exprval_t *val) +{ + switch(val->type) { + case EXPRVAL_VARIANT: + VariantClear(&val->u.var); + return; + case EXPRVAL_IDREF: + if(val->u.idref.disp) + IDispatch_Release(val->u.idref.disp); + return; + case EXPRVAL_NAMEREF: + if(val->u.nameref.disp) + IDispatch_Release(val->u.nameref.disp); + SysFreeString(val->u.nameref.name); + } +} + +/* ECMA-262 3rd Edition 8.7.1 */ +static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret) +{ + V_VT(ret) = VT_EMPTY; + + switch(val->type) { + case EXPRVAL_VARIANT: + return VariantCopy(ret, &val->u.var); + case EXPRVAL_IDREF: + if(!val->u.idref.disp) { + FIXME("throw ReferenceError\n"); + return E_FAIL; + } + + return disp_propget(val->u.idref.disp, val->u.idref.id, ctx->lcid, ret, ei, NULL/*FIXME*/); + default: + ERR("type %d\n", val->type); + return E_FAIL; + } +} + +static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret) +{ + if(val->type == EXPRVAL_VARIANT) { + *ret = val->u.var; + V_VT(&val->u.var) = VT_EMPTY; + return S_OK; + } + + return exprval_value(ctx, val, ei, ret); +} + +static HRESULT exprval_to_boolean(script_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, VARIANT_BOOL *b) +{ + if(exprval->type != EXPRVAL_VARIANT) { + VARIANT val; + HRESULT hres; + + hres = exprval_to_value(ctx, exprval, ei, &val); + if(FAILED(hres)) + return hres; + + hres = to_boolean(&val, b); + VariantClear(&val); + return hres; + } + + return to_boolean(&exprval->u.var, b); +} + +static void exprval_init(exprval_t *val) +{ + val->type = EXPRVAL_VARIANT; + V_VT(&val->u.var) = VT_EMPTY; +} + +static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id) +{ + val->type = EXPRVAL_IDREF; + val->u.idref.disp = disp; + val->u.idref.id = id; + + if(disp) + IDispatch_AddRef(disp); +} + +void scope_release(scope_chain_t *scope) +{ + if(--scope->ref) + return; + + if(scope->next) + scope_release(scope->next); + + IDispatchEx_Release(_IDispatchEx_(scope->obj)); + heap_free(scope); +} + +HRESULT create_exec_ctx(DispatchEx *var_disp, scope_chain_t *scope, exec_ctx_t **ret) { exec_ctx_t *ctx; @@ -36,6 +140,14 @@ HRESULT create_exec_ctx(exec_ctx_t **ret) if(!ctx) return E_OUTOFMEMORY; + IDispatchEx_AddRef(_IDispatchEx_(var_disp)); + ctx->var_disp = var_disp; + + if(scope) { + scope_addref(scope); + ctx->scope_chain = scope; + } + *ret = ctx; return S_OK; } @@ -45,12 +157,176 @@ void exec_release(exec_ctx_t *ctx) if(--ctx->ref) return; + if(ctx->scope_chain) + scope_release(ctx->scope_chain); + if(ctx->var_disp) + IDispatchEx_Release(_IDispatchEx_(ctx->var_disp)); heap_free(ctx); } +static HRESULT dispex_get_id(IDispatchEx *dispex, BSTR name, DWORD flags, DISPID *id) +{ + *id = 0; + + return IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id); +} + +static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id) +{ + IDispatchEx *dispex; + HRESULT hres; + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(FAILED(hres)) { + TRACE("unsing IDispatch\n"); + + *id = 0; + return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id); + } + + hres = dispex_get_id(dispex, name, flags, id); + IDispatchEx_Release(dispex); + return hres; +} + +/* ECMA-262 3rd Edition 8.7.2 */ +static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei) +{ + if(ref->type != EXPRVAL_IDREF) { + FIXME("throw ReferemceError\n"); + return E_FAIL; + } + + return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/); +} + +static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret) +{ + IObjectIdentity *identity; + IUnknown *unk1, *unk2; + HRESULT hres; + + if(disp1 == disp2) { + *ret = TRUE; + return S_OK; + } + + hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1); + if(FAILED(hres)) + return hres; + + hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2); + if(FAILED(hres)) { + IUnknown_Release(unk1); + return hres; + } + + if(unk1 == unk2) { + *ret = TRUE; + }else { + hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity); + if(SUCCEEDED(hres)) { + hres = IObjectIdentity_IsEqualObject(identity, unk2); + IObjectIdentity_Release(identity); + *ret = hres == S_OK; + }else { + *ret = FALSE; + } + } + + IUnknown_Release(unk1); + IUnknown_Release(unk2); + return S_OK; +} + +static inline BOOL is_num_vt(enum VARENUM vt) +{ + return vt == VT_I4 || vt == VT_R8; +} + +static inline DOUBLE num_val(const VARIANT *v) +{ + return V_VT(v) == VT_I4 ? V_I4(v) : V_R8(v); +} + +/* ECMA-262 3rd Edition 11.9.6 */ +HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret) +{ + TRACE("\n"); + + if(V_VT(lval) != V_VT(rval)) { + if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))) { + *ret = num_val(lval) == num_val(rval); + return S_OK; + } + + *ret = FALSE; + return S_OK; + } + + switch(V_VT(lval)) { + case VT_EMPTY: + case VT_NULL: + *ret = VARIANT_TRUE; + break; + case VT_I4: + *ret = V_I4(lval) == V_I4(rval); + break; + case VT_R8: + *ret = V_R8(lval) == V_R8(rval); + break; + case VT_BSTR: + *ret = !strcmpW(V_BSTR(lval), V_BSTR(rval)); + break; + case VT_DISPATCH: + return disp_cmp(V_DISPATCH(lval), V_DISPATCH(rval), ret); + case VT_BOOL: + *ret = !V_BOOL(lval) == !V_BOOL(rval); + break; + default: + FIXME("unimplemented vt %d\n", V_VT(lval)); + return E_NOTIMPL; + } + + return S_OK; +} + +static HRESULT literal_to_var(literal_t *literal, VARIANT *v) +{ + V_VT(v) = literal->vt; + + switch(V_VT(v)) { + case VT_EMPTY: + case VT_NULL: + break; + case VT_I4: + V_I4(v) = literal->u.lval; + break; + case VT_R8: + V_R8(v) = literal->u.dval; + break; + case VT_BSTR: + V_BSTR(v) = SysAllocString(literal->u.wstr); + break; + case VT_BOOL: + V_BOOL(v) = literal->u.bval; + break; + case VT_DISPATCH: + IDispatch_AddRef(literal->u.disp); + V_DISPATCH(v) = literal->u.disp; + break; + default: + ERR("wrong type %d\n", V_VT(v)); + return E_NOTIMPL; + } + + return S_OK; +} + HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv) { script_ctx_t *script = parser->script; + function_declaration_t *func; parser_ctx_t *prev_parser; VARIANT val, tmp; statement_t *stat; @@ -58,6 +334,22 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so return_type_t rt; HRESULT hres = S_OK; + for(func = source->functions; func; func = func->next) { + DispatchEx *func_obj; + VARIANT var; + + hres = create_source_function(parser, func->parameter_list, func->source_elements, ctx->scope_chain, &func_obj); + if(FAILED(hres)) + return hres; + + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(func_obj); + hres = jsdisp_propput_name(ctx->var_disp, func->identifier, script->lcid, &var, ei, NULL); + IDispatchEx_Release(_IDispatchEx_(func_obj)); + if(FAILED(hres)) + return hres; + } + prev_ctx = script->exec_ctx; script->exec_ctx = ctx; @@ -100,18 +392,119 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so return S_OK; } +/* ECMA-262 3rd Edition 10.1.4 */ +static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret) +{ + scope_chain_t *scope; + named_item_t *item; + DISPID id = 0; + HRESULT hres; + + TRACE("%s\n", debugstr_w(identifier)); + + for(scope = ctx->scope_chain; scope; scope = scope->next) { + hres = dispex_get_id(_IDispatchEx_(scope->obj), identifier, 0, &id); + if(SUCCEEDED(hres)) + break; + } + + if(scope) { + exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(scope->obj), id); + return S_OK; + } + + hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->global), identifier, 0, &id); + if(SUCCEEDED(hres)) { + exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id); + return S_OK; + } + + for(item = ctx->parser->script->named_items; item; item = item->next) { + hres = disp_get_id(item->disp, identifier, 0, &id); + if(SUCCEEDED(hres)) + break; + } + + if(item) { + exprval_set_idref(ret, (IDispatch*)item->disp, id); + return S_OK; + } + + hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id); + if(SUCCEEDED(hres)) { + exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id); + return S_OK; + } + + if(flags & EXPR_NEWREF) { + hres = dispex_get_id(_IDispatchEx_(ctx->var_disp), identifier, fdexNameEnsure, &id); + if(FAILED(hres)) + return hres; + + exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->var_disp), id); + return S_OK; + } + + WARN("Could not find identifier %s\n", debugstr_w(identifier)); + return E_FAIL; +} + HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret) { FIXME("\n"); return E_NOTIMPL; } -HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret) +/* ECMA-262 3rd Edition 12.2 */ +static HRESULT variable_list_eval(exec_ctx_t *ctx, variable_declaration_t *var_list, jsexcept_t *ei) { - FIXME("\n"); - return E_NOTIMPL; + variable_declaration_t *iter; + HRESULT hres; + + for(iter = var_list; iter; iter = iter->next) { + VARIANT val; + + if(iter->expr) { + exprval_t exprval; + + hres = expr_eval(ctx, iter->expr, 0, ei, &exprval); + if(FAILED(hres)) + break; + + hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); + exprval_release(&exprval); + if(FAILED(hres)) + break; + }else { + V_VT(&val) = VT_EMPTY; + } + + hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/); + VariantClear(&val); + if(FAILED(hres)) + break; + } + + return hres; } +/* ECMA-262 3rd Edition 12.2 */ +HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) +{ + var_statement_t *stat = (var_statement_t*)_stat; + HRESULT hres; + + TRACE("\n"); + + hres = variable_list_eval(ctx, stat->variable_list, &rt->ei); + if(FAILED(hres)) + return hres; + + V_VT(ret) = VT_EMPTY; + return S_OK; +} + +/* ECMA-262 3rd Edition 12.3 */ HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret) { TRACE("\n"); @@ -120,10 +513,28 @@ HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t * return S_OK; } -HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret) +/* ECMA-262 3rd Edition 12.4 */ +HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret) { - FIXME("\n"); - return E_NOTIMPL; + expression_statement_t *stat = (expression_statement_t*)_stat; + exprval_t exprval; + VARIANT val; + HRESULT hres; + + TRACE("\n"); + + hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval); + if(FAILED(hres)) + return hres; + + hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val); + exprval_release(&exprval); + if(FAILED(hres)) + return hres; + + *ret = val; + TRACE("= %s\n", debugstr_variant(ret)); + return S_OK; } HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret) @@ -204,6 +615,43 @@ HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt return E_NOTIMPL; } +static HRESULT return_bool(exprval_t *ret, DWORD b) +{ + ret->type = EXPRVAL_VARIANT; + V_VT(&ret->u.var) = VT_BOOL; + V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE; + + return S_OK; +} + +static HRESULT get_binary_expr_values(exec_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval) +{ + exprval_t exprval; + HRESULT hres; + + hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval); + if(FAILED(hres)) + return hres; + + hres = exprval_to_value(ctx->parser->script, &exprval, ei, lval); + exprval_release(&exprval); + if(FAILED(hres)) + return hres; + + hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval); + if(SUCCEEDED(hres)) { + hres = exprval_to_value(ctx->parser->script, &exprval, ei, rval); + exprval_release(&exprval); + } + + if(FAILED(hres)) { + VariantClear(lval); + return hres; + } + + return S_OK; +} + HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { FIXME("\n"); @@ -222,10 +670,101 @@ HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, return E_NOTIMPL; } -HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +/* ECMA-262 3rd Edition 11.2.1 */ +HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + member_expression_t *expr = (member_expression_t*)_expr; + IDispatch *obj = NULL; + exprval_t exprval; + VARIANT member; + DISPID id; + BSTR str; + HRESULT hres; + + TRACE("\n"); + + hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); + if(FAILED(hres)) + return hres; + + hres = exprval_to_value(ctx->parser->script, &exprval, ei, &member); + exprval_release(&exprval); + if(FAILED(hres)) + return hres; + + hres = to_object(ctx, &member, &obj); + VariantClear(&member); + if(FAILED(hres)) + return hres; + + str = SysAllocString(expr->identifier); + if(flags & EXPR_STRREF) { + ret->type = EXPRVAL_NAMEREF; + ret->u.nameref.disp = obj; + ret->u.nameref.name = str; + return S_OK; + } + + hres = disp_get_id(obj, str, flags & EXPR_NEW ? fdexNameEnsure : 0, &id); + SysFreeString(str); + if(SUCCEEDED(hres)) { + exprval_set_idref(ret, obj, id); + }else if(!(flags & EXPR_NEWREF) && hres == DISP_E_UNKNOWNNAME) { + exprval_init(ret); + hres = S_OK; + } + + IDispatch_Release(obj); + return hres; +} + +static void free_dp(DISPPARAMS *dp) +{ + DWORD i; + + for(i=0; i < dp->cArgs; i++) + VariantClear(dp->rgvarg+i); + heap_free(dp->rgvarg); +} + +static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp) +{ + VARIANTARG *vargs; + exprval_t exprval; + argument_t *iter; + DWORD cnt = 0, i; + HRESULT hres = S_OK; + + memset(dp, 0, sizeof(*dp)); + + for(iter = args; iter; iter = iter->next) + cnt++; + if(!cnt) + return S_OK; + + vargs = heap_alloc_zero(cnt * sizeof(*vargs)); + if(!vargs) + return E_OUTOFMEMORY; + + for(i = cnt, iter = args; iter; iter = iter->next) { + hres = expr_eval(ctx, iter->expr, 0, ei, &exprval); + if(FAILED(hres)) + break; + + hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i)); + exprval_release(&exprval); + if(FAILED(hres)) + break; + } + + if(FAILED(hres)) { + free_dp(dp); + return hres; + } + + dp->rgvarg = vargs; + dp->cArgs = cnt; + return S_OK; } HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) @@ -234,10 +773,45 @@ HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD fl return E_NOTIMPL; } -HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + call_expression_t *expr = (call_expression_t*)_expr; + VARIANT func, var; + exprval_t exprval; + DISPPARAMS dp; + HRESULT hres; + + TRACE("\n"); + + hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); + if(FAILED(hres)) + return hres; + + hres = args_to_param(ctx, expr->argument_list, ei, &dp); + if(SUCCEEDED(hres)) { + switch(exprval.type) { + case EXPRVAL_IDREF: + hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid, DISPATCH_METHOD, + &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/); + if(flags & EXPR_NOVAL) + V_VT(&var) = VT_EMPTY; + break; + default: + FIXME("unimplemented type %d\n", V_VT(&func)); + hres = E_NOTIMPL; + } + + free_dp(&dp); + } + + exprval_release(&exprval); + if(FAILED(hres)) + return hres; + + TRACE("= %s\n", debugstr_variant(&var)); + ret->type = EXPRVAL_VARIANT; + ret->u.var = var; + return S_OK; } HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) @@ -246,16 +820,41 @@ HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, j return E_NOTIMPL; } -HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +/* ECMA-262 3rd Edition 10.1.4 */ +HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + identifier_expression_t *expr = (identifier_expression_t*)_expr; + BSTR identifier; + HRESULT hres; + + TRACE("\n"); + + identifier = SysAllocString(expr->identifier); + if(!identifier) + return E_OUTOFMEMORY; + + hres = identifier_eval(ctx, identifier, flags, ret); + + SysFreeString(identifier); + return hres; } -HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +/* ECMA-262 3rd Edition 7.8 */ +HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + literal_expression_t *expr = (literal_expression_t*)_expr; + VARIANT var; + HRESULT hres; + + TRACE("\n"); + + hres = literal_to_var(expr->literal, &var); + if(FAILED(hres)) + return hres; + + ret->type = EXPRVAL_VARIANT; + ret->u.var = var; + return S_OK; } HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) @@ -360,10 +959,74 @@ HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, j return E_NOTIMPL; } -HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + unary_expression_t *expr = (unary_expression_t*)_expr; + const WCHAR *str; + exprval_t exprval; + VARIANT val; + HRESULT hres; + + static const WCHAR booleanW[] = {'b','o','o','l','e','a','n',0}; + static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0}; + static const WCHAR numberW[] = {'n','u','m','b','e','r',0}; + static const WCHAR objectW[] = {'o','b','j','e','c','t',0}; + static const WCHAR stringW[] = {'s','t','r','i','n','g',0}; + static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0}; + + TRACE("\n"); + + hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); + if(FAILED(hres)) + return hres; + + hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val); + exprval_release(&exprval); + if(FAILED(hres)) + return hres; + + switch(V_VT(&val)) { + case VT_EMPTY: + str = undefinedW; + break; + case VT_NULL: + str = objectW; + break; + case VT_BOOL: + str = booleanW; + break; + case VT_I4: + case VT_R8: + str = numberW; + break; + case VT_BSTR: + str = stringW; + break; + case VT_DISPATCH: { + DispatchEx *dispex; + + dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val)); + if(dispex) { + str = dispex->builtin_info->class == JSCLASS_FUNCTION ? functionW : objectW; + IDispatchEx_Release(_IDispatchEx_(dispex)); + }else { + str = objectW; + } + break; + } + default: + FIXME("unhandled vt %d\n", V_VT(&val)); + hres = E_NOTIMPL; + } + + VariantClear(&val); + if(FAILED(hres)) + return hres; + + ret->type = EXPRVAL_VARIANT; + V_VT(&ret->u.var) = VT_BSTR; + V_BSTR(&ret->u.var) = SysAllocString(str); + return S_OK; } HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) @@ -414,10 +1077,25 @@ HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, return E_NOTIMPL; } -HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +/* ECMA-262 3rd Edition 11.9.4 */ +HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + binary_expression_t *expr = (binary_expression_t*)_expr; + VARIANT rval, lval; + BOOL b; + HRESULT hres; + + TRACE("\n"); + + hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval); + if(FAILED(hres)) + return hres; + + hres = equal2_values(&rval, &lval, &b); + if(FAILED(hres)) + return hres; + + return return_bool(ret, b); } HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) @@ -427,10 +1105,25 @@ HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD fl return E_NOTIMPL; } -HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +/* ECMA-262 3rd Edition 11.9.5 */ +HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + binary_expression_t *expr = (binary_expression_t*)_expr; + VARIANT rval, lval; + BOOL b; + HRESULT hres; + + TRACE("\n"); + + hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval); + if(FAILED(hres)) + return hres; + + hres = equal2_values(&rval, &lval, &b); + if(FAILED(hres)) + return hres; + + return return_bool(ret, !b); } HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) @@ -463,10 +1156,26 @@ HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWO return E_NOTIMPL; } -HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +/* ECMA-262 3rd Edition 11.4.9 */ +HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + unary_expression_t *expr = (unary_expression_t*)_expr; + exprval_t exprval; + VARIANT_BOOL b; + HRESULT hres; + + TRACE("\n"); + + hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval); + if(FAILED(hres)) + return hres; + + hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b); + exprval_release(&exprval); + if(FAILED(hres)) + return hres; + + return return_bool(ret, !b); } HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) @@ -487,10 +1196,38 @@ HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD return E_NOTIMPL; } -HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +/* ECMA-262 3rd Edition 11.13.1 */ +HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { - FIXME("\n"); - return E_NOTIMPL; + binary_expression_t *expr = (binary_expression_t*)_expr; + exprval_t exprval, exprvalr; + VARIANT rval; + HRESULT hres; + + TRACE("\n"); + + hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval); + if(FAILED(hres)) + return hres; + + hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr); + if(SUCCEEDED(hres)) { + hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval); + exprval_release(&exprvalr); + } + + if(SUCCEEDED(hres)) + hres = put_value(ctx->parser->script, &exprval, &rval, ei); + + exprval_release(&exprval); + if(FAILED(hres)) { + VariantClear(&rval); + return hres; + } + + ret->type = EXPRVAL_VARIANT; + ret->u.var = rval; + return S_OK; } HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 6e91178b431..c8f41b0105c 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -56,10 +56,26 @@ static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size) return jsheap_alloc(&ctx->tmp_heap, size); } +typedef struct _scope_chain_t { + LONG ref; + DispatchEx *obj; + struct _scope_chain_t *next; +} scope_chain_t; + +HRESULT scope_push(scope_chain_t*,DispatchEx*,scope_chain_t**); +void scope_release(scope_chain_t*); + +static inline void scope_addref(scope_chain_t *scope) +{ + scope->ref++; +} + struct _exec_ctx_t { LONG ref; parser_ctx_t *parser; + scope_chain_t *scope_chain; + DispatchEx *var_disp; }; static inline void exec_addref(exec_ctx_t *ctx) @@ -68,13 +84,15 @@ static inline void exec_addref(exec_ctx_t *ctx) } void exec_release(exec_ctx_t*); -HRESULT create_exec_ctx(exec_ctx_t**); +HRESULT create_exec_ctx(DispatchEx*,scope_chain_t*,exec_ctx_t**); HRESULT exec_source(exec_ctx_t*,parser_ctx_t*,source_elements_t*,jsexcept_t*,VARIANT*); typedef struct _statement_t statement_t; typedef struct _expression_t expression_t; typedef struct _parameter_t parameter_t; +HRESULT create_source_function(parser_ctx_t*,parameter_t*,source_elements_t*,scope_chain_t*,DispatchEx**); + typedef struct { VARTYPE vt; union { @@ -215,7 +233,24 @@ HRESULT switch_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*); HRESULT throw_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*); HRESULT try_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*); -typedef struct exprval_t exprval_t; +typedef struct { + enum { + EXPRVAL_VARIANT, + EXPRVAL_IDREF, + EXPRVAL_NAMEREF + } type; + union { + VARIANT var; + struct { + IDispatch *disp; + DISPID id; + } idref; + struct { + IDispatch *disp; + BSTR name; + } nameref; + } u; +} exprval_t; typedef HRESULT (*expression_eval_t)(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*); diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c new file mode 100644 index 00000000000..a9c61e0e756 --- /dev/null +++ b/dlls/jscript/function.c @@ -0,0 +1,244 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * 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 + */ + +#include "jscript.h" +#include "engine.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(jscript); + +typedef struct { + DispatchEx dispex; + builtin_invoke_t value_proc; + DWORD flags; + source_elements_t *source; + parameter_t *parameters; + scope_chain_t *scope_chain; + parser_ctx_t *parser; + DWORD length; +} FunctionInstance; + +static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0}; + +static const WCHAR lengthW[] = {'l','e','n','g','t','h',0}; +static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; +static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0}; +static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0}; +static const WCHAR applyW[] = {'a','p','p','l','y',0}; +static const WCHAR callW[] = {'c','a','l','l',0}; +static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0}; +static const WCHAR propertyIsEnumerableW[] = {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; +static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0}; + +static HRESULT Function_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FunctionInstance *This = (FunctionInstance*)dispex; + + TRACE("%p %d\n", This, This->length); + + switch(flags) { + case DISPATCH_PROPERTYGET: + V_VT(retv) = VT_I4; + V_I4(retv) = This->length; + break; + default: + FIXME("unimplemented flags %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; +} + +static HRESULT Function_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Function_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Function_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Function_apply(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Function_call(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Function_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Function_propertyIsEnumerable(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Function_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static void Function_destructor(DispatchEx *dispex) +{ + FunctionInstance *This = (FunctionInstance*)dispex; + + if(This->parser) + parser_release(This->parser); + if(This->scope_chain) + scope_release(This->scope_chain); + heap_free(This); +} + +static const builtin_prop_t Function_props[] = { + {applyW, Function_apply, PROPF_METHOD}, + {callW, Function_call, PROPF_METHOD}, + {hasOwnPropertyW, Function_hasOwnProperty, PROPF_METHOD}, + {isPrototypeOfW, Function_isPrototypeOf, PROPF_METHOD}, + {lengthW, Function_length, 0}, + {propertyIsEnumerableW, Function_propertyIsEnumerable, PROPF_METHOD}, + {toLocaleStringW, Function_toLocaleString, PROPF_METHOD}, + {toStringW, Function_toString, PROPF_METHOD}, + {valueOfW, Function_valueOf, PROPF_METHOD} +}; + +static const builtin_info_t Function_info = { + JSCLASS_FUNCTION, + {NULL, Function_value, 0}, + sizeof(Function_props)/sizeof(*Function_props), + Function_props, + Function_destructor, + NULL +}; + +static HRESULT create_function(script_ctx_t *ctx, DWORD flags, DispatchEx *prototype, FunctionInstance **ret) +{ + FunctionInstance *function; + HRESULT hres; + + function = heap_alloc_zero(sizeof(FunctionInstance)); + if(!function) + return E_OUTOFMEMORY; + + hres = init_dispex(&function->dispex, ctx, &Function_info, NULL); + if(FAILED(hres)) + return hres; + + function->flags = flags; + function->length = flags & PROPF_ARGMASK; + + if(prototype) { + jsexcept_t jsexcept; + VARIANT var; + + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(prototype); + memset(&jsexcept, 0, sizeof(jsexcept)); + + hres = jsdisp_propput_name(&function->dispex, prototypeW, ctx->lcid, &var, &jsexcept, NULL/*FIXME*/); + if(FAILED(hres)) { + IDispatchEx_Release(_IDispatchEx_(&function->dispex)); + return hres; + } + } + + *ret = function; + return S_OK; +} + +HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, DWORD flags, + DispatchEx *prototype, DispatchEx **ret) +{ + FunctionInstance *function; + HRESULT hres; + + hres = create_function(ctx, flags, prototype, &function); + if(FAILED(hres)) + return hres; + + function->value_proc = value_proc; + + *ret = &function->dispex; + return S_OK; +} + +HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, source_elements_t *source, + scope_chain_t *scope_chain, DispatchEx **ret) +{ + FunctionInstance *function; + parameter_t *iter; + DWORD length = 0; + HRESULT hres; + + hres = create_function(ctx->script, PROPF_CONSTR, NULL, &function); + if(FAILED(hres)) + return hres; + + function->source = source; + function->parameters = parameters; + + if(scope_chain) { + scope_addref(scope_chain); + function->scope_chain = scope_chain; + } + + parser_addref(ctx); + function->parser = ctx; + + for(iter = parameters; iter; iter = iter->next) + length++; + function->length = length; + + *ret = &function->dispex; + return S_OK; +} diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c new file mode 100644 index 00000000000..a347101bfb0 --- /dev/null +++ b/dlls/jscript/global.c @@ -0,0 +1,352 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * 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 + */ + +#include "jscript.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(jscript); + +static const WCHAR NaNW[] = {'N','a','N',0}; +static const WCHAR InfinityW[] = {'I','n','f','i','n','i','t','y',0}; +static const WCHAR ArrayW[] = {'A','r','r','a','y',0}; +static const WCHAR BooleanW[] = {'B','o','o','l','e','a','n',0}; +static const WCHAR DateW[] = {'D','a','t','e',0}; +static const WCHAR FunctionW[] = {'F','u','n','c','t','i','o','n',0}; +static const WCHAR NumberW[] = {'N','u','m','b','e','r',0}; +static const WCHAR ObjectW[] = {'O','b','j','e','c','t',0}; +static const WCHAR StringW[] = {'S','t','r','i','n','g',0}; +static const WCHAR RegExpW[] = {'R','e','g','E','x','p',0}; +static const WCHAR ActiveXObjectW[] = {'A','c','t','i','v','e','X','O','b','j','e','c','t',0}; +static const WCHAR VBArrayW[] = {'V','B','A','r','r','a','y',0}; +static const WCHAR EnumeratorW[] = {'E','n','u','m','e','r','a','t','o','r',0}; +static const WCHAR escapeW[] = {'e','s','c','a','p','e',0}; +static const WCHAR evalW[] = {'e','v','a','l',0}; +static const WCHAR isNaNW[] = {'i','s','N','a','N',0}; +static const WCHAR isFiniteW[] = {'i','s','F','i','n','i','t','e',0}; +static const WCHAR parseIntW[] = {'p','a','r','s','e','I','n','t',0}; +static const WCHAR parseFloatW[] = {'p','a','r','s','e','F','l','o','a','t',0}; +static const WCHAR unescapeW[] = {'u','n','e','s','c','a','p','e',0}; +static const WCHAR GetObjectW[] = {'G','e','t','O','b','j','e','c','t',0}; +static const WCHAR ScriptEngineW[] = {'S','c','r','i','p','t','E','n','g','i','n','e',0}; +static const WCHAR ScriptEngineMajorVersionW[] = + {'S','c','r','i','p','t','E','n','g','i','n','e','M','a','j','o','r','V','e','r','s','i','o','n',0}; +static const WCHAR ScriptEngineMinorVersionW[] = + {'S','c','r','i','p','t','E','n','g','i','n','e','M','i','n','o','r','V','e','r','s','i','o','n',0}; +static const WCHAR ScriptEngineBuildVersionW[] = + {'S','c','r','i','p','t','E','n','g','i','n','e','B','u','i','l','d','V','e','r','s','i','o','n',0}; +static const WCHAR CollectGarbageW[] = {'C','o','l','l','e','c','t','G','a','r','b','a','g','e',0}; +static const WCHAR MathW[] = {'M','a','t','h',0}; + +static HRESULT constructor_call(DispatchEx *constr, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + if(flags != DISPATCH_PROPERTYGET) + return jsdisp_call_value(constr, lcid, flags, dp, retv, ei, sp); + + V_VT(retv) = VT_DISPATCH; + V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(constr); + IDispatchEx_AddRef(_IDispatchEx_(constr)); + return S_OK; +} + +static HRESULT JSGlobal_NaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_Infinity(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_Array(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + TRACE("\n"); + + return constructor_call(dispex->ctx->array_constr, lcid, flags, dp, retv, ei, sp); +} + +static HRESULT JSGlobal_Boolean(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + TRACE("\n"); + + return constructor_call(dispex->ctx->bool_constr, lcid, flags, dp, retv, ei, sp); +} + +static HRESULT JSGlobal_Date(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_Function(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_Number(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + TRACE("\n"); + + return constructor_call(dispex->ctx->number_constr, lcid, flags, dp, retv, ei, sp); +} + +static HRESULT JSGlobal_Object(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + TRACE("\n"); + + return constructor_call(dispex->ctx->object_constr, lcid, flags, dp, retv, ei, sp); +} + +static HRESULT JSGlobal_String(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + TRACE("\n"); + + return constructor_call(dispex->ctx->string_constr, lcid, flags, dp, retv, ei, sp); +} + +static HRESULT JSGlobal_RegExp(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + TRACE("\n"); + + return constructor_call(dispex->ctx->regexp_constr, lcid, flags, dp, retv, ei, sp); +} + +static HRESULT JSGlobal_ActiveXObject(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_VBArray(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_Enumerator(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_escape(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_eval(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_isNaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_isFinite(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_parseInt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + return E_NOTIMPL; +} + +static HRESULT JSGlobal_parseFloat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_unescape(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_GetObject(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_ScriptEngine(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_ScriptEngineMajorVersion(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_ScriptEngineMinorVersion(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_ScriptEngineBuildVersion(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT JSGlobal_CollectGarbage(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static const builtin_prop_t JSGlobal_props[] = { + {ActiveXObjectW, JSGlobal_ActiveXObject, PROPF_METHOD}, + {ArrayW, JSGlobal_Array, PROPF_CONSTR}, + {BooleanW, JSGlobal_Boolean, PROPF_CONSTR}, + {CollectGarbageW, JSGlobal_CollectGarbage, PROPF_METHOD}, + {DateW, JSGlobal_Date, PROPF_CONSTR}, + {EnumeratorW, JSGlobal_Enumerator, PROPF_METHOD}, + {FunctionW, JSGlobal_Function, PROPF_CONSTR}, + {GetObjectW, JSGlobal_GetObject, PROPF_METHOD}, + {InfinityW, JSGlobal_Infinity, 0}, +/* {MathW, JSGlobal_Math, 0}, */ + {NaNW, JSGlobal_NaN, 0}, + {NumberW, JSGlobal_Number, PROPF_CONSTR}, + {ObjectW, JSGlobal_Object, PROPF_CONSTR}, + {RegExpW, JSGlobal_RegExp, PROPF_CONSTR}, + {ScriptEngineW, JSGlobal_ScriptEngine, PROPF_METHOD}, + {ScriptEngineBuildVersionW, JSGlobal_ScriptEngineBuildVersion, PROPF_METHOD}, + {ScriptEngineMajorVersionW, JSGlobal_ScriptEngineMajorVersion, PROPF_METHOD}, + {ScriptEngineMinorVersionW, JSGlobal_ScriptEngineMinorVersion, PROPF_METHOD}, + {StringW, JSGlobal_String, PROPF_CONSTR}, + {VBArrayW, JSGlobal_VBArray, PROPF_METHOD}, + {escapeW, JSGlobal_escape, PROPF_METHOD}, + {evalW, JSGlobal_eval, PROPF_METHOD}, + {isFiniteW, JSGlobal_isFinite, PROPF_METHOD}, + {isNaNW, JSGlobal_isNaN, PROPF_METHOD}, + {parseFloatW, JSGlobal_parseFloat, PROPF_METHOD}, + {parseIntW, JSGlobal_parseInt, PROPF_METHOD|2}, + {unescapeW, JSGlobal_unescape, PROPF_METHOD} +}; + +static const builtin_info_t JSGlobal_info = { + JSCLASS_GLOBAL, + {NULL, NULL, 0}, + sizeof(JSGlobal_props)/sizeof(*JSGlobal_props), + JSGlobal_props, + NULL, + NULL +}; + +static HRESULT init_constructors(script_ctx_t *ctx) +{ + HRESULT hres; + + hres = create_array_constr(ctx, &ctx->array_constr); + if(FAILED(hres)) + return hres; + + hres = create_bool_constr(ctx, &ctx->bool_constr); + if(FAILED(hres)) + return hres; + + hres = create_number_constr(ctx, &ctx->number_constr); + if(FAILED(hres)) + return hres; + + hres = create_object_constr(ctx, &ctx->object_constr); + if(FAILED(hres)) + return hres; + + hres = create_object_constr(ctx, &ctx->regexp_constr); + if(FAILED(hres)) + return hres; + + hres = create_string_constr(ctx, &ctx->string_constr); + if(FAILED(hres)) + return hres; + + return S_OK; +} + +HRESULT init_global(script_ctx_t *ctx) +{ + DispatchEx *math; + VARIANT var; + HRESULT hres; + + if(ctx->global) + return S_OK; + + hres = init_constructors(ctx); + if(FAILED(hres)) + return hres; + + hres = create_dispex(ctx, &JSGlobal_info, NULL, &ctx->global); + if(FAILED(hres)) + return hres; + + hres = create_math(ctx, &math); + if(FAILED(hres)) + return hres; + + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(math); + hres = jsdisp_propput_name(ctx->global, MathW, ctx->lcid, &var, NULL/*FIXME*/, NULL/*FIXME*/); + jsdisp_release(math); + + return hres; +} diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index f8b95c561f5..a104aa9aadf 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -80,7 +80,7 @@ static HRESULT exec_global_code(JScript *This, parser_ctx_t *parser_ctx) VARIANT var; HRESULT hres; - hres = create_exec_ctx(&exec_ctx); + hres = create_exec_ctx(This->ctx->script_disp, NULL, &exec_ctx); if(FAILED(hres)) return hres; @@ -216,7 +216,13 @@ static HRESULT WINAPI JScript_SetScriptSite(IActiveScript *iface, return hres; } - hres = create_dispex(This->ctx, NULL, NULL, &This->ctx->script_disp); + if(!This->ctx->script_disp) { + hres = create_dispex(This->ctx, NULL, NULL, &This->ctx->script_disp); + if(FAILED(hres)) + return hres; + } + + hres = init_global(This->ctx); if(FAILED(hres)) return hres; @@ -306,6 +312,11 @@ static HRESULT WINAPI JScript_Close(IActiveScript *iface) IDispatchEx_Release(_IDispatchEx_(This->ctx->script_disp)); This->ctx->script_disp = NULL; } + + if(This->ctx->global) { + IDispatchEx_Release(_IDispatchEx_(This->ctx->global)); + This->ctx->global = NULL; + } } if(This->site) { @@ -320,8 +331,41 @@ static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface, LPCOLESTR pstrName, DWORD dwFlags) { JScript *This = ACTSCRIPT_THIS(iface); - FIXME("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags); - return E_NOTIMPL; + named_item_t *item; + IDispatch *disp; + IUnknown *unk; + HRESULT hres; + + TRACE("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags); + + if(This->thread_id != GetCurrentThreadId() || !This->ctx || This->ctx->state == SCRIPTSTATE_CLOSED) + return E_UNEXPECTED; + + hres = IActiveScriptSite_GetItemInfo(This->site, pstrName, SCRIPTINFO_IUNKNOWN, &unk, NULL); + if(FAILED(hres)) { + WARN("GetItemInfo failed: %08x\n", hres); + return hres; + } + + hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp); + IUnknown_Release(unk); + if(FAILED(hres)) { + WARN("object does not implement IDispatch\n"); + return hres; + } + + item = heap_alloc(sizeof(*item)); + if(!item) { + IDispatch_Release(disp); + return E_OUTOFMEMORY; + } + + item->disp = disp; + item->flags = dwFlags; + item->next = This->ctx->named_items; + This->ctx->named_items = item; + + return S_OK; } static HRESULT WINAPI JScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib, diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 1084ec4f9d6..2869fc31ed2 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -48,7 +48,16 @@ typedef struct DispatchEx DispatchEx; #define PROPF_CONSTR 0x0400 typedef enum { - JSCLASS_NONE + JSCLASS_NONE, + JSCLASS_ARRAY, + JSCLASS_BOOLEAN, + JSCLASS_FUNCTION, + JSCLASS_GLOBAL, + JSCLASS_MATH, + JSCLASS_NUMBER, + JSCLASS_OBJECT, + JSCLASS_REGEXP, + JSCLASS_STRING } jsclass_t; typedef HRESULT (*builtin_invoke_t)(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*); @@ -85,16 +94,53 @@ struct DispatchEx { #define _IDispatchEx_(x) ((IDispatchEx*) &(x)->lpIDispatchExVtbl) +static inline void jsdisp_release(DispatchEx *jsdisp) +{ + IDispatchEx_Release(_IDispatchEx_(jsdisp)); +} + HRESULT create_dispex(script_ctx_t*,const builtin_info_t*,DispatchEx*,DispatchEx**); +HRESULT init_dispex(DispatchEx*,script_ctx_t*,const builtin_info_t*,DispatchEx*); +HRESULT init_dispex_from_constr(DispatchEx*,script_ctx_t*,const builtin_info_t*,DispatchEx*); +DispatchEx *iface_to_jsdisp(IUnknown*); + +HRESULT disp_call(IDispatch*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*); +HRESULT jsdisp_call_value(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*); +HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); +HRESULT disp_propput(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); +HRESULT jsdisp_propput_name(DispatchEx*,const WCHAR*,LCID,VARIANT*,jsexcept_t*,IServiceProvider*); +HRESULT jsdisp_set_prototype(DispatchEx*,DispatchEx*); + +HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,DWORD,DispatchEx*,DispatchEx**); + +HRESULT create_math(script_ctx_t*,DispatchEx**); + +HRESULT to_boolean(VARIANT*,VARIANT_BOOL*); +HRESULT to_object(exec_ctx_t*,VARIANT*,IDispatch**); + +typedef struct named_item_t { + IDispatch *disp; + DWORD flags; + + struct named_item_t *next; +} named_item_t; struct _script_ctx_t { LONG ref; SCRIPTSTATE state; exec_ctx_t *exec_ctx; + named_item_t *named_items; LCID lcid; DispatchEx *script_disp; + DispatchEx *global; + DispatchEx *array_constr; + DispatchEx *bool_constr; + DispatchEx *number_constr; + DispatchEx *object_constr; + DispatchEx *regexp_constr; + DispatchEx *string_constr; }; void script_release(script_ctx_t*); @@ -104,6 +150,17 @@ static inline void script_addref(script_ctx_t *ctx) ctx->ref++; } +HRESULT init_global(script_ctx_t*); + +HRESULT create_array_constr(script_ctx_t*,DispatchEx**); +HRESULT create_bool_constr(script_ctx_t*,DispatchEx**); +HRESULT create_number_constr(script_ctx_t*,DispatchEx**); +HRESULT create_object_constr(script_ctx_t*,DispatchEx**); +HRESULT create_regexp_constr(script_ctx_t*,DispatchEx**); +HRESULT create_string_constr(script_ctx_t*,DispatchEx**); + +const char *debugstr_variant(const VARIANT*); + HRESULT WINAPI JScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**); typedef struct { diff --git a/dlls/jscript/jscript_main.c b/dlls/jscript/jscript_main.c index 045c96ef0c4..37266e5773c 100644 --- a/dlls/jscript/jscript_main.c +++ b/dlls/jscript/jscript_main.c @@ -38,6 +38,8 @@ static const CLSID CLSID_JScriptAuthor = static const CLSID CLSID_JScriptEncode = {0xf414c262,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}}; +DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); + static HINSTANCE jscript_hinstance; static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c index 4f84e886b98..de04dfbde6f 100644 --- a/dlls/jscript/jsutils.c +++ b/dlls/jscript/jsutils.c @@ -22,6 +22,28 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript); +const char *debugstr_variant(const VARIANT *v) +{ + switch(V_VT(v)) { + case VT_EMPTY: + return wine_dbg_sprintf("{VT_EMPTY}"); + case VT_NULL: + return wine_dbg_sprintf("{VT_NULL}"); + case VT_I4: + return wine_dbg_sprintf("{VT_I4: %d}", V_I4(v)); + case VT_R8: + return wine_dbg_sprintf("{VT_R8: %lf}", V_R8(v)); + case VT_BSTR: + return wine_dbg_sprintf("{VT_BSTR: %s}", debugstr_w(V_BSTR(v))); + case VT_DISPATCH: + return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v)); + case VT_BOOL: + return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v)); + default: + return wine_dbg_sprintf("{vt %d}", V_VT(v)); + } +} + #define MIN_BLOCK_SIZE 128 static inline DWORD block_size(DWORD block) @@ -110,3 +132,50 @@ void jsheap_free(jsheap_t *heap) jsheap_init(heap); } + +/* ECMA-262 3rd Edition 9.2 */ +HRESULT to_boolean(VARIANT *v, VARIANT_BOOL *b) +{ + switch(V_VT(v)) { + case VT_EMPTY: + case VT_NULL: + *b = VARIANT_FALSE; + break; + case VT_I4: + *b = V_I4(v) ? VARIANT_TRUE : VARIANT_FALSE; + break; + case VT_R8: + *b = V_R8(v) ? VARIANT_TRUE : VARIANT_FALSE; + break; + case VT_BSTR: + *b = V_BSTR(v) && *V_BSTR(v) ? VARIANT_TRUE : VARIANT_FALSE; + break; + case VT_DISPATCH: + *b = V_DISPATCH(v) ? VARIANT_TRUE : VARIANT_FALSE; + break; + case VT_BOOL: + *b = V_BOOL(v); + break; + default: + FIXME("unimplemented for vt %d\n", V_VT(v)); + return E_NOTIMPL; + } + + return S_OK; +} + +/* ECMA-262 3rd Edition 9.9 */ +HRESULT to_object(exec_ctx_t *ctx, VARIANT *v, IDispatch **disp) +{ + switch(V_VT(v)) { + case VT_DISPATCH: + IDispatch_AddRef(V_DISPATCH(v)); + *disp = V_DISPATCH(v); + break; + default: + FIXME("unsupported vt %d\n", V_VT(v)); + return E_NOTIMPL; + } + + return S_OK; +} diff --git a/dlls/jscript/math.c b/dlls/jscript/math.c new file mode 100644 index 00000000000..8454cfa87e3 --- /dev/null +++ b/dlls/jscript/math.c @@ -0,0 +1,275 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * 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 + */ + +#include "jscript.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(jscript); + +static const WCHAR EW[] = {'E',0}; +static const WCHAR LOG2EW[] = {'L','O','G','2','E',0}; +static const WCHAR LOG10EW[] = {'L','O','G','1','0',0}; +static const WCHAR LN2W[] = {'L','N','2',0}; +static const WCHAR LN10W[] = {'L','N','1','0',0}; +static const WCHAR PIW[] = {'P','I',0}; +static const WCHAR SQRT2W[] = {'S','Q','R','T','2',0}; +static const WCHAR SQRT1_2W[] = {'S','Q','R','T','1','_','2',0}; +static const WCHAR absW[] = {'a','b','s',0}; +static const WCHAR acosW[] = {'a','c','o','s',0}; +static const WCHAR asinW[] = {'a','s','i','n',0}; +static const WCHAR atanW[] = {'a','t','a','n',0}; +static const WCHAR atan2W[] = {'a','t','a','n','2',0}; +static const WCHAR ceilW[] = {'c','e','i','l',0}; +static const WCHAR cosW[] = {'c','o','s',0}; +static const WCHAR expW[] = {'e','x','p',0}; +static const WCHAR floorW[] = {'f','l','o','o','r',0}; +static const WCHAR logW[] = {'l','o','g',0}; +static const WCHAR maxW[] = {'m','a','x',0}; +static const WCHAR minW[] = {'m','i','n',0}; +static const WCHAR powW[] = {'p','o','w',0}; +static const WCHAR randomW[] = {'r','a','n','d','o','m',0}; +static const WCHAR roundW[] = {'r','o','u','n','d',0}; +static const WCHAR sinW[] = {'s','i','n',0}; +static const WCHAR sqrtW[] = {'s','q','r','t',0}; +static const WCHAR tanW[] = {'t','a','n',0}; + +static HRESULT Math_E(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_LOG2E(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_LOG10E(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_LN2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_LN10(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_PI(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_SQRT2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_SQRT1_2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_abs(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_acos(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_asin(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_atan(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_atan2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_ceil(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_cos(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_exp(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_floor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_log(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_max(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_min(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_pow(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_random(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_round(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_sin(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_sqrt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Math_tan(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static const builtin_prop_t Math_props[] = { + {EW, Math_E, 0}, + {LOG2EW, Math_LOG2E, 0}, + {LOG10EW, Math_LOG10E, 0}, + {LN2W, Math_LN2, 0}, + {LN10W, Math_LN10, 0}, + {PIW, Math_PI, 0}, + {SQRT1_2W, Math_SQRT1_2, 0}, + {SQRT2W, Math_SQRT2, 0}, + {absW, Math_abs, PROPF_METHOD}, + {acosW, Math_acos, PROPF_METHOD}, + {asinW, Math_asin, PROPF_METHOD}, + {atanW, Math_atan, PROPF_METHOD}, + {atan2W, Math_atan2, PROPF_METHOD}, + {ceilW, Math_ceil, PROPF_METHOD}, + {cosW, Math_cos, PROPF_METHOD}, + {expW, Math_exp, PROPF_METHOD}, + {floorW, Math_floor, PROPF_METHOD}, + {logW, Math_log, PROPF_METHOD}, + {maxW, Math_max, PROPF_METHOD}, + {minW, Math_min, PROPF_METHOD}, + {powW, Math_pow, PROPF_METHOD}, + {randomW, Math_random, PROPF_METHOD}, + {roundW, Math_round, PROPF_METHOD}, + {sinW, Math_sin, PROPF_METHOD}, + {sqrtW, Math_sqrt, PROPF_METHOD}, + {tanW, Math_tan, PROPF_METHOD} +}; + +static const builtin_info_t Math_info = { + JSCLASS_MATH, + {NULL, NULL, 0}, + sizeof(Math_props)/sizeof(*Math_props), + Math_props, + NULL, + NULL +}; + +HRESULT create_math(script_ctx_t *ctx, DispatchEx **ret) +{ + return create_dispex(ctx, &Math_info, NULL, ret); +} diff --git a/dlls/jscript/number.c b/dlls/jscript/number.c new file mode 100644 index 00000000000..b4db8639a31 --- /dev/null +++ b/dlls/jscript/number.c @@ -0,0 +1,167 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * 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 + */ + +#include "jscript.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(jscript); + +typedef struct { + DispatchEx dispex; +} NumberInstance; + +static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; +static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0}; +static const WCHAR toFixedW[] = {'t','o','F','i','x','e','d',0}; +static const WCHAR toExponentialW[] = {'t','o','E','x','p','o','n','e','n','t','i','a','l',0}; +static const WCHAR toPrecisionW[] = {'t','o','P','r','e','c','i','s','i','o','n',0}; +static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0}; +static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0}; +static const WCHAR propertyIsEnumerableW[] = + {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; +static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0}; + +static HRESULT Number_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Number_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Number_toFixed(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Number_toExponential(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Number_toPrecision(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Number_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Number_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Number_propertyIsEnumerable(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Number_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Number_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static const builtin_prop_t Number_props[] = { + {hasOwnPropertyW, Number_hasOwnProperty, PROPF_METHOD}, + {isPrototypeOfW, Number_isPrototypeOf, PROPF_METHOD}, + {propertyIsEnumerableW, Number_propertyIsEnumerable, PROPF_METHOD}, + {toExponentialW, Number_toExponential, PROPF_METHOD}, + {toFixedW, Number_toFixed, PROPF_METHOD}, + {toLocaleStringW, Number_toLocaleString, PROPF_METHOD}, + {toPrecisionW, Number_toPrecision, PROPF_METHOD}, + {toStringW, Number_toString, PROPF_METHOD}, + {valueOfW, Number_valueOf, PROPF_METHOD} +}; + +static const builtin_info_t Number_info = { + JSCLASS_NUMBER, + {NULL, Number_value, 0}, + sizeof(Number_props)/sizeof(*Number_props), + Number_props, + NULL, + NULL +}; + +static HRESULT NumberConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT alloc_number(script_ctx_t *ctx, BOOL use_constr, NumberInstance **ret) +{ + NumberInstance *number = heap_alloc_zero(sizeof(NumberInstance)); + HRESULT hres; + + if(use_constr) + hres = init_dispex_from_constr(&number->dispex, ctx, &Number_info, ctx->number_constr); + else + hres = init_dispex(&number->dispex, ctx, &Number_info, NULL); + if(FAILED(hres)) + return hres; + + *ret = number; + return S_OK; +} + +HRESULT create_number_constr(script_ctx_t *ctx, DispatchEx **ret) +{ + NumberInstance *number; + HRESULT hres; + + hres = alloc_number(ctx, FALSE, &number); + if(FAILED(hres)) + return hres; + + hres = create_builtin_function(ctx, NumberConstr_value, PROPF_CONSTR, &number->dispex, ret); + + jsdisp_release(&number->dispex); + return hres; +} diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c new file mode 100644 index 00000000000..2cca6e9905b --- /dev/null +++ b/dlls/jscript/object.c @@ -0,0 +1,125 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * 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 + */ + +#include "jscript.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(jscript); + +static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; +static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0}; +static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0}; +static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0}; +static const WCHAR propertyIsEnumerableW[] = + {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; +static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0}; + +static HRESULT Object_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Object_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Object_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Object_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Object_propertyIsEnumerable(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Object_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT Object_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static void Object_destructor(DispatchEx *dispex) +{ + heap_free(dispex); +} + +static const builtin_prop_t Object_props[] = { + {hasOwnPropertyW, Object_hasOwnProperty, PROPF_METHOD}, + {isPrototypeOfW, Object_isPrototypeOf, PROPF_METHOD}, + {propertyIsEnumerableW, Object_propertyIsEnumerable, PROPF_METHOD}, + {toLocaleStringW, Object_toLocaleString, PROPF_METHOD}, + {toStringW, Object_toString, PROPF_METHOD}, + {valueOfW, Object_valueOf, PROPF_METHOD} +}; + +static const builtin_info_t Object_info = { + JSCLASS_OBJECT, + {NULL, Object_value, 0}, + sizeof(Object_props)/sizeof(*Object_props), + Object_props, + Object_destructor, + NULL +}; + +static HRESULT ObjectConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +HRESULT create_object_constr(script_ctx_t *ctx, DispatchEx **ret) +{ + DispatchEx *object; + HRESULT hres; + + hres = create_dispex(ctx, &Object_info, NULL, &object); + if(FAILED(hres)) + return hres; + + hres = create_builtin_function(ctx, ObjectConstr_value, PROPF_CONSTR, object, ret); + + jsdisp_release(object); + return hres; +} diff --git a/dlls/jscript/regexp.c b/dlls/jscript/regexp.c new file mode 100644 index 00000000000..8bbaa6cb1b5 --- /dev/null +++ b/dlls/jscript/regexp.c @@ -0,0 +1,143 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * 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 + */ + +#include "jscript.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(jscript); + +typedef struct { + DispatchEx dispex; +} RegExpInstance; + +static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; +static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0}; +static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0}; +static const WCHAR propertyIsEnumerableW[] = + {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; +static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0}; + +static HRESULT RegExp_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT RegExp_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT RegExp_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT RegExp_propertyIsEnumerable(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT RegExp_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT RegExp_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static void RegExp_destructor(DispatchEx *dispex) +{ + heap_free(dispex); +} + +static const builtin_prop_t RegExp_props[] = { + {hasOwnPropertyW, RegExp_hasOwnProperty, PROPF_METHOD}, + {isPrototypeOfW, RegExp_isPrototypeOf, PROPF_METHOD}, + {propertyIsEnumerableW, RegExp_propertyIsEnumerable, PROPF_METHOD}, + {toLocaleStringW, RegExp_toLocaleString, PROPF_METHOD}, + {toStringW, RegExp_toString, PROPF_METHOD} +}; + +static const builtin_info_t RegExp_info = { + JSCLASS_REGEXP, + {NULL, RegExp_value, 0}, + sizeof(RegExp_props)/sizeof(*RegExp_props), + RegExp_props, + RegExp_destructor, + NULL +}; + +static HRESULT alloc_regexp(script_ctx_t *ctx, BOOL use_constr, RegExpInstance **ret) +{ + RegExpInstance *regexp; + HRESULT hres; + + regexp = heap_alloc_zero(sizeof(RegExpInstance)); + if(!regexp) + return E_OUTOFMEMORY; + + if(use_constr) + hres = init_dispex_from_constr(®exp->dispex, ctx, &RegExp_info, ctx->regexp_constr); + else + hres = init_dispex(®exp->dispex, ctx, &RegExp_info, NULL); + + if(FAILED(hres)) { + heap_free(regexp); + return hres; + } + + *ret = regexp; + return S_OK; +} + +static HRESULT RegExpConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx **ret) +{ + RegExpInstance *regexp; + HRESULT hres; + + hres = alloc_regexp(ctx, FALSE, ®exp); + if(FAILED(hres)) + return hres; + + hres = create_builtin_function(ctx, RegExpConstr_value, PROPF_CONSTR, ®exp->dispex, ret); + + jsdisp_release(®exp->dispex); + return hres; +} diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c new file mode 100644 index 00000000000..26623ca7fdb --- /dev/null +++ b/dlls/jscript/string.c @@ -0,0 +1,421 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * 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 + */ + +#include "jscript.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(jscript); + +typedef struct { + DispatchEx dispex; +} StringInstance; + +static const WCHAR lengthW[] = {'l','e','n','g','t','h',0}; +static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; +static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0}; +static const WCHAR anchorW[] = {'a','n','c','h','o','r',0}; +static const WCHAR bigW[] = {'b','i','g',0}; +static const WCHAR blinkW[] = {'b','l','i','n','k',0}; +static const WCHAR boldW[] = {'b','o','l','d',0}; +static const WCHAR charAtW[] = {'c','h','a','r','A','t',0}; +static const WCHAR charCodeAtW[] = {'c','h','a','r','C','o','d','e','A','t',0}; +static const WCHAR concatW[] = {'c','o','n','c','a','t',0}; +static const WCHAR fixedW[] = {'f','i','x','e','d',0}; +static const WCHAR fontcolorW[] = {'f','o','n','t','c','o','l','o','r',0}; +static const WCHAR fontsizeW[] = {'f','o','n','t','s','i','z','e',0}; +static const WCHAR indexOfW[] = {'i','n','d','e','x','O','f',0}; +static const WCHAR italicsW[] = {'i','t','a','l','i','c','s',0}; +static const WCHAR lastIndexOfW[] = {'l','a','s','t','I','n','d','e','x','O','f',0}; +static const WCHAR linkW[] = {'l','i','n','k',0}; +static const WCHAR matchW[] = {'m','a','t','c','h',0}; +static const WCHAR replaceW[] = {'r','e','p','l','a','c','e',0}; +static const WCHAR searchW[] = {'s','e','a','r','c','h',0}; +static const WCHAR sliceW[] = {'s','l','i','c','e',0}; +static const WCHAR smallW[] = {'s','m','a','l','l',0}; +static const WCHAR splitW[] = {'s','p','l','i','t',0}; +static const WCHAR strikeW[] = {'s','t','r','i','k','e',0}; +static const WCHAR subW[] = {'s','u','b',0}; +static const WCHAR substringW[] = {'s','u','b','s','t','r','i','n','g',0}; +static const WCHAR substrW[] = {'s','u','b','s','t','r',0}; +static const WCHAR supW[] = {'s','u','p',0}; +static const WCHAR toLowerCaseW[] = {'t','o','L','o','w','e','r','C','a','s','e',0}; +static const WCHAR toUpperCaseW[] = {'t','o','U','p','p','e','r','C','a','s','e',0}; +static const WCHAR toLocaleLowerCaseW[] = {'t','o','L','o','c','a','l','e','L','o','w','e','r','C','a','s','e',0}; +static const WCHAR toLocaleUpperCaseW[] = {'t','o','L','o','c','a','l','e','U','p','p','e','r','C','a','s','e',0}; +static const WCHAR localeCompareW[] = {'l','o','c','a','l','e','C','o','m','p','a','r','e',0}; +static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0}; +static const WCHAR propertyIsEnumerableW[] = + {'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0}; +static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0}; + +static void String_destructor(DispatchEx *dispex) +{ + FIXME("\n"); +} + +static HRESULT String_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_anchor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_big(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_blink(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_bold(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_charAt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_charCodeAt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_concat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_fixed(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_fontcolor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_fontsize(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_indexOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_italics(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_lastIndexOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_link(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_match(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_replace(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_search(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_small(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_split(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_strike(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_sub(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_substring(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_substr(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_sup(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_toLowerCase(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_toUpperCase(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_toLocaleLowerCase(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_toLocaleUpperCase(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_localeCompare(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_propertyIsEnumerable(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT String_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static const builtin_prop_t String_props[] = { + {anchorW, String_anchor, PROPF_METHOD}, + {bigW, String_big, PROPF_METHOD}, + {blinkW, String_blink, PROPF_METHOD}, + {boldW, String_bold, PROPF_METHOD}, + {charAtW, String_charAt, PROPF_METHOD}, + {charCodeAtW, String_charCodeAt, PROPF_METHOD}, + {concatW, String_concat, PROPF_METHOD}, + {fixedW, String_fixed, PROPF_METHOD}, + {fontcolorW, String_fontcolor, PROPF_METHOD}, + {fontsizeW, String_fontsize, PROPF_METHOD}, + {hasOwnPropertyW, String_hasOwnProperty, PROPF_METHOD}, + {indexOfW, String_indexOf, PROPF_METHOD}, + {isPrototypeOfW, String_isPrototypeOf, PROPF_METHOD}, + {italicsW, String_italics, PROPF_METHOD}, + {lastIndexOfW, String_lastIndexOf, PROPF_METHOD}, + {lengthW, String_length, 0}, + {linkW, String_link, PROPF_METHOD}, + {localeCompareW, String_localeCompare, PROPF_METHOD}, + {matchW, String_match, PROPF_METHOD}, + {propertyIsEnumerableW, String_propertyIsEnumerable, PROPF_METHOD}, + {replaceW, String_replace, PROPF_METHOD}, + {searchW, String_search, PROPF_METHOD}, + {sliceW, String_slice, PROPF_METHOD}, + {smallW, String_small, PROPF_METHOD}, + {splitW, String_split, PROPF_METHOD}, + {strikeW, String_strike, PROPF_METHOD}, + {substringW, String_substring, PROPF_METHOD}, + {substrW, String_substr, PROPF_METHOD}, + {subW, String_sub, PROPF_METHOD}, + {supW, String_sup, PROPF_METHOD}, + {toLocaleLowerCaseW, String_toLocaleLowerCase, PROPF_METHOD}, + {toLocaleUpperCaseW, String_toLocaleUpperCase, PROPF_METHOD}, + {toLowerCaseW, String_toLowerCase, PROPF_METHOD}, + {toStringW, String_toString, PROPF_METHOD}, + {toUpperCaseW, String_toUpperCase, PROPF_METHOD}, + {valueOfW, String_valueOf, PROPF_METHOD} +}; + +static const builtin_info_t String_info = { + JSCLASS_STRING, + {NULL, String_value, 0}, + sizeof(String_props)/sizeof(*String_props), + String_props, + String_destructor, + NULL +}; + +static HRESULT StringConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT string_alloc(script_ctx_t *ctx, BOOL use_constr, StringInstance **ret) +{ + StringInstance *string; + HRESULT hres; + + string = heap_alloc_zero(sizeof(StringInstance)); + if(!string) + return E_OUTOFMEMORY; + + if(use_constr) + hres = init_dispex_from_constr(&string->dispex, ctx, &String_info, ctx->string_constr); + else + hres = init_dispex(&string->dispex, ctx, &String_info, NULL); + if(FAILED(hres)) { + heap_free(string); + return hres; + } + + *ret = string; + return S_OK; +} + +HRESULT create_string_constr(script_ctx_t *ctx, DispatchEx **ret) +{ + StringInstance *string; + HRESULT hres; + + hres = string_alloc(ctx, FALSE, &string); + if(FAILED(hres)) + return hres; + + hres = create_builtin_function(ctx, StringConstr_value, PROPF_CONSTR, &string->dispex, ret); + + jsdisp_release(&string->dispex); + return hres; +} diff --git a/dlls/jscript/tests/Makefile.in b/dlls/jscript/tests/Makefile.in index 01cd58e4ab3..1730cae3403 100644 --- a/dlls/jscript/tests/Makefile.in +++ b/dlls/jscript/tests/Makefile.in @@ -9,6 +9,8 @@ CTESTS = \ jscript.c \ run.c +RC_SRCS = rsrc.rc + @MAKE_TEST_RULES@ @DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js new file mode 100644 index 00000000000..088468aa16f --- /dev/null +++ b/dlls/jscript/tests/lang.js @@ -0,0 +1,72 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * 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 + */ + +ok(true, "true is not true?"); +ok(!false, "!false is not true"); +ok(!undefined, "!undefined is not true"); +ok(!null, "!null is not true"); +ok(!0, "!0 is not true"); +ok(!0.0, "!0.0 is not true"); + +ok(1 === 1, "1 === 1 is false"); +ok(!(1 === 2), "!(1 === 2) is false"); +ok(1.0 === 1, "1.0 === 1 is false"); +ok("abc" === "abc", "\"abc\" === \"abc\" is false"); +ok(true === true, "true === true is false"); +ok(null === null, "null === null is false"); +ok(undefined === undefined, "undefined === undefined is false"); +ok(!(undefined === null), "!(undefined === null) is false"); + +ok(1 !== 2, "1 !== 2 is false"); +ok(null !== undefined, "null !== undefined is false"); + +var trueVar = true; +ok(trueVar, "trueVar is not true"); + +ok(ScriptEngine.length === 0, "ScriptEngine.length is not 0"); + +function testFunc1(x, y) { + return true; +} + +ok(testFunc1.length === 2, "testFunc1.length is not 2"); + +ok(Object.prototype !== undefined, "Object.prototype is undefined"); +ok(Object.prototype.prototype === undefined, "Object.prototype is not undefined"); +ok(String.prototype !== undefined, "String.prototype is undefined"); +ok(Array.prototype !== undefined, "Array.prototype is undefined"); +ok(Boolean.prototype !== undefined, "Boolean.prototype is undefined"); +ok(Number.prototype !== undefined, "Number.prototype is undefined"); +ok(RegExp.prototype !== undefined, "RegExp.prototype is undefined"); +ok(Math !== undefined, "Math is undefined"); +ok(Math.prototype === undefined, "Math.prototype is not undefined"); + +ok(typeof(0) === "number", "typeof(0) is not number"); +ok(typeof(1.5) === "number", "typeof(1.5) is not number"); +ok(typeof("abc") === "string", "typeof(\"abc\") is not string"); +ok(typeof("") === "string", "typeof(\"\") is not string"); +ok(typeof(true) === "boolean", "typeof(true) is not boolean"); +ok(typeof(null) === "object", "typeof(null) is not object"); +ok(typeof(undefined) === "undefined", "typeof(undefined) is not undefined"); +ok(typeof(Math) === "object", "typeof(Math) is not object"); +ok(typeof(String.prototype) === "object", "typeof(String.prototype) is not object"); +ok(typeof(testFunc1) === "function", "typeof(testFunc1) is not function"); +ok(typeof(String) === "function", "typeof(String) is not function"); +ok(typeof(ScriptEngine) === "function", "typeof(ScriptEngine) is not function"); + +reportSuccess(); diff --git a/programs/regedit/regproc.h b/dlls/jscript/tests/rsrc.rc similarity index 66% copy from programs/regedit/regproc.h copy to dlls/jscript/tests/rsrc.rc index 7122379307a..ba7a46041de 100644 --- a/programs/regedit/regproc.h +++ b/dlls/jscript/tests/rsrc.rc @@ -1,6 +1,5 @@ /* - * Copyright 1999 Sylvain St-Germain - * Copyright 2002 Andriy Palamarchuk + * Copyright 2008 Jacek Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,12 +16,5 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#define KEY_MAX_LEN 1024 - -const CHAR *getAppName(void); - -BOOL export_registry_key(CHAR *file_name, CHAR *reg_key_name); -BOOL import_registry_file(FILE *in); -void delete_registry_key(WCHAR *reg_key_name); -WCHAR* GetWideString(const char* strA); -CHAR* GetMultiByteString(const WCHAR* strW); +/* @makedep: lang.js */ +lang.js 40 "lang.js" diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index b9daee42a9e..46e33873a8a 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -57,8 +57,24 @@ static const CLSID CLSID_JScript = expect_ ## func = called_ ## func = FALSE; \ }while(0) +DEFINE_EXPECT(global_propget_d); +DEFINE_EXPECT(global_propget_i); +DEFINE_EXPECT(global_propput_d); +DEFINE_EXPECT(global_propput_i); +DEFINE_EXPECT(global_success_d); +DEFINE_EXPECT(global_success_i); + +#define DISPID_GLOBAL_TESTPROPGET 0x1000 +#define DISPID_GLOBAL_TESTPROPPUT 0x1001 +#define DISPID_GLOBAL_REPORTSUCCESS 0x1002 +#define DISPID_GLOBAL_TRACE 0x1003 +#define DISPID_GLOBAL_OK 0x1004 + static const WCHAR testW[] = {'t','e','s','t',0}; +static BOOL strict_dispid_check; +static const char *test_name = "(null)"; + static const char *debugstr_w(LPCWSTR str) { static char buf[1024]; @@ -82,6 +98,13 @@ static BSTR a2bstr(const char *str) return ret; } +static int strcmp_wa(LPCWSTR strw, const char *stra) +{ + WCHAR buf[512]; + MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR)); + return lstrcmpW(strw, buf); +} + static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) { *ppv = NULL; @@ -173,12 +196,125 @@ static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { + if(!strcmp_wa(bstrName, "ok")) { + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + *pid = DISPID_GLOBAL_OK; + return S_OK; + } + if(!strcmp_wa(bstrName, "trace")) { + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + *pid = DISPID_GLOBAL_TRACE; + return S_OK; + } + if(!strcmp_wa(bstrName, "reportSuccess")) { + CHECK_EXPECT(global_success_d); + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + *pid = DISPID_GLOBAL_REPORTSUCCESS; + return S_OK; + } + if(!strcmp_wa(bstrName, "testPropGet")) { + CHECK_EXPECT(global_propget_d); + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + *pid = DISPID_GLOBAL_TESTPROPGET; + return S_OK; + } + if(!strcmp_wa(bstrName, "testPropPut")) { + CHECK_EXPECT(global_propput_d); + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + *pid = DISPID_GLOBAL_TESTPROPPUT; + return S_OK; + } + + if(strict_dispid_check) + ok(0, "unexpected call %s\n", debugstr_w(bstrName)); return DISP_E_UNKNOWNNAME; } static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { + switch(id) { + case DISPID_GLOBAL_OK: + ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(!pvarRes, "pvarRes != NULL\n"); + ok(pei != NULL, "pei == NULL\n"); + + ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg)); + ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg)); + ok(V_BOOL(pdp->rgvarg+1), "%s: %s\n", test_name, debugstr_w(V_BSTR(pdp->rgvarg))); + + return S_OK; + + case DISPID_GLOBAL_TRACE: + ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(!pvarRes, "pvarRes != NULL\n"); + ok(pei != NULL, "pei == NULL\n"); + + ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg)); + if(V_VT(pdp->rgvarg) == VT_BSTR) + trace("%s: %s\n", test_name, debugstr_w(V_BSTR(pdp->rgvarg))); + + return S_OK; + + case DISPID_GLOBAL_REPORTSUCCESS: + CHECK_EXPECT(global_success_i); + + ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(!pvarRes, "pvarRes != NULL\n"); + ok(pei != NULL, "pei == NULL\n"); + + return S_OK; + + case DISPID_GLOBAL_TESTPROPGET: + CHECK_EXPECT(global_propget_i); + + ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(!pdp->rgvarg, "rgvarg != NULL\n"); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pvarRes != NULL, "pvarRes == NULL\n"); + ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes)); + ok(pei != NULL, "pei == NULL\n"); + + V_VT(pvarRes) = VT_I4; + V_I4(pvarRes) = 1; + + return S_OK; + + case DISPID_GLOBAL_TESTPROPPUT: + CHECK_EXPECT(global_propput_i); + + ok(wFlags == INVOKE_PROPERTYPUT, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); + ok(pdp->rgdispidNamedArgs != NULL, "rgdispidNamedArgs == NULL\n"); + ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs); + ok(pdp->cNamedArgs == 1, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pdp->rgdispidNamedArgs[0] == DISPID_PROPERTYPUT, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]); + ok(!pvarRes, "pvarRes != NULL\n"); + + ok(V_VT(pdp->rgvarg) == VT_I4, "V_VT(pdp->rgvarg)=%d\n", V_VT(pdp->rgvarg)); + ok(V_I4(pdp->rgvarg) == 1, "V_I4(pdp->rgvarg)=%d\n", V_I4(pdp->rgvarg)); + return S_OK; + } + + ok(0, "unexpected call %x\n", id); return DISP_E_MEMBERNOTFOUND; } @@ -326,7 +462,6 @@ static void parse_script(BSTR script_str) hres = IActiveScript_AddNamedItem(engine, testW, SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS); - todo_wine ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres); hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED); @@ -346,10 +481,61 @@ static void parse_script_a(const char *src) SysFreeString(tmp); } +static void run_from_res(const char *name) +{ + const char *data; + DWORD size, len; + BSTR str; + HRSRC src; + + strict_dispid_check = FALSE; + test_name = name; + + src = FindResourceA(NULL, name, (LPCSTR)40); + ok(src != NULL, "Could not find resource %s\n", name); + + size = SizeofResource(NULL, src); + data = LoadResource(NULL, src); + + len = MultiByteToWideChar(CP_ACP, 0, data, size, NULL, 0); + str = SysAllocStringLen(NULL, len-1); + len = MultiByteToWideChar(CP_ACP, 0, data, size, str, len); + + SET_EXPECT(global_success_d); + SET_EXPECT(global_success_i); + parse_script(str); + CHECK_CALLED(global_success_d); + CHECK_CALLED(global_success_i); + + SysFreeString(str); +} + static void run_tests(void) { + strict_dispid_check = TRUE; + parse_script_a(""); parse_script_a("/* empty */ ;"); + + SET_EXPECT(global_propget_d); + SET_EXPECT(global_propget_i); + parse_script_a("testPropGet;"); + CHECK_CALLED(global_propget_d); + CHECK_CALLED(global_propget_i); + + SET_EXPECT(global_propput_d); + SET_EXPECT(global_propput_i); + parse_script_a("testPropPut = 1;"); + CHECK_CALLED(global_propput_d); + CHECK_CALLED(global_propput_i); + + SET_EXPECT(global_success_d); + SET_EXPECT(global_success_i); + parse_script_a("reportSuccess();"); + CHECK_CALLED(global_success_d); + CHECK_CALLED(global_success_i); + + run_from_res("lang.js"); } START_TEST(run) diff --git a/dlls/mlang/mlang.c b/dlls/mlang/mlang.c index 01706319b9a..e2f09700f55 100644 --- a/dlls/mlang/mlang.c +++ b/dlls/mlang/mlang.c @@ -3049,7 +3049,9 @@ static HRESULT WINAPI fnIMLangFontLink2_GetStrCodePages( IMLangFontLink2* This, DWORD *pdwCodePages, long *pcchCodePages) { FIXME("(%p)->%s %li %x %p %p\n",This, debugstr_wn(pszSrc,cchSrc),cchSrc,dwPriorityCodePages,pdwCodePages,pcchCodePages); - return E_NOTIMPL; + *pdwCodePages = 0; + *pcchCodePages = 1; + return S_OK; } static HRESULT WINAPI fnIMLangFontLink2_CodePageToCodePages(IMLangFontLink2* This, diff --git a/dlls/mshtml/htmldoc3.c b/dlls/mshtml/htmldoc3.c index 92ed1cc3247..8c602903813 100644 --- a/dlls/mshtml/htmldoc3.c +++ b/dlls/mshtml/htmldoc3.c @@ -58,16 +58,14 @@ static ULONG WINAPI HTMLDocument3_Release(IHTMLDocument3 *iface) static HRESULT WINAPI HTMLDocument3_GetTypeInfoCount(IHTMLDocument3 *iface, UINT *pctinfo) { HTMLDocument *This = HTMLDOC3_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo); } static HRESULT WINAPI HTMLDocument3_GetTypeInfo(IHTMLDocument3 *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLDocument *This = HTMLDOC3_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLDocument3_GetIDsOfNames(IHTMLDocument3 *iface, REFIID riid, @@ -75,9 +73,7 @@ static HRESULT WINAPI HTMLDocument3_GetIDsOfNames(IHTMLDocument3 *iface, REFIID LCID lcid, DISPID *rgDispId) { HTMLDocument *This = HTMLDOC3_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLDocument3_Invoke(IHTMLDocument3 *iface, DISPID dispIdMember, @@ -85,9 +81,8 @@ static HRESULT WINAPI HTMLDocument3_Invoke(IHTMLDocument3 *iface, DISPID dispIdM VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLDocument *This = HTMLDOC3_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLDocument3_releaseCapture(IHTMLDocument3 *iface) @@ -549,16 +544,14 @@ static ULONG WINAPI HTMLDocument4_Release(IHTMLDocument4 *iface) static HRESULT WINAPI HTMLDocument4_GetTypeInfoCount(IHTMLDocument4 *iface, UINT *pctinfo) { HTMLDocument *This = HTMLDOC4_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo); } static HRESULT WINAPI HTMLDocument4_GetTypeInfo(IHTMLDocument4 *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLDocument *This = HTMLDOC4_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLDocument4_GetIDsOfNames(IHTMLDocument4 *iface, REFIID riid, @@ -566,9 +559,7 @@ static HRESULT WINAPI HTMLDocument4_GetIDsOfNames(IHTMLDocument4 *iface, REFIID LCID lcid, DISPID *rgDispId) { HTMLDocument *This = HTMLDOC4_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLDocument4_Invoke(IHTMLDocument4 *iface, DISPID dispIdMember, @@ -576,9 +567,8 @@ static HRESULT WINAPI HTMLDocument4_Invoke(IHTMLDocument4 *iface, DISPID dispIdM VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLDocument *This = HTMLDOC4_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLDocument4_focus(IHTMLDocument4 *iface) diff --git a/dlls/mshtml/htmldoc5.c b/dlls/mshtml/htmldoc5.c index 33025380a1a..b4430450d3d 100644 --- a/dlls/mshtml/htmldoc5.c +++ b/dlls/mshtml/htmldoc5.c @@ -58,25 +58,21 @@ static ULONG WINAPI HTMLDocument5_Release(IHTMLDocument5 *iface) static HRESULT WINAPI HTMLDocument5_GetTypeInfoCount(IHTMLDocument5 *iface, UINT *pctinfo) { HTMLDocument *This = HTMLDOC5_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo); } static HRESULT WINAPI HTMLDocument5_GetTypeInfo(IHTMLDocument5 *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLDocument *This = HTMLDOC5_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLDocument5_GetIDsOfNames(IHTMLDocument5 *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { HTMLDocument *This = HTMLDOC5_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLDocument5_Invoke(IHTMLDocument5 *iface, DISPID dispIdMember, @@ -84,9 +80,8 @@ static HRESULT WINAPI HTMLDocument5_Invoke(IHTMLDocument5 *iface, DISPID dispIdM VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLDocument *This = HTMLDOC5_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLDocument5_put_onmousewheel(IHTMLDocument5 *iface, VARIANT v) diff --git a/dlls/mshtml/htmlgeneric.c b/dlls/mshtml/htmlgeneric.c index 816c4aec0f6..daa48df73ba 100644 --- a/dlls/mshtml/htmlgeneric.c +++ b/dlls/mshtml/htmlgeneric.c @@ -66,25 +66,21 @@ static ULONG WINAPI HTMLGenericElement_Release(IHTMLGenericElement *iface) static HRESULT WINAPI HTMLGenericElement_GetTypeInfoCount(IHTMLGenericElement *iface, UINT *pctinfo) { HTMLGenericElement *This = HTMLGENERIC_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->element.node.dispex), pctinfo); } static HRESULT WINAPI HTMLGenericElement_GetTypeInfo(IHTMLGenericElement *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLGenericElement *This = HTMLGENERIC_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->element.node.dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLGenericElement_GetIDsOfNames(IHTMLGenericElement *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { HTMLGenericElement *This = HTMLGENERIC_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLGenericElement_Invoke(IHTMLGenericElement *iface, DISPID dispIdMember, @@ -92,9 +88,8 @@ static HRESULT WINAPI HTMLGenericElement_Invoke(IHTMLGenericElement *iface, DISP VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLGenericElement *This = HTMLGENERIC_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->element.node.dispex), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLGenericElement_get_recordset(IHTMLGenericElement *iface, IDispatch **p) diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index e0c06194b97..50c3c65e86f 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -67,16 +67,14 @@ static ULONG WINAPI HTMLImgElement_Release(IHTMLImgElement *iface) static HRESULT WINAPI HTMLImgElement_GetTypeInfoCount(IHTMLImgElement *iface, UINT *pctinfo) { HTMLImgElement *This = HTMLIMG_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->element.node.dispex), pctinfo); } static HRESULT WINAPI HTMLImgElement_GetTypeInfo(IHTMLImgElement *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLImgElement *This = HTMLIMG_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->element.node.dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLImgElement_GetIDsOfNames(IHTMLImgElement *iface, REFIID riid, @@ -84,9 +82,7 @@ static HRESULT WINAPI HTMLImgElement_GetIDsOfNames(IHTMLImgElement *iface, REFII LCID lcid, DISPID *rgDispId) { HTMLImgElement *This = HTMLIMG_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLImgElement_Invoke(IHTMLImgElement *iface, DISPID dispIdMember, @@ -94,9 +90,8 @@ static HRESULT WINAPI HTMLImgElement_Invoke(IHTMLImgElement *iface, DISPID dispI VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLImgElement *This = HTMLIMG_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->element.node.dispex), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLImgElement_put_isMap(IHTMLImgElement *iface, VARIANT_BOOL v) diff --git a/dlls/mshtml/htmlinput.c b/dlls/mshtml/htmlinput.c index f8a646650ac..028201a6809 100644 --- a/dlls/mshtml/htmlinput.c +++ b/dlls/mshtml/htmlinput.c @@ -751,25 +751,21 @@ static ULONG WINAPI HTMLInputTextElement_Release(IHTMLInputTextElement *iface) static HRESULT WINAPI HTMLInputTextElement_GetTypeInfoCount(IHTMLInputTextElement *iface, UINT *pctinfo) { HTMLInputElement *This = HTMLINPUTTEXT_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->element.node.dispex), pctinfo); } static HRESULT WINAPI HTMLInputTextElement_GetTypeInfo(IHTMLInputTextElement *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLInputElement *This = HTMLINPUTTEXT_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->element.node.dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLInputTextElement_GetIDsOfNames(IHTMLInputTextElement *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { HTMLInputElement *This = HTMLINPUTTEXT_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLInputTextElement_Invoke(IHTMLInputTextElement *iface, DISPID dispIdMember, @@ -777,9 +773,8 @@ static HRESULT WINAPI HTMLInputTextElement_Invoke(IHTMLInputTextElement *iface, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLInputElement *This = HTMLINPUTTEXT_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->element.node.dispex), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLInputTextElement_get_type(IHTMLInputTextElement *iface, BSTR *p) diff --git a/dlls/mshtml/htmloption.c b/dlls/mshtml/htmloption.c index efb983031c2..accae83221c 100644 --- a/dlls/mshtml/htmloption.c +++ b/dlls/mshtml/htmloption.c @@ -68,16 +68,14 @@ static ULONG WINAPI HTMLOptionElement_Release(IHTMLOptionElement *iface) static HRESULT WINAPI HTMLOptionElement_GetTypeInfoCount(IHTMLOptionElement *iface, UINT *pctinfo) { HTMLOptionElement *This = HTMLOPTION_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->element.node.dispex), pctinfo); } static HRESULT WINAPI HTMLOptionElement_GetTypeInfo(IHTMLOptionElement *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLOptionElement *This = HTMLOPTION_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->element.node.dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLOptionElement_GetIDsOfNames(IHTMLOptionElement *iface, REFIID riid, @@ -85,9 +83,7 @@ static HRESULT WINAPI HTMLOptionElement_GetIDsOfNames(IHTMLOptionElement *iface, LCID lcid, DISPID *rgDispId) { HTMLOptionElement *This = HTMLOPTION_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLOptionElement_Invoke(IHTMLOptionElement *iface, DISPID dispIdMember, @@ -95,9 +91,8 @@ static HRESULT WINAPI HTMLOptionElement_Invoke(IHTMLOptionElement *iface, DISPID VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLOptionElement *This = HTMLOPTION_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->element.node.dispex), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLOptionElement_put_selected(IHTMLOptionElement *iface, VARIANT_BOOL v) diff --git a/dlls/mshtml/htmlscript.c b/dlls/mshtml/htmlscript.c index 36512adc98c..965619e0ebd 100644 --- a/dlls/mshtml/htmlscript.c +++ b/dlls/mshtml/htmlscript.c @@ -68,16 +68,14 @@ static ULONG WINAPI HTMLScriptElement_Release(IHTMLScriptElement *iface) static HRESULT WINAPI HTMLScriptElement_GetTypeInfoCount(IHTMLScriptElement *iface, UINT *pctinfo) { HTMLScriptElement *This = HTMLSCRIPT_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->element.node.dispex), pctinfo); } static HRESULT WINAPI HTMLScriptElement_GetTypeInfo(IHTMLScriptElement *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLScriptElement *This = HTMLSCRIPT_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->element.node.dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLScriptElement_GetIDsOfNames(IHTMLScriptElement *iface, REFIID riid, @@ -85,9 +83,7 @@ static HRESULT WINAPI HTMLScriptElement_GetIDsOfNames(IHTMLScriptElement *iface, LCID lcid, DISPID *rgDispId) { HTMLScriptElement *This = HTMLSCRIPT_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLScriptElement_Invoke(IHTMLScriptElement *iface, DISPID dispIdMember, @@ -95,9 +91,8 @@ static HRESULT WINAPI HTMLScriptElement_Invoke(IHTMLScriptElement *iface, DISPID VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLScriptElement *This = HTMLSCRIPT_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->element.node.dispex), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLScriptElement_put_src(IHTMLScriptElement *iface, BSTR v) diff --git a/dlls/mshtml/htmltable.c b/dlls/mshtml/htmltable.c index 88f6e75cdf9..3d13205ec55 100644 --- a/dlls/mshtml/htmltable.c +++ b/dlls/mshtml/htmltable.c @@ -68,16 +68,14 @@ static ULONG WINAPI HTMLTable_Release(IHTMLTable *iface) static HRESULT WINAPI HTMLTable_GetTypeInfoCount(IHTMLTable *iface, UINT *pctinfo) { HTMLTable *This = HTMLTABLE_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->element.node.dispex), pctinfo); } static HRESULT WINAPI HTMLTable_GetTypeInfo(IHTMLTable *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLTable *This = HTMLTABLE_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->element.node.dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLTable_GetIDsOfNames(IHTMLTable *iface, REFIID riid, @@ -85,9 +83,7 @@ static HRESULT WINAPI HTMLTable_GetIDsOfNames(IHTMLTable *iface, REFIID riid, LCID lcid, DISPID *rgDispId) { HTMLTable *This = HTMLTABLE_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLTable_Invoke(IHTMLTable *iface, DISPID dispIdMember, @@ -95,9 +91,8 @@ static HRESULT WINAPI HTMLTable_Invoke(IHTMLTable *iface, DISPID dispIdMember, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLTable *This = HTMLTABLE_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->element.node.dispex), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLTable_put_cols(IHTMLTable *iface, long v) diff --git a/dlls/mshtml/htmltextarea.c b/dlls/mshtml/htmltextarea.c index 6e94174c98e..96df5f86cf3 100644 --- a/dlls/mshtml/htmltextarea.c +++ b/dlls/mshtml/htmltextarea.c @@ -68,16 +68,14 @@ static ULONG WINAPI HTMLTextAreaElement_Release(IHTMLTextAreaElement *iface) static HRESULT WINAPI HTMLTextAreaElement_GetTypeInfoCount(IHTMLTextAreaElement *iface, UINT *pctinfo) { HTMLTextAreaElement *This = HTMLTXTAREA_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->element.node.dispex), pctinfo); } static HRESULT WINAPI HTMLTextAreaElement_GetTypeInfo(IHTMLTextAreaElement *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLTextAreaElement *This = HTMLTXTAREA_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->element.node.dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLTextAreaElement_GetIDsOfNames(IHTMLTextAreaElement *iface, REFIID riid, @@ -85,9 +83,7 @@ static HRESULT WINAPI HTMLTextAreaElement_GetIDsOfNames(IHTMLTextAreaElement *if LCID lcid, DISPID *rgDispId) { HTMLTextAreaElement *This = HTMLTXTAREA_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLTextAreaElement_Invoke(IHTMLTextAreaElement *iface, DISPID dispIdMember, @@ -95,9 +91,8 @@ static HRESULT WINAPI HTMLTextAreaElement_Invoke(IHTMLTextAreaElement *iface, DI VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLTextAreaElement *This = HTMLTXTAREA_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->element.node.dispex), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLTextAreaElement_get_type(IHTMLTextAreaElement *iface, BSTR *p) diff --git a/dlls/mshtml/htmltextcont.c b/dlls/mshtml/htmltextcont.c index 212784cf4d0..f73bb0be3e4 100644 --- a/dlls/mshtml/htmltextcont.c +++ b/dlls/mshtml/htmltextcont.c @@ -58,16 +58,14 @@ static ULONG WINAPI HTMLTextContainer_Release(IHTMLTextContainer *iface) static HRESULT WINAPI HTMLTextContainer_GetTypeInfoCount(IHTMLTextContainer *iface, UINT *pctinfo) { HTMLTextContainer *This = HTMLTEXTCONT_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->element.node.dispex), pctinfo); } static HRESULT WINAPI HTMLTextContainer_GetTypeInfo(IHTMLTextContainer *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLTextContainer *This = HTMLTEXTCONT_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->element.node.dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLTextContainer_GetIDsOfNames(IHTMLTextContainer *iface, REFIID riid, @@ -75,9 +73,7 @@ static HRESULT WINAPI HTMLTextContainer_GetIDsOfNames(IHTMLTextContainer *iface, LCID lcid, DISPID *rgDispId) { HTMLTextContainer *This = HTMLTEXTCONT_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLTextContainer_Invoke(IHTMLTextContainer *iface, DISPID dispIdMember, @@ -85,9 +81,8 @@ static HRESULT WINAPI HTMLTextContainer_Invoke(IHTMLTextContainer *iface, DISPID VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLTextContainer *This = HTMLTEXTCONT_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->element.node.dispex), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLTextContainer_createControlRange(IHTMLTextContainer *iface, diff --git a/dlls/mshtml/htmltextnode.c b/dlls/mshtml/htmltextnode.c index 69c287d02be..d0a08664baa 100644 --- a/dlls/mshtml/htmltextnode.c +++ b/dlls/mshtml/htmltextnode.c @@ -68,16 +68,14 @@ static ULONG WINAPI HTMLDOMTextNode_Release(IHTMLDOMTextNode *iface) static HRESULT WINAPI HTMLDOMTextNode_GetTypeInfoCount(IHTMLDOMTextNode *iface, UINT *pctinfo) { HTMLDOMTextNode *This = HTMLTEXT_THIS(iface); - FIXME("(%p)->(%p)\n", This, pctinfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->node.dispex), pctinfo); } static HRESULT WINAPI HTMLDOMTextNode_GetTypeInfo(IHTMLDOMTextNode *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { HTMLDOMTextNode *This = HTMLTEXT_THIS(iface); - FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - return E_NOTIMPL; + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->node.dispex), iTInfo, lcid, ppTInfo); } static HRESULT WINAPI HTMLDOMTextNode_GetIDsOfNames(IHTMLDOMTextNode *iface, REFIID riid, @@ -85,9 +83,7 @@ static HRESULT WINAPI HTMLDOMTextNode_GetIDsOfNames(IHTMLDOMTextNode *iface, REF LCID lcid, DISPID *rgDispId) { HTMLDOMTextNode *This = HTMLTEXT_THIS(iface); - FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - return E_NOTIMPL; + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->node.dispex), riid, rgszNames, cNames, lcid, rgDispId); } static HRESULT WINAPI HTMLDOMTextNode_Invoke(IHTMLDOMTextNode *iface, DISPID dispIdMember, @@ -95,9 +91,8 @@ static HRESULT WINAPI HTMLDOMTextNode_Invoke(IHTMLDOMTextNode *iface, DISPID dis VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLDOMTextNode *This = HTMLTEXT_THIS(iface); - FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - return E_NOTIMPL; + return IDispatchEx_Invoke(DISPATCHEX(&This->node.dispex), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); } static HRESULT WINAPI HTMLDOMTextNode_put_data(IHTMLDOMTextNode *iface, BSTR v) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 8a8efe75d45..cb43c5d4d50 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -3838,7 +3838,7 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package) MSIFEATURE *feature; UINT rc; HKEY hkey; - HKEY userdata; + HKEY userdata = NULL; if (!msi_check_publish(package)) return ERROR_SUCCESS; @@ -5564,7 +5564,8 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) { MSIPACKAGE *package = param; MSICOMPONENT *comp; - LPCWSTR sourcename, destname; + LPCWSTR sourcename; + LPWSTR destname = NULL; LPWSTR sourcedir = NULL, destdir = NULL; LPWSTR source = NULL, dest = NULL; int options; @@ -5582,7 +5583,6 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) } sourcename = MSI_RecordGetString(rec, 3); - destname = MSI_RecordGetString(rec, 4); options = MSI_RecordGetInteger(rec, 7); sourcedir = msi_dup_property(package, MSI_RecordGetString(rec, 5)); @@ -5617,11 +5617,20 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) wildcards = strchrW(source, '*') || strchrW(source, '?'); - if (!destname && !wildcards) + if (MSI_RecordIsNull(rec, 4)) { - destname = strdupW(sourcename); - if (!destname) - goto done; + if (!wildcards) + { + destname = strdupW(sourcename); + if (!destname) + goto done; + } + } + else + { + destname = strdupW(MSI_RecordGetString(rec, 4)); + if (destname) + reduce_to_longfilename(destname); } size = 0; @@ -5658,6 +5667,7 @@ static UINT ITERATE_MoveFiles( MSIRECORD *rec, LPVOID param ) done: msi_free(sourcedir); msi_free(destdir); + msi_free(destname); msi_free(source); msi_free(dest); diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index adfe28eb26b..239abb63c4c 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -575,6 +575,7 @@ static const CHAR mov_move_file_dat[] = "FileKey\tComponent_\tSourceName\tDestNa "kazakhstan\taugustus\t\tkiribati\tFILEPATHGOOD\tMSITESTDIR\t1\n" "laos\taugustus\tlatvia\tlebanon\tSourceDir\tMSITESTDIR\t1\n" "namibia\taugustus\tnauru\tkiribati\tSourceDir\tMSITESTDIR\t1\n" + "pakistan\taugustus\tperu\tsfn|poland\tSourceDir\tMSITESTDIR\t1\n" "wildcard\taugustus\tapp*\twildcard\tSourceDir\tMSITESTDIR\t1\n" "single\taugustus\tf?o\tsingle\tSourceDir\tMSITESTDIR\t1\n" "wildcardnodest\taugustus\tbudd*\t\tSourceDir\tMSITESTDIR\t1\n" @@ -4390,6 +4391,7 @@ static void test_movefiles(void) create_file("kenya", 100); CreateDirectoryA("latvia", NULL); create_file("nauru", 100); + create_file("peru", 100); create_file("apple", 100); create_file("application", 100); create_file("ape", 100); @@ -4430,6 +4432,7 @@ static void test_movefiles(void) ok(delete_pf("msitest\\kiribati", TRUE), "File not moved\n"); ok(!delete_pf("msitest\\lebanon", TRUE), "File moved\n"); ok(!delete_pf("msitest\\lebanon", FALSE), "Directory moved\n"); + ok(delete_pf("msitest\\poland", TRUE), "File not moved\n"); /* either apple or application will be moved depending on directory order */ if (!delete_pf("msitest\\apple", TRUE)) ok(delete_pf("msitest\\application", TRUE), "File not moved\n"); @@ -4462,6 +4465,7 @@ static void test_movefiles(void) ok(!DeleteFileA("kenya"), "File not moved\n"); ok(RemoveDirectoryA("latvia"), "Directory moved\n"); ok(!DeleteFileA("nauru"), "File not moved\n"); + ok(!DeleteFileA("peru"), "File not moved\n"); ok(!DeleteFileA("apple"), "File not moved\n"); ok(!DeleteFileA("application"), "File not moved\n"); ok(DeleteFileA("ape"), "File moved\n"); diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c index 3775cbd4509..2ef86d9ccbd 100644 --- a/dlls/msi/tests/package.c +++ b/dlls/msi/tests/package.c @@ -7726,65 +7726,66 @@ struct access_res { BOOL gothandle; DWORD lasterr; + BOOL ignore; }; static const struct access_res create[16] = { - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS } + { TRUE, ERROR_SUCCESS, TRUE }, + { TRUE, ERROR_SUCCESS, TRUE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, TRUE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, TRUE } }; static const struct access_res create_commit[16] = { - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS } + { TRUE, ERROR_SUCCESS, TRUE }, + { TRUE, ERROR_SUCCESS, TRUE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, TRUE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, TRUE } }; static const struct access_res create_close[16] = { - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, { TRUE, ERROR_SUCCESS } }; @@ -7804,6 +7805,9 @@ static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD for (j = 0; j < 4; j++) { + if (ares[idx].ignore) + continue; + if (j == 0) share = 0; if (j == 1) share = FILE_SHARE_READ; if (j == 2) share = FILE_SHARE_WRITE; diff --git a/dlls/msxml3/saxreader.c b/dlls/msxml3/saxreader.c index 554b048ba96..d0ba6b5967c 100644 --- a/dlls/msxml3/saxreader.c +++ b/dlls/msxml3/saxreader.c @@ -1680,6 +1680,57 @@ static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int siz return S_OK; } +static HRESULT internal_parseStream(saxreader *This, IStream *stream, BOOL vbInterface) +{ + saxlocator *locator; + HRESULT hr; + ULONG dataRead; + char data[1024]; + + hr = IStream_Read(stream, data, sizeof(data), &dataRead); + if(hr != S_OK) + return hr; + + hr = SAXLocator_create(This, &locator, vbInterface); + if(FAILED(hr)) + return E_FAIL; + + locator->pParserCtxt = xmlCreatePushParserCtxt( + &locator->saxreader->sax, locator, + data, dataRead, NULL); + if(!locator->pParserCtxt) + { + ISAXLocator_Release((ISAXLocator*)&locator->lpSAXLocatorVtbl); + return E_FAIL; + } + + while(1) + { + hr = IStream_Read(stream, data, sizeof(data), &dataRead); + if(hr != S_OK) + break; + + if(xmlParseChunk(locator->pParserCtxt, data, dataRead, 0)) hr = E_FAIL; + else hr = locator->ret; + + if(hr != S_OK) break; + + if(dataRead != sizeof(data)) + { + if(xmlParseChunk(locator->pParserCtxt, data, 0, 1)) hr = E_FAIL; + else hr = locator->ret; + + break; + } + } + + locator->pParserCtxt->sax = NULL; + xmlFreeParserCtxt(locator->pParserCtxt); + locator->pParserCtxt = NULL; + ISAXLocator_Release((ISAXLocator*)&locator->lpSAXLocatorVtbl); + return hr; +} + static HRESULT WINAPI internal_getEntityResolver( saxreader *This, void *pEntityResolver, @@ -1867,47 +1918,7 @@ static HRESULT WINAPI internal_parse( if(stream || IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream) == S_OK) { - STATSTG dataInfo; - ULONG dataRead; - char *data; - - while(1) - { - hr = IStream_Stat(stream, &dataInfo, STATFLAG_NONAME); - if(hr == E_PENDING) continue; - break; - } - if(hr != S_OK) - { - IStream_Release(stream); - break; - } - - data = HeapAlloc(GetProcessHeap(), 0, - dataInfo.cbSize.QuadPart); - if(!data) - { - IStream_Release(stream); - break; - } - - while(1) - { - hr = IStream_Read(stream, data, - dataInfo.cbSize.QuadPart, &dataRead); - if(hr == E_PENDING) continue; - break; - } - if(hr != S_OK) - { - HeapFree(GetProcessHeap(), 0, data); - IStream_Release(stream); - break; - } - - hr = internal_parseBuffer(This, data, - dataInfo.cbSize.QuadPart, vbInterface); - HeapFree(GetProcessHeap(), 0, data); + hr = internal_parseStream(This, stream, vbInterface); IStream_Release(stream); break; } @@ -2161,7 +2172,7 @@ static HRESULT WINAPI saxxmlreader_putProperty( return E_NOTIMPL; } -static HRESULT WINAPI saxxmlreader_getEntityResolver( +static HRESULT WINAPI saxxmlreader_get_entityResolver( IVBSAXXMLReader* iface, IVBSAXEntityResolver **pEntityResolver) { @@ -2169,7 +2180,7 @@ static HRESULT WINAPI saxxmlreader_getEntityResolver( return internal_getEntityResolver(This, pEntityResolver, TRUE); } -static HRESULT WINAPI saxxmlreader_putEntityResolver( +static HRESULT WINAPI saxxmlreader_put_entityResolver( IVBSAXXMLReader* iface, IVBSAXEntityResolver *pEntityResolver) { @@ -2177,7 +2188,7 @@ static HRESULT WINAPI saxxmlreader_putEntityResolver( return internal_putEntityResolver(This, pEntityResolver, TRUE); } -static HRESULT WINAPI saxxmlreader_getContentHandler( +static HRESULT WINAPI saxxmlreader_get_contentHandler( IVBSAXXMLReader* iface, IVBSAXContentHandler **ppContentHandler) { @@ -2185,7 +2196,7 @@ static HRESULT WINAPI saxxmlreader_getContentHandler( return internal_getContentHandler(This, ppContentHandler, TRUE); } -static HRESULT WINAPI saxxmlreader_putContentHandler( +static HRESULT WINAPI saxxmlreader_put_contentHandler( IVBSAXXMLReader* iface, IVBSAXContentHandler *contentHandler) { @@ -2193,7 +2204,7 @@ static HRESULT WINAPI saxxmlreader_putContentHandler( return internal_putContentHandler(This, contentHandler, TRUE); } -static HRESULT WINAPI saxxmlreader_getDTDHandler( +static HRESULT WINAPI saxxmlreader_get_dtdHandler( IVBSAXXMLReader* iface, IVBSAXDTDHandler **pDTDHandler) { @@ -2201,7 +2212,7 @@ static HRESULT WINAPI saxxmlreader_getDTDHandler( return internal_getDTDHandler(This, pDTDHandler, TRUE); } -static HRESULT WINAPI saxxmlreader_putDTDHandler( +static HRESULT WINAPI saxxmlreader_put_dtdHandler( IVBSAXXMLReader* iface, IVBSAXDTDHandler *pDTDHandler) { @@ -2209,7 +2220,7 @@ static HRESULT WINAPI saxxmlreader_putDTDHandler( return internal_putDTDHandler(This, pDTDHandler, TRUE); } -static HRESULT WINAPI saxxmlreader_getErrorHandler( +static HRESULT WINAPI saxxmlreader_get_errorHandler( IVBSAXXMLReader* iface, IVBSAXErrorHandler **pErrorHandler) { @@ -2217,7 +2228,7 @@ static HRESULT WINAPI saxxmlreader_getErrorHandler( return internal_getErrorHandler(This, pErrorHandler, TRUE); } -static HRESULT WINAPI saxxmlreader_putErrorHandler( +static HRESULT WINAPI saxxmlreader_put_errorHandler( IVBSAXXMLReader* iface, IVBSAXErrorHandler *errorHandler) { @@ -2225,7 +2236,7 @@ static HRESULT WINAPI saxxmlreader_putErrorHandler( return internal_putErrorHandler(This, errorHandler, TRUE); } -static HRESULT WINAPI saxxmlreader_getBaseURL( +static HRESULT WINAPI saxxmlreader_get_baseURL( IVBSAXXMLReader* iface, const WCHAR **pBaseUrl) { @@ -2235,7 +2246,7 @@ static HRESULT WINAPI saxxmlreader_getBaseURL( return E_NOTIMPL; } -static HRESULT WINAPI saxxmlreader_putBaseURL( +static HRESULT WINAPI saxxmlreader_put_baseURL( IVBSAXXMLReader* iface, const WCHAR *pBaseUrl) { @@ -2245,7 +2256,7 @@ static HRESULT WINAPI saxxmlreader_putBaseURL( return E_NOTIMPL; } -static HRESULT WINAPI saxxmlreader_getSecureBaseURL( +static HRESULT WINAPI saxxmlreader_get_secureBaseURL( IVBSAXXMLReader* iface, const WCHAR **pSecureBaseUrl) { @@ -2256,7 +2267,7 @@ static HRESULT WINAPI saxxmlreader_getSecureBaseURL( } -static HRESULT WINAPI saxxmlreader_putSecureBaseURL( +static HRESULT WINAPI saxxmlreader_put_secureBaseURL( IVBSAXXMLReader* iface, const WCHAR *secureBaseUrl) { @@ -2295,18 +2306,18 @@ static const struct IVBSAXXMLReaderVtbl saxreader_vtbl = saxxmlreader_putFeature, saxxmlreader_getProperty, saxxmlreader_putProperty, - saxxmlreader_getEntityResolver, - saxxmlreader_putEntityResolver, - saxxmlreader_getContentHandler, - saxxmlreader_putContentHandler, - saxxmlreader_getDTDHandler, - saxxmlreader_putDTDHandler, - saxxmlreader_getErrorHandler, - saxxmlreader_putErrorHandler, - saxxmlreader_getBaseURL, - saxxmlreader_putBaseURL, - saxxmlreader_getSecureBaseURL, - saxxmlreader_putSecureBaseURL, + saxxmlreader_get_entityResolver, + saxxmlreader_put_entityResolver, + saxxmlreader_get_contentHandler, + saxxmlreader_put_contentHandler, + saxxmlreader_get_dtdHandler, + saxxmlreader_put_dtdHandler, + saxxmlreader_get_errorHandler, + saxxmlreader_put_errorHandler, + saxxmlreader_get_baseURL, + saxxmlreader_put_baseURL, + saxxmlreader_get_secureBaseURL, + saxxmlreader_put_secureBaseURL, saxxmlreader_parse, saxxmlreader_parseURL }; @@ -2445,7 +2456,7 @@ static HRESULT WINAPI isaxxmlreader_getBaseURL( const WCHAR **pBaseUrl) { saxreader *This = impl_from_ISAXXMLReader( iface ); - return IVBSAXXMLReader_get_getBaseURL( + return IVBSAXXMLReader_get_baseURL( (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, pBaseUrl); } @@ -2455,7 +2466,7 @@ static HRESULT WINAPI isaxxmlreader_putBaseURL( const WCHAR *pBaseUrl) { saxreader *This = impl_from_ISAXXMLReader( iface ); - return IVBSAXXMLReader_put_putBaseURL( + return IVBSAXXMLReader_put_baseURL( (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, pBaseUrl); } @@ -2465,7 +2476,7 @@ static HRESULT WINAPI isaxxmlreader_getSecureBaseURL( const WCHAR **pSecureBaseUrl) { saxreader *This = impl_from_ISAXXMLReader( iface ); - return IVBSAXXMLReader_get_getSecureBaseURL( + return IVBSAXXMLReader_get_secureBaseURL( (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, pSecureBaseUrl); } @@ -2475,7 +2486,7 @@ static HRESULT WINAPI isaxxmlreader_putSecureBaseURL( const WCHAR *secureBaseUrl) { saxreader *This = impl_from_ISAXXMLReader( iface ); - return IVBSAXXMLReader_put_putSecureBaseURL( + return IVBSAXXMLReader_put_secureBaseURL( (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, secureBaseUrl); } diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 25b3a3241ef..123a558ab94 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -469,6 +469,18 @@ PDEVICE_OBJECT WINAPI IoGetRelatedDeviceObject( PFILE_OBJECT obj ) return NULL; } +static CONFIGURATION_INFORMATION configuration_information; + +/*********************************************************************** + * IoGetConfigurationInformation (NTOSKRNL.EXE.@) + */ +PCONFIGURATION_INFORMATION WINAPI IoGetConfigurationInformation(void) +{ + FIXME( "partial stub\n" ); + /* FIXME: return actual devices on system */ + return &configuration_information; +} + /*********************************************************************** * IoRegisterDriverReinitialization (NTOSKRNL.EXE.@) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 8f308a2fd61..bdd153782f7 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -377,7 +377,7 @@ @ stub IoGetAttachedDeviceReference @ stub IoGetBaseFileSystemDeviceObject @ stub IoGetBootDiskInformation -@ stub IoGetConfigurationInformation +@ stdcall IoGetConfigurationInformation() @ stub IoGetCurrentProcess @ stub IoGetDeviceAttachmentBaseRef @ stub IoGetDeviceInterfaceAlias diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c index d825ab66bfa..6a7158b2685 100644 --- a/dlls/ole32/tests/storage32.c +++ b/dlls/ole32/tests/storage32.c @@ -1003,65 +1003,66 @@ struct access_res { BOOL gothandle; DWORD lasterr; + BOOL ignore; }; static const struct access_res create[16] = { - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS } + { TRUE, ERROR_SUCCESS, TRUE }, + { TRUE, ERROR_SUCCESS, TRUE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, TRUE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, TRUE } }; static const struct access_res create_commit[16] = { - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { FALSE, ERROR_SHARING_VIOLATION }, - { TRUE, ERROR_SUCCESS } + { TRUE, ERROR_SUCCESS, TRUE }, + { TRUE, ERROR_SUCCESS, TRUE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, TRUE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { FALSE, ERROR_SHARING_VIOLATION, FALSE }, + { TRUE, ERROR_SUCCESS, TRUE } }; static const struct access_res create_close[16] = { - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, - { TRUE, ERROR_SUCCESS }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, + { TRUE, ERROR_SUCCESS, FALSE }, { TRUE, ERROR_SUCCESS } }; @@ -1081,6 +1082,9 @@ static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD for (j = 0; j < 4; j++) { + if (ares[idx].ignore) + continue; + if (j == 0) share = 0; if (j == 1) share = FILE_SHARE_READ; if (j == 2) share = FILE_SHARE_WRITE; diff --git a/dlls/oleaut32/hash.c b/dlls/oleaut32/hash.c index 32c1086b7ef..12c93894621 100644 --- a/dlls/oleaut32/hash.c +++ b/dlls/oleaut32/hash.c @@ -510,6 +510,9 @@ ULONG WINAPI LHashValOfNameSysA( SYSKIND skind, LCID lcid, LPCSTR lpStr) ULONG nHiWord, nLoWord = 0x0deadbee; const unsigned char *str = (const unsigned char *)lpStr, *pnLookup = NULL; + TRACE("(%d, %d, %s) %s\n", skind, lcid, debugstr_a(lpStr), + (skind == SYS_WIN16) ? "SYS_WIN16" : (skind == SYS_WIN32) ? "SYS_WIN32" : ""); + if (!str) return 0; diff --git a/dlls/qmgr/job.c b/dlls/qmgr/job.c index 32dadd84477..e344027ed2b 100644 --- a/dlls/qmgr/job.c +++ b/dlls/qmgr/job.c @@ -456,8 +456,8 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyCmdLine( static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyCmdLine( IBackgroundCopyJob2 *iface, - LPWSTR prog, - LPWSTR params) + LPWSTR *prog, + LPWSTR *params) { FIXME("Not implemented\n"); return E_NOTIMPL; diff --git a/dlls/quartz/tests/avisplitter.c b/dlls/quartz/tests/avisplitter.c index 82fd4cfa77d..f4c81578e5d 100644 --- a/dlls/quartz/tests/avisplitter.c +++ b/dlls/quartz/tests/avisplitter.c @@ -206,11 +206,8 @@ static void test_threads() return; } - /* Before doing anything */ + /* Before doing anything (number of threads at the start differs per OS) */ baselevel = count_threads(); - expected = 1; - ok(baselevel == expected, - "Basic amount of threads should be %d, not %d!\n", expected, baselevel); file = CreateFileW(wfile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); @@ -374,11 +371,7 @@ static void test_threads() IBaseFilter_GetState(pavi, INFINITE, &state); curlevel = count_threads(); - /* On a 2 stream filter, there are 4 or 5 threads (seems to be 5) - * One is the thread we are in. That leaves 3 or 4 for other dark purposes - * Wine is 1 thread short! - */ - ok(curlevel == expected || curlevel == expected + 1, + ok(curlevel == expected, "Amount of threads should be %d not %d\n", expected, curlevel); IBaseFilter_Pause(pavi); @@ -452,8 +445,10 @@ fail: if (pfile) IUnknown_Release(pfile); - ok(baselevel == 1, - "Basic amount of threads should be %d, not %d!\n", 1, baselevel); + curlevel = count_threads(); + todo_wine + ok(curlevel == baselevel, + "Amount of threads should be %d not %d\n", baselevel, curlevel); } START_TEST(avisplitter) diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 0867d27d1c2..37c1c1f2a17 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -1122,9 +1122,12 @@ static HRESULT TestFilter_Create(const CLSID* pClsid, const TestFilterPinData *p error: - for (i = 0; i < nPins; i++) + if (pTestFilter->ppPins) { - if (pTestFilter->ppPins[i]) IPin_Release(pTestFilter->ppPins[i]); + for (i = 0; i < nPins; i++) + { + if (pTestFilter->ppPins[i]) IPin_Release(pTestFilter->ppPins[i]); + } } CoTaskMemFree(pTestFilter->ppPins); DeleteCriticalSection(&pTestFilter->csFilter); diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index ea94019d96c..41dce8615c1 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -38,7 +38,7 @@ static CHAR string1[MAX_PATH], string2[MAX_PATH], string3[MAX_PATH]; WideCharToMultiByte(CP_ACP, 0, szString1, -1, string1, MAX_PATH, NULL, NULL); \ WideCharToMultiByte(CP_ACP, 0, szString2, -1, string2, MAX_PATH, NULL, NULL); \ WideCharToMultiByte(CP_ACP, 0, szString3, -1, string3, MAX_PATH, NULL, NULL); \ - ok(!lstrcmpW(szString3, szString1) || !lstrcmpW(szString3, szString1), \ + ok(!lstrcmpW(szString3, szString1) || !lstrcmpW(szString3, szString2), \ format, string1, string2, string3); static HMODULE hmoduleRichEdit; @@ -3217,7 +3217,7 @@ static void test_EM_SETTEXTEX(void) 'm', 'e', 'T', 'e', 'x', 't', 0}; WCHAR TestItem1altn[] = {'T','T','e','s','t','S','o','m','e','T','e','x','t', - '\n','t','S','o','m','e','T','e','x','t',0}; + '\r','t','S','o','m','e','T','e','x','t',0}; WCHAR TestItem2[] = {'T', 'e', 's', 't', 'S', 'o', 'm', 'e', 'T', 'e', 'x', 't', diff --git a/dlls/shdocvw/events.c b/dlls/shdocvw/events.c index 2fba55c486d..85903595295 100644 --- a/dlls/shdocvw/events.c +++ b/dlls/shdocvw/events.c @@ -286,7 +286,7 @@ static void ConnectionPoint_Create(REFIID riid, ConnectionPoint **cp, static void ConnectionPoint_Destroy(ConnectionPoint *This) { - int i; + DWORD i; for(i=0; isinks_size; i++) { if(This->sinks[i]) diff --git a/dlls/shdocvw/factory.c b/dlls/shdocvw/factory.c index 29929476c95..ec3e7a65c04 100644 --- a/dlls/shdocvw/factory.c +++ b/dlls/shdocvw/factory.c @@ -215,7 +215,7 @@ static HRESULT register_server(BOOL doregister) STRTABLEA strtable; STRENTRYA pse[14]; static CLSID const *clsids[14]; - int i = 0; + unsigned int i = 0; HRESULT hres; INF_SET_CLSID(CUrlHistory); diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c index b7be1f1ffbd..bd549a16719 100644 --- a/dlls/shlwapi/ordinal.c +++ b/dlls/shlwapi/ordinal.c @@ -2261,6 +2261,25 @@ HRESULT WINAPI QISearch( } /************************************************************************* + * @ [SHLWAPI.220] + * + * Set the Font for a window and the "PropDlgFont" property of the parent window. + * + * PARAMS + * hWnd [I] Parent Window to set the property + * id [I] Index of child Window to set the Font + * + * RETURNS + * Success: S_OK + * + */ +HRESULT WINAPI SHSetDefaultDialogFont(HWND hWnd, INT id) +{ + FIXME("(%p, %d) stub\n", hWnd, id); + return S_OK; +} + +/************************************************************************* * @ [SHLWAPI.221] * * Remove the "PropDlgFont" property from a window. diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec index 0e63e9f0c1f..f86bd7cd1a0 100644 --- a/dlls/shlwapi/shlwapi.spec +++ b/dlls/shlwapi/shlwapi.spec @@ -217,7 +217,7 @@ 217 stdcall -noname SHUnicodeToAnsi(wstr ptr ptr) 218 stdcall -noname SHUnicodeToAnsiCP(long wstr ptr ptr) 219 stdcall -noname QISearch(long long long long) -220 stub -noname SHSetDefaultDialogFont +220 stdcall -noname SHSetDefaultDialogFont(ptr long) 221 stdcall -noname SHRemoveDefaultDialogFont(ptr) 222 stdcall -noname SHGlobalCounterCreate(long) 223 stdcall -noname SHGlobalCounterGetValue(long) diff --git a/dlls/urlmon/tests/protocol.c b/dlls/urlmon/tests/protocol.c index d5037216a0f..b986dfcbb7f 100644 --- a/dlls/urlmon/tests/protocol.c +++ b/dlls/urlmon/tests/protocol.c @@ -350,7 +350,8 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL CHECK_CALLED(ReportProgress_CONNECTING); } else todo_wine { CHECK_NOT_CALLED(ReportProgress_FINDINGRESOURCE); - CHECK_NOT_CALLED(ReportProgress_CONNECTING); + /* IE7 does call this */ + CLEAR_CALLED(ReportProgress_CONNECTING); } CHECK_CALLED(ReportProgress_SENDINGREQUEST); SET_EXPECT(OnResponse); diff --git a/dlls/urlmon/tests/url.c b/dlls/urlmon/tests/url.c index f315070bb81..e2cc08429a5 100644 --- a/dlls/urlmon/tests/url.c +++ b/dlls/urlmon/tests/url.c @@ -2122,7 +2122,8 @@ static void test_BindToStorage(int protocol, BOOL emul, DWORD t) CHECK_CALLED(OnProgress_CONNECTING); }else todo_wine { CHECK_NOT_CALLED(OnProgress_FINDINGRESOURCE); - CHECK_NOT_CALLED(OnProgress_CONNECTING); + /* IE7 does call this */ + CLEAR_CALLED(OnProgress_CONNECTING); } } if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST) @@ -2281,7 +2282,8 @@ static void test_BindToObject(int protocol, BOOL emul) CHECK_CALLED(Obj_OnProgress_CONNECTING); }else todo_wine { CHECK_NOT_CALLED(Obj_OnProgress_FINDINGRESOURCE); - CHECK_NOT_CALLED(Obj_OnProgress_CONNECTING); + /* IE7 does call this */ + CLEAR_CALLED(Obj_OnProgress_CONNECTING); } } if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST) { @@ -2383,8 +2385,10 @@ static void test_URLDownloadToFile(DWORD prot, BOOL emul) CHECK_CALLED(QueryInterface_IHttpNegotiate2); CHECK_CALLED(GetRootSecurityId); } - if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST) + if(test_protocol == FILE_TEST) CHECK_CALLED(OnProgress_SENDINGREQUEST); + else if(test_protocol == HTTP_TEST) + CLEAR_CALLED(OnProgress_SENDINGREQUEST); /* not called by IE7 */ if(test_protocol == HTTP_TEST) CHECK_CALLED(OnResponse); CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE); diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index 2bbaab97d64..21e1554d059 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -2187,13 +2187,16 @@ BOOL WINAPI EndDeferWindowPos( HDWP hdwp ) pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp ); if (!pDWP) return FALSE; - for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++) + for (i = 0, winpos = pDWP->winPos; res && i < pDWP->actualCount; i++, winpos++) { TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n", winpos->hwnd, winpos->hwndInsertAfter, winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags); - if (!(res = USER_SetWindowPos( winpos ))) break; + if (WIN_IsCurrentThread( winpos->hwnd )) + res = USER_SetWindowPos( winpos ); + else + res = SendMessageW( winpos->hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)winpos ); } USER_HEAP_FREE( hdwp ); return res; diff --git a/dlls/winealsa.drv/dscapture.c b/dlls/winealsa.drv/dscapture.c index 6c5b4a4986d..872a80c8b3c 100644 --- a/dlls/winealsa.drv/dscapture.c +++ b/dlls/winealsa.drv/dscapture.c @@ -884,7 +884,7 @@ static HRESULT WINAPI IDsCaptureDriverImpl_Open(PIDSCDRIVER iface) return hr; } - err = snd_pcm_open(&pcm, WOutDev[This->wDevID].pcmname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); + err = snd_pcm_open(&pcm, WInDev[This->wDevID].pcmname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); if (err < 0) goto err; err = snd_pcm_hw_params_any(pcm, hw_params); if (err < 0) goto err; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 3cfc6061b50..9e0cf4f70ca 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -7356,10 +7356,17 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE pPresentationParameters->hDeviceWindow != swapchain->presentParms.hDeviceWindow) { ERR("Cannot change the device window yet\n"); } - if(pPresentationParameters->EnableAutoDepthStencil != swapchain->presentParms.EnableAutoDepthStencil) { - ERR("What do do about a changed auto depth stencil parameter?\n"); + if (pPresentationParameters->EnableAutoDepthStencil && !This->auto_depth_stencil_buffer) { + WARN("Auto depth stencil enabled, but no auto depth stencil present, returning WINED3DERR_INVALIDCALL\n"); + return WINED3DERR_INVALIDCALL; } + /* Reset the depth stencil */ + if (pPresentationParameters->EnableAutoDepthStencil) + IWineD3DDevice_SetDepthStencilSurface(iface, This->auto_depth_stencil_buffer); + else + IWineD3DDevice_SetDepthStencilSurface(iface, NULL); + delete_opengl_contexts(iface, (IWineD3DSwapChain *) swapchain); if(pPresentationParameters->Windowed) { diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index e89dbf30398..f8159fd336a 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -3672,7 +3672,7 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF * * Basically we want (in homogeneous coordinates) z = z * 2 - 1. However, shaders are run * before the homogeneous divide, so we have to take the w into account: z = ((z / w) * 2 - 1) * w, - * which is the same as z = z / 2 - w. + * which is the same as z = z * 2 - w. */ shader_addline(buffer, "gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;\n"); diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 61ccab66d5c..358ad141d8b 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3905,16 +3905,6 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock divide by the Width/Height, so we need the half range(1.0) to translate by half a pixel. - Note that when rendering offscreen, we need to translate 1 pixel - (2/h in normalized device coordinates) down after doing the flip, - because of the way the viewport transformation works in OpenGL: - (-1,1) in normalized device coordinates corresponds to the upper - left corner of the upper left pixel in the viewport. (-1,-1) - corresponds to lower left corner of the lower left pixel in the - viewport. In other words, the upper left corner of the pixel - *below* the lower left pixel in the viewport. See also section - 2.11.1 "Controlling the Viewport" of the GL 2.1 spec. - The other fun is that d3d's output z range after the transformation is [0;1], but opengl's is [-1;1]. Since the z buffer is in range [0;1] for both, gl scales [-1;1] to [0;1]. This would mean that we end up in [0.5;1] and loose a lot @@ -3922,6 +3912,24 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock [0;1] to [-1;1], so when gl undoes that we utilize the full z range */ + /* + * Careful with the order of operations here, we're essentially working backwards: + * x = x + 1/w; + * y = (y - 1/h) * flip; + * z = z * 2 - 1; + * + * Becomes: + * glTranslatef(0.0, 0.0, -1.0); + * glScalef(1.0, 1.0, 2.0); + * + * glScalef(1.0, flip, 1.0); + * glTranslatef(1/w, -1/h, 0.0); + * + * This is equivalent to: + * glTranslatef(1/w, -flip/h, -1.0) + * glScalef(1.0, flip, 2.0); + */ + if (stateblock->wineD3DDevice->render_offscreen) { /* D3D texture coordinates are flipped compared to OpenGL ones, so * render everything upside down when rendering offscreen. */ @@ -4517,7 +4525,7 @@ static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, W */ if (useVertexShaderFunction) { device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0; - device->posFixup[3] = -1.0 / stateblock->viewport.Height; + device->posFixup[3] = -device->posFixup[1] / stateblock->viewport.Height; } } @@ -4649,7 +4657,7 @@ static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, W static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { stateblock->wineD3DDevice->posFixup[2] = 1.0 / stateblock->viewport.Width; - stateblock->wineD3DDevice->posFixup[3] = -1.0 / stateblock->viewport.Height; + stateblock->wineD3DDevice->posFixup[3] = -stateblock->wineD3DDevice->posFixup[1] / stateblock->viewport.Height; if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) { transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context); } diff --git a/dlls/winex11.drv/dib.c b/dlls/winex11.drv/dib.c index 461da16c414..f0179431e0e 100644 --- a/dlls/winex11.drv/dib.c +++ b/dlls/winex11.drv/dib.c @@ -3922,7 +3922,7 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, { X_PHYSBITMAP *physBitmap = X11DRV_get_phys_bitmap( hbitmap ); X11DRV_DIB_IMAGEBITS_DESCR descr; - BITMAP bitmap; + DIBSECTION ds; LONG width, height, tmpheight; INT result; @@ -3939,7 +3939,7 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, if (!lines || (startscan >= height)) return 0; - if (!GetObjectW( hbitmap, sizeof(bitmap), &bitmap )) return 0; + if (!GetObjectW( hbitmap, sizeof(ds), &ds )) return 0; if (startscan + lines > height) lines = height - startscan; @@ -3986,7 +3986,7 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, descr.ySrc = 0; descr.xDest = 0; descr.yDest = height - startscan - lines; - descr.width = bitmap.bmWidth; + descr.width = ds.dsBm.bmWidth; descr.height = lines; descr.useShm = FALSE; descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8; @@ -3998,27 +3998,27 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, * cheap - saves a round trip to the X server */ if (descr.compression == BI_RGB && coloruse == DIB_RGB_COLORS && - descr.infoBpp == bitmap.bmBitsPixel && + descr.infoBpp == ds.dsBm.bmBitsPixel && physBitmap->base && physBitmap->size < 65536) { - unsigned int srcwidthb = bitmap.bmWidthBytes; + unsigned int srcwidthb = ds.dsBm.bmWidthBytes; int dstwidthb = X11DRV_DIB_GetDIBWidthBytes( width, descr.infoBpp ); LPBYTE dbits = physBitmap->base, sbits = (LPBYTE)bits + (startscan * srcwidthb); int widthb; UINT y; TRACE("syncing compatible set bits to app bits\n"); - if ((tmpheight < 0) ^ (bitmap.bmHeight < 0)) + if ((tmpheight < 0) ^ (ds.dsBmih.biHeight < 0)) { dbits += dstwidthb * (lines-1); dstwidthb = -dstwidthb; } - X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READWRITE ); + X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READWRITE ); widthb = min(srcwidthb, abs(dstwidthb)); for (y = 0; y < lines; y++, dbits += dstwidthb, sbits += srcwidthb) memcpy(dbits, sbits, widthb); - X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READONLY ); - physBitmap->status = DIB_Status_InSync; + X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READONLY ); + physBitmap->status = DIB_Status_InSync; } X11DRV_DIB_Unlock( physBitmap, TRUE ); diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index e431786a985..32befa4a746 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -1354,29 +1354,6 @@ static void X11DRV_ClientMessage( HWND hwnd, XEvent *xev ) } -/********************************************************************** - * X11DRV_WindowMessage (X11DRV.@) - */ -LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) -{ - switch(msg) - { - case WM_X11DRV_ACQUIRE_SELECTION: - return X11DRV_AcquireClipboard( hwnd ); - case WM_X11DRV_DELETE_WINDOW: - return SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 ); - case WM_X11DRV_SET_WIN_FORMAT: - return X11DRV_set_win_format( hwnd, (XID)wp ); - case WM_X11DRV_RESIZE_DESKTOP: - X11DRV_resize_desktop( LOWORD(lp), HIWORD(lp) ); - return 0; - default: - FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp ); - return 0; - } -} - - /*********************************************************************** * X11DRV_SendInput (X11DRV.@) */ diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index d3dc16b0e6c..3aa97aa59e3 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -352,12 +352,24 @@ static void sync_window_style( Display *display, struct x11drv_win_data *data ) * * Update the X11 window region. */ -static void sync_window_region( Display *display, struct x11drv_win_data *data, HRGN hrgn ) +static void sync_window_region( Display *display, struct x11drv_win_data *data, HRGN win_region ) { #ifdef HAVE_LIBXSHAPE + HRGN hrgn = win_region; + if (!data->whole_window) return; data->shaped = FALSE; + if (hrgn == (HRGN)1) /* hack: win_region == 1 means retrieve region from server */ + { + if (!(hrgn = CreateRectRgn( 0, 0, 0, 0 ))) return; + if (GetWindowRgn( data->hwnd, hrgn ) == ERROR) + { + DeleteObject( hrgn ); + hrgn = 0; + } + } + if (!hrgn) { wine_tsx11_lock(); @@ -380,6 +392,7 @@ static void sync_window_region( Display *display, struct x11drv_win_data *data, data->shaped = TRUE; } } + if (hrgn && hrgn != win_region) DeleteObject( hrgn ); #endif /* HAVE_LIBXSHAPE */ } @@ -428,9 +441,9 @@ static void sync_window_text( Display *display, Window win, const WCHAR *text ) /*********************************************************************** - * X11DRV_set_win_format + * set_win_format */ -BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id ) +static BOOL set_win_format( HWND hwnd, XID fbconfig_id ) { struct x11drv_win_data *data; XVisualInfo *vis; @@ -1343,7 +1356,6 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat int cx, cy, mask; XSetWindowAttributes attr; WCHAR text[1024]; - HRGN hrgn; if (!(cx = data->window_rect.right - data->window_rect.left)) cx = 1; if (!(cy = data->window_rect.bottom - data->window_rect.top)) cy = 1; @@ -1391,11 +1403,8 @@ static Window create_whole_window( Display *display, struct x11drv_win_data *dat sync_window_text( display, data->whole_window, text ); /* set the window region */ - if ((hrgn = CreateRectRgn( 0, 0, 0, 0 ))) - { - if (GetWindowRgn( data->hwnd, hrgn ) != ERROR) sync_window_region( display, data, hrgn ); - DeleteObject( hrgn ); - } + sync_window_region( display, data, (HRGN)1 ); + wine_tsx11_lock(); XFlush( display ); /* make sure the window exists before we start painting to it */ wine_tsx11_unlock(); @@ -2158,17 +2167,42 @@ int X11DRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ) { sync_window_region( thread_display(), data, hrgn ); } - else if (GetWindowThreadProcessId( hwnd, NULL ) != GetCurrentThreadId()) + else if (X11DRV_get_whole_window( hwnd )) { - FIXME( "not supported on other thread window %p\n", hwnd ); - SetLastError( ERROR_INVALID_WINDOW_HANDLE ); - return FALSE; + SendMessageW( hwnd, WM_X11DRV_SET_WIN_REGION, 0, 0 ); } - return TRUE; } +/********************************************************************** + * X11DRV_WindowMessage (X11DRV.@) + */ +LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) +{ + struct x11drv_win_data *data; + + switch(msg) + { + case WM_X11DRV_ACQUIRE_SELECTION: + return X11DRV_AcquireClipboard( hwnd ); + case WM_X11DRV_DELETE_WINDOW: + return SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 ); + case WM_X11DRV_SET_WIN_FORMAT: + return set_win_format( hwnd, (XID)wp ); + case WM_X11DRV_SET_WIN_REGION: + if ((data = X11DRV_get_win_data( hwnd ))) sync_window_region( thread_display(), data, (HRGN)1 ); + return 0; + case WM_X11DRV_RESIZE_DESKTOP: + X11DRV_resize_desktop( LOWORD(lp), HIWORD(lp) ); + return 0; + default: + FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp ); + return 0; + } +} + + /*********************************************************************** * is_netwm_supported */ diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 8f5c828dcff..7ed91b395cc 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -668,6 +668,7 @@ enum x11drv_window_messages WM_X11DRV_ACQUIRE_SELECTION = 0x80001000, WM_X11DRV_DELETE_WINDOW, WM_X11DRV_SET_WIN_FORMAT, + WM_X11DRV_SET_WIN_REGION, WM_X11DRV_RESIZE_DESKTOP }; @@ -715,7 +716,6 @@ extern struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd ); extern Window X11DRV_get_whole_window( HWND hwnd ); extern Window X11DRV_get_client_window( HWND hwnd ); extern XIC X11DRV_get_ic( HWND hwnd ); -extern BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig ); extern int pixelformat_from_fbconfig_id( XID fbconfig_id ); extern XVisualInfo *visual_from_fbconfig_id( XID fbconfig_id ); diff --git a/dlls/winhttp/Makefile.in b/dlls/winhttp/Makefile.in index 287ee4d9717..5617a1dc80d 100644 --- a/dlls/winhttp/Makefile.in +++ b/dlls/winhttp/Makefile.in @@ -14,6 +14,9 @@ C_SRCS = \ request.c \ session.c +RC_SRCS = \ + version.rc + @MAKE_DLL_RULES@ @DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index 1abfbdd723f..450366be4b0 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -464,11 +464,7 @@ BOOL netconn_query_data_available( netconn_t *conn, DWORD *available ) return TRUE; } #ifdef FIONREAD - if (!(ret = ioctl( conn->socket, FIONREAD, &unread ))) - { - TRACE("%d bytes of queued, but unread data\n", unread); - *available += unread; - } + if (!(ret = ioctl( conn->socket, FIONREAD, &unread ))) *available = unread; #endif return TRUE; } diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index d1fc0059c1c..f377087ade7 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -619,7 +619,7 @@ static BOOL query_headers( request_t *request, DWORD level, LPCWSTR name, LPVOID } default: { - if (attr > sizeof(attribute_table)/sizeof(attribute_table[0]) || !attribute_table[attr]) + if (attr >= sizeof(attribute_table)/sizeof(attribute_table[0]) || !attribute_table[attr]) { FIXME("attribute %u not implemented\n", attr); return FALSE; @@ -1132,16 +1132,120 @@ static BOOL receive_data( request_t *request, void *buffer, DWORD size, DWORD *r return TRUE; } +static DWORD get_chunk_size( const char *buffer ) +{ + const char *p; + DWORD size = 0; + + for (p = buffer; *p; p++) + { + if (*p >= '0' && *p <= '9') size = size * 16 + *p - '0'; + else if (*p >= 'a' && *p <= 'f') size = size * 16 + *p - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') size = size * 16 + *p - 'A' + 10; + else if (*p == ';') break; + } + return size; +} + +static BOOL receive_data_chunked( request_t *request, void *buffer, DWORD size, DWORD *read, BOOL async ) +{ + char reply[MAX_REPLY_LEN], *p = buffer; + DWORD buflen, to_read, to_write = size; + int bytes_read; + + *read = 0; + for (;;) + { + if (*read == size) break; + + if (request->content_length == ~0UL) /* new chunk */ + { + buflen = sizeof(reply); + if (!netconn_get_next_line( &request->netconn, reply, &buflen )) break; + + if (!(request->content_length = get_chunk_size( reply ))) + { + /* zero sized chunk marks end of transfer; read any trailing headers and return */ + read_reply( request, FALSE ); + break; + } + } + to_read = min( to_write, request->content_length - request->content_read ); + + if (!netconn_recv( &request->netconn, p, to_read, async ? 0 : MSG_WAITALL, &bytes_read )) + { + if (bytes_read != to_read) + { + ERR("Not all data received %d/%d\n", bytes_read, to_read); + } + /* always return success, even if the network layer returns an error */ + *read = 0; + break; + } + if (!bytes_read) break; + + request->content_read += bytes_read; + to_write -= bytes_read; + *read += bytes_read; + p += bytes_read; + + if (request->content_read == request->content_length) /* chunk complete */ + { + request->content_read = 0; + request->content_length = ~0UL; + + buflen = sizeof(reply); + if (!netconn_get_next_line( &request->netconn, reply, &buflen )) + { + ERR("Malformed chunk\n"); + *read = 0; + break; + } + } + } + return TRUE; +} + +static BOOL read_data( request_t *request, void *buffer, DWORD to_read, DWORD *read, BOOL async ) +{ + static const WCHAR chunked[] = {'c','h','u','n','k','e','d',0}; + + BOOL ret; + WCHAR encoding[20]; + DWORD num_bytes, buflen = sizeof(encoding); + + if (query_headers( request, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, encoding, &buflen, NULL ) && + !strcmpiW( encoding, chunked )) + { + ret = receive_data_chunked( request, buffer, to_read, &num_bytes, async ); + } + else + ret = receive_data( request, buffer, to_read, &num_bytes, async ); + + if (async) + { + if (ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_READ_COMPLETE, buffer, num_bytes ); + else + { + WINHTTP_ASYNC_RESULT result; + result.dwResult = API_READ_DATA; + result.dwError = get_last_error(); + send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, &result, sizeof(result) ); + } + } + if (ret && read) *read = num_bytes; + return ret; +} + /* read any content returned by the server so that the connection can be reused */ static void drain_content( request_t *request ) { DWORD bytes_read; char buffer[2048]; - if (request->content_length == ~0UL) return; for (;;) { - if (!receive_data( request, buffer, sizeof(buffer), &bytes_read, FALSE ) || !bytes_read) return; + if (!read_data( request, buffer, sizeof(buffer), &bytes_read, FALSE ) || !bytes_read) return; } } @@ -1163,14 +1267,16 @@ static BOOL receive_response( request_t *request, BOOL async ) if (!query_headers( request, query, NULL, &request->content_length, &size, NULL )) request->content_length = ~0UL; - if (status == 200) break; if (status == 301 || status == 302) { if (request->hdr.disable_flags & WINHTTP_DISABLE_REDIRECTS) break; drain_content( request ); if (!(ret = handle_redirect( request ))) break; + ret = send_request( request, NULL, 0, NULL, 0, 0, 0, FALSE ); /* recurse synchronously */ + continue; } - ret = send_request( request, NULL, 0, NULL, 0, 0, 0, FALSE ); /* recurse synchronously */ + if (status == 401) FIXME("authentication not supported\n"); + break; } if (async) @@ -1238,7 +1344,26 @@ static BOOL query_data( request_t *request, LPDWORD available, BOOL async ) BOOL ret; DWORD num_bytes; - ret = netconn_query_data_available( &request->netconn, &num_bytes ); + if ((ret = netconn_query_data_available( &request->netconn, &num_bytes ))) + { + if (request->content_read < request->content_length) + { + if (!num_bytes) + { + char buffer[4096]; + size_t to_read = min( sizeof(buffer), request->content_length - request->content_read ); + + ret = netconn_recv( &request->netconn, buffer, to_read, MSG_PEEK, (int *)&num_bytes ); + if (ret && !num_bytes) WARN("expected more data to be available\n"); + } + } + else if (num_bytes) + { + WARN("extra data available %u\n", num_bytes); + ret = FALSE; + } + } + TRACE("%u bytes available\n", num_bytes); if (async) { @@ -1302,111 +1427,6 @@ BOOL WINAPI WinHttpQueryDataAvailable( HINTERNET hrequest, LPDWORD available ) return ret; } -static DWORD get_chunk_size( const char *buffer ) -{ - const char *p; - DWORD size = 0; - - for (p = buffer; *p; p++) - { - if (*p >= '0' && *p <= '9') size = size * 16 + *p - '0'; - else if (*p >= 'a' && *p <= 'f') size = size * 16 + *p - 'a' + 10; - else if (*p >= 'A' && *p <= 'F') size = size * 16 + *p - 'A' + 10; - else if (*p == ';') break; - } - return size; -} - -static BOOL receive_data_chunked( request_t *request, void *buffer, DWORD size, DWORD *read, BOOL async ) -{ - char reply[MAX_REPLY_LEN], *p = buffer; - DWORD buflen, to_read, to_write = size; - int bytes_read; - - *read = 0; - for (;;) - { - if (*read == size) break; - - if (request->content_length == ~0UL) /* new chunk */ - { - buflen = sizeof(reply); - if (!netconn_get_next_line( &request->netconn, reply, &buflen )) break; - - if (!(request->content_length = get_chunk_size( reply ))) - { - /* zero sized chunk marks end of transfer; read any trailing headers and return */ - read_reply( request, FALSE ); - break; - } - } - to_read = min( to_write, request->content_length - request->content_read ); - - if (!netconn_recv( &request->netconn, p, to_read, async ? 0 : MSG_WAITALL, &bytes_read )) - { - if (bytes_read != to_read) - { - ERR("Not all data received %d/%d\n", bytes_read, to_read); - } - /* always return success, even if the network layer returns an error */ - *read = 0; - break; - } - if (!bytes_read) break; - - request->content_read += bytes_read; - to_write -= bytes_read; - *read += bytes_read; - p += bytes_read; - - if (request->content_read == request->content_length) /* chunk complete */ - { - request->content_read = 0; - request->content_length = ~0UL; - - buflen = sizeof(reply); - if (!netconn_get_next_line( &request->netconn, reply, &buflen )) - { - ERR("Malformed chunk\n"); - *read = 0; - break; - } - } - } - return TRUE; -} - -static BOOL read_data( request_t *request, void *buffer, DWORD to_read, DWORD *read, BOOL async ) -{ - static const WCHAR chunked[] = {'c','h','u','n','k','e','d',0}; - - BOOL ret; - WCHAR encoding[20]; - DWORD num_bytes, buflen = sizeof(encoding); - - if (query_headers( request, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, encoding, &buflen, NULL ) && - !strcmpiW( encoding, chunked )) - { - ret = receive_data_chunked( request, buffer, to_read, &num_bytes, async ); - } - else - ret = receive_data( request, buffer, to_read, &num_bytes, async ); - - if (async) - { - if (ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_READ_COMPLETE, buffer, num_bytes ); - else - { - WINHTTP_ASYNC_RESULT result; - result.dwResult = API_READ_DATA; - result.dwError = get_last_error(); - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, &result, sizeof(result) ); - } - } - if (ret && read) *read = num_bytes; - return ret; -} - static void task_read_data( task_header_t *task ) { read_data_t *r = (read_data_t *)task; diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index 4e2289640bb..927c34708a8 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -271,7 +271,7 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf request_t *request = (request_t *)hdr; if (!(cert = netconn_get_certificate( &request->netconn ))) return FALSE; - memcpy( buffer, cert, sizeof(CERT_CONTEXT) ); + *(CERT_CONTEXT **)buffer = (CERT_CONTEXT *)cert; *buflen = sizeof(cert); return TRUE; } diff --git a/dlls/winhttp/tests/notification.c b/dlls/winhttp/tests/notification.c index 784e35082a4..64adaeac188 100644 --- a/dlls/winhttp/tests/notification.c +++ b/dlls/winhttp/tests/notification.c @@ -54,10 +54,12 @@ struct info unsigned int count; unsigned int index; HANDLE wait; + unsigned int line; }; static void CALLBACK check_notification( HINTERNET handle, DWORD_PTR context, DWORD status, LPVOID buffer, DWORD buflen ) { + BOOL status_ok, function_ok; struct info *info = (struct info *)context; unsigned int i = info->index; @@ -68,20 +70,23 @@ static void CALLBACK check_notification( HINTERNET handle, DWORD_PTR context, DW } ok(i < info->count, "unexpected notification 0x%08x\n", status); if (i >= info->count) return; + + status_ok = (info->test[i].status == status); + function_ok = (info->test[i].function == info->function); if (!info->test[i].todo) { - ok(info->test[i].status == status, "expected status 0x%08x got 0x%08x\n", info->test[i].status, status); - ok(info->test[i].function == info->function, "expected function %u got %u\n", info->test[i].function, info->function); + ok(status_ok, "%u: expected status 0x%08x got 0x%08x\n", info->line, info->test[i].status, status); + ok(function_ok, "%u: expected function %u got %u\n", info->line, info->test[i].function, info->function); } else { - todo_wine ok(info->test[i].status == status, "expected status 0x%08x got 0x%08x\n", info->test[i].status, status); - if (info->test[i].status == status) + todo_wine ok(status_ok, "%u: expected status 0x%08x got 0x%08x\n", info->line, info->test[i].status, status); + if (status_ok) { - todo_wine ok(info->test[i].function == info->function, "expected function %u got %u\n", info->test[i].function, info->function); + todo_wine ok(function_ok, "%u: expected function %u got %u\n", info->line, info->test[i].function, info->function); } } - if (info->test[i].status == status) info->index++; + if (status_ok) info->index++; if (status & WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS) SetEvent( info->wait ); } @@ -104,6 +109,12 @@ static const struct notification cache_test[] = { winhttp_close_handle, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, 1 } }; +static void setup_test( struct info *info, enum api function, unsigned int line ) +{ + info->function = function; + info->line = line; +} + static void test_connection_cache( void ) { static const WCHAR codeweavers[] = {'w','w','w','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0}; @@ -126,19 +137,19 @@ static void test_connection_cache( void ) ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); - info.function = winhttp_connect; + setup_test( &info, winhttp_connect, __LINE__ ); con = WinHttpConnect( ses, codeweavers, 0, 0 ); ok(con != NULL, "failed to open a connection %u\n", GetLastError()); - info.function = winhttp_open_request; + setup_test( &info, winhttp_open_request, __LINE__ ); req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); ok(req != NULL, "failed to open a request %u\n", GetLastError()); - info.function = winhttp_send_request; + setup_test( &info, winhttp_send_request, __LINE__ ); ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); ok(ret, "failed to send request %u\n", GetLastError()); - info.function = winhttp_receive_response; + setup_test( &info, winhttp_receive_response, __LINE__ ); ret = WinHttpReceiveResponse( req, NULL ); ok(ret, "failed to receive response %u\n", GetLastError()); @@ -147,12 +158,12 @@ static void test_connection_cache( void ) ok(ret, "failed unexpectedly %u\n", GetLastError()); ok(status == 200, "request failed unexpectedly %u\n", status); - info.function = winhttp_close_handle; + setup_test( &info, winhttp_close_handle, __LINE__ ); WinHttpCloseHandle( req ); WinHttpCloseHandle( con ); WinHttpCloseHandle( ses ); - Sleep(1500); /* make sure connection is evicted from cache */ + Sleep(2000); /* make sure connection is evicted from cache */ info.index = 0; @@ -164,22 +175,22 @@ static void test_connection_cache( void ) ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); - info.function = winhttp_connect; + setup_test( &info, winhttp_connect, __LINE__ ); con = WinHttpConnect( ses, codeweavers, 0, 0 ); ok(con != NULL, "failed to open a connection %u\n", GetLastError()); - info.function = winhttp_open_request; + setup_test( &info, winhttp_open_request, __LINE__ ); req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); ok(req != NULL, "failed to open a request %u\n", GetLastError()); ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); - info.function = winhttp_send_request; + setup_test( &info, winhttp_send_request, __LINE__ ); ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); ok(ret, "failed to send request %u\n", GetLastError()); - info.function = winhttp_receive_response; + setup_test( &info, winhttp_receive_response, __LINE__ ); ret = WinHttpReceiveResponse( req, NULL ); ok(ret, "failed to receive response %u\n", GetLastError()); @@ -188,7 +199,7 @@ static void test_connection_cache( void ) ok(ret, "failed unexpectedly %u\n", GetLastError()); ok(status == 200, "request failed unexpectedly %u\n", status); - info.function = winhttp_close_handle; + setup_test( &info, winhttp_close_handle, __LINE__ ); WinHttpCloseHandle( req ); WinHttpCloseHandle( con ); WinHttpCloseHandle( ses ); @@ -244,18 +255,18 @@ static void test_redirect( void ) ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); - info.function = winhttp_connect; + setup_test( &info, winhttp_connect, __LINE__ ); con = WinHttpConnect( ses, codeweavers, 0, 0 ); ok(con != NULL, "failed to open a connection %u\n", GetLastError()); - info.function = winhttp_open_request; + setup_test( &info, winhttp_open_request, __LINE__ ); req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); ok(req != NULL, "failed to open a request %u\n", GetLastError()); - info.function = winhttp_send_request; + setup_test( &info, winhttp_send_request, __LINE__ ); ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); - info.function = winhttp_receive_response; + setup_test( &info, winhttp_receive_response, __LINE__ ); ret = WinHttpReceiveResponse( req, NULL ); ok(ret, "failed to receive response %u\n", GetLastError()); @@ -264,7 +275,7 @@ static void test_redirect( void ) ok(ret, "failed unexpectedly %u\n", GetLastError()); ok(status == 200, "request failed unexpectedly %u\n", status); - info.function = winhttp_close_handle; + setup_test( &info, winhttp_close_handle, __LINE__ ); WinHttpCloseHandle( req ); WinHttpCloseHandle( con ); WinHttpCloseHandle( ses ); @@ -327,21 +338,21 @@ static void test_async( void ) ret = WinHttpSetOption( ses, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) ); ok(ret, "failed to set context value %u\n", GetLastError()); - info.function = winhttp_connect; + setup_test( &info, winhttp_connect, __LINE__ ); con = WinHttpConnect( ses, codeweavers, 0, 0 ); ok(con != NULL, "failed to open a connection %u\n", GetLastError()); - info.function = winhttp_open_request; + setup_test( &info, winhttp_open_request, __LINE__ ); req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); ok(req != NULL, "failed to open a request %u\n", GetLastError()); - info.function = winhttp_send_request; + setup_test( &info, winhttp_send_request, __LINE__ ); ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); ok(ret, "failed to send request %u\n", GetLastError()); WaitForSingleObject( info.wait, INFINITE ); - info.function = winhttp_receive_response; + setup_test( &info, winhttp_receive_response, __LINE__ ); ret = WinHttpReceiveResponse( req, NULL ); ok(ret, "failed to receive response %u\n", GetLastError()); @@ -352,19 +363,19 @@ static void test_async( void ) ok(ret, "failed unexpectedly %u\n", GetLastError()); ok(status == 200, "request failed unexpectedly %u\n", status); - info.function = winhttp_query_data; + setup_test( &info, winhttp_query_data, __LINE__ ); ret = WinHttpQueryDataAvailable( req, NULL ); ok(ret, "failed to query data available %u\n", GetLastError()); WaitForSingleObject( info.wait, INFINITE ); - info.function = winhttp_read_data; + setup_test( &info, winhttp_read_data, __LINE__ ); ret = WinHttpReadData( req, buffer, sizeof(buffer), NULL ); ok(ret, "failed to query data available %u\n", GetLastError()); WaitForSingleObject( info.wait, INFINITE ); - info.function = winhttp_close_handle; + setup_test( &info, winhttp_close_handle, __LINE__ ); WinHttpCloseHandle( req ); WinHttpCloseHandle( con ); WinHttpCloseHandle( ses ); @@ -375,6 +386,6 @@ START_TEST (notification) { test_connection_cache(); test_redirect(); - Sleep(1500); /* make sure previous connection is evicted from cache */ + Sleep(2000); /* make sure previous connection is evicted from cache */ test_async(); } diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index 71e4efa788c..79148053309 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "wine/test.h" @@ -556,8 +557,9 @@ static void test_secure_connection(void) static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0}; HANDLE ses, con, req; - DWORD size, status, policy; + DWORD size, status, policy, bitness; BOOL ret; + CERT_CONTEXT *cert; ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); ok(ses != NULL, "failed to open session %u\n", GetLastError()); @@ -591,6 +593,14 @@ static void test_secure_connection(void) ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); ok(ret, "failed to send request %u\n", GetLastError()); + size = sizeof(cert); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size ); + ok(ret, "failed to retrieve certificate context %u\n", GetLastError()); + + size = sizeof(bitness); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size ); + ok(ret, "failed to retrieve key bitness %u\n", GetLastError()); + ret = WinHttpReceiveResponse(req, NULL); ok(ret, "failed to receive response %u\n", GetLastError()); diff --git a/programs/regedit/regproc.h b/dlls/winhttp/version.rc similarity index 66% copy from programs/regedit/regproc.h copy to dlls/winhttp/version.rc index 7122379307a..3dca59ff3a9 100644 --- a/programs/regedit/regproc.h +++ b/dlls/winhttp/version.rc @@ -1,6 +1,5 @@ /* - * Copyright 1999 Sylvain St-Germain - * Copyright 2002 Andriy Palamarchuk + * Copyright 2008 Robert Shearman * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,12 +16,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#define KEY_MAX_LEN 1024 +#define WINE_FILEDESCRIPTION_STR "Wine HTTP Library" +#define WINE_FILENAME_STR "winhttp.dll" +#define WINE_FILEVERSION_MAJOR 5 +#define WINE_FILEVERSION_MINOR 1 +#define WINE_FILEVERSION_BUILD 2600 +#define WINE_FILEVERSION_PLATFORMID 2180 -const CHAR *getAppName(void); - -BOOL export_registry_key(CHAR *file_name, CHAR *reg_key_name); -BOOL import_registry_file(FILE *in); -void delete_registry_key(WCHAR *reg_key_name); -WCHAR* GetWideString(const char* strA); -CHAR* GetMultiByteString(const WCHAR* strW); +#include "wine/wine_common_ver.rc" diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 69d678c8fa8..f95f8bd401a 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2345,6 +2345,12 @@ int WINAPI WS_ioctlsocket(SOCKET s, LONG cmd, WS_u_long *argp) long newcmd = cmd; TRACE("socket %04lx, cmd %08x, ptr %p\n", s, cmd, argp); + /* broken apps like defcon pass the argp value directly instead of a pointer to it */ + if(IS_INTRESOURCE(argp)) + { + SetLastError(WSAEFAULT); + return SOCKET_ERROR; + } switch( cmd ) { diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 5883078a978..0643d00cff4 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -3,6 +3,7 @@ * * Copyright 2002 Martin Wilck * Copyright 2005 Thomas Kho + * Copyright 2008 Jeff Zaroyko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1012,13 +1013,14 @@ static void test_so_reuseaddr(void) rc = setsockopt(s2, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse)); ok(rc==0, "setsockopt() failed error: %d\n", WSAGetLastError()); - todo_wine { + /* On Win2k3 and above, all SO_REUSEADDR seems to do is to allow binding to + * a port immediately after closing another socket on that port, so + * basically following the BSD socket semantics here. */ + closesocket(s1); rc = bind(s2, (struct sockaddr*)&saddr, sizeof(saddr)); ok(rc==0, "bind() failed error: %d\n", WSAGetLastError()); - } closesocket(s2); - closesocket(s1); } /************* Array containing the tests to run **********/ @@ -1989,6 +1991,31 @@ static void test_inet_addr(void) ok(addr == INADDR_NONE, "inet_addr succeeded unexpectedly\n"); } +static void test_ioctlsocket(void) +{ + SOCKET sock; + int ret; + long cmds[] = {FIONBIO, FIONREAD, SIOCATMARK}; + int i; + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + ok(sock != INVALID_SOCKET, "Creating the socket failed: %d\n", WSAGetLastError()); + if(sock == INVALID_SOCKET) + { + skip("Can't continue without a socket.\n"); + return; + } + + for(i = 0; i < sizeof(cmds)/sizeof(long); i++) + { + /* broken apps like defcon pass the argp value directly instead of a pointer to it */ + ret = ioctlsocket(sock, cmds[i], (u_long *)1); + ok(ret == SOCKET_ERROR, "ioctlsocket succeeded unexpectedly\n"); + ret = WSAGetLastError(); + ok(ret == WSAEFAULT, "expected WSAEFAULT, got %d instead\n", ret); + } +} + static DWORD WINAPI drain_socket_thread(LPVOID arg) { char buffer[1024]; @@ -2187,8 +2214,7 @@ static void test_write_events(void) } end: - if (buffer != NULL) - HeapFree(GetProcessHeap(), 0, buffer); + HeapFree(GetProcessHeap(), 0, buffer); if (src != INVALID_SOCKET) closesocket(src); if (dst != INVALID_SOCKET) @@ -2305,6 +2331,7 @@ START_TEST( sock ) test_accept(); test_getsockname(); test_inet_addr(); + test_ioctlsocket(); test_dns(); test_gethostbyname_hack(); diff --git a/include/amstream.idl b/include/amstream.idl index 1433f7a5102..d1cdd4c7e00 100644 --- a/include/amstream.idl +++ b/include/amstream.idl @@ -64,7 +64,6 @@ typedef [v1_enum] enum { RenderData = 2 } OUTPUT_STATE; -/* [ object, uuid(7DB01C96-C0C3-11d0-8FF1-00C04FD9189D), @@ -81,7 +80,6 @@ interface IDirectShowStream : IDispatch [propget, id(3), helpstring("property Audio")] HRESULT Audio([out, retval] OUTPUT_STATE *pVal); [propput, id(3), helpstring("propetry Audio")] HRESULT Audio([in] OUTPUT_STATE newVal); }; -*/ [ object, @@ -93,7 +91,7 @@ interface IAMMultiMediaStream : IMultiMediaStream HRESULT Initialize( [in] STREAM_TYPE StreamType, [in] DWORD dwFlags, - [in, optional] IGraphBuilder *pFilterGraph); + [in] IGraphBuilder *pFilterGraph); HRESULT GetFilterGraph( [out] IGraphBuilder **ppGraphBuilder); @@ -102,10 +100,10 @@ interface IAMMultiMediaStream : IMultiMediaStream [out] IMediaStreamFilter **ppFilter); HRESULT AddMediaStream( - [in, optional] IUnknown *pStreamObject, - [in, optional] const MSPID *PurposeId, + [in] IUnknown *pStreamObject, + [in] const MSPID *PurposeId, [in] DWORD dwFlags, - [out, optional] IMediaStream **ppNewStream); + [out] IMediaStream **ppNewStream); HRESULT OpenFile( [in] LPCWSTR pszFileName, @@ -129,7 +127,7 @@ pointer_default(unique) interface IAMMediaStream : IMediaStream { HRESULT Initialize( - [in, optional] IUnknown *pSourceObject, + [in] IUnknown *pSourceObject, [in] DWORD dwFlags, [in] REFMSPID PurposeId, [in] const STREAM_TYPE StreamType); @@ -233,9 +231,9 @@ interface IAMMediaTypeStream : IMediaStream HRESULT CreateSample( [in] long lSampleSize, - [in, optional] BYTE * pbBuffer, + [in] BYTE * pbBuffer, [in] DWORD dwFlags, - [in, optional] IUnknown *pUnkOuter, + [in] IUnknown *pUnkOuter, [out] IAMMediaTypeSample ** ppAMMediaTypeSample); HRESULT GetStreamAllocatorRequirements( diff --git a/include/bits1_5.idl b/include/bits1_5.idl index 0bb27cac8f3..274a7de5121 100644 --- a/include/bits1_5.idl +++ b/include/bits1_5.idl @@ -30,7 +30,7 @@ import "bits.idl"; interface IBackgroundCopyJob2 : IBackgroundCopyJob { HRESULT SetNotifyCmdLine([unique] LPCWSTR prog, [unique] LPCWSTR params); - HRESULT GetNotifyCmdLine([out] LPWSTR prog, [out] LPWSTR params); + HRESULT GetNotifyCmdLine([out] LPWSTR *prog, [out] LPWSTR *params); typedef struct _BG_JOB_REPLY_PROGRESS { diff --git a/include/ddk/ntddk.h b/include/ddk/ntddk.h index cbc9cfad7f2..3ad2156f363 100644 --- a/include/ddk/ntddk.h +++ b/include/ddk/ntddk.h @@ -46,6 +46,21 @@ typedef enum _BUS_DATA_TYPE MaximumBusDataType } BUS_DATA_TYPE, *PBUS_DATA_TYPE; +typedef struct _CONFIGURATION_INFORMATION +{ + ULONG DiskCount; + ULONG FloppyCount; + ULONG CdRomCount; + ULONG TapeCount; + ULONG ScsiPortCount; + ULONG SerialCount; + ULONG ParallelCount; + BOOLEAN AtDiskPrimaryAddressClaimed; + BOOLEAN AtDiskSecondaryAddressClaimed; + ULONG Version; + ULONG MediumChangerCount; +} CONFIGURATION_INFORMATION, *PCONFIGURATION_INFORMATION; + typedef VOID (WINAPI *PDRIVER_REINITIALIZE)(PDRIVER_OBJECT,PVOID,ULONG); void WINAPI IoRegisterDriverReinitialization(PDRIVER_OBJECT,PDRIVER_REINITIALIZE,PVOID); diff --git a/include/ddstream.idl b/include/ddstream.idl index 644401559ac..947e2bcde4f 100644 --- a/include/ddstream.idl +++ b/include/ddstream.idl @@ -44,14 +44,14 @@ pointer_default(unique) interface IDirectDrawMediaStream : IMediaStream { HRESULT GetFormat( - [out, optional] DDSURFACEDESC *pDDSDCurrent, - [out, optional] IDirectDrawPalette **ppDirectDrawPalette, - [out, optional] DDSURFACEDESC *pDDSDDesired, - [out, optional] DWORD *pdwFlags); + [out] DDSURFACEDESC *pDDSDCurrent, + [out] IDirectDrawPalette **ppDirectDrawPalette, + [out] DDSURFACEDESC *pDDSDDesired, + [out] DWORD *pdwFlags); HRESULT SetFormat( [in] const DDSURFACEDESC *pDDSurfaceDesc, - [in, optional] IDirectDrawPalette *pDirectDrawPalette); + [in] IDirectDrawPalette *pDirectDrawPalette); HRESULT GetDirectDraw( [out] IDirectDraw **ppDirectDraw); @@ -60,8 +60,8 @@ interface IDirectDrawMediaStream : IMediaStream [in] IDirectDraw *pDirectDraw); HRESULT CreateSample( - [in, optional] IDirectDrawSurface *pSurface, - [in, optional] const RECT *pRect, + [in] IDirectDrawSurface *pSurface, + [in] const RECT *pRect, [in] DWORD dwFlags, [out] IDirectDrawStreamSample **ppSample); @@ -79,8 +79,8 @@ pointer_default(unique) interface IDirectDrawStreamSample : IStreamSample { HRESULT GetSurface( - [out, optional] IDirectDrawSurface ** ppDirectDrawSurface, - [out, optional] RECT * pRect); + [out] IDirectDrawSurface ** ppDirectDrawSurface, + [out] RECT * pRect); HRESULT SetRect( [in] const RECT * pRect); diff --git a/include/msinkaut.idl b/include/msinkaut.idl index 607229d8c50..12dc1076ca1 100644 --- a/include/msinkaut.idl +++ b/include/msinkaut.idl @@ -637,8 +637,8 @@ cpp_quote("#endif /* _WINGDI_ */") HRESULT NearestPoint( [in] long X, [in] long Y, - [in, out] float PointOnStroke, - [in, out] float DistanceFromPacket, + [in, out] float *PointOnStroke, + [in, out] float *DistanceFromPacket, [out, retval] IInkStrokeDisp **Stroke); HRESULT CreateStrokes( [in] VARIANT StrokeIds, diff --git a/include/msxml2.idl b/include/msxml2.idl index ab10f1407f1..eae84c4db36 100644 --- a/include/msxml2.idl +++ b/include/msxml2.idl @@ -1736,40 +1736,40 @@ interface IVBSAXXMLReader : IDispatch HRESULT putProperty( [in] const WCHAR * pProp, [in] VARIANT value); [propget, id(DISPID_SAX_XMLREADER_ENTITYRESOLVER)] - HRESULT getEntityResolver( + HRESULT entityResolver( [out, retval] IVBSAXEntityResolver ** ppEntityResolver); [propputref, id(DISPID_SAX_XMLREADER_ENTITYRESOLVER)] - HRESULT putEntityResolver( [in] IVBSAXEntityResolver * pEntityResolver); + HRESULT entityResolver( [in] IVBSAXEntityResolver * pEntityResolver); [propget, id(DISPID_SAX_XMLREADER_CONTENTHANDLER)] - HRESULT getContentHandler( + HRESULT contentHandler( [out, retval] IVBSAXContentHandler ** pContentHandler); [propputref, id(DISPID_SAX_XMLREADER_CONTENTHANDLER)] - HRESULT putContentHandler([in] IVBSAXContentHandler * contentHandler); + HRESULT contentHandler([in] IVBSAXContentHandler * contentHandler); [propget, id(DISPID_SAX_XMLREADER_DTDHANDLER)] - HRESULT getDTDHandler([out, retval] IVBSAXDTDHandler ** pDTDHandler); + HRESULT dtdHandler([out, retval] IVBSAXDTDHandler ** pDTDHandler); [propputref, id(DISPID_SAX_XMLREADER_DTDHANDLER)] - HRESULT putDTDHandler([in] IVBSAXDTDHandler * pDTDHandler); + HRESULT dtdHandler([in] IVBSAXDTDHandler * pDTDHandler); [propget, id(DISPID_SAX_XMLREADER_ERRORHANDLER)] - HRESULT getErrorHandler([out, retval] IVBSAXErrorHandler ** pErrorHandler); + HRESULT errorHandler([out, retval] IVBSAXErrorHandler ** pErrorHandler); [propputref, id(DISPID_SAX_XMLREADER_ERRORHANDLER)] - HRESULT putErrorHandler([in] IVBSAXErrorHandler * errorHandler); + HRESULT errorHandler([in] IVBSAXErrorHandler * errorHandler); [propget, id(DISPID_SAX_XMLREADER_BASEURL)] - HRESULT getBaseURL([out, retval] const WCHAR ** pBaseUrl); + HRESULT baseURL([out, retval] const WCHAR ** pBaseUrl); [propput, id(DISPID_SAX_XMLREADER_BASEURL)] - HRESULT putBaseURL([in] const WCHAR * pBaseUrl); + HRESULT baseURL([in] const WCHAR * pBaseUrl); [propget, id(DISPID_SAX_XMLREADER_SECUREBASEURL)] - HRESULT getSecureBaseURL([out, retval] const WCHAR ** pSecureBaseUrl); + HRESULT secureBaseURL([out, retval] const WCHAR ** pSecureBaseUrl); [propput, id(DISPID_SAX_XMLREADER_SECUREBASEURL)] - HRESULT putSecureBaseURL([in] const WCHAR * secureBaseUrl); + HRESULT secureBaseURL([in] const WCHAR * secureBaseUrl); - [propget, id(DISPID_SAX_XMLREADER_PARSE)] + [id(DISPID_SAX_XMLREADER_PARSE)] HRESULT parse( [in] VARIANT varInput); - [propput, id(DISPID_SAX_XMLREADER_PARSE)] + [id(DISPID_SAX_XMLREADER_PARSEURL)] HRESULT parseURL([in] const WCHAR * url); } diff --git a/include/rpcndr.h b/include/rpcndr.h index 2503a3adbed..38f3c5fd0c2 100644 --- a/include/rpcndr.h +++ b/include/rpcndr.h @@ -189,7 +189,7 @@ typedef struct _MIDL_STUB_MESSAGE ULONG_PTR MaxCount; ULONG Offset; ULONG ActualCount; - void * (__RPC_API *pfnAllocate)(size_t); + void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(size_t); void (__RPC_API *pfnFree)(void *); unsigned char *StackTop; unsigned char *pPresentedType; @@ -316,7 +316,7 @@ typedef struct _USER_MARSHAL_CB typedef struct _MALLOC_FREE_STRUCT { - void * (__RPC_USER *pfnAllocate)(size_t); + void * (__WINE_ALLOC_SIZE(1) __RPC_USER *pfnAllocate)(size_t); void (__RPC_USER *pfnFree)(void *); } MALLOC_FREE_STRUCT; @@ -329,7 +329,7 @@ typedef struct _COMM_FAULT_OFFSETS typedef struct _MIDL_STUB_DESC { void *RpcInterfaceInformation; - void * (__RPC_API *pfnAllocate)(size_t); + void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(size_t); void (__RPC_API *pfnFree)(void *); union { handle_t *pAutoHandle; @@ -468,7 +468,7 @@ typedef struct _NDR_USER_MARSHAL_INFO_LEVEL1 { void *Buffer; ULONG BufferSize; - void * (__RPC_API *pfnAllocate)(size_t); + void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(size_t); void (__RPC_API *pfnFree)(void *); struct IRpcChannelBuffer *pRpcChannelBuffer; ULONG_PTR Reserved[5]; @@ -662,7 +662,7 @@ RPCRTAPI RPC_STATUS RPC_ENTRY ULONG *pFaultStatus, RPC_STATUS Status_ ); RPCRTAPI void* RPC_ENTRY - NdrOleAllocate( size_t Size ); + NdrOleAllocate( size_t Size ) __WINE_ALLOC_SIZE(1); RPCRTAPI void RPC_ENTRY NdrOleFree( void* NodeToFree ); @@ -723,11 +723,11 @@ RPCRTAPI void RPC_ENTRY RPCRTAPI void RPC_ENTRY NdrRpcSmSetClientToOsf( PMIDL_STUB_MESSAGE pMessage ); RPCRTAPI void * RPC_ENTRY - NdrRpcSmClientAllocate( size_t Size ); + NdrRpcSmClientAllocate( size_t Size ) __WINE_ALLOC_SIZE(1); RPCRTAPI void RPC_ENTRY NdrRpcSmClientFree( void *NodeToFree ); RPCRTAPI void * RPC_ENTRY - NdrRpcSsDefaultAllocate( size_t Size ); + NdrRpcSsDefaultAllocate( size_t Size ) __WINE_ALLOC_SIZE(1); RPCRTAPI void RPC_ENTRY NdrRpcSsDefaultFree( void *NodeToFree ); diff --git a/include/shobjidl.idl b/include/shobjidl.idl index 23a1fdebb9a..7a4bd88e187 100644 --- a/include/shobjidl.idl +++ b/include/shobjidl.idl @@ -1248,7 +1248,8 @@ cpp_quote("#define INewShortcutHook WINELIB_NAME_AW(INewShortcutHook)") [ object, uuid(000214e1-0000-0000-c000-000000000046), - pointer_default(unique) + pointer_default(unique), + local ] interface INewShortcutHookA : IUnknown { @@ -1278,7 +1279,8 @@ interface INewShortcutHookA : IUnknown [ object, uuid(000214f7-0000-0000-c000-000000000046), - pointer_default(unique) + pointer_default(unique), + local ] interface INewShortcutHookW : IUnknown { @@ -1307,7 +1309,8 @@ interface INewShortcutHookW : IUnknown [ object, uuid(85788d00-6807-11d0-b810-00c04fd706ec), - pointer_default(unique) + pointer_default(unique), + local ] interface IRunnableTask : IUnknown { diff --git a/include/vmr9.idl b/include/vmr9.idl index b7f916c2dd7..bb3681cd22d 100644 --- a/include/vmr9.idl +++ b/include/vmr9.idl @@ -25,8 +25,8 @@ typedef LONGLONG REFERENCE_TIME; typedef DWORD D3DFORMAT; typedef DWORD D3DPOOL; typedef HANDLE HMONITOR; -typedef struct { } AM_MEDIA_TYPE; -typedef struct { } D3DCOLOR; +typedef struct { char dummy; } AM_MEDIA_TYPE; +typedef struct { char dummy; } D3DCOLOR; cpp_quote("#endif") interface IVMRSurface9; diff --git a/include/wincrypt.h b/include/wincrypt.h index e6006ee7c5c..4b28f93df09 100644 --- a/include/wincrypt.h +++ b/include/wincrypt.h @@ -1082,7 +1082,7 @@ typedef BOOL (WINAPI *PFN_CERT_ENUM_PHYSICAL_STORE)(const void *pvSystemStore, void *pvReserved, void *pvArg); /* Encode/decode object */ -typedef LPVOID (WINAPI *PFN_CRYPT_ALLOC)(size_t cbsize); +typedef LPVOID (__WINE_ALLOC_SIZE(1) WINAPI *PFN_CRYPT_ALLOC)(size_t cbsize); typedef VOID (WINAPI *PFN_CRYPT_FREE)(LPVOID pv); typedef struct _CRYPT_ENCODE_PARA { diff --git a/include/wine/pthread.h b/include/wine/pthread.h index 1971ebb40c0..a8d5ba30de5 100644 --- a/include/wine/pthread.h +++ b/include/wine/pthread.h @@ -25,6 +25,11 @@ struct wine_pthread_callbacks; #include +#ifndef HAVE_SIGSET_T +struct sigset_t; +typedef struct sigset_t sigset_t; +#endif + #ifdef HAVE_PTHREAD_H #define _GNU_SOURCE diff --git a/include/xmldom.idl b/include/xmldom.idl index bf85acfb7f0..31c5e6628a1 100644 --- a/include/xmldom.idl +++ b/include/xmldom.idl @@ -720,6 +720,20 @@ interface IXMLDOMParseError : IDispatch HRESULT filepos([retval, out] long * filePos); } +[ + hidden, + uuid(3efaa427-272f-11d2-836f-0000f87a7782) +] +dispinterface XMLDOMDocumentEvents +{ + properties: + methods: + [id(DISPID_XMLDOMEVENT_ONDATAAVAILABLE)] + HRESULT ondataavailable(); + + [id(DISPID_XMLDOMEVENT_ONREADYSTATECHANGE)] + HRESULT onreadystatechange(); +} [ uuid(2933bf90-7b36-11d2-b20e-00c04f983e60) diff --git a/include/xmldomdid.h b/include/xmldomdid.h index a299157c3ac..d241a9cd10d 100644 --- a/include/xmldomdid.h +++ b/include/xmldomdid.h @@ -197,5 +197,9 @@ #define DISPID_DOM_ERROR_FILEPOS 0x000000b7 #define DISPID_DOM_ERROR__TOP 0x000000b8 +#define DISPID_XMLDOMEVENT 197 +#define DISPID_XMLDOMEVENT_ONREADYSTATECHANGE DISPID_READYSTATECHANGE +#define DISPID_XMLDOMEVENT_ONDATAAVAILABLE 198 +#define DISPID_XMLDOMEVENT__TOP 199 #endif /* __XMLDOMDID_H__ */ diff --git a/programs/notepad/main.c b/programs/notepad/main.c index f231f207d00..a9d3c3b1512 100644 --- a/programs/notepad/main.c +++ b/programs/notepad/main.c @@ -31,6 +31,7 @@ #include "main.h" #include "dialog.h" #include "notepad_res.h" +#include "wine/unicode.h" NOTEPAD_GLOBALS Globals; static ATOM aFINDMSGSTRING; @@ -590,7 +591,7 @@ static void HandleCommandLine(LPWSTR cmdline) static const WCHAR txtW[] = { '.','t','x','t',0 }; /* try to find file with ".txt" extension */ - if (!lstrcmp(txtW, cmdline + lstrlen(cmdline) - lstrlen(txtW))) + if (strchrW(PathFindFileNameW(cmdline), '.')) { file_exists = FALSE; file_name = cmdline; diff --git a/programs/regedit/framewnd.c b/programs/regedit/framewnd.c index ea0d39b35e5..c08831e7f95 100644 --- a/programs/regedit/framewnd.c +++ b/programs/regedit/framewnd.c @@ -372,11 +372,7 @@ static BOOL ExportRegistryFile(HWND hWnd, BOOL export_branch) ofn.lpTemplateName = MAKEINTRESOURCEW(IDD_EXPORT_TEMPLATE); if (GetSaveFileNameW(&ofn)) { BOOL result; - CHAR* fileA = GetMultiByteString(ofn.lpstrFile); - CHAR* sectionA = GetMultiByteString((LPWSTR)ofn.lCustData); - result = export_registry_key(fileA, sectionA); - HeapFree(GetProcessHeap(), 0, fileA); - HeapFree(GetProcessHeap(), 0, sectionA); + result = export_registry_key(ofn.lpstrFile, (LPWSTR)ofn.lCustData); if (!result) { /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/ return FALSE; diff --git a/programs/regedit/regedit.c b/programs/regedit/regedit.c index 8e7136b66aa..148d40b2978 100644 --- a/programs/regedit/regedit.c +++ b/programs/regedit/regedit.c @@ -196,6 +196,7 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s) } case ACTION_EXPORT: { CHAR filename[MAX_PATH]; + WCHAR* filenameW; filename[0] = '\0'; get_file_name(&s, filename); @@ -205,14 +206,19 @@ static BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s) exit(1); } + filenameW = GetWideString(filename); if (s[0]) { CHAR reg_key_name[KEY_MAX_LEN]; + WCHAR* reg_key_nameW; get_file_name(&s, reg_key_name); - export_registry_key(filename, reg_key_name); + reg_key_nameW = GetWideString(reg_key_name); + export_registry_key(filenameW, reg_key_nameW); + HeapFree(GetProcessHeap(), 0, reg_key_nameW); } else { - export_registry_key(filename, NULL); + export_registry_key(filenameW, NULL); } + HeapFree(GetProcessHeap(), 0, filenameW); break; } default: diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c index b9825d4a8e0..ff4918c2739 100644 --- a/programs/regedit/regproc.c +++ b/programs/regedit/regproc.c @@ -84,6 +84,26 @@ WCHAR* GetWideString(const char* strA) } /****************************************************************************** + * Allocates memory and convers input from multibyte to wide chars + * Returned string must be freed by the caller + */ +WCHAR* GetWideStringN(const char* strA, int chars, DWORD *len) +{ + if(strA) + { + WCHAR* strW = NULL; + *len = MultiByteToWideChar(CP_ACP, 0, strA, chars, NULL, 0); + + strW = HeapAlloc(GetProcessHeap(), 0, *len * sizeof(WCHAR)); + CHECK_ENOUGH_MEMORY(strW); + MultiByteToWideChar(CP_ACP, 0, strA, chars, strW, *len); + return strW; + } + *len = 0; + return NULL; +} + +/****************************************************************************** * Allocates memory and convers input from wide chars to multibyte * Returned string must be freed by the caller */ @@ -103,6 +123,26 @@ char* GetMultiByteString(const WCHAR* strW) } /****************************************************************************** + * Allocates memory and convers input from wide chars to multibyte + * Returned string must be freed by the caller + */ +char* GetMultiByteStringN(const WCHAR* strW, int chars, DWORD* len) +{ + if(strW) + { + char* strA = NULL; + *len = WideCharToMultiByte(CP_ACP, 0, strW, chars, NULL, 0, NULL, NULL); + + strA = HeapAlloc(GetProcessHeap(), 0, *len); + CHECK_ENOUGH_MEMORY(strA); + WideCharToMultiByte(CP_ACP, 0, strW, chars, strA, *len, NULL, NULL); + return strA; + } + *len = 0; + return NULL; +} + +/****************************************************************************** * Converts a hex representation of a DWORD into a DWORD. */ static BOOL convertHexToDWord(WCHAR* str, DWORD *dw) @@ -244,46 +284,7 @@ static void REGPROC_unescape_string(WCHAR* str) str[val_idx] = '\0'; } -/****************************************************************************** - * Parses HKEY_SOME_ROOT\some\key\path to get the root key handle and - * extract the key path (what comes after the first '\'). - */ -static BOOL parseKeyName(LPSTR lpKeyName, HKEY *hKey, LPSTR *lpKeyPath) -{ - LPSTR lpSlash; - unsigned int i, len; - - if (lpKeyName == NULL) - return FALSE; - - lpSlash = strchr(lpKeyName, '\\'); - if (lpSlash) - { - len = lpSlash-lpKeyName; - } - else - { - len = strlen(lpKeyName); - lpSlash = lpKeyName+len; - } - *hKey = NULL; - for (i = 0; i < REG_CLASS_NUMBER; i++) { - if (strncmp(lpKeyName, reg_class_names[i], len) == 0 && - len == strlen(reg_class_names[i])) { - *hKey = reg_class_keys[i]; - break; - } - } - if (*hKey == NULL) - return FALSE; - - if (*lpSlash != '\0') - lpSlash++; - *lpKeyPath = lpSlash; - return TRUE; -} - -static BOOL parseKeyNameW(LPWSTR lpKeyName, HKEY *hKey, LPWSTR *lpKeyPath) +static BOOL parseKeyName(LPWSTR lpKeyName, HKEY *hKey, LPWSTR *lpKeyPath) { WCHAR* lpSlash = NULL; unsigned int i, len; @@ -341,7 +342,7 @@ static HKEY currentKeyHandle = NULL; * val_name - name of the registry value * val_data - registry value data */ -static LONG setValue(WCHAR* val_name, WCHAR* val_data) +static LONG setValue(WCHAR* val_name, WCHAR* val_data, BOOL is_unicode) { LONG res; DWORD dwDataType, dwParseType; @@ -390,6 +391,14 @@ static LONG setValue(WCHAR* val_name, WCHAR* val_data) lpbData = convertHexCSVToHex(val_data, &dwLen); if (!lpbData) return ERROR_INVALID_DATA; + + if(dwDataType == REG_MULTI_SZ && !is_unicode) + { + LPBYTE tmp = lpbData; + lpbData = (LPBYTE)GetWideStringN((char*)lpbData, dwLen, &dwLen); + dwLen *= sizeof(WCHAR); + HeapFree(GetProcessHeap(), 0, tmp); + } } else /* unknown format */ { @@ -425,7 +434,7 @@ static LONG openKeyW(WCHAR* stdInput) return ERROR_INVALID_PARAMETER; /* Get the registry class */ - if (!parseKeyNameW(stdInput, &keyClass, &keyPath)) + if (!parseKeyName(stdInput, &keyClass, &keyPath)) return ERROR_INVALID_PARAMETER; res = RegCreateKeyExW( @@ -470,7 +479,7 @@ static void closeKey(void) * line - registry file unwrapped line. Should have the registry value name and * complete registry value data. */ -static void processSetValue(WCHAR* line) +static void processSetValue(WCHAR* line, BOOL is_unicode) { WCHAR* val_name; /* registry value name */ WCHAR* val_data; /* registry value data */ @@ -518,7 +527,7 @@ static void processSetValue(WCHAR* line) val_data = line + line_idx; REGPROC_unescape_string(val_name); - res = setValue(val_name, val_data); + res = setValue(val_name, val_data, is_unicode); if ( res != ERROR_SUCCESS ) { char* val_nameA = GetMultiByteString(val_name); @@ -536,8 +545,9 @@ static void processSetValue(WCHAR* line) /****************************************************************************** * This function receives the currently read entry and performs the * corresponding action. + * isUnicode affects parsing of REG_MULTI_SZ values */ -static void processRegEntry(WCHAR* stdInput) +static void processRegEntry(WCHAR* stdInput, BOOL isUnicode) { /* * We encountered the end of the file, make sure we @@ -572,7 +582,7 @@ static void processRegEntry(WCHAR* stdInput) (( stdInput[0] == '@') || /* reading a default @=data pair */ ( stdInput[0] == '\"'))) /* reading a new value=data pair */ { - processSetValue(stdInput); + processSetValue(stdInput, isUnicode); } else { /* Since we are assuming that the file format is valid we must be @@ -696,10 +706,10 @@ void processRegLinesA(FILE *in) break; /* That is the full virtual line */ } - processRegEntry(lineW); + processRegEntry(lineW, FALSE); HeapFree(GetProcessHeap(), 0, lineW); } - processRegEntry(NULL); + processRegEntry(NULL, FALSE); HeapFree(GetProcessHeap(), 0, line); } @@ -805,14 +815,14 @@ void processRegLinesW(FILE *in) if(!s_eol) break; - processRegEntry(s); + processRegEntry(s, TRUE); s = s_eol + 1; s_eol = 0; continue; /* That is the full virtual line */ } } - processRegEntry(NULL); + processRegEntry(NULL, TRUE); HeapFree(GetProcessHeap(), 0, buf); } @@ -852,7 +862,7 @@ static void REGPROC_print_error(void) * required_len - length of the string to place to the buffer in characters. * The length does not include the terminating null character. */ -static void REGPROC_resize_char_buffer(CHAR **buffer, DWORD *len, DWORD required_len) +static void REGPROC_resize_char_buffer(WCHAR **buffer, DWORD *len, DWORD required_len) { required_len++; if (required_len > *len) { @@ -868,9 +878,10 @@ static void REGPROC_resize_char_buffer(CHAR **buffer, DWORD *len, DWORD required /****************************************************************************** * Prints string str to file */ -static void REGPROC_export_string(FILE *file, CHAR *str) +static void REGPROC_export_string(FILE *file, WCHAR *str) { - size_t len = strlen(str); + CHAR* strA = GetMultiByteString(str); + size_t len = strlen(strA); size_t i; /* escaping characters */ @@ -891,6 +902,7 @@ static void REGPROC_export_string(FILE *file, CHAR *str) break; } } + HeapFree(GetProcessHeap(), 0, strA); } /****************************************************************************** @@ -910,8 +922,8 @@ static void REGPROC_export_string(FILE *file, CHAR *str) * val_size - size of the buffer for storing values in bytes. */ static void export_hkey(FILE *file, HKEY key, - CHAR **reg_key_name_buf, DWORD *reg_key_name_len, - CHAR **val_name_buf, DWORD *val_name_len, + WCHAR **reg_key_name_buf, DWORD *reg_key_name_len, + WCHAR **val_name_buf, DWORD *val_name_len, BYTE **val_buf, DWORD *val_size) { DWORD max_sub_key_len; @@ -921,15 +933,16 @@ static void export_hkey(FILE *file, HKEY key, DWORD i; BOOL more_data; LONG ret; + CHAR* bufA; /* get size information and resize the buffers if necessary */ - if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, + if (RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL, &max_sub_key_len, NULL, NULL, &max_val_name_len, &max_val_size, NULL, NULL ) != ERROR_SUCCESS) { REGPROC_print_error(); } - curr_len = strlen(*reg_key_name_buf); + curr_len = strlenW(*reg_key_name_buf); REGPROC_resize_char_buffer(reg_key_name_buf, reg_key_name_len, max_sub_key_len + curr_len + 1); REGPROC_resize_char_buffer(val_name_buf, val_name_len, @@ -943,7 +956,9 @@ static void export_hkey(FILE *file, HKEY key, /* output data for the current key */ fputs("\n[", file); - fputs(*reg_key_name_buf, file); + bufA = GetMultiByteString(*reg_key_name_buf); + fputs(bufA, file); + HeapFree(GetProcessHeap(), 0, bufA); fputs("]\n", file); /* print all the values */ i = 0; @@ -952,7 +967,7 @@ static void export_hkey(FILE *file, HKEY key, DWORD value_type; DWORD val_name_len1 = *val_name_len; DWORD val_size1 = *val_size; - ret = RegEnumValue(key, i, *val_name_buf, &val_name_len1, NULL, + ret = RegEnumValueW(key, i, *val_name_buf, &val_name_len1, NULL, &value_type, *val_buf, &val_size1); if (ret != ERROR_SUCCESS) { more_data = FALSE; @@ -974,7 +989,7 @@ static void export_hkey(FILE *file, HKEY key, case REG_SZ: case REG_EXPAND_SZ: fputs("\"", file); - if (val_size1) REGPROC_export_string(file, (char*) *val_buf); + if (val_size1) REGPROC_export_string(file, (WCHAR*) *val_buf); fputs("\"\n", file); break; @@ -993,26 +1008,36 @@ static void export_hkey(FILE *file, HKEY key, /* falls through */ case REG_BINARY: { DWORD i1; - const CHAR *hex_prefix; - CHAR buf[20]; + const WCHAR *hex_prefix; + WCHAR buf[20]; int cur_pos; + const WCHAR hex[] = {'h','e','x',':',0}; + const WCHAR delim[] = {'"','"','=',0}; + CHAR* hex_prefixA; + BYTE* val_buf1 = *val_buf; + DWORD val_buf1_size = val_size1; if (value_type == REG_BINARY) { - hex_prefix = "hex:"; + hex_prefix = hex; } else { + const WCHAR hex_format[] = {'h','e','x','(','%','d',')',':',0}; hex_prefix = buf; - sprintf(buf, "hex(%d):", value_type); + wsprintfW(buf, hex_format, value_type); + if(value_type == REG_MULTI_SZ) + val_buf1 = (BYTE*)GetMultiByteStringN((WCHAR*)*val_buf, val_size1 / sizeof(WCHAR), &val_buf1_size); } /* position of where the next character will be printed */ /* NOTE: yes, strlen("hex:") is used even for hex(x): */ - cur_pos = strlen("\"\"=") + strlen("hex:") + - strlen(*val_name_buf); - - fputs(hex_prefix, file); - for (i1 = 0; i1 < val_size1; i1++) { - fprintf(file, "%02x", (unsigned int)(*val_buf)[i1]); - if (i1 + 1 < val_size1) { + cur_pos = lstrlenW(delim) + lstrlenW(hex) + + lstrlenW(*val_name_buf); + + hex_prefixA = GetMultiByteString(hex_prefix); + fputs(hex_prefixA, file); + HeapFree(GetProcessHeap(), 0, hex_prefixA); + for (i1 = 0; i1 < val_buf1_size; i1++) { + fprintf(file, "%02x", (unsigned int)(val_buf1)[i1]); + if (i1 + 1 < val_buf1_size) { fputs(",", file); } cur_pos += 3; @@ -1023,6 +1048,8 @@ static void export_hkey(FILE *file, HKEY key, cur_pos = 2; } } + if(value_type == REG_MULTI_SZ) + HeapFree(GetProcessHeap(), 0, val_buf1); fputs("\n", file); break; } @@ -1036,7 +1063,7 @@ static void export_hkey(FILE *file, HKEY key, while(more_data) { DWORD buf_len = *reg_key_name_len - curr_len; - ret = RegEnumKeyEx(key, i, *reg_key_name_buf + curr_len + 1, &buf_len, + ret = RegEnumKeyExW(key, i, *reg_key_name_buf + curr_len + 1, &buf_len, NULL, NULL, NULL, NULL); if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA) { more_data = FALSE; @@ -1047,7 +1074,7 @@ static void export_hkey(FILE *file, HKEY key, HKEY subkey; i++; - if (RegOpenKey(key, *reg_key_name_buf + curr_len + 1, + if (RegOpenKeyW(key, *reg_key_name_buf + curr_len + 1, &subkey) == ERROR_SUCCESS) { export_hkey(file, subkey, reg_key_name_buf, reg_key_name_len, val_name_buf, val_name_len, val_buf, val_size); @@ -1063,20 +1090,24 @@ static void export_hkey(FILE *file, HKEY key, /****************************************************************************** * Open file for export. */ -static FILE *REGPROC_open_export_file(CHAR *file_name) +static FILE *REGPROC_open_export_file(WCHAR *file_name) { FILE *file; + WCHAR dash = '-'; - if (strcmp(file_name,"-")==0) + if (strncmpW(file_name,&dash,1)==0) file=stdout; else { - file = fopen(file_name, "w"); + CHAR* file_nameA = GetMultiByteString(file_name); + file = fopen(file_nameA, "w"); if (!file) { perror(""); - fprintf(stderr,"%s: Can't open file \"%s\"\n", getAppName(), file_name); + fprintf(stderr,"%s: Can't open file \"%s\"\n", getAppName(), file_nameA); + HeapFree(GetProcessHeap(), 0, file_nameA); exit(1); } + HeapFree(GetProcessHeap(), 0, file_nameA); } fputs("REGEDIT4\n", file); return file; @@ -1090,10 +1121,10 @@ static FILE *REGPROC_open_export_file(CHAR *file_name) * reg_key_name - registry branch to export. The whole registry is exported if * reg_key_name is NULL or contains an empty string. */ -BOOL export_registry_key(CHAR *file_name, CHAR *reg_key_name) +BOOL export_registry_key(WCHAR *file_name, WCHAR *reg_key_name) { - CHAR *reg_key_name_buf; - CHAR *val_name_buf; + WCHAR *reg_key_name_buf; + WCHAR *val_name_buf; BYTE *val_buf; DWORD reg_key_name_len = KEY_MAX_LEN; DWORD val_name_len = KEY_MAX_LEN; @@ -1109,17 +1140,19 @@ BOOL export_registry_key(CHAR *file_name, CHAR *reg_key_name) if (reg_key_name && reg_key_name[0]) { HKEY reg_key_class; - CHAR *branch_name = NULL; + WCHAR *branch_name = NULL; HKEY key; REGPROC_resize_char_buffer(®_key_name_buf, ®_key_name_len, - strlen(reg_key_name)); - strcpy(reg_key_name_buf, reg_key_name); + lstrlenW(reg_key_name)); + lstrcpyW(reg_key_name_buf, reg_key_name); /* open the specified key */ if (!parseKeyName(reg_key_name, ®_key_class, &branch_name)) { + CHAR* key_nameA = GetMultiByteString(reg_key_name); fprintf(stderr,"%s: Incorrect registry class specification in '%s'\n", - getAppName(), reg_key_name); + getAppName(), key_nameA); + HeapFree(GetProcessHeap(), 0, key_nameA); exit(1); } if (!branch_name[0]) { @@ -1129,7 +1162,7 @@ BOOL export_registry_key(CHAR *file_name, CHAR *reg_key_name) ®_key_name_buf, ®_key_name_len, &val_name_buf, &val_name_len, &val_buf, &val_size); - } else if (RegOpenKey(reg_key_class, branch_name, &key) == ERROR_SUCCESS) { + } else if (RegOpenKeyW(reg_key_class, branch_name, &key) == ERROR_SUCCESS) { file = REGPROC_open_export_file(file_name); export_hkey(file, key, ®_key_name_buf, ®_key_name_len, @@ -1137,8 +1170,10 @@ BOOL export_registry_key(CHAR *file_name, CHAR *reg_key_name) &val_buf, &val_size); RegCloseKey(key); } else { + CHAR* key_nameA = GetMultiByteString(reg_key_name); fprintf(stderr,"%s: Can't export. Registry key '%s' does not exist!\n", - getAppName(), reg_key_name); + getAppName(), key_nameA); + HeapFree(GetProcessHeap(), 0, key_nameA); REGPROC_print_error(); } } else { @@ -1152,7 +1187,7 @@ BOOL export_registry_key(CHAR *file_name, CHAR *reg_key_name) reg_class_keys[i] != HKEY_CURRENT_USER && reg_class_keys[i] != HKEY_CURRENT_CONFIG && reg_class_keys[i] != HKEY_DYN_DATA) { - strcpy(reg_key_name_buf, reg_class_names[i]); + lstrcpyW(reg_key_name_buf, reg_class_namesW[i]); export_hkey(file, reg_class_keys[i], ®_key_name_buf, ®_key_name_len, &val_name_buf, &val_name_len, @@ -1209,7 +1244,7 @@ void delete_registry_key(WCHAR *reg_key_name) if (!reg_key_name || !reg_key_name[0]) return; - if (!parseKeyNameW(reg_key_name, &key_class, &key_name)) { + if (!parseKeyName(reg_key_name, &key_class, &key_name)) { char* reg_key_nameA = GetMultiByteString(reg_key_name); fprintf(stderr,"%s: Incorrect registry class specification in '%s'\n", getAppName(), reg_key_nameA); diff --git a/programs/regedit/regproc.h b/programs/regedit/regproc.h index 7122379307a..d063506197e 100644 --- a/programs/regedit/regproc.h +++ b/programs/regedit/regproc.h @@ -21,7 +21,7 @@ const CHAR *getAppName(void); -BOOL export_registry_key(CHAR *file_name, CHAR *reg_key_name); +BOOL export_registry_key(WCHAR *file_name, WCHAR *reg_key_name); BOOL import_registry_file(FILE *in); void delete_registry_key(WCHAR *reg_key_name); WCHAR* GetWideString(const char* strA); diff --git a/programs/wordpad/wordpad.c b/programs/wordpad/wordpad.c index d98758aa880..adad55c7fa3 100644 --- a/programs/wordpad/wordpad.c +++ b/programs/wordpad/wordpad.c @@ -467,7 +467,7 @@ static void set_default_font(void) SendMessageW(hEditorWnd, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM)&fmt); } -static void on_fontlist_modified(HWND hwndFontList, LPWSTR wszNewFaceName) +static void on_fontlist_modified(LPWSTR wszNewFaceName) { CHARFORMAT2W format; ZeroMemory(&format, sizeof(format)); @@ -1702,7 +1702,7 @@ static int context_menu(LPARAM lParam) return 0; } -static LRESULT OnCreate( HWND hWnd, WPARAM wParam, LPARAM lParam) +static LRESULT OnCreate( HWND hWnd ) { HWND hToolBarWnd, hFormatBarWnd, hReBarWnd, hFontListWnd, hSizeListWnd, hRulerWnd; HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE); @@ -1858,7 +1858,7 @@ static LRESULT OnCreate( HWND hWnd, WPARAM wParam, LPARAM lParam) return 0; } -static LRESULT OnUser( HWND hWnd, WPARAM wParam, LPARAM lParam) +static LRESULT OnUser( HWND hWnd ) { HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR); HWND hwndReBar = GetDlgItem(hWnd, IDC_REBAR); @@ -1910,7 +1910,7 @@ static LRESULT OnUser( HWND hWnd, WPARAM wParam, LPARAM lParam) return 0; } -static LRESULT OnNotify( HWND hWnd, WPARAM wParam, LPARAM lParam) +static LRESULT OnNotify( HWND hWnd, LPARAM lParam) { HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR); HWND hwndReBar = GetDlgItem(hWnd, IDC_REBAR); @@ -1925,10 +1925,10 @@ static LRESULT OnNotify( HWND hWnd, WPARAM wParam, LPARAM lParam) NMCBEENDEDIT *endEdit = (NMCBEENDEDIT *)lParam; if(pHdr->hwndFrom == hwndFontList) { - on_fontlist_modified(hwndFontList, (LPWSTR)endEdit->szText); + on_fontlist_modified((LPWSTR)endEdit->szText); } else if (pHdr->hwndFrom == hwndSizeList) { - on_sizelist_modified(hwndSizeList, (LPWSTR)endEdit->szText); + on_sizelist_modified(hwndFontList,(LPWSTR)endEdit->szText); } } return 0; @@ -2322,7 +2322,7 @@ static LRESULT OnCommand( HWND hWnd, WPARAM wParam, LPARAM lParam) WCHAR buffer[LF_FACESIZE]; HWND hwndFontList = (HWND)lParam; get_comboexlist_selection(hwndFontList, buffer, LF_FACESIZE); - on_fontlist_modified(hwndFontList, buffer); + on_fontlist_modified(buffer); } break; @@ -2343,7 +2343,7 @@ static LRESULT OnCommand( HWND hWnd, WPARAM wParam, LPARAM lParam) return 0; } -static LRESULT OnInitPopupMenu( HWND hWnd, WPARAM wParam, LPARAM lParam ) +static LRESULT OnInitPopupMenu( HWND hWnd, WPARAM wParam ) { HMENU hMenu = (HMENU)wParam; HWND hwndEditor = GetDlgItem(hWnd, IDC_EDITOR); @@ -2456,13 +2456,13 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara switch(msg) { case WM_CREATE: - return OnCreate( hWnd, wParam, lParam ); + return OnCreate( hWnd ); case WM_USER: - return OnUser( hWnd, wParam, lParam ); + return OnUser( hWnd ); case WM_NOTIFY: - return OnNotify( hWnd, wParam, lParam ); + return OnNotify( hWnd, lParam ); case WM_COMMAND: if(preview_isactive()) @@ -2494,7 +2494,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara return 0; case WM_INITMENUPOPUP: - return OnInitPopupMenu( hWnd, wParam, lParam ); + return OnInitPopupMenu( hWnd, wParam ); case WM_SIZE: return OnSize( hWnd, wParam, lParam ); diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index b30b323ed16..27068705d30 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -354,10 +354,10 @@ static void read_importlib(importlib_t *importlib) file_name = wpp_find_include(importlib->name, NULL); if(file_name) { - fd = open(file_name, O_RDONLY); + fd = open(file_name, O_RDONLY | O_BINARY ); free(file_name); }else { - fd = open(importlib->name, O_RDONLY); + fd = open(importlib->name, O_RDONLY | O_BINARY ); } if(fd < 0) diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index 97ec4ec7df9..28a74f20f73 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -885,7 +885,9 @@ static int encode_type( next_vt = VT_VOID; encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size); - if(type->ref && (type->ref->type == RPC_FC_IP)) { + /* these types already have an implicit pointer, so we don't need to + * add another */ + if(next_vt == VT_DISPATCH || next_vt == VT_UNKNOWN) { chat("encode_type: skipping ptr\n"); *encoded_type = target_type; *width = 4; @@ -1030,24 +1032,6 @@ static int encode_type( *encoded_type = typeoffset; *width = 0; *alignment = 1; - - if(type->type == RPC_FC_IP) { - for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if ((typedata[0] == ((0x7fff << 16) | VT_PTR)) && (typedata[1] == *encoded_type)) break; - } - if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (0x7fff << 16) | VT_PTR; - typedata[1] = *encoded_type; - } - *encoded_type = typeoffset; - *width = 4; - *alignment = 4; - *decoded_size += 8; - } break; } @@ -1177,7 +1161,9 @@ static int encode_var( dump_type(type); encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size); - if(type->type == RPC_FC_IP) return 2; + /* these types already have an implicit pointer, so we don't need to + * add another */ + if(vt == VT_DISPATCH || vt == VT_UNKNOWN) return 2; return 0; } @@ -1648,7 +1634,6 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var) varflags |= 0x01; /* VARFLAG_FREADONLY */ break; /* FIXME: VARFLAG_FREPLACEABLE */ - break; case ATTR_REQUESTEDIT: varflags |= 0x08; /* VARFLAG_FREQUESTEDIT */ break; -- 2.11.4.GIT