[URL] some basic implementation of url.dll

Raphael fenix at club-internet.fr
Fri Apr 9 18:45:24 CDT 2004


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

 Changelog:
  - add the intshcut.h (Internet Shortcut defs) header
  - basic implementation of IUniformResourceLocatorA and  
IUniformResourceLocatorW (i think it should be the same object but for 
now ...)

Now, if anyone understand how it must be really implemented please fill the 
space :)

Regards,
Raphael
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFAdzWXp7NA3AmQTU4RArMRAKCJ+XZPMm9yehU161vLRAXQ86ZLEACfeyEr
Kkbwd4jVAkcGk3EEq8324Fk=
=kMmA
-----END PGP SIGNATURE-----
-------------- next part --------------
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ include/intshcut.h	2004-04-10 01:31:36.821096312 +0200
@@ -0,0 +1,90 @@
+/*
+ * Internet Shortcut Interface include file
+ *
+ * Copyright 2004 Raphael Junqueira
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_INTSHCUT_H
+#define __WINE_INTSHCUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define E_FLAGS                     MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, 0x1000)
+#define IS_E_EXEC_FAILED            MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, 0x2002)
+#define URL_E_INVALID_SYNTAX        MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, 0x1001)
+#define URL_E_UNREGISTERED_PROTOCOL MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, 0x1002)
+#define URL_E_UNREGISTERED_PROTOCOL MAKE_SCODE(SEVERITY_ERROR, FACILITY_ITF, 0x1002)
+
+typedef struct _URLINVOKECOMMANDINFOA {
+  DWORD  dwcbSize;
+  DWORD  dwFlags;
+  HWND   hwndParent;
+  LPCSTR pcszVerb;
+} URLINVOKECOMMANDINFOA, *PURLINVOKECOMMANDINFOA;
+
+typedef struct _URLINVOKECOMMANDINFOW {
+  DWORD   dwcbSize;
+  DWORD   dwFlags;
+  HWND    hwndParent;
+  LPCWSTR pcszVerb;
+} URLINVOKECOMMANDINFOW, *PURLINVOKECOMMANDINFOW;
+
+typedef struct IUniformResourceLocatorA IUniformResourceLocatorA;
+typedef struct IUniformResourceLocatorW IUniformResourceLocatorW;
+
+/*****************************************************************************
+ * IUniformResourceLocatorA interface
+ */
+#define INTERFACE IUniformResourceLocatorA
+#define IUniformResourceLocatorA_METHODS \
+  IUnknown_METHODS \
+  STDMETHOD(SetURL)(THIS_ LPCSTR pcstrURL, DWORD dwFlags) PURE; \
+  STDMETHOD(GetURL)(THIS_ LPSTR* pstrURL) PURE; \
+  STDMETHOD(InvokeCommand)(THIS_ PURLINVOKECOMMANDINFOA pInv) PURE;
+ICOM_DEFINE(IUniformResourceLocatorA,IUnknown)
+#undef INTERFACE
+
+
+/*****************************************************************************
+ * IUniformResourceLocatorW interface
+ */
+#define INTERFACE IUniformResourceLocatorW
+#define IUniformResourceLocatorW_METHODS \
+  IUnknown_METHODS \
+  STDMETHOD(SetURL)(THIS_ LPCWSTR pcstrURL, DWORD dwFlags) PURE; \
+  STDMETHOD(GetURL)(THIS_ LPWSTR* pstrURL) PURE; \
+  STDMETHOD(InvokeCommand)(THIS_ PURLINVOKECOMMANDINFOW pInv) PURE;
+ICOM_DEFINE(IUniformResourceLocatorW,IUnknown)
+#undef INTERFACE
+
+
+HRESULT WINAPI TranslateURLA(PCSTR pURL, DWORD dwFlags, PSTR* pTranslURL);
+HRESULT WINAPI TranslateURLW(PCWSTR pURL, DWORD dwFlags, PWSTR* pTranslURL);
+
+HRESULT WINAPI URLAssociationDialogA(HWND hwndParent, DWORD dwFlags, PCSTR pszFile, PCSTR pURL, PSTR pBuf, UINT iBufLen);
+HRESULT WINAPI URLAssociationDialogW(HWND hwndParent, DWORD dwFlags, PCWSTR pszFile, PCWSTR pURL, PWSTR pBuf, UINT iBufLen);
+HRESULT WINAPI MIMEAssociationDialogA(HWND hwndParent, DWORD dwFlags, PCSTR pszFile, PCSTR pMIMEContentType, PSTR pBuf, UINT iBufLen);
+HRESULT WINAPI MIMEAssociationDialogW(HWND hwndParent, DWORD dwFlags, PCWSTR pszFile, PCWSTR pMIMEContentType, PWSTR pBuf, UINT iBufLen);
+BOOL    WINAPI InetIsOffline(DWORD dwFlags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
-------------- next part --------------
? dlls/url/internet_shortcut.c
? dlls/url/regsvr.c
? dlls/url/url_private.h
Index: dlls/url/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/url/Makefile.in,v
retrieving revision 1.6
diff -u -r1.6 Makefile.in
--- dlls/url/Makefile.in	11 Oct 2003 01:09:17 -0000	1.6
+++ dlls/url/Makefile.in	9 Apr 2004 23:42:00 -0000
@@ -3,8 +3,12 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = url.dll
+IMPORTS   = ole32 user32 advapi32 kernel32
+EXTRALIBS = -luuid
 
-C_SRCS = url_main.c
+C_SRCS = url_main.c \
+	 internet_shortcut.c \
+	 regsvr.c
 
 @MAKE_DLL_RULES@
 
Index: dlls/url/url.spec
===================================================================
RCS file: /home/wine/wine/dlls/url/url.spec,v
retrieving revision 1.4
diff -u -r1.4 url.spec
--- dlls/url/url.spec	21 Jun 2002 19:15:49 -0000	1.4
+++ dlls/url/url.spec	9 Apr 2004 23:42:00 -0000
@@ -1,7 +1,7 @@
 @ stub AddMIMEFileTypesPS
 @ stub AutodialHookCallback
-@ stub DllCanUnloadNow
-@ stub DllGetClassObject
+@ stdcall DllCanUnloadNow() URL_DllCanUnloadNow
+@ stdcall DllGetClassObject(ptr ptr ptr) URL_DllGetClassObject
 @ stub DummyEntryPoint
 @ stub DummyEntryPointA
 @ stub FileProtocolHandler
Index: dlls/url/url_main.c
===================================================================
RCS file: /home/wine/wine/dlls/url/url_main.c,v
retrieving revision 1.1
diff -u -r1.1 url_main.c
--- dlls/url/url_main.c	14 Sep 2001 21:36:31 -0000	1.1
+++ dlls/url/url_main.c	9 Apr 2004 23:42:00 -0000
@@ -1 +1,172 @@
-/* nothing here yet */
+/* 
+ * Url
+ * 
+ * Copyright 2004 Raphael Junqueira
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "objbase.h"
+#include "wine/debug.h"
+
+#include "url_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(url);
+
+/**
+ * Read:
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_int/shell_int_programming/shortcuts/internet_shortcuts.asp
+ */
+
+/* At process attach */
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+  TRACE("%p,%lx,%p\n", hInstDLL, fdwReason, lpvReserved);
+  if (fdwReason == DLL_PROCESS_ATTACH) {
+    DisableThreadLibraryCalls(hInstDLL);    
+  }
+  return TRUE;
+}
+
+/*******************************************************************************
+ * Url ClassFactory
+ */
+typedef struct {
+  /* IUnknown fields */
+  ICOM_VFIELD(IClassFactory);
+  DWORD      ref; 
+  REFCLSID   rclsid;
+  HRESULT   (*pfnCreateInstanceFactory)(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj);
+} IClassFactoryImpl;
+
+static HRESULT WINAPI UrlCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
+  ICOM_THIS(IClassFactoryImpl,iface);
+  
+  FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
+  return E_NOINTERFACE;
+}
+
+static ULONG WINAPI UrlCF_AddRef(LPCLASSFACTORY iface) {
+  ICOM_THIS(IClassFactoryImpl,iface);
+  return ++(This->ref);
+}
+
+static ULONG WINAPI UrlCF_Release(LPCLASSFACTORY iface) {
+  ICOM_THIS(IClassFactoryImpl,iface);
+  /* static class, won't be  freed */
+  return --(This->ref);
+}
+
+static HRESULT WINAPI UrlCF_CreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj) {
+  ICOM_THIS(IClassFactoryImpl,iface);
+  
+  TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
+  return This->pfnCreateInstanceFactory(iface, pOuter, riid, ppobj);
+}
+
+static HRESULT WINAPI UrlCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
+  ICOM_THIS(IClassFactoryImpl,iface);
+  FIXME("(%p)->(%d),stub!\n",This,dolock);
+  return S_OK;
+}
+
+static ICOM_VTABLE(IClassFactory) UrlCF_Vtbl = {
+  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+  UrlCF_QueryInterface,
+  UrlCF_AddRef,
+  UrlCF_Release,
+  UrlCF_CreateInstance,
+  UrlCF_LockServer
+};
+
+static IClassFactoryImpl URL_CFS[] = {
+  { &UrlCF_Vtbl, 1, &CLSID_InternetShortcut,  URL_CreateInternetShortcut },
+  { &UrlCF_Vtbl, 1, &CLSID_InternetExplorer,  URL_CreateInternetExplorer },
+  { &UrlCF_Vtbl, 1, &CLSID_InternetMIME,      URL_CreateInternetMIME },
+  { NULL, 0, NULL, NULL }
+};
+
+/***********************************************************************
+ *             DllCanUnloadNow (URL.@)
+ */
+BOOL WINAPI URL_DllCanUnloadNow(void)
+{
+    return S_FALSE;
+}
+
+/***********************************************************************
+ *		DllGetClassObject (URL.@)
+ */
+HRESULT WINAPI URL_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+    int i = 0;
+
+    TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+    while (NULL != URL_CFS[i].rclsid) {
+      if (IsEqualGUID(rclsid, URL_CFS[i].rclsid)) {
+	UrlCF_AddRef((IClassFactory*) &URL_CFS[i]);
+	*ppv = &URL_CFS[i];
+	return S_OK;
+      }
+      ++i;
+    }
+
+    FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+    return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+/*
+Writing registry key value: key = HKEY_CLASSES_ROOT\CLSID\{FBF23B41-E3F0-101B-8488-00AA003E56F8}; value name = ; value = MIME and Internet Property Sheet Hook; Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\CLSID\{FBF23B41-E3F0-101B-8488-00AA003E56F8}\InProcServer32; value name = ; value = url.dll; Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\CLSID\{FBF23B41-E3F0-101B-8488-00AA003E56F8}\InProcServer32; value name = ThreadingModel; value = Apartment; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\NewShortcutHandlers; value name = {FBF23B40-E3F0-101B-8488-00AA003E56F8}; value = ; Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\CLSID\{FBF23B42-E3F0-101B-8488-00AA003E56F8}\DefaultIcon; value name = ; value = C:\Program Files\Plus!\Microsoft Internet\iexplore.exe,-32528; Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\CLSID\{FBF23B42-E3F0-101B-8488-00AA003E56F8}\InProcServer32; value name = ; value = url.dll; Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\CLSID\{FBF23B42-E3F0-101B-8488-00AA003E56F8}\InProcServer32; value name = ThreadingModel; value = Apartment; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnceEx\101; value name = 000; value = C:\WTSRV\System32\oleaut32.dll|DllRegisterServer; Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\CLSID\{FBF23B42-E3F0-101B-8488-00AA003E56F8}\ShellEx\PropertySheetHandlers\{FBF23B42-E3F0-101B-8488-00AA003E56F8}; value name = ; value = ; Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\CLSID\{FBF23B42-E3F0-101B-8488-00AA003E56F8}\ShellFolder; value name = ; value = ; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\NewShortcutHandlers; value name = {FBF23B40-E3F0-101B-8488-00AA003E56F8}; value = ; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\URL\DefaultPrefix; value name = ; value = http://; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\URL\Prefixes; value name = ftp; value = ftp://; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\URL\Prefixes; value name = gopher; value = gopher://; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\URL\Prefixes; value name = home; value = http://; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\URL\Prefixes; value name = mosaic; value = http://; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\URL\Prefixes; value name = www; value = http://; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock\Autodial; value name = AutodialDllName32; value = wininet.dll; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock\Autodial; value name = AutodialFcnName32; value = InternetAutodialCallback; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\IEXPLORE.EXE; value name = ; value = C:\PROGRA~1\Plus!\MICROS~1\iexplore.exe; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\IEXPLORE.EXE; value name = Path; value = C:\PROGRA~1\Plus!\MICROS~1\;; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs; value name = SHLWAPI; value = SHLWAPI.DLL; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\Session Manager\KnownDLLs; value name = WININET; value = WININET.DLL; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\Session Manager\KnownDLLs; value name = URLMON; value = URLMON.DLL; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\Session Manager\KnownDLLs; value name = NETAPI32; value = NETAPI32.DLL; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\Session Manager\KnownDLLs; value name = MSRATING; value = MSRATING.DLL; Succeeded.
+Writing registry key value: key = HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\Session Manager\KnownDLLs; value name = URL; value = URL.DLL; Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\InternetExplorer.Application; value name = ; value = Internet Explorer; Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\InternetExplorer.Application\CLSID; value name = ; value = {0002DF01-0000-0000-C000-000000000046}; Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\InternetExplorer.Application\CurVer; value name = ; value = InternetExplorer.Application.1; Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\InternetExplorer.Application.1; value name = ; value = Internet Explorer (Ver 1.0); Succeeded.
+Writing registry key value: key = HKEY_CLASSES_ROOT\InternetExplorer.Application.1\CLSID; value name = ; value = {0002DF01-0000-0000-C000-000000000046}; Succeeded.
+*/
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/url/internet_shortcut.c	2004-04-10 01:13:49.104134175 +0200
@@ -0,0 +1,195 @@
+/* 
+ * IUniformResourceLocatorA Impl
+ * 
+ * Copyright 2004 Raphael Junqueira
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "objbase.h"
+#include "wine/debug.h"
+
+#include "url_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(url);
+
+/* IUniformResourceLocatorA IUnknown parts follow: */
+HRESULT WINAPI IUniformResourceLocatorAImpl_QueryInterface(IUniformResourceLocatorA* iface, REFIID riid, LPVOID *ppobj) {
+    ICOM_THIS(IUniformResourceLocatorAImpl,iface);
+
+    if (IsEqualGUID(riid, &IID_IUnknown)
+        || IsEqualGUID(riid, &IID_IUniformResourceLocatorA)) {
+      IUniformResourceLocatorAImpl_AddRef(iface);
+      *ppobj = This;
+      return S_OK;
+    } else if (IsEqualIID(riid, &IID_IPersistFile)) {
+      *ppobj = (LPVOID) &This->PersistVtbl;
+      IPersistFile_AddRef((LPPERSISTFILE) &This->PersistVtbl);
+      return S_OK;      
+    }
+
+    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
+    return E_NOINTERFACE;
+}
+
+ULONG WINAPI IUniformResourceLocatorAImpl_AddRef(IUniformResourceLocatorA* iface) {
+    ICOM_THIS(IUniformResourceLocatorAImpl,iface);
+    TRACE("(%p) : AddRef from %ld\n", This, This->ref);
+    return ++(This->ref);
+}
+
+ULONG WINAPI IUniformResourceLocatorAImpl_Release(IUniformResourceLocatorA* iface) {
+    ICOM_THIS(IUniformResourceLocatorAImpl,iface);
+    ULONG ref = --This->ref;
+    TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
+    if (ref == 0) {
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+    return ref;
+}
+
+/* IUniformResourceLocatorAImpl Interface follow: */
+HRESULT WINAPI IUniformResourceLocatorAImpl_SetURL(IUniformResourceLocatorA* iface, LPCSTR pcstrURL, DWORD dwFlags) {
+  return S_OK;
+}
+
+HRESULT WINAPI IUniformResourceLocatorAImpl_GetURL(IUniformResourceLocatorA* iface, LPSTR* pstrURL) {
+  return S_OK;
+}
+
+HRESULT WINAPI IUniformResourceLocatorAImpl_InvokeCommand(IUniformResourceLocatorA* iface, PURLINVOKECOMMANDINFOA pInv) {
+  return S_OK;
+}
+
+
+ICOM_VTABLE(IUniformResourceLocatorA) IUniformResourceLocatorA_Vtbl =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IUniformResourceLocatorAImpl_QueryInterface,
+    IUniformResourceLocatorAImpl_AddRef,
+    IUniformResourceLocatorAImpl_Release,
+    IUniformResourceLocatorAImpl_SetURL,
+    IUniformResourceLocatorAImpl_GetURL,
+    IUniformResourceLocatorAImpl_InvokeCommand
+};
+
+/* IUniformResourceLocatorW IUnknown parts follow: */
+HRESULT WINAPI IUniformResourceLocatorWImpl_QueryInterface(IUniformResourceLocatorW* iface, REFIID riid, LPVOID *ppobj)
+{
+    ICOM_THIS(IUniformResourceLocatorWImpl,iface);
+
+    if (IsEqualGUID(riid, &IID_IUnknown)
+        || IsEqualGUID(riid, &IID_IUniformResourceLocatorW)) {
+        IUniformResourceLocatorWImpl_AddRef(iface);
+        *ppobj = This;
+        return S_OK;
+    } else if (IsEqualIID(riid, &IID_IPersistFile)) {
+      *ppobj = (LPVOID) &This->PersistVtbl;
+      IPersistFile_AddRef((LPPERSISTFILE) &This->PersistVtbl);
+      return S_OK;      
+    }
+
+    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
+    return E_NOINTERFACE;
+}
+
+ULONG WINAPI IUniformResourceLocatorWImpl_AddRef(IUniformResourceLocatorW* iface) {
+    ICOM_THIS(IUniformResourceLocatorWImpl,iface);
+    TRACE("(%p) : AddRef from %ld\n", This, This->ref);
+    return ++(This->ref);
+}
+
+ULONG WINAPI IUniformResourceLocatorWImpl_Release(IUniformResourceLocatorW* iface) {
+    ICOM_THIS(IUniformResourceLocatorWImpl,iface);
+    ULONG ref = --This->ref;
+    TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
+    if (ref == 0) {
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+    return ref;
+}
+
+/* IUniformResourceLocatorWImpl Interface follow: */
+HRESULT WINAPI IUniformResourceLocatorWImpl_SetURL(IUniformResourceLocatorW* iface, LPCWSTR pcstrURL, DWORD dwFlags) {
+  return S_OK;
+}
+
+HRESULT WINAPI IUniformResourceLocatorWImpl_GetURL(IUniformResourceLocatorW* iface, LPWSTR* pstrURL) {
+  return S_OK;
+}
+
+HRESULT WINAPI IUniformResourceLocatorWImpl_InvokeCommand(IUniformResourceLocatorW* iface, PURLINVOKECOMMANDINFOW pInv) {
+  return S_OK;
+}
+
+ICOM_VTABLE(IUniformResourceLocatorW) IUniformResourceLocatorW_Vtbl =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+    IUniformResourceLocatorWImpl_QueryInterface,
+    IUniformResourceLocatorWImpl_AddRef,
+    IUniformResourceLocatorWImpl_Release,
+    IUniformResourceLocatorWImpl_SetURL,
+    IUniformResourceLocatorWImpl_GetURL,
+    IUniformResourceLocatorWImpl_InvokeCommand
+};
+
+
+HRESULT URL_CreateInternetShortcut(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj) {
+
+  TRACE("(%p, %s, %p)\n", punkOuter, debugstr_guid(riid), ppobj);
+
+  if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IUniformResourceLocatorA)) {  
+    IUniformResourceLocatorAImpl* loc;
+    loc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IUniformResourceLocatorAImpl));
+    if (NULL == loc) {
+      *ppobj = NULL;
+      return E_OUTOFMEMORY;
+    }
+    loc->lpVtbl = &IUniformResourceLocatorA_Vtbl;
+    loc->ref = 0; /* will be inited with QueryInterface */
+    return IUniformResourceLocatorAImpl_QueryInterface((IUniformResourceLocatorA*)loc, riid, ppobj);
+  } else if (IsEqualGUID(riid, &IID_IUniformResourceLocatorW)) {  
+    IUniformResourceLocatorWImpl* loc;
+    loc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IUniformResourceLocatorWImpl));
+    if (NULL == loc) {
+      *ppobj = NULL;
+      return E_OUTOFMEMORY;
+    }
+    loc->lpVtbl = &IUniformResourceLocatorW_Vtbl;
+    loc->ref = 0; /* will be inited with QueryInterface */
+    return IUniformResourceLocatorWImpl_QueryInterface((IUniformResourceLocatorW*)loc, riid, ppobj);
+  }
+  WARN("(%s, %p): no interface found.\n", debugstr_guid(riid), ppobj);
+  return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+HRESULT URL_CreateInternetMIME(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj) {
+  WARN("(%s, %p): no interface found.\n", debugstr_guid(riid), ppobj);
+  return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+HRESULT URL_CreateInternetExplorer(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj) {
+  WARN("(%s, %p): no interface found.\n", debugstr_guid(riid), ppobj);
+  return CLASS_E_CLASSNOTAVAILABLE;
+}
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/url/regsvr.c	2004-04-10 01:31:04.412380360 +0200
@@ -0,0 +1,588 @@
+/*
+ *	self-registerable dll functions for url.dll
+ *
+ * Copyright (C) 2004 Raphael Junqueira
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "winerror.h"
+
+#include "ole2.h"
+#include "olectl.h"
+
+#include "wine/debug.h"
+
+#include "initguid.h"
+#include "url_private.h"
+
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+ * Near the bottom of this file are the exported DllRegisterServer and
+ * DllUnregisterServer, which make all this worthwhile.
+ */
+
+/***********************************************************************
+ *		interface for self-registering
+ */
+struct regsvr_interface {
+    IID const *iid;		/* NULL for end of list */
+    LPCSTR name;		/* can be NULL to omit */
+    IID const *base_iid;	/* can be NULL to omit */
+    int num_methods;		/* can be <0 to omit */
+    CLSID const *ps_clsid;	/* can be NULL to omit */
+    CLSID const *ps_clsid32;	/* can be NULL to omit */
+};
+
+static HRESULT register_interfaces(struct regsvr_interface const *list);
+static HRESULT unregister_interfaces(struct regsvr_interface const *list);
+
+/**
+ * @todo: maybe adding typelibs support here
+ * [Software\\Classes\\CLSID\\{000C1090-0000-0000-C000-000000000046}\\TypeLib] 1080380217
+ * @="{000C1092-0000-0000-C000-000000000046}"
+ */
+struct regsvr_coclass {
+    CLSID const *clsid;		/* NULL for end of list */
+    LPCSTR name;		/* can be NULL to omit */
+    LPCSTR iph32;		/* can be NULL to omit */
+    LPCSTR ips;			/* can be NULL to omit */
+    LPCSTR ips32;		/* can be NULL to omit */
+    LPCSTR ips32_tmodel;	/* can be NULL to omit, if apartment, iph32 must be set */
+    LPCSTR progid;		/* can be NULL to omit */
+    LPCSTR viprogid;		/* can be NULL to omit */
+    LPCSTR progid_extra;	/* can be NULL to omit */
+};
+
+static HRESULT register_coclasses(struct regsvr_coclass const *list);
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
+
+/***********************************************************************
+ *		static string constants
+ */
+static WCHAR const interface_keyname[10] = {
+    'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
+static WCHAR const base_ifa_keyname[14] = {
+    'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
+    'e', 0 };
+static WCHAR const num_methods_keyname[11] = {
+    'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
+static WCHAR const ps_clsid_keyname[15] = {
+    'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+    'i', 'd', 0 };
+static WCHAR const ps_clsid32_keyname[17] = {
+    'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+    'i', 'd', '3', '2', 0 };
+static WCHAR const clsid_keyname[6] = {
+    'C', 'L', 'S', 'I', 'D', 0 };
+static WCHAR const curver_keyname[7] = {
+    'C', 'u', 'r', 'V', 'e', 'r', 0 };
+static WCHAR const iph32_keyname[] = {
+    'I', 'n', 'P', 'r', 'o', 'c', 'H', 'a', 'n', 'd', 'l', 'e', 'r',
+    '3', '2', 0 };
+static WCHAR const ips_keyname[13] = {
+    'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+    0 };
+static WCHAR const ips32_keyname[15] = {
+    'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+    '3', '2', 0 };
+static WCHAR const progid_keyname[7] = {
+    'P', 'r', 'o', 'g', 'I', 'D', 0 };
+static WCHAR const viprogid_keyname[25] = {
+    'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
+    'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
+    0 };
+static char const tmodel_valuename[] = "ThreadingModel";
+
+/***********************************************************************
+ *		static helper functions
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
+static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
+				   WCHAR const *value);
+static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
+				   char const *value);
+static LONG register_progid(WCHAR const *clsid,
+			    char const *progid, char const *curver_progid,
+			    char const *name, char const *extra);
+static LONG recursive_delete_key(HKEY key);
+static LONG recursive_delete_keyA(HKEY base, char const *name);
+static LONG recursive_delete_keyW(HKEY base, WCHAR const *name);
+
+/***********************************************************************
+ *		register_interfaces
+ */
+static HRESULT register_interfaces(struct regsvr_interface const *list) {
+    LONG res = ERROR_SUCCESS;
+    HKEY interface_key;
+
+    res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
+			  KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->iid; ++list) {
+	WCHAR buf[39];
+	HKEY iid_key;
+
+	StringFromGUID2(list->iid, buf, 39);
+	res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
+			      KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
+	if (res != ERROR_SUCCESS) goto error_close_interface_key;
+
+	if (list->name) {
+	    res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
+				 (CONST BYTE*)(list->name),
+				 strlen(list->name) + 1);
+	    if (res != ERROR_SUCCESS) goto error_close_iid_key;
+	}
+
+	if (list->base_iid) {
+	    register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
+	    if (res != ERROR_SUCCESS) goto error_close_iid_key;
+	}
+
+	if (0 <= list->num_methods) {
+	    static WCHAR const fmt[3] = { '%', 'd', 0 };
+	    HKEY key;
+
+	    res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
+				  KEY_READ | KEY_WRITE, NULL, &key, NULL);
+	    if (res != ERROR_SUCCESS) goto error_close_iid_key;
+
+	    wsprintfW(buf, fmt, list->num_methods);
+	    res = RegSetValueExW(key, NULL, 0, REG_SZ,
+				 (CONST BYTE*)buf,
+				 (lstrlenW(buf) + 1) * sizeof(WCHAR));
+	    RegCloseKey(key);
+
+	    if (res != ERROR_SUCCESS) goto error_close_iid_key;
+	}
+
+	if (list->ps_clsid) {
+	    register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
+	    if (res != ERROR_SUCCESS) goto error_close_iid_key;
+	}
+
+	if (list->ps_clsid32) {
+	    register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
+	    if (res != ERROR_SUCCESS) goto error_close_iid_key;
+	}
+
+    error_close_iid_key:
+	RegCloseKey(iid_key);
+    }
+
+error_close_interface_key:
+    RegCloseKey(interface_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *		unregister_interfaces
+ */
+static HRESULT unregister_interfaces(struct regsvr_interface const *list) {
+    LONG res = ERROR_SUCCESS;
+    HKEY interface_key;
+
+    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
+			KEY_READ | KEY_WRITE, &interface_key);
+    if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->iid; ++list) {
+	WCHAR buf[39];
+
+	StringFromGUID2(list->iid, buf, 39);
+	res = recursive_delete_keyW(interface_key, buf);
+    }
+
+    RegCloseKey(interface_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *		register_coclasses
+ */
+static HRESULT register_coclasses(struct regsvr_coclass const *list) {
+    LONG res = ERROR_SUCCESS;
+    HKEY coclass_key;
+
+    res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
+			  KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+	WCHAR buf[39];
+	HKEY clsid_key;
+
+	StringFromGUID2(list->clsid, buf, 39);
+	res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
+			      KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
+	if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+	if (list->name) {
+	    res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
+				 (CONST BYTE*)(list->name),
+				 strlen(list->name) + 1);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+	}
+
+	if (list->iph32) {
+	    HKEY iph32_key;
+
+	    res = RegCreateKeyExW(clsid_key, iph32_keyname, 0, NULL, 0,
+				  KEY_READ | KEY_WRITE, NULL,
+				  &iph32_key, NULL);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+	    res = RegSetValueExA(iph32_key, NULL, 0, REG_SZ,
+				 (CONST BYTE*)list->iph32,
+				 lstrlenA(list->iph32) + 1);
+	    RegCloseKey(iph32_key);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+	}
+
+	if (list->ips) {
+	    res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+	}
+
+	if (list->ips32) {
+	    HKEY ips32_key;
+
+	    res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
+				  KEY_READ | KEY_WRITE, NULL,
+				  &ips32_key, NULL);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+	    res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
+				 (CONST BYTE*)list->ips32,
+				 lstrlenA(list->ips32) + 1);
+	    if (res == ERROR_SUCCESS && list->ips32_tmodel)
+		res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
+				     (CONST BYTE*)list->ips32_tmodel,
+				     strlen(list->ips32_tmodel) + 1);
+	    RegCloseKey(ips32_key);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+	}
+
+	if (list->progid) {
+	    res = register_key_defvalueA(clsid_key, progid_keyname,
+					 list->progid);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+	    res = register_progid(buf, list->progid, NULL,
+				  list->name, list->progid_extra);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+	}
+
+	if (list->viprogid) {
+	    res = register_key_defvalueA(clsid_key, viprogid_keyname,
+					 list->viprogid);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+	    res = register_progid(buf, list->viprogid, list->progid,
+				  list->name, list->progid_extra);
+	    if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+	}
+
+    error_close_clsid_key:
+	RegCloseKey(clsid_key);
+    }
+
+error_close_coclass_key:
+    RegCloseKey(coclass_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *		unregister_coclasses
+ */
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list) {
+    LONG res = ERROR_SUCCESS;
+    HKEY coclass_key;
+
+    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
+			KEY_READ | KEY_WRITE, &coclass_key);
+    if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+	WCHAR buf[39];
+
+	StringFromGUID2(list->clsid, buf, 39);
+	res = recursive_delete_keyW(coclass_key, buf);
+	if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+	if (list->progid) {
+	    res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid);
+	    if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+	}
+
+	if (list->viprogid) {
+	    res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->viprogid);
+	    if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+	}
+    }
+
+error_close_coclass_key:
+    RegCloseKey(coclass_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *		regsvr_key_guid
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid) {
+    WCHAR buf[39];
+
+    StringFromGUID2(guid, buf, 39);
+    return register_key_defvalueW(base, name, buf);
+}
+
+/***********************************************************************
+ *		regsvr_key_defvalueW
+ */
+static LONG register_key_defvalueW(
+    HKEY base,
+    WCHAR const *name,
+    WCHAR const *value) {
+    LONG res;
+    HKEY key;
+
+    res = RegCreateKeyExW(base, name, 0, NULL, 0,
+			  KEY_READ | KEY_WRITE, NULL, &key, NULL);
+    if (res != ERROR_SUCCESS) return res;
+    res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+			 (lstrlenW(value) + 1) * sizeof(WCHAR));
+    RegCloseKey(key);
+    return res;
+}
+
+/***********************************************************************
+ *		regsvr_key_defvalueA
+ */
+static LONG register_key_defvalueA(
+    HKEY base,
+    WCHAR const *name,
+    char const *value) {
+    LONG res;
+    HKEY key;
+
+    res = RegCreateKeyExW(base, name, 0, NULL, 0,
+			  KEY_READ | KEY_WRITE, NULL, &key, NULL);
+    if (res != ERROR_SUCCESS) return res;
+    res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+			 lstrlenA(value) + 1);
+    RegCloseKey(key);
+    return res;
+}
+
+/***********************************************************************
+ *		regsvr_progid
+ */
+static LONG register_progid(
+    WCHAR const *clsid,
+    char const *progid,
+    char const *curver_progid,
+    char const *name,
+    char const *extra) {
+    LONG res;
+    HKEY progid_key;
+
+    res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
+			  NULL, 0, KEY_READ | KEY_WRITE, NULL,
+			  &progid_key, NULL);
+    if (res != ERROR_SUCCESS) return res;
+
+    if (name) {
+	res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
+			     (CONST BYTE*)name, strlen(name) + 1);
+	if (res != ERROR_SUCCESS) goto error_close_progid_key;
+    }
+
+    if (clsid) {
+	res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
+	if (res != ERROR_SUCCESS) goto error_close_progid_key;
+    }
+
+    if (curver_progid) {
+	res = register_key_defvalueA(progid_key, curver_keyname,
+				     curver_progid);
+	if (res != ERROR_SUCCESS) goto error_close_progid_key;
+    }
+
+    if (extra) {
+	HKEY extra_key;
+
+	res = RegCreateKeyExA(progid_key, extra, 0,
+			      NULL, 0, KEY_READ | KEY_WRITE, NULL,
+			      &extra_key, NULL);
+	if (res == ERROR_SUCCESS)
+	    RegCloseKey(extra_key);
+    }
+
+error_close_progid_key:
+    RegCloseKey(progid_key);
+    return res;
+}
+
+/***********************************************************************
+ *		recursive_delete_key
+ */
+static LONG recursive_delete_key(HKEY key) {
+    LONG res;
+    WCHAR subkey_name[MAX_PATH];
+    DWORD cName;
+    HKEY subkey;
+
+    for (;;) {
+	cName = sizeof(subkey_name) / sizeof(WCHAR);
+	res = RegEnumKeyExW(key, 0, subkey_name, &cName,
+			    NULL, NULL, NULL, NULL);
+	if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
+	    res = ERROR_SUCCESS; /* presumably we're done enumerating */
+	    break;
+	}
+	res = RegOpenKeyExW(key, subkey_name, 0,
+			    KEY_READ | KEY_WRITE, &subkey);
+	if (res == ERROR_FILE_NOT_FOUND) continue;
+	if (res != ERROR_SUCCESS) break;
+
+	res = recursive_delete_key(subkey);
+	RegCloseKey(subkey);
+	if (res != ERROR_SUCCESS) break;
+    }
+
+    if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
+    return res;
+}
+
+/***********************************************************************
+ *		recursive_delete_keyA
+ */
+static LONG recursive_delete_keyA(HKEY base, char const *name) {
+    LONG res;
+    HKEY key;
+
+    res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key);
+    if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
+    if (res != ERROR_SUCCESS) return res;
+    res = recursive_delete_key(key);
+    RegCloseKey(key);
+    return res;
+}
+
+/***********************************************************************
+ *		recursive_delete_keyW
+ */
+static LONG recursive_delete_keyW(HKEY base, WCHAR const *name) {
+    LONG res;
+    HKEY key;
+
+    res = RegOpenKeyExW(base, name, 0, KEY_READ | KEY_WRITE, &key);
+    if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
+    if (res != ERROR_SUCCESS) return res;
+    res = recursive_delete_key(key);
+    RegCloseKey(key);
+    return res;
+}
+
+/***********************************************************************
+ *		coclass list
+ */
+static struct regsvr_coclass const coclass_list[] = {
+    {     
+        &CLSID_InternetShortcut,
+	"Internet Shortcut",
+	"url.dll",
+	NULL,
+	NULL,
+	"Apartment",
+	NULL,
+	NULL
+    },    
+    {
+        &CLSID_InternetMIME,
+	"MIME and Internet Property Sheet Hook",
+	"url.dll",
+	NULL,
+	NULL,
+	"Apartment",
+	NULL,
+	NULL
+    },    
+    {     
+        &CLSID_InternetExplorer,
+	"Internet Explorer",
+	"url.dll",
+	NULL,
+	NULL,
+	"Apartment",
+	NULL,
+	NULL
+    },    
+    { NULL }			/* list terminator */
+};
+
+/***********************************************************************
+ *		interface list
+ */
+static struct regsvr_interface const interface_list[] = {
+    { NULL }			/* list terminator */
+};
+
+/***********************************************************************
+ *		DllRegisterServer
+ */
+HRESULT WINAPI URL_DllRegisterServer(void) {
+    HRESULT hr;
+
+    TRACE("\n");
+
+    hr = register_coclasses(coclass_list);
+    if (SUCCEEDED(hr))
+	hr = register_interfaces(interface_list);
+    return hr;
+}
+
+/***********************************************************************
+ *		DllUnregisterServer
+ */
+HRESULT WINAPI URL_DllUnregisterServer(void) {
+    HRESULT hr;
+
+    TRACE("\n");
+
+    hr = unregister_coclasses(coclass_list);
+    if (SUCCEEDED(hr))
+	hr = unregister_interfaces(interface_list);
+    return hr;
+}
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/url/url_private.h	2004-04-10 01:30:46.257340393 +0200
@@ -0,0 +1,112 @@
+/*
+ * Url private include file
+ *
+ * Copyright 2004 Raphael Junqueira
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_URL_PRIVATE_H
+#define __WINE_URL_PRIVATE_H
+
+#ifndef __WINE_CONFIG_H
+# error You must include config.h to use this header
+#endif
+
+#include <ole2.h>
+#include <winbase.h>
+#include <winerror.h>
+#include <intshcut.h>
+
+DEFINE_GUID(CLSID_InternetShortcut,    0xfbf23b40,0xe3f0,0x101b,0x84,0x88,0x00,0xaa,0x00,0x3e,0x56,0xf8);
+/**
+ * Not sure about that
+ */
+DEFINE_GUID(CLSID_InternetExplorer,    0xfbf23b42,0xe3f0,0x101b,0x84,0x88,0x00,0xaa,0x00,0x3e,0x56,0xf8);
+/** 
+ * TOSEE: 
+ *   seems that CLSID_InternetMIME should be on shell32 ? 
+ */
+DEFINE_GUID(CLSID_InternetMIME,        0xfbf23b41,0xe3f0,0x101b,0x84,0x88,0x00,0xaa,0x00,0x3e,0x56,0xf8);
+
+DEFINE_GUID(IID_IUniformResourceLocatorA, 0xfbf23b80,0xe3f0,0x101b,0x84,0x88,0x00,0xaa,0x00,0x3e,0x56,0xf8);
+DEFINE_GUID(IID_IUniformResourceLocatorW, 0xcabb0da0,0xda57,0x11cf,0x99,0x74,0x00,0x20,0xaf,0xd7,0x97,0x62);
+
+/* Url Interfaces: */
+typedef struct IUniformResourceLocatorAImpl IUniformResourceLocatorAImpl;
+typedef struct IUniformResourceLocatorWImpl IUniformResourceLocatorWImpl;
+
+/* ------------------------- */
+/* IUniformResourceLocatorA */
+/* ------------------------- */
+
+/*****************************************************************************
+ * Predeclare the interface implementation structures
+ */
+extern ICOM_VTABLE(IUniformResourceLocatorA) IUniformResourceLocatorA_Vtbl;
+static ICOM_VTABLE(IPersistFile)             IUniformResourceLocatorAPersist_Vtbl;
+
+/*****************************************************************************
+ * IUniformResourceLocatorA implementation structure
+ */
+struct IUniformResourceLocatorAImpl {
+  /* IUnknown fields */
+  ICOM_VFIELD(IUniformResourceLocatorA);
+  ICOM_VTABLE(IPersistFile)* PersistVtbl;
+  DWORD         ref;
+  /* IUniformResourceLocatorA fields */
+};
+
+ULONG WINAPI IUniformResourceLocatorAImpl_AddRef(IUniformResourceLocatorA* iface);
+ULONG WINAPI IUniformResourceLocatorAImpl_Release(IUniformResourceLocatorA* iface);
+HRESULT WINAPI IUniformResourceLocatorAImpl_SetURL(IUniformResourceLocatorA* iface, LPCSTR pcstrURL, DWORD dwFlags);
+HRESULT WINAPI IUniformResourceLocatorAImpl_GetURL(IUniformResourceLocatorA* iface, LPSTR* pstrURL);
+HRESULT WINAPI IUniformResourceLocatorAImpl_InvokeCommand(IUniformResourceLocatorA* iface, PURLINVOKECOMMANDINFOA pInv);
+
+/* ------------------------- */
+/* IUniformResourceLocatorW */
+/* ------------------------- */
+
+/*****************************************************************************
+ * Predeclare the interface implementation structures
+ */
+extern ICOM_VTABLE(IUniformResourceLocatorW) IUniformResourceLocatorW_Vtbl;
+static ICOM_VTABLE(IPersistFile)             IUniformResourceLocatorWPersist_Vtbl;
+
+/*****************************************************************************
+ * IUniformResourceLocatorW implementation structure
+ */
+struct IUniformResourceLocatorWImpl {
+  /* IUnknown fields */
+  ICOM_VFIELD(IUniformResourceLocatorW);
+  ICOM_VTABLE(IPersistFile)* PersistVtbl;
+  DWORD         ref;
+  /* IUniformResourceLocatorW fields */
+};
+
+ULONG WINAPI IUniformResourceLocatorWImpl_AddRef(IUniformResourceLocatorW* iface);
+ULONG WINAPI IUniformResourceLocatorWImpl_Release(IUniformResourceLocatorW* iface);
+HRESULT WINAPI IUniformResourceLocatorWImpl_SetURL(IUniformResourceLocatorW* iface, LPCWSTR pcstrURL, DWORD dwFlags);
+HRESULT WINAPI IUniformResourceLocatorWImpl_GetURL(IUniformResourceLocatorW* iface, LPWSTR* pstrURL);
+HRESULT WINAPI IUniformResourceLocatorWImpl_InvokeCommand(IUniformResourceLocatorW* iface, PURLINVOKECOMMANDINFOW pInv);
+
+/**
+ * Factories
+ */
+extern HRESULT URL_CreateInternetShortcut(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj);
+extern HRESULT URL_CreateInternetMIME(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj);
+extern HRESULT URL_CreateInternetExplorer(LPCLASSFACTORY iface, LPUNKNOWN punkOuter, REFIID riid, LPVOID *ppobj);
+
+#endif


More information about the wine-patches mailing list