Bug 661991 - dynamically load entry point to SHCreateItemFromParsingName and share this with jump list code. r=ehsan.

This commit is contained in:
Jim Mathies 2011-12-14 15:22:46 -06:00
Родитель a464c22dde
Коммит 33d873ac37
5 изменённых файлов: 46 добавлений и 40 удалений

Просмотреть файл

@ -55,16 +55,12 @@
#include "mozIAsyncFavicons.h" #include "mozIAsyncFavicons.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "JumpListBuilder.h" #include "JumpListBuilder.h"
#include "nsToolkit.h"
namespace mozilla { namespace mozilla {
namespace widget { namespace widget {
// SHCreateItemFromParsingName is only available on vista and up. We only load this if we
// need to call it on win7+.
JumpListLink::SHCreateItemFromParsingNamePtr JumpListLink::createItemFromParsingName = nsnull;
const PRUnichar JumpListLink::kSehllLibraryName[] = L"shell32.dll";
const char JumpListItem::kJumpListCacheDir[] = "jumpListCache"; const char JumpListItem::kJumpListCacheDir[] = "jumpListCache";
HMODULE JumpListLink::sShellDll = nsnull;
// ISUPPORTS Impl's // ISUPPORTS Impl's
NS_IMPL_ISUPPORTS1(JumpListItem, NS_IMPL_ISUPPORTS1(JumpListItem,
@ -742,18 +738,11 @@ nsresult JumpListLink::GetShellItem(nsCOMPtr<nsIJumpListItem>& item, nsRefPtr<IS
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// Load vista+ SHCreateItemFromParsingName // Load vista+ SHCreateItemFromParsingName
if (createItemFromParsingName == nsnull) { if (!nsToolkit::VistaCreateItemFromParsingNameInit())
if (sShellDll) return NS_ERROR_UNEXPECTED;
return NS_ERROR_UNEXPECTED;
sShellDll = ::LoadLibraryW(kSehllLibraryName);
if (sShellDll)
createItemFromParsingName = (SHCreateItemFromParsingNamePtr)GetProcAddress(sShellDll, "SHCreateItemFromParsingName");
if (createItemFromParsingName == nsnull)
return NS_ERROR_UNEXPECTED;
}
// Create the IShellItem // Create the IShellItem
if (FAILED(createItemFromParsingName(NS_ConvertASCIItoUTF16(spec).get(), if (FAILED(nsToolkit::createItemFromParsingName(NS_ConvertASCIItoUTF16(spec).get(),
NULL, IID_PPV_ARGS(&psi)))) NULL, IID_PPV_ARGS(&psi))))
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;

Просмотреть файл

@ -118,14 +118,9 @@ public:
static nsresult GetJumpListLink(IShellItem *pItem, nsCOMPtr<nsIJumpListLink>& aLink); static nsresult GetJumpListLink(IShellItem *pItem, nsCOMPtr<nsIJumpListLink>& aLink);
protected: protected:
typedef HRESULT (WINAPI * SHCreateItemFromParsingNamePtr)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
nsString mUriTitle; nsString mUriTitle;
nsCOMPtr<nsIURI> mURI; nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsICryptoHash> mCryptoHash; nsCOMPtr<nsICryptoHash> mCryptoHash;
static const PRUnichar kSehllLibraryName[];
static HMODULE sShellDll;
static SHCreateItemFromParsingNamePtr createItemFromParsingName;
}; };
class JumpListShortcut : public JumpListItem, public nsIJumpListShortcut class JumpListShortcut : public JumpListItem, public nsIJumpListShortcut

Просмотреть файл

@ -68,6 +68,7 @@ static const DWORD kDialogTimerID = 9999;
static const unsigned long kDialogTimerTimeout = 300; static const unsigned long kDialogTimerTimeout = 300;
#define MAX_EXTENSION_LENGTH 10 #define MAX_EXTENSION_LENGTH 10
#define FILE_BUFFER_SIZE 4096
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Helper classes // Helper classes
@ -612,11 +613,12 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir)
// initial strings // initial strings
dialog->SetTitle(mTitle.get()); dialog->SetTitle(mTitle.get());
if (!aInitialDir.IsEmpty()) { if (!aInitialDir.IsEmpty() &&
nsToolkit::VistaCreateItemFromParsingNameInit()) {
nsRefPtr<IShellItem> folder; nsRefPtr<IShellItem> folder;
if (SUCCEEDED(SHCreateItemFromParsingName(aInitialDir.get(), NULL, if (SUCCEEDED(nsToolkit::createItemFromParsingName(aInitialDir.get(), NULL,
IID_IShellItem, IID_IShellItem,
getter_AddRefs(folder)))) { getter_AddRefs(folder)))) {
dialog->SetFolder(folder); dialog->SetFolder(folder);
} }
} }
@ -938,11 +940,12 @@ nsFilePicker::ShowFilePicker(const nsString& aInitialDir)
} }
// initial location // initial location
if (!aInitialDir.IsEmpty()) { if (!aInitialDir.IsEmpty() &&
nsToolkit::VistaCreateItemFromParsingNameInit()) {
nsRefPtr<IShellItem> folder; nsRefPtr<IShellItem> folder;
if (SUCCEEDED(SHCreateItemFromParsingName(aInitialDir.get(), NULL, if (SUCCEEDED(nsToolkit::createItemFromParsingName(aInitialDir.get(), NULL,
IID_IShellItem, IID_IShellItem,
getter_AddRefs(folder)))) { getter_AddRefs(folder)))) {
dialog->SetFolder(folder); dialog->SetFolder(folder);
} }
} }

Просмотреть файл

@ -54,11 +54,14 @@
#include <unknwn.h> #include <unknwn.h>
nsToolkit* nsToolkit::gToolkit = nsnull; nsToolkit* nsToolkit::gToolkit = nsnull;
HINSTANCE nsToolkit::mDllInstance = 0; HINSTANCE nsToolkit::mDllInstance = 0;
static const unsigned long kD3DUsageDelay = 5000; static const unsigned long kD3DUsageDelay = 5000;
// SHCreateItemFromParsingName is only available on vista and up.
nsToolkit::SHCreateItemFromParsingNamePtr nsToolkit::createItemFromParsingName = nsnull;
const PRUnichar nsToolkit::kSehllLibraryName[] = L"shell32.dll";
HMODULE nsToolkit::sShellDll = nsnull;
static void static void
StartAllowingD3D9(nsITimer *aTimer, void *aClosure) StartAllowingD3D9(nsITimer *aTimer, void *aClosure)
{ {
@ -122,6 +125,24 @@ nsToolkit::StartAllowingD3D9()
nsWindow::StartAllowingD3D9(false); nsWindow::StartAllowingD3D9(false);
} }
// Load and store Vista+ SHCreateItemFromParsingName
bool
nsToolkit::VistaCreateItemFromParsingNameInit()
{
if (createItemFromParsingName)
return true;
if (sShellDll)
return false;
sShellDll = LoadLibraryW(kSehllLibraryName);
if (!sShellDll)
return false;
createItemFromParsingName = (SHCreateItemFromParsingNamePtr)
GetProcAddress(sShellDll, "SHCreateItemFromParsingName");
if (createItemFromParsingName == nsnull)
return false;
return true;
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// Return the nsToolkit for the current thread. If a toolkit does not // Return the nsToolkit for the current thread. If a toolkit does not

Просмотреть файл

@ -43,7 +43,8 @@
#include "nsITimer.h" #include "nsITimer.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include <windows.h>
#include <shobjidl.h>
#include <imm.h> #include <imm.h>
// Avoid including windowsx.h to prevent macro pollution // Avoid including windowsx.h to prevent macro pollution
@ -54,15 +55,6 @@
#define GET_Y_LPARAM(pt) (short(HIWORD(pt))) #define GET_Y_LPARAM(pt) (short(HIWORD(pt)))
#endif #endif
// we used to use MAX_PATH
// which works great for one file
// but for multiple files, the format is
// dirpath\0\file1\0file2\0...filen\0\0
// and that can quickly be more than MAX_PATH (260)
// see bug #172001 for more details
#define FILE_BUFFER_SIZE 4096
/** /**
* Makes sure exit/enter mouse messages are always dispatched. * Makes sure exit/enter mouse messages are always dispatched.
* In the case where the mouse has exited the outer most window the * In the case where the mouse has exited the outer most window the
@ -121,12 +113,18 @@ public:
static void Startup(HMODULE hModule); static void Startup(HMODULE hModule);
static void Shutdown(); static void Shutdown();
static void StartAllowingD3D9(); static void StartAllowingD3D9();
static bool VistaCreateItemFromParsingNameInit();
typedef HRESULT (WINAPI * SHCreateItemFromParsingNamePtr)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
static SHCreateItemFromParsingNamePtr createItemFromParsingName;
protected: protected:
static nsToolkit* gToolkit; static nsToolkit* gToolkit;
nsCOMPtr<nsITimer> mD3D9Timer; nsCOMPtr<nsITimer> mD3D9Timer;
MouseTrailer mMouseTrailer; MouseTrailer mMouseTrailer;
static const PRUnichar kSehllLibraryName[];
static HMODULE sShellDll;
}; };
#endif // TOOLKIT_H #endif // TOOLKIT_H