From 99c4aca480e28fa90d122ab750997e826a87bdd5 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 23 Aug 2010 15:07:30 +0200 Subject: [PATCH] mshtml: Provide profile directory to Gecko. --- dlls/mshtml/Makefile.in | 2 +- dlls/mshtml/nsembed.c | 110 +++++++++++++++++++++++++++++++++++++++- dlls/mshtml/nsiface.idl | 12 +++++ 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/dlls/mshtml/Makefile.in b/dlls/mshtml/Makefile.in index 2b4671765fe..224a5fa97c3 100644 --- a/dlls/mshtml/Makefile.in +++ b/dlls/mshtml/Makefile.in @@ -4,7 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = mshtml.dll IMPORTLIB = mshtml -IMPORTS = strmiids uuid urlmon shlwapi ole32 oleaut32 user32 gdi32 advapi32 +IMPORTS = strmiids uuid urlmon shlwapi shell32 ole32 oleaut32 user32 gdi32 advapi32 EXTRADEFS = -DCOM_NO_WINDOWS_H DELAYIMPORTS = wininet diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index b2f14dd1985..8ea99a2327a 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -27,6 +27,7 @@ #include "winuser.h" #include "winreg.h" #include "ole2.h" +#include "shlobj.h" #include "wine/debug.h" #include "wine/unicode.h" @@ -70,6 +71,7 @@ static HINSTANCE hXPCOM = NULL; static nsIServiceManager *pServMgr = NULL; static nsIComponentManager *pCompMgr = NULL; static nsIMemory *nsmem = NULL; +static nsIFile *profile_directory; static const WCHAR wszNsContainer[] = {'N','s','C','o','n','t','a','i','n','e','r',0}; @@ -77,6 +79,107 @@ static ATOM nscontainer_class; static WCHAR gecko_path[MAX_PATH]; static unsigned gecko_path_len; +static nsresult NSAPI nsDirectoryServiceProvider_QueryInterface(nsIDirectoryServiceProvider *iface, + nsIIDRef riid, void **result) +{ + if(IsEqualGUID(&IID_nsISupports, riid)) { + TRACE("(IID_nsISupports %p)\n", result); + *result = iface; + }else if(IsEqualGUID(&IID_nsIDirectoryServiceProvider, riid)) { + TRACE("(IID_nsIDirectoryServiceProvider %p)\n", result); + *result = iface; + }else { + WARN("(%s %p)\n", debugstr_guid(riid), result); + *result = NULL; + return NS_NOINTERFACE; + } + + nsISupports_AddRef((nsISupports*)*result); + return NS_OK; +} + +static nsrefcnt NSAPI nsDirectoryServiceProvider_AddRef(nsIDirectoryServiceProvider *iface) +{ + return 2; +} + +static nsrefcnt NSAPI nsDirectoryServiceProvider_Release(nsIDirectoryServiceProvider *iface) +{ + return 1; +} + +static nsresult create_profile_directory(void) +{ + static const WCHAR wine_geckoW[] = {'\\','w','i','n','e','_','g','e','c','k','o',0}; + + WCHAR path[MAX_PATH + sizeof(wine_geckoW)/sizeof(WCHAR)]; + nsAString str; + PRBool exists; + nsresult nsres; + HRESULT hres; + + hres = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_DEFAULT, path); + if(FAILED(hres)) { + ERR("SHGetFolderPath failed: %08x\n", hres); + return NS_ERROR_FAILURE; + } + + strcatW(path, wine_geckoW); + nsAString_InitDepend(&str, path); + nsres = NS_NewLocalFile(&str, FALSE, &profile_directory); + nsAString_Finish(&str); + if(NS_FAILED(nsres)) { + ERR("NS_NewLocalFile failed: %08x\n", nsres); + return nsres; + } + + nsres = nsIFile_Exists(profile_directory, &exists); + if(NS_FAILED(nsres)) { + ERR("Exists failed: %08x\n", nsres); + return nsres; + } + + if(!exists) { + nsres = nsIFile_Create(profile_directory, 1, 0700); + if(NS_FAILED(nsres)) + ERR("Create failed: %08x\n", nsres); + } + + return nsres; +} + +static nsresult NSAPI nsDirectoryServiceProvider_GetFile(nsIDirectoryServiceProvider *iface, + const char *prop, PRBool *persistent, nsIFile **_retval) +{ + TRACE("(%s %p %p)\n", debugstr_a(prop), persistent, _retval); + + if(!strcmp(prop, "ProfD")) { + if(!profile_directory) { + nsresult nsres; + + nsres = create_profile_directory(); + if(NS_FAILED(nsres)) + return nsres; + } + + return nsIFile_Clone(profile_directory, _retval); + } + + return NS_ERROR_FAILURE; +} + +#undef NSWEAKREF_THIS + +static const nsIDirectoryServiceProviderVtbl nsDirectoryServiceProviderVtbl = { + nsDirectoryServiceProvider_QueryInterface, + nsDirectoryServiceProvider_AddRef, + nsDirectoryServiceProvider_Release, + nsDirectoryServiceProvider_GetFile +}; + +static nsIDirectoryServiceProvider nsDirectoryServiceProvider = + { &nsDirectoryServiceProviderVtbl }; + static LRESULT WINAPI nsembed_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { NSContainer *This; @@ -424,7 +527,7 @@ static BOOL init_xpcom(const PRUnichar *gre_path) return FALSE; } - nsres = NS_InitXPCOM2(&pServMgr, gre_dir, NULL); + nsres = NS_InitXPCOM2(&pServMgr, gre_dir, &nsDirectoryServiceProvider); if(NS_FAILED(nsres)) { ERR("NS_InitXPCOM2 failed: %08x\n", nsres); FreeLibrary(hXPCOM); @@ -785,6 +888,11 @@ void close_gecko(void) release_nsio(); + if(profile_directory) { + nsIFile_Release(profile_directory); + profile_directory = NULL; + } + if(pCompMgr) nsIComponentManager_Release(pCompMgr); diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index ab50ee1b603..5b4ab6a1717 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -1917,6 +1917,8 @@ interface nsIFile : nsISupports nsresult SetPermissionsOfLink(PRUint32 pPermissions); nsresult GetLastModifiedTime(PRInt64 *aLastModifiedTime); nsresult SetLastModifiedTime(PRInt64 aLastModifiedTime); + nsresult GetLastModifiedTimeOfLink(PRInt64 *aLastModifiedTimeOfLink); + nsresult SetLastModifiedTimeOfLink(PRInt64 aLastModifiedTimeOfLink); nsresult GetFileSize(PRInt64 *aFileSize); nsresult SetFileSize(PRInt64 aFileSize); nsresult GetFileSizeOfLink(PRInt64 *aFileSizeOfLink); @@ -1968,6 +1970,16 @@ interface nsIPrefBranch : nsISupports nsresult ResetBranch(const char *aStartingAt); } +[ + object, + uuid(bbf8cab0-d43a-11d3-8cc2-00609792278c), + local +] +interface nsIDirectoryServiceProvider : nsISupports +{ + nsresult GetFile(const char *prop, PRBool *persistent, nsIFile **_retval); +} + [ object, uuid(15fd6940-8ea7-11d3-93ad-00104ba0fd40),