Jacek Caban : mshtml: Wrap nsIExternalProtocolHandler.

Alexandre Julliard julliard at wine.codeweavers.com
Mon May 14 10:52:41 CDT 2007


Module: wine
Branch: master
Commit: 836c672dcfcb602e282df20f4efae793c4dbf4ac
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=836c672dcfcb602e282df20f4efae793c4dbf4ac

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Sat May 12 16:12:04 2007 +0200

mshtml: Wrap nsIExternalProtocolHandler.

---

 dlls/mshtml/nsiface.idl |   27 +++++++-
 dlls/mshtml/nsio.c      |  184 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 209 insertions(+), 2 deletions(-)

diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl
index 85b0e30..817030b 100644
--- a/dlls/mshtml/nsiface.idl
+++ b/dlls/mshtml/nsiface.idl
@@ -86,7 +86,6 @@ interface nsISupports
 typedef nsISupports nsISHistory;
 typedef nsISupports nsISimpleEnumerator;
 typedef nsISupports nsIWidget;
-typedef nsISupports nsIProtocolHandler;
 typedef nsISupports nsIDOMAbstractView;
 typedef nsISupports nsIHttpHeaderVisitor;
 typedef nsISupports nsIDOMBarProp;
@@ -1196,6 +1195,32 @@ interface nsIFile : nsISupports
 
 [
     object,
+    uuid(15fd6940-8ea7-11d3-93ad-00104ba0fd40)
+    /* FROZEN */
+]
+interface nsIProtocolHandler : nsISupports
+{
+    nsresult GetScheme(nsACString *aScheme);
+    nsresult GetDefaultPort(PRInt32 *aDefaultPort);
+    nsresult GetProtocolFlags(PRUint32 *aProtocolFlags);
+    nsresult NewURI(const nsACString *aSpec, const char *aOriginCharset,
+                    nsIURI *aBaseURI, nsIURI **_retval);
+    nsresult NewChannel(nsIURI *aURI, nsIChannel **_retval);
+    nsresult AllowPort(PRInt32 port, const char *scheme, PRBool *_retval);
+}
+
+[
+    object,
+    uuid(0e61f3b2-34d7-4c79-bfdc-4860bc7341b7)
+    /* NOT_FROZEN */
+]
+interface nsIExternalProtocolHandler : nsIProtocolHandler
+{
+    nsresult ExternalAppExistsForScheme(const nsACString *scheme, PRBool *_retval);
+}
+
+[
+    object,
     uuid(bddeda3f-9020-4d12-8c70-984ee9f7935e)
     /* FROZEN */
 ]
diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c
index e3eba43..e7cf487 100644
--- a/dlls/mshtml/nsio.c
+++ b/dlls/mshtml/nsio.c
@@ -1698,6 +1698,167 @@ static nsresult create_uri(nsIURI *uri, NSContainer *container, nsIWineURI **_re
     return NS_OK;
 }
 
+typedef struct {
+    const nsIProtocolHandlerVtbl  *lpProtocolHandlerVtbl;
+
+    LONG ref;
+
+    nsIProtocolHandler *nshandler;
+} nsProtocolHandler;
+
+#define NSPROTHANDLER(x)  ((nsIProtocolHandler*)  &(x)->lpProtocolHandlerVtbl)
+
+#define NSPROTHANDLER_THIS(iface) DEFINE_THIS(nsProtocolHandler, ProtocolHandler, iface)
+
+static nsresult NSAPI nsProtocolHandler_QueryInterface(nsIProtocolHandler *iface, nsIIDRef riid,
+        nsQIResult result)
+{
+    nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
+
+    *result = NULL;
+
+    if(IsEqualGUID(&IID_nsISupports, riid)) {
+        TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
+        *result = NSPROTHANDLER(This);
+    }else if(IsEqualGUID(&IID_nsIProtocolHandler, riid)) {
+        TRACE("(%p)->(IID_nsIProtocolHandler %p)\n", This, result);
+        *result = NSPROTHANDLER(This);
+    }else if(IsEqualGUID(&IID_nsIExternalProtocolHandler, riid)) {
+        TRACE("(%p)->(IID_nsIExternalProtocolHandler %p), returning NULL\n", This, result);
+        return NS_NOINTERFACE;
+    }
+
+    if(*result) {
+        nsISupports_AddRef((nsISupports*)*result);
+        return NS_OK;
+    }
+
+    WARN("(%s %p)\nn", debugstr_guid(riid), result);
+    return NS_NOINTERFACE;
+}
+
+static nsrefcnt NSAPI nsProtocolHandler_AddRef(nsIProtocolHandler *iface)
+{
+    nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static nsrefcnt NSAPI nsProtocolHandler_Release(nsIProtocolHandler *iface)
+{
+    nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(!ref) {
+        if(This->nshandler)
+            nsIProtocolHandler_Release(This->nshandler);
+        mshtml_free(This);
+    }
+
+    return ref;
+}
+
+static nsresult NSAPI nsProtocolHandler_GetScheme(nsIProtocolHandler *iface, nsACString *aScheme)
+{
+    nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
+
+    TRACE("(%p)->(%p)\n", This, aScheme);
+
+    if(This->nshandler)
+        return nsIProtocolHandler_GetScheme(This->nshandler, aScheme);
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+static nsresult NSAPI nsProtocolHandler_GetDefaultPort(nsIProtocolHandler *iface,
+        PRInt32 *aDefaultPort)
+{
+    nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
+
+    TRACE("(%p)->(%p)\n", This, aDefaultPort);
+
+    if(This->nshandler)
+        return nsIProtocolHandler_GetDefaultPort(This->nshandler, aDefaultPort);
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+static nsresult NSAPI nsProtocolHandler_GetProtocolFlags(nsIProtocolHandler *iface,
+                                                         PRUint32 *aProtocolFlags)
+{
+    nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
+
+    TRACE("(%p)->(%p)\n", This, aProtocolFlags);
+
+    if(This->nshandler)
+        return nsIProtocolHandler_GetProtocolFlags(This->nshandler, aProtocolFlags);
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+static nsresult NSAPI nsProtocolHandler_NewURI(nsIProtocolHandler *iface,
+        const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
+{
+    nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
+
+    TRACE("((%p)->%p %s %p %p)\n", This, aSpec, debugstr_a(aOriginCharset), aBaseURI, _retval);
+
+    if(This->nshandler)
+        return nsIProtocolHandler_NewURI(This->nshandler, aSpec, aOriginCharset, aBaseURI, _retval);
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+static nsresult NSAPI nsProtocolHandler_NewChannel(nsIProtocolHandler *iface,
+        nsIURI *aURI, nsIChannel **_retval)
+{
+    nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
+
+    TRACE("(%p)->(%p %p)\n", This, aURI, _retval);
+
+    if(This->nshandler)
+        return nsIProtocolHandler_NewChannel(This->nshandler, aURI, _retval);
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+static nsresult NSAPI nsProtocolHandler_AllowPort(nsIProtocolHandler *iface,
+        PRInt32 port, const char *scheme, PRBool *_retval)
+{
+    nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
+
+    TRACE("(%p)->(%d %s %p)\n", This, port, debugstr_a(scheme), _retval);
+
+    if(This->nshandler)
+        return nsIProtocolHandler_AllowPort(This->nshandler, port, scheme, _retval);
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+#undef NSPROTHANDLER_THIS
+
+static const nsIProtocolHandlerVtbl nsProtocolHandlerVtbl = {
+    nsProtocolHandler_QueryInterface,
+    nsProtocolHandler_AddRef,
+    nsProtocolHandler_Release,
+    nsProtocolHandler_GetScheme,
+    nsProtocolHandler_GetDefaultPort,
+    nsProtocolHandler_GetProtocolFlags,
+    nsProtocolHandler_NewURI,
+    nsProtocolHandler_NewChannel,
+    nsProtocolHandler_AllowPort
+};
+
+static nsIProtocolHandler *create_protocol_handler(nsIProtocolHandler *nshandler)
+{
+    nsProtocolHandler *ret = mshtml_alloc(sizeof(nsProtocolHandler));
+
+    ret->lpProtocolHandlerVtbl = &nsProtocolHandlerVtbl;
+    ret->ref = 1;
+    ret->nshandler = nshandler;
+
+    return NSPROTHANDLER(ret);
+}
+
 static nsresult NSAPI nsIOService_QueryInterface(nsIIOService *iface, nsIIDRef riid,
                                                  nsQIResult result)
 {
@@ -1733,8 +1894,29 @@ static nsrefcnt NSAPI nsIOService_Release(nsIIOService *iface)
 static nsresult NSAPI nsIOService_GetProtocolHandler(nsIIOService *iface, const char *aScheme,
                                                      nsIProtocolHandler **_retval)
 {
+    nsIExternalProtocolHandler *nsexthandler;
+    nsIProtocolHandler *nshandler;
+    nsresult nsres;
+
     TRACE("(%s %p)\n", debugstr_a(aScheme), _retval);
-    return nsIIOService_GetProtocolHandler(nsio, aScheme, _retval);
+
+    nsres = nsIIOService_GetProtocolHandler(nsio, aScheme, &nshandler);
+    if(NS_FAILED(nsres)) {
+        WARN("GetProtocolHandler failed: %08x\n", nsres);
+        return nsres;
+    }
+
+    nsres = nsIProtocolHandler_QueryInterface(nshandler, &IID_nsIExternalProtocolHandler,
+                                              (void**)&nsexthandler);
+    if(NS_FAILED(nsres)) {
+        *_retval = nshandler;
+        return NS_OK;
+    }
+
+    nsIExternalProtocolHandler_Release(nsexthandler);
+    *_retval = create_protocol_handler(nshandler);
+    TRACE("return %p\n", *_retval);
+    return NS_OK;
 }
 
 static nsresult NSAPI nsIOService_GetProtocolFlags(nsIIOService *iface, const char *aScheme,




More information about the wine-cvs mailing list