From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 32 +++++++++- dlls/mshtml/mshtml_private.h | 4 ++ dlls/mshtml/mshtml_private_iface.idl | 18 ++++++ dlls/mshtml/omnavigator.c | 94 ++++++++++++++++++++++++++++ dlls/mshtml/tests/documentmode.js | 12 +++- 5 files changed, 158 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index edd0de177bd..716b60b56c0 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3190,6 +3190,24 @@ static HRESULT WINAPI window_private_get_console(IWineHTMLWindowPrivate *iface, return S_OK; }
+static HRESULT WINAPI window_private_get_msCrypto(IWineHTMLWindowPrivate *iface, IDispatch **crypto) +{ + HTMLInnerWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface)->inner_window; + + TRACE("iface %p, crypto %p.\n", iface, crypto); + + if(!This->crypto) { + HRESULT hres = create_crypto(This, &This->crypto); + if(FAILED(hres)) + return hres; + } + + *crypto = (IDispatch*)This->crypto; + if(This->crypto) + IWineMSHTMLCrypto_AddRef(This->crypto); + return S_OK; +} + static const IWineHTMLWindowPrivateVtbl WineHTMLWindowPrivateVtbl = { window_private_QueryInterface, window_private_AddRef, @@ -3202,6 +3220,7 @@ static const IWineHTMLWindowPrivateVtbl WineHTMLWindowPrivateVtbl = { window_private_cancelAnimationFrame, window_private_get_console, window_private_matchMedia, + window_private_get_msCrypto, };
static inline HTMLWindow *impl_from_IWineHTMLWindowCompatPrivateVtbl(IWineHTMLWindowCompatPrivate *iface) @@ -3717,6 +3736,8 @@ static void HTMLWindow_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCa note_cc_edge((nsISupports*)This->session_storage, "session_storage", cb); if(This->local_storage) note_cc_edge((nsISupports*)This->local_storage, "local_storage", cb); + if(This->crypto) + note_cc_edge((nsISupports*)This->crypto, "crypto", cb); if(This->dom_window) note_cc_edge((nsISupports*)This->dom_window, "dom_window", cb); traverse_variant(&This->performance, "performance", cb); @@ -3762,6 +3783,11 @@ static void HTMLWindow_unlink(DispatchEx *dispex) This->local_storage = NULL; IHTMLStorage_Release(local_storage); } + if(This->crypto) { + IWineMSHTMLCrypto *crypto = This->crypto; + This->crypto = NULL; + IWineMSHTMLCrypto_Release(crypto); + } unlink_variant(&This->performance); unlink_ref(&This->dom_window); } @@ -4238,13 +4264,17 @@ static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compa {DISPID_UNKNOWN} }; const dispex_hook_t *const window6_hooks = window6_ie9_hooks + 1; + static const dispex_hook_t private_ie10_hooks[] = { + {DISPID_IWINEHTMLWINDOWPRIVATE_MSCRYPTO}, + {DISPID_UNKNOWN} + };
if(compat_mode >= COMPAT_MODE_IE9) dispex_info_add_interface(info, IHTMLWindow7_tid, NULL); else dispex_info_add_interface(info, IWineHTMLWindowCompatPrivate_tid, NULL); if(compat_mode >= COMPAT_MODE_IE10) - dispex_info_add_interface(info, IWineHTMLWindowPrivate_tid, NULL); + dispex_info_add_interface(info, IWineHTMLWindowPrivate_tid, compat_mode < COMPAT_MODE_IE11 ? private_ie10_hooks : NULL);
dispex_info_add_interface(info, IHTMLWindow6_tid, compat_mode >= COMPAT_MODE_IE9 ? window6_ie9_hooks : window6_hooks); if(compat_mode < COMPAT_MODE_IE9) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 5c885ae5de4..fa0d2fac30e 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -322,6 +322,7 @@ struct constructor; XIID(IWinePageTransitionEvent) \ XIID(IWineXMLHttpRequestPrivate) \ XIID(IWineMSHTMLConsole) \ + XIID(IWineMSHTMLCrypto) \ XIID(IWineMSHTMLMediaQueryList) \ XIID(IWineMSHTMLMutationObserver)
@@ -442,6 +443,7 @@ typedef struct { X(ClientRectList) \ X(Comment) \ X(Console) \ + X(Crypto) \ X(CustomEvent) \ X(DOMImplementation) \ X(DOMParser) \ @@ -807,6 +809,7 @@ struct HTMLInnerWindow { IHTMLStorage *session_storage; IHTMLStorage *local_storage; IWineMSHTMLConsole *console; + IWineMSHTMLCrypto *crypto;
BOOL static_props_filled; BOOL performance_initialized; @@ -1743,4 +1746,5 @@ IInternetSecurityManager *get_security_manager(void);
extern HINSTANCE hInst; void create_console(HTMLInnerWindow *window, IWineMSHTMLConsole **ret); +HRESULT create_crypto(HTMLInnerWindow *window, IWineMSHTMLCrypto **ret); HRESULT create_media_query_list(HTMLInnerWindow *window, BSTR media_query, IDispatch **ret); diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index 14bcae098ee..ff53b4b39d6 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -113,6 +113,22 @@ interface IWineMSHTMLMediaQueryList : IDispatch HRESULT removeListener([in] VARIANT *listener); }
+[ + odl, + oleautomation, + dual, + hidden, + uuid(fd55b4b6-2813-4fb4-829d-380099474ab2) +] +interface IWineMSHTMLCrypto : IDispatch +{ + [propget, id(1)] + HRESULT subtle([retval, out] IDispatch **subtle); + [id(2)] + HRESULT getRandomValues([in] VARIANT *typedArray, [retval, out] IDispatch **ret); +} + +const long DISPID_IWINEHTMLWINDOWPRIVATE_MSCRYPTO = 54; [ odl, oleautomation, @@ -130,6 +146,8 @@ interface IWineHTMLWindowPrivate : IDispatch HRESULT console([retval, out] IDispatch **console); [id(53)] HRESULT matchMedia([in] BSTR media_query, [retval, out] IDispatch **media_query_list); + [propget, id(DISPID_IWINEHTMLWINDOWPRIVATE_MSCRYPTO)] + HRESULT msCrypto([retval, out] IDispatch **crypto); }
[ diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 4320836b4f6..5d2b1a7c902 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -2712,3 +2712,97 @@ HRESULT create_media_query_list(HTMLInnerWindow *window, BSTR media_query, IDisp *ret = (IDispatch*)&media_query_list->IWineMSHTMLMediaQueryList_iface; return S_OK; } + +struct crypto { + DispatchEx dispex; + IWineMSHTMLCrypto IWineMSHTMLCrypto_iface; +}; + +static inline struct crypto *impl_from_IWineMSHTMLCrypto(IWineMSHTMLCrypto *iface) +{ + return CONTAINING_RECORD(iface, struct crypto, IWineMSHTMLCrypto_iface); +} + +DISPEX_IDISPATCH_IMPL(crypto, IWineMSHTMLCrypto, impl_from_IWineMSHTMLCrypto(iface)->dispex) + +static HRESULT WINAPI crypto_get_subtle(IWineMSHTMLCrypto *iface, IDispatch **subtle) +{ + struct crypto *crypto = impl_from_IWineMSHTMLCrypto(iface); + + FIXME("(%p)->(%p)\n", crypto, subtle); + + return E_NOTIMPL; +} + +static HRESULT WINAPI crypto_getRandomValues(IWineMSHTMLCrypto *iface, VARIANT *typedArray, IDispatch **ret) +{ + struct crypto *crypto = impl_from_IWineMSHTMLCrypto(iface); + + FIXME("(%p)->(%p %p)\n", crypto, typedArray, ret); + + return E_NOTIMPL; +} + +static const IWineMSHTMLCryptoVtbl WineMSHTMLCryptoVtbl = { + crypto_QueryInterface, + crypto_AddRef, + crypto_Release, + crypto_GetTypeInfoCount, + crypto_GetTypeInfo, + crypto_GetIDsOfNames, + crypto_Invoke, + crypto_get_subtle, + crypto_getRandomValues +}; + +static inline struct crypto *crypto_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, struct crypto, dispex); +} + +static void *crypto_query_interface(DispatchEx *dispex, REFIID riid) +{ + struct crypto *This = crypto_from_DispatchEx(dispex); + + if(IsEqualGUID(&IID_IWineMSHTMLCrypto, riid)) + return &This->IWineMSHTMLCrypto_iface; + + return NULL; +} + +static void crypto_destructor(DispatchEx *dispex) +{ + struct crypto *This = crypto_from_DispatchEx(dispex); + free(This); +} + +static const dispex_static_data_vtbl_t crypto_dispex_vtbl = { + .query_interface = crypto_query_interface, + .destructor = crypto_destructor, +}; + +static const tid_t crypto_iface_tids[] = { + IWineMSHTMLCrypto_tid, + 0 +}; +dispex_static_data_t Crypto_dispex = { + .id = OBJID_Crypto, + .vtbl = &crypto_dispex_vtbl, + .disp_tid = IWineMSHTMLCrypto_tid, + .iface_tids = crypto_iface_tids, + .min_compat_mode = COMPAT_MODE_IE11, +}; + +HRESULT create_crypto(HTMLInnerWindow *window, IWineMSHTMLCrypto **ret) +{ + struct crypto *crypto; + + if(!(crypto = calloc(1, sizeof(*crypto)))) + return E_OUTOFMEMORY; + + crypto->IWineMSHTMLCrypto_iface.lpVtbl = &WineMSHTMLCryptoVtbl; + init_dispatch(&crypto->dispex, &Crypto_dispex, window, dispex_compat_mode(&window->event_target.dispex)); + + *ret = &crypto->IWineMSHTMLCrypto_iface; + return S_OK; +} diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index a930e216b5a..8ad9a141bb5 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -351,6 +351,7 @@ sync_test("builtin_toString", function() { test("mediaQueryList", window.matchMedia("(hover:hover)"), "MediaQueryList"); } if(v >= 11) { + test("crypto", window.msCrypto, "Crypto"); test("MutationObserver", new window.MutationObserver(function() {}), "MutationObserver"); } if(v >= 9) { @@ -983,6 +984,7 @@ sync_test("window_props", function() { test_exposed("performance", true); test_exposed("console", v >= 10); test_exposed("matchMedia", v >= 10); + test_exposed("msCrypto", v >= 11); test_exposed("Document", v >= 9); test_exposed("HTMLDocument", v === 8 || v >= 11, v === 8); test_exposed("XMLDocument", v >= 11); @@ -4111,6 +4113,12 @@ sync_test("prototypes", function() { }else { ok(!("Console" in window), "Console found in window"); } + if(v >= 11) { + check(msCrypto, Crypto.prototype, "crypto"); + check(Crypto.prototype, Object.prototype, "crypto prototype"); + }else { + ok(!("msCrypto" in window), "msCrypto found in window"); + } if(v >= 10) { check(window.matchMedia("(hover:hover)"), MediaQueryList.prototype, "media query"); check(MediaQueryList.prototype, Object.prototype, "media query prototype"); @@ -4169,6 +4177,8 @@ sync_test("prototype props", function() { check(Attr, [ "expando", "name", "ownerElement", "specified", "value" ]); check(CharacterData, [ "appendData", "data", "deleteData", "insertData", "length", "replaceData", "substringData" ]); check(Comment, [ "text" ]); + if(v >= 11) + check(Crypto, [ "getRandomValues", "subtle" ]); check(CSSStyleDeclaration, [ ["alignContent",11], ["alignItems",11], ["alignSelf",11], "alignmentBaseline", ["animation",10], ["animationDelay",10], ["animationDirection",10], ["animationDuration",10], ["animationFillMode",10], ["animationIterationCount",10], ["animationName",10], @@ -4672,7 +4682,7 @@ async_test("window own props", function() { ], [ ["AesGcmEncryptResult",11], ["ANGLE_instanced_arrays",11], ["AnimationEvent",10], ["ApplicationCache",10], "Audio", ["AudioTrack",10], ["AudioTrackList",10], "BeforeUnloadEvent", ["Blob",10], "BookmarkCollection", "CanvasGradient", "CanvasPattern", "CanvasPixelArray", "CanvasRenderingContext2D", "CDATASection", ["CloseEvent",10], - "CompositionEvent", "ControlRangeCollection", "Coordinates", ["Crypto",11], ["CryptoOperation",11], "CSSFontFaceRule", "CSSImportRule", ["CSSKeyframeRule",10], ["CSSKeyframesRule",10], + "CompositionEvent", "ControlRangeCollection", "Coordinates", ["CryptoOperation",11], "CSSFontFaceRule", "CSSImportRule", ["CSSKeyframeRule",10], ["CSSKeyframesRule",10], "CSSMediaRule", "CSSNamespaceRule", "CSSPageRule", "CSSRuleList", "DataTransfer", "Debug", ["DeviceAcceleration",11], ["DeviceMotionEvent",11], ["DeviceOrientationEvent",11], ["DeviceRotationRate",11], ["DOMError",10], "DOMException", ["DOMSettableTokenList",10], ["DOMStringList",10], ["DOMStringMap",11], "DragEvent", ["ErrorEvent",10], "EventException", ["EXT_texture_filter_anisotropic",11], ["File",10], ["FileList",10], ["FileReader",10],
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 2 + dlls/mshtml/mshtml_private_iface.idl | 40 +++++ dlls/mshtml/omnavigator.c | 225 ++++++++++++++++++++++++++- dlls/mshtml/tests/documentmode.js | 5 +- 4 files changed, 268 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index fa0d2fac30e..40add3f1dc0 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -323,6 +323,7 @@ struct constructor; XIID(IWineXMLHttpRequestPrivate) \ XIID(IWineMSHTMLConsole) \ XIID(IWineMSHTMLCrypto) \ + XIID(IWineMSHTMLSubtleCrypto) \ XIID(IWineMSHTMLMediaQueryList) \ XIID(IWineMSHTMLMutationObserver)
@@ -521,6 +522,7 @@ typedef struct { X(StorageEvent) \ X(StyleSheet) \ X(StyleSheetList) \ + X(SubtleCrypto) \ X(Text) \ X(TextRange) \ X(UIEvent) \ diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index ff53b4b39d6..ac336d6c360 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -128,6 +128,46 @@ interface IWineMSHTMLCrypto : IDispatch HRESULT getRandomValues([in] VARIANT *typedArray, [retval, out] IDispatch **ret); }
+[ + odl, + oleautomation, + dual, + hidden, + uuid(fd55b4b6-2813-4fb4-829d-380099474ab3) +] +interface IWineMSHTMLSubtleCrypto : IDispatch +{ + [id(1)] + HRESULT encrypt([in] VARIANT *algorithm, [in] VARIANT *key, [in] VARIANT *data, [retval, out] IDispatch **result); + [id(2)] + HRESULT decrypt([in] VARIANT *algorithm, [in] VARIANT *key, [in] VARIANT *data, [retval, out] IDispatch **result); + [id(3)] + HRESULT sign([in] VARIANT *algorithm, [in] VARIANT *key, [in] VARIANT *data, [retval, out] IDispatch **signature); + [id(4)] + HRESULT verify([in] VARIANT *algorithm, [in] VARIANT *key, [in] VARIANT *signature, [in] VARIANT *data, + [retval, out] IDispatch **result); + [id(5)] + HRESULT digest([in] VARIANT *algorithm, [in] VARIANT *data, [retval, out] IDispatch **digest); + [id(6)] + HRESULT generateKey([in] VARIANT *algorithm, VARIANT_BOOL extractable, [in] VARIANT *keyUsages, + [retval, out] IDispatch **result); + [id(7)] + HRESULT deriveKey([in] VARIANT *algorithm, [in] VARIANT *baseKey, [in] VARIANT *derivedKeyAlgorithm, + VARIANT_BOOL extractable, [in] VARIANT *keyUsages, [retval, out] IDispatch **result); + [id(8)] + HRESULT importKey([in] BSTR format, [in] VARIANT *keyData, [in] VARIANT *algorithm, VARIANT_BOOL extractable, + [in] VARIANT *keyUsages, [retval, out] IDispatch **result); + [id(9)] + HRESULT exportKey([in] BSTR format, [in] VARIANT *key, [retval, out] IDispatch **result); + [id(10)] + HRESULT wrapKey([in] BSTR format, [in] VARIANT *key, [in] VARIANT *wrappingKey, [in] VARIANT *wrapAlgo, + [retval, out] IDispatch **result); + [id(11)] + HRESULT unwrapKey([in] BSTR format, [in] VARIANT *wrappedKey, [in] VARIANT *unwrappingKey, + [in] VARIANT *unwrapAlgo, [in] VARIANT *unwrappedKeyAlgo, VARIANT_BOOL extractable, + [in] VARIANT *keyUsages, [retval, out] IDispatch **result); +} + const long DISPID_IWINEHTMLWINDOWPRIVATE_MSCRYPTO = 54; [ odl, diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 5d2b1a7c902..c6a107bbb20 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -2713,9 +2713,195 @@ HRESULT create_media_query_list(HTMLInnerWindow *window, BSTR media_query, IDisp return S_OK; }
+struct crypto_subtle { + DispatchEx dispex; + IWineMSHTMLSubtleCrypto IWineMSHTMLSubtleCrypto_iface; +}; + +static inline struct crypto_subtle *impl_from_IWineMSHTMLSubtleCrypto(IWineMSHTMLSubtleCrypto *iface) +{ + return CONTAINING_RECORD(iface, struct crypto_subtle, IWineMSHTMLSubtleCrypto_iface); +} + +DISPEX_IDISPATCH_IMPL(crypto_subtle, IWineMSHTMLSubtleCrypto, impl_from_IWineMSHTMLSubtleCrypto(iface)->dispex) + +static HRESULT WINAPI crypto_subtle_encrypt(IWineMSHTMLSubtleCrypto *iface, VARIANT *algorithm, VARIANT *key, + VARIANT *data, IDispatch **result) +{ + struct crypto_subtle *subtle = impl_from_IWineMSHTMLSubtleCrypto(iface); + + FIXME("(%p)->(%p %p %p %p)\n", subtle, algorithm, key, data, result); + + return E_NOTIMPL; +} + +static HRESULT WINAPI crypto_subtle_decrypt(IWineMSHTMLSubtleCrypto *iface, VARIANT *algorithm, VARIANT *key, + VARIANT *data, IDispatch **result) +{ + struct crypto_subtle *subtle = impl_from_IWineMSHTMLSubtleCrypto(iface); + + FIXME("(%p)->(%p %p %p %p)\n", subtle, algorithm, key, data, result); + + return E_NOTIMPL; +} + +static HRESULT WINAPI crypto_subtle_sign(IWineMSHTMLSubtleCrypto *iface, VARIANT *algorithm, VARIANT *key, + VARIANT *data, IDispatch **signature) +{ + struct crypto_subtle *subtle = impl_from_IWineMSHTMLSubtleCrypto(iface); + + FIXME("(%p)->(%p %p %p %p)\n", subtle, algorithm, key, data, signature); + + return E_NOTIMPL; +} + +static HRESULT WINAPI crypto_subtle_verify(IWineMSHTMLSubtleCrypto *iface, VARIANT *algorithm, VARIANT *key, + VARIANT *signature, VARIANT *data, IDispatch **result) +{ + struct crypto_subtle *subtle = impl_from_IWineMSHTMLSubtleCrypto(iface); + + FIXME("(%p)->(%p %p %p %p %p)\n", subtle, algorithm, key, signature, data, result); + + return E_NOTIMPL; +} + +static HRESULT WINAPI crypto_subtle_digest(IWineMSHTMLSubtleCrypto *iface, VARIANT *algorithm, VARIANT *data, + IDispatch **digest) +{ + struct crypto_subtle *subtle = impl_from_IWineMSHTMLSubtleCrypto(iface); + + FIXME("(%p)->(%p %p %p)\n", subtle, algorithm, data, digest); + + return E_NOTIMPL; +} + +static HRESULT WINAPI crypto_subtle_generateKey(IWineMSHTMLSubtleCrypto *iface, VARIANT *algorithm, + VARIANT_BOOL extractable, VARIANT *keyUsages, IDispatch **result) +{ + struct crypto_subtle *subtle = impl_from_IWineMSHTMLSubtleCrypto(iface); + + FIXME("(%p)->(%p %x %p %p)\n", subtle, algorithm, extractable, keyUsages, result); + + return E_NOTIMPL; +} + +static HRESULT WINAPI crypto_subtle_deriveKey(IWineMSHTMLSubtleCrypto *iface, VARIANT *algorithm, VARIANT *baseKey, + VARIANT *derivedKeyAlgorithm, VARIANT_BOOL extractable, VARIANT *keyUsages, IDispatch **result) +{ + struct crypto_subtle *subtle = impl_from_IWineMSHTMLSubtleCrypto(iface); + + FIXME("(%p)->(%p %p %p %x %p %p)\n", subtle, algorithm, baseKey, derivedKeyAlgorithm, extractable, + keyUsages, result); + + return E_NOTIMPL; +} + +static HRESULT WINAPI crypto_subtle_importKey(IWineMSHTMLSubtleCrypto *iface, BSTR format, VARIANT *keyData, + VARIANT *algorithm, VARIANT_BOOL extractable, VARIANT *keyUsages, IDispatch **result) +{ + struct crypto_subtle *subtle = impl_from_IWineMSHTMLSubtleCrypto(iface); + + FIXME("(%p)->(%s %p %p %x %p %p)\n", subtle, debugstr_w(format), keyData, algorithm, extractable, + keyUsages, result); + + return E_NOTIMPL; +} + +static HRESULT WINAPI crypto_subtle_exportKey(IWineMSHTMLSubtleCrypto *iface, BSTR format, VARIANT *key, + IDispatch **result) +{ + struct crypto_subtle *subtle = impl_from_IWineMSHTMLSubtleCrypto(iface); + + FIXME("(%p)->(%s %p %p)\n", subtle, debugstr_w(format), key, result); + + return E_NOTIMPL; +} + +static HRESULT WINAPI crypto_subtle_wrapKey(IWineMSHTMLSubtleCrypto *iface, BSTR format, VARIANT *key, + VARIANT *wrappingKey, VARIANT *wrapAlgo, IDispatch **result) +{ + struct crypto_subtle *subtle = impl_from_IWineMSHTMLSubtleCrypto(iface); + + FIXME("(%p)->(%s %p %p %p %p)\n", subtle, debugstr_w(format), key, wrappingKey, wrapAlgo, result); + + return E_NOTIMPL; +} + +static HRESULT WINAPI crypto_subtle_unwrapKey(IWineMSHTMLSubtleCrypto *iface, BSTR format, VARIANT *wrappedKey, + VARIANT *unwrappingKey, VARIANT *unwrapAlgo, VARIANT *unwrappedKeyAlgo, VARIANT_BOOL extractable, + VARIANT *keyUsages, IDispatch **result) +{ + struct crypto_subtle *subtle = impl_from_IWineMSHTMLSubtleCrypto(iface); + + FIXME("(%p)->(%s %p %p %p %p %x %p %p)\n", subtle, debugstr_w(format), wrappedKey, unwrappingKey, unwrapAlgo, + unwrappedKeyAlgo, extractable, keyUsages, result); + + return E_NOTIMPL; +} + +static const IWineMSHTMLSubtleCryptoVtbl WineMSHTMLSubtleCryptoVtbl = { + crypto_subtle_QueryInterface, + crypto_subtle_AddRef, + crypto_subtle_Release, + crypto_subtle_GetTypeInfoCount, + crypto_subtle_GetTypeInfo, + crypto_subtle_GetIDsOfNames, + crypto_subtle_Invoke, + crypto_subtle_encrypt, + crypto_subtle_decrypt, + crypto_subtle_sign, + crypto_subtle_verify, + crypto_subtle_digest, + crypto_subtle_generateKey, + crypto_subtle_deriveKey, + crypto_subtle_importKey, + crypto_subtle_exportKey, + crypto_subtle_wrapKey, + crypto_subtle_unwrapKey +}; + +static inline struct crypto_subtle *crypto_subtle_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, struct crypto_subtle, dispex); +} + +static void *crypto_subtle_query_interface(DispatchEx *dispex, REFIID riid) +{ + struct crypto_subtle *subtle = crypto_subtle_from_DispatchEx(dispex); + + if(IsEqualGUID(&IID_IWineMSHTMLSubtleCrypto, riid)) + return &subtle->IWineMSHTMLSubtleCrypto_iface; + + return NULL; +} + +static void crypto_subtle_destructor(DispatchEx *dispex) +{ + struct crypto_subtle *subtle = crypto_subtle_from_DispatchEx(dispex); + free(subtle); +} + +static const dispex_static_data_vtbl_t crypto_subtle_dispex_vtbl = { + .query_interface = crypto_subtle_query_interface, + .destructor = crypto_subtle_destructor +}; + +static const tid_t crypto_subtle_iface_tids[] = { + IWineMSHTMLSubtleCrypto_tid, + 0 +}; +dispex_static_data_t SubtleCrypto_dispex = { + .id = OBJID_SubtleCrypto, + .vtbl = &crypto_subtle_dispex_vtbl, + .disp_tid = IWineMSHTMLSubtleCrypto_tid, + .iface_tids = crypto_subtle_iface_tids, + .min_compat_mode = COMPAT_MODE_IE11, +}; + struct crypto { DispatchEx dispex; IWineMSHTMLCrypto IWineMSHTMLCrypto_iface; + struct crypto_subtle *subtle; };
static inline struct crypto *impl_from_IWineMSHTMLCrypto(IWineMSHTMLCrypto *iface) @@ -2729,9 +2915,11 @@ static HRESULT WINAPI crypto_get_subtle(IWineMSHTMLCrypto *iface, IDispatch **su { struct crypto *crypto = impl_from_IWineMSHTMLCrypto(iface);
- FIXME("(%p)->(%p)\n", crypto, subtle); + TRACE("(%p)->(%p)\n", crypto, subtle);
- return E_NOTIMPL; + *subtle = (IDispatch*)&crypto->subtle->dispex.IWineJSDispatchHost_iface; + IWineMSHTMLSubtleCrypto_AddRef(&crypto->subtle->IWineMSHTMLSubtleCrypto_iface); + return S_OK; }
static HRESULT WINAPI crypto_getRandomValues(IWineMSHTMLCrypto *iface, VARIANT *typedArray, IDispatch **ret) @@ -2770,6 +2958,25 @@ static void *crypto_query_interface(DispatchEx *dispex, REFIID riid) return NULL; }
+static void crypto_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct crypto *This = crypto_from_DispatchEx(dispex); + + if(This->subtle) + note_cc_edge((nsISupports*)&This->subtle->dispex.IWineJSDispatchHost_iface, "subtle", cb); +} + +static void crypto_unlink(DispatchEx *dispex) +{ + struct crypto *This = crypto_from_DispatchEx(dispex); + + if(This->subtle) { + struct crypto_subtle *subtle = This->subtle; + This->subtle = NULL; + IWineJSDispatchHost_Release(&subtle->dispex.IWineJSDispatchHost_iface); + } +} + static void crypto_destructor(DispatchEx *dispex) { struct crypto *This = crypto_from_DispatchEx(dispex); @@ -2779,6 +2986,8 @@ static void crypto_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t crypto_dispex_vtbl = { .query_interface = crypto_query_interface, .destructor = crypto_destructor, + .traverse = crypto_traverse, + .unlink = crypto_unlink };
static const tid_t crypto_iface_tids[] = { @@ -2795,13 +3004,23 @@ dispex_static_data_t Crypto_dispex = {
HRESULT create_crypto(HTMLInnerWindow *window, IWineMSHTMLCrypto **ret) { + compat_mode_t compat_mode = dispex_compat_mode(&window->event_target.dispex); + struct crypto_subtle *subtle; struct crypto *crypto;
if(!(crypto = calloc(1, sizeof(*crypto)))) return E_OUTOFMEMORY; + if(!(subtle = calloc(1, sizeof(*subtle)))) { + free(crypto); + return E_OUTOFMEMORY; + }
crypto->IWineMSHTMLCrypto_iface.lpVtbl = &WineMSHTMLCryptoVtbl; - init_dispatch(&crypto->dispex, &Crypto_dispex, window, dispex_compat_mode(&window->event_target.dispex)); + crypto->subtle = subtle; + init_dispatch(&crypto->dispex, &Crypto_dispex, window, compat_mode); + + subtle->IWineMSHTMLSubtleCrypto_iface.lpVtbl = &WineMSHTMLSubtleCryptoVtbl; + init_dispatch(&subtle->dispex, &SubtleCrypto_dispex, window, compat_mode);
*ret = &crypto->IWineMSHTMLCrypto_iface; return S_OK; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 8ad9a141bb5..3a856a62a7d 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -352,6 +352,7 @@ sync_test("builtin_toString", function() { } if(v >= 11) { test("crypto", window.msCrypto, "Crypto"); + test("crypto.subtle", window.msCrypto.subtle, "SubtleCrypto"); test("MutationObserver", new window.MutationObserver(function() {}), "MutationObserver"); } if(v >= 9) { @@ -4505,6 +4506,8 @@ sync_test("prototype props", function() { check(ProgressEvent, [ "initProgressEvent", "lengthComputable", "loaded", "total" ]); check(StorageEvent, [ "initStorageEvent", "key", "newValue", "oldValue", "storageArea", "url" ]); check(StyleSheet, [ "disabled", "href", "media", "ownerNode", "parentStyleSheet", "title", "type" ]); + if(v >= 11) + check(SubtleCrypto, [ "decrypt", "deriveKey", "digest", "encrypt", "exportKey", "generateKey", "importKey", "sign", "unwrapKey", "verify", "wrapKey" ]); check(Text, [ "removeNode", "replaceNode", "replaceWholeText", "splitText", "swapNode", "wholeText" ], [ "replaceWholeText", "wholeText" ]); check(UIEvent, [ "detail", "initUIEvent", "view" ], null, [ "deviceSessionId" ]); if(v < 11) @@ -4701,7 +4704,7 @@ async_test("window own props", function() { ["MSStreamReader",10], "MutationEvent", ["MutationRecord",11], "NodeFilter", "NodeIterator", ["OES_element_index_uint",11], ["OES_standard_derivatives",11], ["OES_texture_float",11], ["OES_texture_float_linear",11], "PerformanceEntry", "PerformanceMark", "PerformanceMeasure", ["PerformanceNavigationTiming",11], "PerformanceResourceTiming", ["Plugin",11], ["PluginArray",9,10], ["PointerEvent",11], ["PopStateEvent",10], "Position", "PositionError", "ProcessingInstruction", "RangeException", "RegExpError", "Selection", ["SourceBuffer",11], - ["SourceBufferList",11], "StyleMedia", "StyleSheetPageList", ["SubtleCrypto",11], "SVGAElement", "SVGAngle", "SVGAnimatedAngle", "SVGAnimatedBoolean", "SVGAnimatedEnumeration", + ["SourceBufferList",11], "StyleMedia", "StyleSheetPageList", "SVGAElement", "SVGAngle", "SVGAnimatedAngle", "SVGAnimatedBoolean", "SVGAnimatedEnumeration", "SVGAnimatedInteger", "SVGAnimatedLength", "SVGAnimatedLengthList", "SVGAnimatedNumber", "SVGAnimatedNumberList", "SVGAnimatedPreserveAspectRatio", "SVGAnimatedRect", "SVGAnimatedString", "SVGAnimatedTransformList", "SVGClipPathElement", ["SVGComponentTransferFunctionElement",10], "SVGDefsElement", "SVGDescElement", "SVGElementInstance", "SVGElementInstanceList", "SVGEllipseElement", "SVGException", ["SVGFEBlendElement",10], ["SVGFEColorMatrixElement",10], ["SVGFEComponentTransferElement",10], ["SVGFECompositeElement",10],
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/arraybuf.c | 34 ++++++++++++++ dlls/jscript/dispex.c | 8 ++++ dlls/jscript/jscript.h | 1 + dlls/jscript/jsdisp.idl | 1 + dlls/mshtml/omnavigator.c | 19 +++++++- dlls/mshtml/tests/documentmode.js | 77 +++++++++++++++++++++++++++++++ 6 files changed, 138 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/arraybuf.c b/dlls/jscript/arraybuf.c index a01ac7d3321..7135034c482 100644 --- a/dlls/jscript/arraybuf.c +++ b/dlls/jscript/arraybuf.c @@ -19,6 +19,14 @@
#include <limits.h> #include <math.h> +#include <stdarg.h> +#include <stdlib.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "ntsecapi.h"
#include "jscript.h"
@@ -1388,3 +1396,29 @@ HRESULT init_arraybuf_constructors(script_ctx_t *ctx)
return hres; } + +HRESULT typed_array_get_random_values(jsdisp_t *obj) +{ + TypedArrayInstance *typedarr; + DWORD size; + + if(!obj || obj->builtin_info->class < FIRST_TYPEDARRAY_JSCLASS || obj->builtin_info->class > LAST_TYPEDARRAY_JSCLASS) + return E_INVALIDARG; + + if(obj->builtin_info->class == JSCLASS_FLOAT32ARRAY || obj->builtin_info->class == JSCLASS_FLOAT64ARRAY) { + /* FIXME: Return TypeMismatchError */ + return E_FAIL; + } + + typedarr = typedarr_from_jsdisp(obj); + size = typedarr->length * typed_array_descs[obj->builtin_info->class - FIRST_TYPEDARRAY_JSCLASS].size; + if(size > 65536) { + /* FIXME: Return QuotaExceededError */ + return E_FAIL; + } + + if(!RtlGenRandom(&typedarr->buffer->buf[typedarr->offset], size)) + return HRESULT_FROM_WIN32(GetLastError()); + + return S_OK; +} diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 897df1a0773..64e00277b21 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -2430,6 +2430,13 @@ static HRESULT WINAPI WineJSDispatch_GetScriptGlobal(IWineJSDispatch *iface, IWi return S_OK; }
+static HRESULT WINAPI WineJSDispatch_GetRandomValues(IWineJSDispatch *iface) +{ + jsdisp_t *This = impl_from_IWineJSDispatch(iface); + + return typed_array_get_random_values(This); +} + static IWineJSDispatchVtbl DispatchExVtbl = { DispatchEx_QueryInterface, DispatchEx_AddRef, @@ -2451,6 +2458,7 @@ static IWineJSDispatchVtbl DispatchExVtbl = { WineJSDispatch_DefineProperty, WineJSDispatch_UpdateProperty, WineJSDispatch_GetScriptGlobal, + WineJSDispatch_GetRandomValues, };
jsdisp_t *as_jsdisp(IDispatch *disp) diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 42d52898892..af36dd8568c 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -494,6 +494,7 @@ HRESULT regexp_string_match(script_ctx_t*,jsdisp_t*,jsstr_t*,jsval_t*);
BOOL bool_obj_value(jsdisp_t*); unsigned array_get_length(jsdisp_t*); +HRESULT typed_array_get_random_values(jsdisp_t*); HRESULT localize_number(script_ctx_t*,DOUBLE,BOOL,jsstr_t**);
BOOL is_builtin_eval_func(jsdisp_t*); diff --git a/dlls/jscript/jsdisp.idl b/dlls/jscript/jsdisp.idl index a9941b98070..5252e68a63d 100644 --- a/dlls/jscript/jsdisp.idl +++ b/dlls/jscript/jsdisp.idl @@ -56,6 +56,7 @@ interface IWineJSDispatch : IDispatchEx HRESULT DefineProperty(const WCHAR *name, unsigned int flags, VARIANT *v); HRESULT UpdateProperty(struct property_info *desc); HRESULT GetScriptGlobal(IWineJSDispatchHost **ret); + HRESULT GetRandomValues(); }
[ diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index c6a107bbb20..fea947a3759 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -2925,10 +2925,25 @@ static HRESULT WINAPI crypto_get_subtle(IWineMSHTMLCrypto *iface, IDispatch **su static HRESULT WINAPI crypto_getRandomValues(IWineMSHTMLCrypto *iface, VARIANT *typedArray, IDispatch **ret) { struct crypto *crypto = impl_from_IWineMSHTMLCrypto(iface); + IWineJSDispatch *jsdisp; + HRESULT hres;
- FIXME("(%p)->(%p %p)\n", crypto, typedArray, ret); + TRACE("(%p)->(%p %p)\n", crypto, typedArray, ret);
- return E_NOTIMPL; + if(V_VT(typedArray) != VT_DISPATCH || !V_DISPATCH(typedArray)) + return E_INVALIDARG; + + hres = IDispatch_QueryInterface(V_DISPATCH(typedArray), &IID_IWineJSDispatch, (void**)&jsdisp); + if(FAILED(hres)) + return E_INVALIDARG; + + hres = IWineJSDispatch_GetRandomValues(jsdisp); + IWineJSDispatch_Release(jsdisp); + if(SUCCEEDED(hres) && ret) { + *ret = V_DISPATCH(typedArray); + IDispatch_AddRef(*ret); + } + return hres; }
static const IWineMSHTMLCryptoVtbl WineMSHTMLCryptoVtbl = { diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 3a856a62a7d..76197e2d2e1 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3703,6 +3703,83 @@ sync_test("__defineSetter__", function() { ok(x.setterVal === 9, "x.setterVal after setting bar = " + x.setterVal); });
+sync_test("Crypto", function() { + var crypto = window.msCrypto, arr, r; + if(!crypto) return; + + var list = [ + [ "Int8Array", 65536 ], + [ "Uint8Array", 65536 ], + [ "Int16Array", 32768 ], + [ "Uint16Array", 32768 ], + [ "Int32Array", 16384 ], + [ "Uint32Array", 16384 ] + ]; + for(var i = 0; i < list.length; i++) { + var constr = list[i][0]; + arr = (window[constr])(list[i][1]); + + ok(arr[0] === 0, constr + "[0] = " + arr[0]); + ok(arr[1] === 0, constr + "[1] = " + arr[1]); + r = crypto.getRandomValues(arr); + ok(r === arr, "getRandomValues returned " + r); + + arr = (window[constr])(list[i][1]+1); + try { + crypto.getRandomValues(arr); + }catch(ex) { + var n = ex.number >>> 0; + todo_wine. + ok(ex.name === "QuotaExceededError", "getRandomValues(oversized " + constr + ") threw " + ex.name); + todo_wine. + ok(n === 0, "getRandomValues(oversized " + constr + ") threw code " + n); + todo_wine. + ok(ex.message === "QuotaExceededError", "getRandomValues(oversized " + constr + ") threw message " + ex.message); + } + } + + try { + crypto.getRandomValues(null); + ok(false, "getRandomValues(null) did not throw exception"); + }catch(e) { + ok(e.number === 0x70057 - 0x80000000, "getRandomValues(null) threw " + e.number); + } + try { + crypto.getRandomValues(external.nullDisp); + ok(false, "getRandomValues(nullDisp) did not throw exception"); + }catch(e) { + ok(e.number === 0x70057 - 0x80000000, "getRandomValues(nullDisp) threw " + e.number); + } + try { + crypto.getRandomValues([1,2,3]); + ok(false, "getRandomValues([1,2,3]) did not throw exception"); + }catch(e) { + ok(e.number === 0x70057 - 0x80000000, "getRandomValues([1,2,3]) threw " + e.number); + } + arr = Float32Array(2); + try { + crypto.getRandomValues(arr); + ok(false, "getRandomValues(Float32Array) did not throw exception"); + }catch(ex) { + var n = ex.number >>> 0; + todo_wine. + ok(ex.name === "TypeMismatchError", "getRandomValues(Float32Array) threw " + ex.name); + todo_wine. + ok(n === 0, "getRandomValues(Float32Array) threw code " + n); + } + arr = Float64Array(2); + try { + crypto.getRandomValues(arr); + ok(false, "getRandomValues(Float64Array) did not throw exception"); + }catch(ex) { + var n = ex.number >>> 0; + todo_wine. + ok(ex.name === "TypeMismatchError", "getRandomValues(Float64Array) threw " + ex.name); + todo_wine. + ok(n === 0, "getRandomValues(Float64Array) threw code " + n); + } +}); + sync_test("MutationObserver", function() { if (!window.MutationObserver) { return;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/arraybuf.c | 14 ++++++++++++++ dlls/jscript/jscript.c | 7 +++++++ dlls/jscript/jscript.h | 1 + dlls/jscript/jsdisp.idl | 1 + dlls/mshtml/tests/xhr.js | 14 ++++++++++++++ dlls/mshtml/xmlhttprequest.c | 31 +++++++++++++++++++++++++++++-- 6 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/arraybuf.c b/dlls/jscript/arraybuf.c index 7135034c482..c99b96e5cad 100644 --- a/dlls/jscript/arraybuf.c +++ b/dlls/jscript/arraybuf.c @@ -177,6 +177,20 @@ static HRESULT create_arraybuf(script_ctx_t *ctx, DWORD size, ArrayBufferInstanc return S_OK; }
+HRESULT create_arraybuffer(script_ctx_t *ctx, DWORD size, IWineJSDispatch **ret, void **data) +{ + ArrayBufferInstance *buf; + HRESULT hres; + + hres = create_arraybuf(ctx, size, &buf); + if(FAILED(hres)) + return hres; + + *ret = &buf->dispex.IWineJSDispatch_iface; + *data = buf->buf; + return S_OK; +} + static HRESULT ArrayBufferConstr_isView(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index b65b95b1e0f..30727a5ab2b 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -1477,6 +1477,12 @@ static HRESULT WINAPI WineJScript_CreateObject(IWineJScript *iface, IWineJSDispa return hres; }
+static HRESULT WINAPI WineJScript_CreateArrayBuffer(IWineJScript *iface, DWORD size, IWineJSDispatch **arraybuf, void **data) +{ + JScript *This = impl_from_IWineJScript(iface); + return create_arraybuffer(This->ctx, size, arraybuf, data); +} + static HRESULT WINAPI WineJScript_FillGlobals(IWineJScript *iface, IWineJSDispatchHost *script_global) { JScript *This = impl_from_IWineJScript(iface); @@ -1490,6 +1496,7 @@ static const IWineJScriptVtbl WineJScriptVtbl = { WineJScript_InitHostObject, WineJScript_InitHostConstructor, WineJScript_CreateObject, + WineJScript_CreateArrayBuffer, WineJScript_FillGlobals, };
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index af36dd8568c..b0b65c37c72 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -297,6 +297,7 @@ void handle_dispatch_exception(script_ctx_t *ctx, EXCEPINFO *ei); HRESULT create_object(script_ctx_t*,jsdisp_t*,jsdisp_t**); HRESULT create_math(script_ctx_t*,jsdisp_t**); HRESULT create_array(script_ctx_t*,DWORD,jsdisp_t**); +HRESULT create_arraybuffer(script_ctx_t*,DWORD,IWineJSDispatch**,void**); HRESULT create_regexp(script_ctx_t*,jsstr_t*,DWORD,jsdisp_t**); HRESULT create_regexp_var(script_ctx_t*,jsval_t,jsval_t*,jsdisp_t**); HRESULT create_string(script_ctx_t*,jsstr_t*,jsdisp_t**); diff --git a/dlls/jscript/jsdisp.idl b/dlls/jscript/jsdisp.idl index 5252e68a63d..b0d881509c4 100644 --- a/dlls/jscript/jsdisp.idl +++ b/dlls/jscript/jsdisp.idl @@ -94,5 +94,6 @@ interface IWineJScript : IUnknown HRESULT InitHostObject(IWineJSDispatchHost *host_obj, IWineJSDispatch *prototype, UINT32 flags, IWineJSDispatch **ret); HRESULT InitHostConstructor(IWineJSDispatchHost *constr, const WCHAR *method_name, IWineJSDispatch **ret); HRESULT CreateObject(IWineJSDispatch **ret); + HRESULT CreateArrayBuffer(DWORD size, IWineJSDispatch **ret, void **data); HRESULT FillGlobals(IWineJSDispatchHost *script_global); } diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index 8de2b01545d..ca79bab1358 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -455,6 +455,20 @@ async_test("response", function() { [ "arraybuffer", "image/png", function() { if(xhr.readyState < 4) ok(xhr.response === undefined, "response for arraybuffer with state " + state + " = " + xhr.response); + else { + var buf = xhr.response; + ok(buf instanceof ArrayBuffer, "response for arraybuffer not instanceof ArrayBuffer"); + ok(buf.byteLength === xml.length, "response for arraybuffer byteLength = " + buf.byteLength); + buf = new Uint8Array(buf); + for(var i = 0; i < buf.length; i++) { + if(buf[i] !== xml.charCodeAt(i)) { + var a = new Array(buf.length); + for(var j = 0; j < a.length; j++) a[j] = buf[j]; + ok(false, "response for arraybuffer is wrong (first bad char at pos " + i + "): " + a); + break; + } + } + } }], [ "blob", "wine/test", function() { if(xhr.readyState < 4) diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 6c95088b59e..0aadf00aaa0 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -140,6 +140,7 @@ struct xhr { BOOLEAN synchronous; DWORD magic; DWORD pending_events_magic; + IDispatch *response_obj; HTMLInnerWindow *window; nsIXMLHttpRequest *nsxhr; XMLHttpReqEventListener *event_listener; @@ -1082,9 +1083,19 @@ static HRESULT WINAPI HTMLXMLHttpRequest_private_get_response(IWineXMLHttpReques { HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface); HRESULT hres = S_OK; + UINT32 buf_size; + nsresult nsres; + void *buf;
TRACE("(%p)->(%p)\n", This, p);
+ if(This->xhr.response_obj) { + V_VT(p) = VT_DISPATCH; + V_DISPATCH(p) = This->xhr.response_obj; + IDispatch_AddRef(This->xhr.response_obj); + return S_OK; + } + switch(This->xhr.response_type) { case response_type_empty: case response_type_text: @@ -1103,10 +1114,18 @@ static HRESULT WINAPI HTMLXMLHttpRequest_private_get_response(IWineXMLHttpReques V_VT(p) = VT_EMPTY; break; } + nsres = nsIXMLHttpRequest_GetResponseBuffer(This->xhr.nsxhr, NULL, 0, &buf_size); + assert(nsres == NS_OK); + if(This->xhr.response_type == response_type_arraybuf) { - FIXME("response_type_arraybuf\n"); - return E_NOTIMPL; + hres = IWineJScript_CreateArrayBuffer(This->xhr.window->jscript, buf_size, (IWineJSDispatch**)&This->xhr.response_obj, &buf); + if(SUCCEEDED(hres)) { + nsres = nsIXMLHttpRequest_GetResponseBuffer(This->xhr.nsxhr, buf, buf_size, &buf_size); + assert(nsres == NS_OK); + } + break; } + FIXME("response_type_blob\n"); return E_NOTIMPL;
@@ -1118,6 +1137,11 @@ static HRESULT WINAPI HTMLXMLHttpRequest_private_get_response(IWineXMLHttpReques assert(0); }
+ if(SUCCEEDED(hres) && This->xhr.response_obj) { + V_VT(p) = VT_DISPATCH; + V_DISPATCH(p) = This->xhr.response_obj; + IDispatch_AddRef(This->xhr.response_obj); + } return hres; }
@@ -1439,6 +1463,8 @@ static void xhr_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback note_cc_edge((nsISupports*)&xhr->window->base.IHTMLWindow2_iface, "window", cb); if(xhr->pending_progress_event) note_cc_edge((nsISupports*)&xhr->pending_progress_event->IDOMEvent_iface, "pending_progress_event", cb); + if(xhr->response_obj) + note_cc_edge((nsISupports*)xhr->response_obj, "response_obj", cb); if(xhr->nsxhr) note_cc_edge((nsISupports*)xhr->nsxhr, "nsxhr", cb); traverse_event_target(&xhr->event_target, cb); @@ -1462,6 +1488,7 @@ static void xhr_unlink(DispatchEx *dispex) xhr->pending_progress_event = NULL; IDOMEvent_Release(&pending_progress_event->IDOMEvent_iface); } + unlink_ref(&xhr->response_obj); unlink_ref(&xhr->nsxhr); release_event_target(&xhr->event_target); }
Jacek Caban (@jacek) commented about dlls/mshtml/omnavigator.c:
static HRESULT WINAPI crypto_getRandomValues(IWineMSHTMLCrypto *iface, VARIANT *typedArray, IDispatch **ret) { struct crypto *crypto = impl_from_IWineMSHTMLCrypto(iface);
- IWineJSDispatch *jsdisp;
- HRESULT hres;
- FIXME("(%p)->(%p %p)\n", crypto, typedArray, ret);
- TRACE("(%p)->(%p %p)\n", crypto, typedArray, ret);
- return E_NOTIMPL;
- if(V_VT(typedArray) != VT_DISPATCH || !V_DISPATCH(typedArray))
return E_INVALIDARG;
Could `typedArray` be `IDispatch *` in IDL file instead of `VARIANT`?
Jacek Caban (@jacek) commented about dlls/mshtml/tests/documentmode.js:
ok(x.setterVal === 9, "x.setterVal after setting bar = " + x.setterVal);});
+sync_test("Crypto", function() {
- var crypto = window.msCrypto, arr, r;
Note that instead of `window.msCrypto` you could use just `msCrypto`. Then the extra variable does not seem very useful.