mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backout f1acc52a59da (bug 719983) & 6771bd53e267 (bug 699247) for 30% WinXp Ts regression
This commit is contained in:
parent
945463763f
commit
ada565efab
@ -353,6 +353,16 @@ nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
OSVERSIONINFO osVerInfo = {0};
|
||||
osVerInfo.dwOSVersionInfoSize = sizeof(osVerInfo);
|
||||
GetVersionEx(&osVerInfo);
|
||||
// Always disabled on 2K or less. (bug 536303)
|
||||
if (osVerInfo.dwMajorVersion < 5 ||
|
||||
(osVerInfo.dwMajorVersion == 5 && osVerInfo.dwMinorVersion == 0))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (!prefs) {
|
||||
return false;
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsSetDllDirectory.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -302,7 +303,7 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
|
||||
}
|
||||
|
||||
if (protectCurrentDirectory) {
|
||||
SetDllDirectory(NULL);
|
||||
mozilla::NS_SetDllDirectory(NULL);
|
||||
}
|
||||
|
||||
nsresult rv = plugin->Load(outLibrary);
|
||||
@ -310,7 +311,7 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
|
||||
*outLibrary = NULL;
|
||||
|
||||
if (protectCurrentDirectory) {
|
||||
SetDllDirectory(L"");
|
||||
mozilla::NS_SetDllDirectory(L"");
|
||||
}
|
||||
|
||||
if (restoreOrigDir) {
|
||||
|
@ -147,7 +147,7 @@ PluginProcessChild::Init()
|
||||
}
|
||||
if (protectCurrentDirectory) {
|
||||
SanitizeEnvironmentVariables();
|
||||
SetDllDirectory(L"");
|
||||
NS_SetDllDirectory(L"");
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -107,14 +107,33 @@ static const char *MapErrorCode(int rc)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static HINSTANCE sspi_lib;
|
||||
static PSecurityFunctionTableW sspi;
|
||||
|
||||
static nsresult
|
||||
InitSSPI()
|
||||
{
|
||||
PSecurityFunctionTableW (*initFun)(void);
|
||||
|
||||
LOG((" InitSSPI\n"));
|
||||
|
||||
sspi = InitSecurityInterfaceW();
|
||||
sspi_lib = LoadLibraryW(L"secur32.dll");
|
||||
if (!sspi_lib) {
|
||||
sspi_lib = LoadLibraryW(L"security.dll");
|
||||
if (!sspi_lib) {
|
||||
LOG(("SSPI library not found"));
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
initFun = (PSecurityFunctionTableW (*)(void))
|
||||
GetProcAddress(sspi_lib, "InitSecurityInterfaceW");
|
||||
if (!initFun) {
|
||||
LOG(("InitSecurityInterfaceW not found"));
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
sspi = initFun();
|
||||
if (!sspi) {
|
||||
LOG(("InitSecurityInterfaceW failed"));
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -81,6 +81,18 @@ GetCairoAntialiasOption(gfxFont::AntialiasOption anAntialiasOption)
|
||||
#define FE_FONTSMOOTHINGCLEARTYPE 2
|
||||
#endif
|
||||
|
||||
static bool
|
||||
HasClearType()
|
||||
{
|
||||
OSVERSIONINFO versionInfo;
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
|
||||
return (GetVersionEx(&versionInfo) &&
|
||||
(versionInfo.dwMajorVersion > 5 ||
|
||||
(versionInfo.dwMajorVersion == 5 &&
|
||||
versionInfo.dwMinorVersion >= 1))); // XP or newer
|
||||
}
|
||||
|
||||
static bool
|
||||
UsingClearType()
|
||||
{
|
||||
@ -88,6 +100,10 @@ UsingClearType()
|
||||
if (!SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothing, 0) ||
|
||||
!fontSmoothing)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasClearType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,6 @@
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
#include <usp10.h>
|
||||
#include <t2embapi.h>
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -103,6 +102,50 @@ BuildKeyNameFromFontName(nsAString &aName)
|
||||
// Implementation of gfxPlatformFontList for Win32 GDI,
|
||||
// using GDI font enumeration APIs to get the list of fonts
|
||||
|
||||
// from t2embapi.h, included in Platform SDK 6.1 but not 6.0
|
||||
|
||||
#ifndef __t2embapi__
|
||||
|
||||
#define TTLOAD_PRIVATE 0x00000001
|
||||
#define LICENSE_PREVIEWPRINT 0x0004
|
||||
#define E_NONE 0x0000L
|
||||
|
||||
typedef unsigned long( WINAPIV *READEMBEDPROC ) ( void*, void*, const unsigned long );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usStructSize; // size in bytes of structure client should set to sizeof(TTLOADINFO)
|
||||
unsigned short usRefStrSize; // size in wide characters of pusRefStr including NULL terminator
|
||||
unsigned short *pusRefStr; // reference or actual string.
|
||||
}TTLOADINFO;
|
||||
|
||||
LONG WINAPI TTLoadEmbeddedFont
|
||||
(
|
||||
HANDLE* phFontReference, // on completion, contains handle to identify embedded font installed
|
||||
// on system
|
||||
ULONG ulFlags, // flags specifying the request
|
||||
ULONG* pulPrivStatus, // on completion, contains the embedding status
|
||||
ULONG ulPrivs, // allows for the reduction of licensing privileges
|
||||
ULONG* pulStatus, // on completion, may contain status flags for request
|
||||
READEMBEDPROC lpfnReadFromStream, // callback function for doc/disk reads
|
||||
LPVOID lpvReadStream, // the input stream tokin
|
||||
LPWSTR szWinFamilyName, // the new 16 bit windows family name can be NULL
|
||||
LPSTR szMacFamilyName, // the new 8 bit mac family name can be NULL
|
||||
TTLOADINFO* pTTLoadInfo // optional security
|
||||
);
|
||||
|
||||
#endif // __t2embapi__
|
||||
|
||||
typedef LONG( WINAPI *TTLoadEmbeddedFontProc ) (HANDLE* phFontReference, ULONG ulFlags, ULONG* pulPrivStatus, ULONG ulPrivs, ULONG* pulStatus,
|
||||
READEMBEDPROC lpfnReadFromStream, LPVOID lpvReadStream, LPWSTR szWinFamilyName,
|
||||
LPSTR szMacFamilyName, TTLOADINFO* pTTLoadInfo);
|
||||
|
||||
typedef LONG( WINAPI *TTDeleteEmbeddedFontProc ) (HANDLE hFontReference, ULONG ulFlags, ULONG* pulStatus);
|
||||
|
||||
|
||||
static TTLoadEmbeddedFontProc TTLoadEmbeddedFontPtr = nsnull;
|
||||
static TTDeleteEmbeddedFontProc TTDeleteEmbeddedFontPtr = nsnull;
|
||||
|
||||
class WinUserFontData : public gfxUserFontData {
|
||||
public:
|
||||
WinUserFontData(HANDLE aFontRef, bool aIsEmbedded)
|
||||
@ -114,7 +157,7 @@ public:
|
||||
if (mIsEmbedded) {
|
||||
ULONG pulStatus;
|
||||
LONG err;
|
||||
err = TTDeleteEmbeddedFont(mFontRef, 0, &pulStatus);
|
||||
err = TTDeleteEmbeddedFontPtr(mFontRef, 0, &pulStatus);
|
||||
#if DEBUG
|
||||
if (err != E_NONE) {
|
||||
char buf[256];
|
||||
@ -551,6 +594,8 @@ GDIFontFamily::FindStyleVariations()
|
||||
gfxGDIFontList::gfxGDIFontList()
|
||||
{
|
||||
mFontSubstitutes.Init(50);
|
||||
|
||||
InitializeFontEmbeddingProcs();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -737,6 +782,15 @@ gfxGDIFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
||||
return fe;
|
||||
}
|
||||
|
||||
void gfxGDIFontList::InitializeFontEmbeddingProcs()
|
||||
{
|
||||
HMODULE fontlib = LoadLibraryW(L"t2embed.dll");
|
||||
if (!fontlib)
|
||||
return;
|
||||
TTLoadEmbeddedFontPtr = (TTLoadEmbeddedFontProc) GetProcAddress(fontlib, "TTLoadEmbeddedFont");
|
||||
TTDeleteEmbeddedFontPtr = (TTDeleteEmbeddedFontProc) GetProcAddress(fontlib, "TTDeleteEmbeddedFont");
|
||||
}
|
||||
|
||||
// used to control stream read by Windows TTLoadEmbeddedFont API
|
||||
|
||||
class EOTFontStreamReader {
|
||||
@ -840,6 +894,10 @@ gfxGDIFontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
|
||||
};
|
||||
FontDataDeleter autoDelete(aFontData);
|
||||
|
||||
// if calls aren't available, bail
|
||||
if (!TTLoadEmbeddedFontPtr || !TTDeleteEmbeddedFontPtr)
|
||||
return nsnull;
|
||||
|
||||
bool hasVertical;
|
||||
bool isCFF = gfxFontUtils::IsCffFont(aFontData, hasVertical);
|
||||
|
||||
@ -878,11 +936,11 @@ gfxGDIFontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
|
||||
EOTFontStreamReader eotReader(aFontData, aLength, buffer, eotlen,
|
||||
&overlayNameData);
|
||||
|
||||
ret = TTLoadEmbeddedFont(&fontRef, TTLOAD_PRIVATE, &privStatus,
|
||||
LICENSE_PREVIEWPRINT, &pulStatus,
|
||||
EOTFontStreamReader::ReadEOTStream,
|
||||
&eotReader,
|
||||
(PRUnichar*)(fontName.get()), 0, 0);
|
||||
ret = TTLoadEmbeddedFontPtr(&fontRef, TTLOAD_PRIVATE, &privStatus,
|
||||
LICENSE_PREVIEWPRINT, &pulStatus,
|
||||
EOTFontStreamReader::ReadEOTStream,
|
||||
&eotReader,
|
||||
(PRUnichar*)(fontName.get()), 0, 0);
|
||||
if (ret != E_NONE) {
|
||||
fontRef = nsnull;
|
||||
char buf[256];
|
||||
|
@ -223,6 +223,7 @@ public:
|
||||
// based on http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
|
||||
enum {
|
||||
kWindowsUnknown = 0,
|
||||
kWindows2000 = 0x50000,
|
||||
kWindowsXP = 0x50001,
|
||||
kWindowsServer2003 = 0x50002,
|
||||
kWindowsVista = 0x60000,
|
||||
|
@ -165,7 +165,7 @@ EnableBatteryNotifications()
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// for Windows XP. If we remove Windows XP support,
|
||||
// for Windows 2000 and Windwos XP. If we remove Windows XP support,
|
||||
// we should remove timer-based power notification
|
||||
sUpdateTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
if (sUpdateTimer) {
|
||||
|
@ -74,7 +74,7 @@ main(int argc, char* argv[])
|
||||
// the details.
|
||||
if (proctype != GeckoProcessType_Plugin) {
|
||||
mozilla::SanitizeEnvironmentVariables();
|
||||
SetDllDirectory(L"");
|
||||
mozilla::NS_SetDllDirectory(L"");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -79,6 +79,9 @@ nsAutodial::nsAutodial()
|
||||
mNumRASConnectionEntries(0),
|
||||
mAutodialServiceDialingLocation(-1)
|
||||
{
|
||||
mOSVerInfo.dwOSVersionInfoSize = sizeof(mOSVerInfo);
|
||||
GetVersionEx(&mOSVerInfo);
|
||||
|
||||
// Initializations that can be made again since RAS OS settings can
|
||||
// change.
|
||||
Init();
|
||||
@ -429,27 +432,22 @@ nsresult nsAutodial::GetDefaultEntryName(PRUnichar* entryName, int bufferSize)
|
||||
//
|
||||
// For Windows XP: HKCU/Software/Microsoft/RAS Autodial/Default/DefaultInternet.
|
||||
// or HKLM/Software/Microsoft/RAS Autodial/Default/DefaultInternet.
|
||||
// For Windows 2K: HKCU/RemoteAccess/InternetProfile.
|
||||
|
||||
const PRUnichar* key = L"Software\\Microsoft\\RAS Autodial\\Default";
|
||||
const PRUnichar* val = L"DefaultInternet";
|
||||
const PRUnichar* key = nsnull;
|
||||
const PRUnichar* val = nsnull;
|
||||
|
||||
HKEY hKey = 0;
|
||||
LONG result = 0;
|
||||
|
||||
|
||||
// Try HKCU first.
|
||||
result = ::RegOpenKeyExW(
|
||||
HKEY_CURRENT_USER,
|
||||
key,
|
||||
0,
|
||||
KEY_READ,
|
||||
&hKey);
|
||||
|
||||
if (result != ERROR_SUCCESS)
|
||||
// Windows 2000
|
||||
if ((mOSVerInfo.dwMajorVersion == 5) && (mOSVerInfo.dwMinorVersion == 0)) // Windows 2000
|
||||
{
|
||||
// If not present, try HKLM.
|
||||
key = L"RemoteAccess";
|
||||
val = L"InternetProfile";
|
||||
|
||||
result = ::RegOpenKeyExW(
|
||||
HKEY_LOCAL_MACHINE,
|
||||
HKEY_CURRENT_USER,
|
||||
key,
|
||||
0,
|
||||
KEY_READ,
|
||||
@ -460,6 +458,36 @@ nsresult nsAutodial::GetDefaultEntryName(PRUnichar* entryName, int bufferSize)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
else // Windows XP
|
||||
{
|
||||
key = L"Software\\Microsoft\\RAS Autodial\\Default";
|
||||
val = L"DefaultInternet";
|
||||
|
||||
|
||||
// Try HKCU first.
|
||||
result = ::RegOpenKeyExW(
|
||||
HKEY_CURRENT_USER,
|
||||
key,
|
||||
0,
|
||||
KEY_READ,
|
||||
&hKey);
|
||||
|
||||
if (result != ERROR_SUCCESS)
|
||||
{
|
||||
// If not present, try HKLM.
|
||||
result = ::RegOpenKeyExW(
|
||||
HKEY_LOCAL_MACHINE,
|
||||
key,
|
||||
0,
|
||||
KEY_READ,
|
||||
&hKey);
|
||||
|
||||
if (result != ERROR_SUCCESS)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DWORD entryType = 0;
|
||||
|
@ -126,6 +126,9 @@ private:
|
||||
// Don't try to dial again within a few seconds of when user pressed cancel.
|
||||
static PRIntervalTime mDontRetryUntil;
|
||||
|
||||
// OS version info.
|
||||
OSVERSIONINFO mOSVerInfo;
|
||||
|
||||
public:
|
||||
|
||||
// ctor
|
||||
|
@ -960,8 +960,18 @@ nsSocketTransportService::DiscoverMaxCount()
|
||||
gMaxCount = rlimitData.rlim_cur - 250;
|
||||
|
||||
#elif defined(XP_WIN) && !defined(WIN_CE)
|
||||
// win 95, 98, etc had a limit of 100 - so we will just
|
||||
// use the historical 50 in every case older than XP (0x501).
|
||||
// >= XP is confirmed to have at least 1000
|
||||
gMaxCount = SOCKET_LIMIT_TARGET;
|
||||
|
||||
OSVERSIONINFO osInfo = { sizeof(OSVERSIONINFO) };
|
||||
if (GetVersionEx(&osInfo)) {
|
||||
PRInt32 version =
|
||||
(osInfo.dwMajorVersion & 0xff) << 8 |
|
||||
(osInfo.dwMinorVersion & 0xff);
|
||||
if (version >= 0x501) /* xp or later */
|
||||
gMaxCount = SOCKET_LIMIT_TARGET;
|
||||
}
|
||||
#else
|
||||
// other platforms are harder to test - so leave at safe legacy value
|
||||
#endif
|
||||
|
@ -653,6 +653,8 @@ nsHttpHandler::BuildUserAgent()
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
typedef BOOL (WINAPI *IsWow64ProcessP) (HANDLE, PBOOL);
|
||||
|
||||
#define WNT_BASE "Windows NT %ld.%ld"
|
||||
#define W64_PREFIX "; Win64"
|
||||
#endif
|
||||
@ -715,7 +717,10 @@ nsHttpHandler::InitUserAgentComponents()
|
||||
format = WNT_BASE W64_PREFIX "; x64";
|
||||
#else
|
||||
BOOL isWow64 = FALSE;
|
||||
if (!IsWow64Process(GetCurrentProcess(), &isWow64)) {
|
||||
IsWow64ProcessP fnIsWow64Process = (IsWow64ProcessP)
|
||||
GetProcAddress(GetModuleHandleW(L"kernel32"), "IsWow64Process");
|
||||
if (fnIsWow64Process &&
|
||||
!fnIsWow64Process(GetCurrentProcess(), &isWow64)) {
|
||||
isWow64 = FALSE;
|
||||
}
|
||||
format = isWow64
|
||||
|
@ -59,11 +59,42 @@
|
||||
#include <iptypes.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
typedef DWORD (WINAPI *GetAdaptersAddressesFunc)(ULONG, DWORD, PVOID,
|
||||
PIP_ADAPTER_ADDRESSES,
|
||||
PULONG);
|
||||
typedef DWORD (WINAPI *GetAdaptersInfoFunc)(PIP_ADAPTER_INFO, PULONG);
|
||||
typedef DWORD (WINAPI *GetIfEntryFunc)(PMIB_IFROW);
|
||||
typedef DWORD (WINAPI *GetIpAddrTableFunc)(PMIB_IPADDRTABLE, PULONG, BOOL);
|
||||
typedef DWORD (WINAPI *NotifyAddrChangeFunc)(PHANDLE, LPOVERLAPPED);
|
||||
typedef void (WINAPI *NcFreeNetconPropertiesFunc)(NETCON_PROPERTIES*);
|
||||
|
||||
static HMODULE sNetshell;
|
||||
static HMODULE sIPHelper, sNetshell;
|
||||
static GetAdaptersAddressesFunc sGetAdaptersAddresses;
|
||||
static GetAdaptersInfoFunc sGetAdaptersInfo;
|
||||
static GetIfEntryFunc sGetIfEntry;
|
||||
static GetIpAddrTableFunc sGetIpAddrTable;
|
||||
static NotifyAddrChangeFunc sNotifyAddrChange;
|
||||
static NcFreeNetconPropertiesFunc sNcFreeNetconProperties;
|
||||
|
||||
static void InitIPHelperLibrary(void)
|
||||
{
|
||||
if (!sIPHelper) {
|
||||
sIPHelper = LoadLibraryW(L"iphlpapi.dll");
|
||||
if (sIPHelper) {
|
||||
sGetAdaptersAddresses = (GetAdaptersAddressesFunc)
|
||||
GetProcAddress(sIPHelper, "GetAdaptersAddresses");
|
||||
sGetAdaptersInfo = (GetAdaptersInfoFunc)
|
||||
GetProcAddress(sIPHelper, "GetAdaptersInfo");
|
||||
sGetIfEntry = (GetIfEntryFunc)
|
||||
GetProcAddress(sIPHelper, "GetIfEntry");
|
||||
sGetIpAddrTable = (GetIpAddrTableFunc)
|
||||
GetProcAddress(sIPHelper, "GetIpAddrTable");
|
||||
sNotifyAddrChange = (NotifyAddrChangeFunc)
|
||||
GetProcAddress(sIPHelper, "NotifyAddrChange");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void InitNetshellLibrary(void)
|
||||
{
|
||||
if (!sNetshell) {
|
||||
@ -77,6 +108,18 @@ static void InitNetshellLibrary(void)
|
||||
|
||||
static void FreeDynamicLibraries(void)
|
||||
{
|
||||
if (sIPHelper)
|
||||
{
|
||||
sGetAdaptersAddresses = nsnull;
|
||||
sGetAdaptersInfo = nsnull;
|
||||
sGetIfEntry = nsnull;
|
||||
sGetIpAddrTable = nsnull;
|
||||
sNotifyAddrChange = nsnull;
|
||||
|
||||
FreeLibrary(sIPHelper);
|
||||
sIPHelper = nsnull;
|
||||
}
|
||||
|
||||
if (sNetshell) {
|
||||
sNcFreeNetconProperties = nsnull;
|
||||
FreeLibrary(sNetshell);
|
||||
@ -95,6 +138,8 @@ nsNotifyAddrListener::nsNotifyAddrListener()
|
||||
, mCheckAttempted(false)
|
||||
, mShutdownEvent(nsnull)
|
||||
{
|
||||
mOSVerInfo.dwOSVersionInfoSize = sizeof(mOSVerInfo);
|
||||
GetVersionEx(&mOSVerInfo);
|
||||
}
|
||||
|
||||
nsNotifyAddrListener::~nsNotifyAddrListener()
|
||||
@ -142,10 +187,17 @@ nsNotifyAddrListener::Run()
|
||||
OVERLAPPED overlapped = { 0 };
|
||||
bool shuttingDown = false;
|
||||
|
||||
InitIPHelperLibrary();
|
||||
|
||||
if (!sNotifyAddrChange) {
|
||||
CloseHandle(ev);
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
overlapped.hEvent = ev;
|
||||
while (!shuttingDown) {
|
||||
HANDLE h;
|
||||
DWORD ret = NotifyAddrChange(&h, &overlapped);
|
||||
DWORD ret = sNotifyAddrChange(&h, &overlapped);
|
||||
|
||||
if (ret == ERROR_IO_PENDING) {
|
||||
ret = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
|
||||
@ -184,6 +236,11 @@ nsNotifyAddrListener::Init(void)
|
||||
//
|
||||
// CheckLinkStatus();
|
||||
|
||||
// only start a thread on Windows 2000 or later
|
||||
if (mOSVerInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
|
||||
mOSVerInfo.dwMajorVersion < 5)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (!observerService)
|
||||
@ -257,6 +314,125 @@ nsNotifyAddrListener::ChangeEvent::Run()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DWORD
|
||||
nsNotifyAddrListener::GetOperationalStatus(DWORD aAdapterIndex)
|
||||
{
|
||||
DWORD status = MIB_IF_OPER_STATUS_CONNECTED;
|
||||
|
||||
// try to get operational status on WinNT--on Win98, it consistently gives
|
||||
// me the wrong status, dagnabbit
|
||||
if (mOSVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
|
||||
// If this fails, assume it's connected. Didn't find a KB, but it
|
||||
// failed for me w/Win2K SP2, and succeeded for me w/Win2K SP3.
|
||||
if (sGetIfEntry) {
|
||||
MIB_IFROW ifRow;
|
||||
|
||||
ifRow.dwIndex = aAdapterIndex;
|
||||
if (sGetIfEntry(&ifRow) == ERROR_SUCCESS)
|
||||
status = ifRow.dwOperStatus;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls GetIpAddrTable to check whether a link is up. Assumes so if any
|
||||
* adapter has a non-zero IP (v4) address. Sets mLinkUp if GetIpAddrTable
|
||||
* succeeds, but doesn't set mStatusKnown.
|
||||
* Returns ERROR_SUCCESS on success, and a Win32 error code otherwise.
|
||||
*/
|
||||
DWORD
|
||||
nsNotifyAddrListener::CheckIPAddrTable(void)
|
||||
{
|
||||
if (!sGetIpAddrTable)
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
|
||||
ULONG size = 0;
|
||||
DWORD ret = sGetIpAddrTable(nsnull, &size, FALSE);
|
||||
if (ret == ERROR_INSUFFICIENT_BUFFER && size > 0) {
|
||||
PMIB_IPADDRTABLE table = (PMIB_IPADDRTABLE) malloc(size);
|
||||
if (!table)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
ret = sGetIpAddrTable(table, &size, FALSE);
|
||||
if (ret == ERROR_SUCCESS) {
|
||||
bool linkUp = false;
|
||||
|
||||
for (DWORD i = 0; !linkUp && i < table->dwNumEntries; i++) {
|
||||
if (GetOperationalStatus(table->table[i].dwIndex) >=
|
||||
MIB_IF_OPER_STATUS_CONNECTED &&
|
||||
table->table[i].dwAddr != 0 &&
|
||||
// Nor a loopback
|
||||
table->table[i].dwAddr != 0x0100007F)
|
||||
linkUp = true;
|
||||
}
|
||||
mLinkUp = linkUp;
|
||||
}
|
||||
free(table);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a link is up by calling GetAdaptersInfo. If any adapter's
|
||||
* operational status is at least MIB_IF_OPER_STATUS_CONNECTED, checks:
|
||||
* 1. If it's configured for DHCP, the link is considered up if the DHCP
|
||||
* server is initialized.
|
||||
* 2. If it's not configured for DHCP, the link is considered up if it has a
|
||||
* nonzero IP address.
|
||||
* Sets mLinkUp and mStatusKnown if GetAdaptersInfo succeeds.
|
||||
* Returns ERROR_SUCCESS on success, and a Win32 error code otherwise. If the
|
||||
* call is not present on the current platform, returns ERROR_NOT_SUPPORTED.
|
||||
*/
|
||||
DWORD
|
||||
nsNotifyAddrListener::CheckAdaptersInfo(void)
|
||||
{
|
||||
if (!sGetAdaptersInfo)
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
|
||||
ULONG adaptersLen = 0;
|
||||
|
||||
DWORD ret = sGetAdaptersInfo(0, &adaptersLen);
|
||||
if (ret == ERROR_BUFFER_OVERFLOW && adaptersLen > 0) {
|
||||
PIP_ADAPTER_INFO adapters = (PIP_ADAPTER_INFO) malloc(adaptersLen);
|
||||
if (!adapters)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
ret = sGetAdaptersInfo(adapters, &adaptersLen);
|
||||
if (ret == ERROR_SUCCESS) {
|
||||
bool linkUp = false;
|
||||
PIP_ADAPTER_INFO ptr;
|
||||
|
||||
for (ptr = adapters; ptr && !linkUp; ptr = ptr->Next) {
|
||||
if (GetOperationalStatus(ptr->Index) >=
|
||||
MIB_IF_OPER_STATUS_CONNECTED) {
|
||||
if (ptr->DhcpEnabled) {
|
||||
if (PL_strcmp(ptr->DhcpServer.IpAddress.String,
|
||||
"255.255.255.255")) {
|
||||
// it has a DHCP server, therefore it must have
|
||||
// a usable address
|
||||
linkUp = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PIP_ADDR_STRING ipAddr;
|
||||
for (ipAddr = &ptr->IpAddressList; ipAddr && !linkUp;
|
||||
ipAddr = ipAddr->Next) {
|
||||
if (PL_strcmp(ipAddr->IpAddress.String, "0.0.0.0")) {
|
||||
linkUp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mLinkUp = linkUp;
|
||||
mStatusKnown = true;
|
||||
free(adapters);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL
|
||||
nsNotifyAddrListener::CheckIsGateway(PIP_ADAPTER_ADDRESSES aAdapter)
|
||||
{
|
||||
@ -371,19 +547,22 @@ nsNotifyAddrListener::CheckAdaptersAddresses(void)
|
||||
GAA_FLAG_SKIP_FRIENDLY_NAME | GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
|
||||
|
||||
if (!sGetAdaptersAddresses)
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
|
||||
ULONG len = 16384;
|
||||
|
||||
PIP_ADAPTER_ADDRESSES addresses = (PIP_ADAPTER_ADDRESSES) malloc(len);
|
||||
if (!addresses)
|
||||
return ERROR_OUTOFMEMORY;
|
||||
|
||||
DWORD ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &len);
|
||||
DWORD ret = sGetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &len);
|
||||
if (ret == ERROR_BUFFER_OVERFLOW) {
|
||||
free(addresses);
|
||||
addresses = (PIP_ADAPTER_ADDRESSES) malloc(len);
|
||||
if (!addresses)
|
||||
return ERROR_BUFFER_OVERFLOW;
|
||||
ret = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &len);
|
||||
ret = sGetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &len);
|
||||
}
|
||||
|
||||
if (ret == ERROR_SUCCESS) {
|
||||
@ -416,6 +595,10 @@ nsNotifyAddrListener::CheckLinkStatus(void)
|
||||
const char *event;
|
||||
|
||||
ret = CheckAdaptersAddresses();
|
||||
if (ret == ERROR_NOT_SUPPORTED)
|
||||
ret = CheckAdaptersInfo();
|
||||
if (ret == ERROR_NOT_SUPPORTED)
|
||||
ret = CheckIPAddrTable();
|
||||
if (ret != ERROR_SUCCESS)
|
||||
mLinkUp = true; // I can't tell, so assume there's a link
|
||||
|
||||
|
@ -81,6 +81,9 @@ protected:
|
||||
nsresult Shutdown(void);
|
||||
nsresult SendEventToUI(const char *aEventID);
|
||||
|
||||
DWORD GetOperationalStatus(DWORD aAdapterIndex);
|
||||
DWORD CheckIPAddrTable(void);
|
||||
DWORD CheckAdaptersInfo(void);
|
||||
DWORD CheckAdaptersAddresses(void);
|
||||
BOOL CheckIsGateway(PIP_ADAPTER_ADDRESSES aAdapter);
|
||||
BOOL CheckICSStatus(PWCHAR aAdapterName);
|
||||
@ -88,6 +91,7 @@ protected:
|
||||
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
|
||||
OSVERSIONINFO mOSVerInfo;
|
||||
HANDLE mShutdownEvent;
|
||||
};
|
||||
|
||||
|
@ -527,7 +527,10 @@ endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 version winspool comdlg32 imm32 msimg32 shlwapi psapi ws2_32 dbghelp rasapi32 rasdlg iphlpapi uxtheme setupapi t2embed secur32)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,shell32 ole32 uuid version winspool comdlg32 imm32 winmm wsock32 msimg32 shlwapi psapi ws2_32 dbghelp rasapi32 rasdlg)
|
||||
ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC))
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,imagehlp)
|
||||
endif
|
||||
ifdef MOZ_CRASHREPORTER
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,wininet)
|
||||
endif
|
||||
@ -538,14 +541,10 @@ ifdef _MSC_VER
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,delayimp)
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
-DELAYLOAD:gkmedias.dll \
|
||||
-DELAYLOAD:psapi.dll \
|
||||
-DELAYLOAD:dbghelp.dll \
|
||||
-DELAYLOAD:rasapi32.dll \
|
||||
-DELAYLOAD:rasdlg.dll \
|
||||
-DELAYLOAD:comdlg32.dll \
|
||||
-DELAYLOAD:winspool.drv \
|
||||
-DELAYLOAD:t2embed.dll \
|
||||
-DELAYLOAD:secur32.dll \
|
||||
$(NULL)
|
||||
ifdef ACCESSIBILITY
|
||||
EXTRA_DSO_LDOPTS += -DELAYLOAD:oleacc.dll
|
||||
|
@ -77,7 +77,7 @@ int wmain(int argc, WCHAR **argv)
|
||||
{
|
||||
#ifndef XRE_DONT_PROTECT_DLL_LOAD
|
||||
mozilla::SanitizeEnvironmentVariables();
|
||||
SetDllDirectoryW(L"");
|
||||
mozilla::NS_SetDllDirectory(L"");
|
||||
#endif
|
||||
|
||||
#ifdef XRE_WANT_DLL_BLOCKLIST
|
||||
|
@ -247,6 +247,13 @@ nsMIMEInfoWin::GetProperty(const nsAString& aName, nsIVariant* *_retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
typedef HRESULT (STDMETHODCALLTYPE *MySHParseDisplayName)
|
||||
(PCWSTR pszName,
|
||||
IBindCtx *pbc,
|
||||
LPITEMIDLIST *ppidl,
|
||||
SFGAOF sfgaoIn,
|
||||
SFGAOF *psfgaoOut);
|
||||
|
||||
// this implementation was pretty much copied verbatime from
|
||||
// Tony Robinson's code in nsExternalProtocolWin.cpp
|
||||
nsresult
|
||||
@ -267,6 +274,15 @@ nsMIMEInfoWin::LoadUriInternal(nsIURI * aURL)
|
||||
nsCAutoString urlSpec;
|
||||
aURL->GetAsciiSpec(urlSpec);
|
||||
|
||||
// Some versions of windows (Win2k before SP3, Win XP before SP1)
|
||||
// crash in ShellExecute on long URLs (bug 161357).
|
||||
// IE 5 and 6 support URLS of 2083 chars in length, 2K is safe
|
||||
const PRUint32 maxSafeURL(2048);
|
||||
if (urlSpec.Length() > maxSafeURL)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
HMODULE hDll = NULL;
|
||||
|
||||
static const PRUnichar cmdVerb[] = L"open";
|
||||
SHELLEXECUTEINFOW sinfo;
|
||||
memset(&sinfo, 0, sizeof(sinfo));
|
||||
@ -281,14 +297,22 @@ nsMIMEInfoWin::LoadUriInternal(nsIURI * aURL)
|
||||
SFGAOF sfgao;
|
||||
|
||||
// Bug 394974
|
||||
if (SUCCEEDED(SHParseDisplayName(NS_ConvertUTF8toUTF16(urlSpec).get(),
|
||||
NULL, &pidl, 0, &sfgao))) {
|
||||
sinfo.lpIDList = pidl;
|
||||
sinfo.fMask |= SEE_MASK_INVOKEIDLIST;
|
||||
hDll = ::LoadLibraryW(L"shell32.dll");
|
||||
MySHParseDisplayName pMySHParseDisplayName = NULL;
|
||||
// Version 6.0 and higher
|
||||
if (pMySHParseDisplayName =
|
||||
(MySHParseDisplayName)::GetProcAddress(hDll, "SHParseDisplayName")) {
|
||||
if (SUCCEEDED(pMySHParseDisplayName(NS_ConvertUTF8toUTF16(urlSpec).get(),
|
||||
NULL, &pidl, 0, &sfgao))) {
|
||||
sinfo.lpIDList = pidl;
|
||||
sinfo.fMask |= SEE_MASK_INVOKEIDLIST;
|
||||
} else {
|
||||
// SHParseDisplayName exists, but failed. Bailing out as work around for
|
||||
// Microsoft Security Bulletin MS07-061
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
// SHParseDisplayName failed. Bailing out as work around for
|
||||
// Microsoft Security Bulletin MS07-061
|
||||
rv = NS_ERROR_FAILURE;
|
||||
sinfo.lpFile = NS_ConvertUTF8toUTF16(urlSpec).get();
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
BOOL result = ShellExecuteExW(&sinfo);
|
||||
@ -297,6 +321,8 @@ nsMIMEInfoWin::LoadUriInternal(nsIURI * aURL)
|
||||
}
|
||||
if (pidl)
|
||||
CoTaskMemFree(pidl);
|
||||
if (hDll)
|
||||
::FreeLibrary(hDll);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -272,6 +272,31 @@ static void normalizeDriverId(nsString& driverid) {
|
||||
}
|
||||
}
|
||||
|
||||
// Setup API functions
|
||||
typedef HDEVINFO (WINAPI*SetupDiGetClassDevsWFunc)(
|
||||
CONST GUID *ClassGuid,
|
||||
PCWSTR Enumerator,
|
||||
HWND hwndParent,
|
||||
DWORD Flags
|
||||
);
|
||||
typedef BOOL (WINAPI*SetupDiEnumDeviceInfoFunc)(
|
||||
HDEVINFO DeviceInfoSet,
|
||||
DWORD MemberIndex,
|
||||
PSP_DEVINFO_DATA DeviceInfoData
|
||||
);
|
||||
typedef BOOL (WINAPI*SetupDiGetDeviceRegistryPropertyWFunc)(
|
||||
HDEVINFO DeviceInfoSet,
|
||||
PSP_DEVINFO_DATA DeviceInfoData,
|
||||
DWORD Property,
|
||||
PDWORD PropertyRegDataType,
|
||||
PBYTE PropertyBuffer,
|
||||
DWORD PropertyBufferSize,
|
||||
PDWORD RequiredSize
|
||||
);
|
||||
typedef BOOL (WINAPI*SetupDiDestroyDeviceInfoListFunc)(
|
||||
HDEVINFO DeviceInfoSet
|
||||
);
|
||||
|
||||
// The device ID is a string like PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD
|
||||
// this function is used to extract the id's out of it
|
||||
PRUint32
|
||||
@ -337,157 +362,180 @@ GfxInfo::Init()
|
||||
mDeviceID = displayDevice.DeviceID;
|
||||
mDeviceString = displayDevice.DeviceString;
|
||||
|
||||
/* create a device information set composed of the current display device */
|
||||
HDEVINFO devinfo = SetupDiGetClassDevsW(NULL, mDeviceID.get(), NULL,
|
||||
DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
|
||||
|
||||
if (devinfo != INVALID_HANDLE_VALUE) {
|
||||
HKEY key;
|
||||
LONG result;
|
||||
WCHAR value[255];
|
||||
DWORD dwcbData;
|
||||
SP_DEVINFO_DATA devinfoData;
|
||||
DWORD memberIndex = 0;
|
||||
HMODULE setupapi = LoadLibraryW(L"setupapi.dll");
|
||||
|
||||
devinfoData.cbSize = sizeof(devinfoData);
|
||||
NS_NAMED_LITERAL_STRING(driverKeyPre, "System\\CurrentControlSet\\Control\\Class\\");
|
||||
/* enumerate device information elements in the device information set */
|
||||
while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) {
|
||||
/* get a string that identifies the device's driver key */
|
||||
if (SetupDiGetDeviceRegistryPropertyW(devinfo,
|
||||
&devinfoData,
|
||||
SPDRP_DRIVER,
|
||||
NULL,
|
||||
(PBYTE)value,
|
||||
sizeof(value),
|
||||
NULL)) {
|
||||
nsAutoString driverKey(driverKeyPre);
|
||||
driverKey += value;
|
||||
result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey.BeginReading(), 0, KEY_QUERY_VALUE, &key);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
/* we've found the driver we're looking for */
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"DriverVersion", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result == ERROR_SUCCESS)
|
||||
mDriverVersion = value;
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"DriverDate", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result == ERROR_SUCCESS)
|
||||
mDriverDate = value;
|
||||
RegCloseKey(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (setupapi) {
|
||||
SetupDiGetClassDevsWFunc setupGetClassDevs = (SetupDiGetClassDevsWFunc)
|
||||
GetProcAddress(setupapi, "SetupDiGetClassDevsW");
|
||||
SetupDiEnumDeviceInfoFunc setupEnumDeviceInfo = (SetupDiEnumDeviceInfoFunc)
|
||||
GetProcAddress(setupapi, "SetupDiEnumDeviceInfo");
|
||||
SetupDiGetDeviceRegistryPropertyWFunc setupGetDeviceRegistryProperty = (SetupDiGetDeviceRegistryPropertyWFunc)
|
||||
GetProcAddress(setupapi, "SetupDiGetDeviceRegistryPropertyW");
|
||||
SetupDiDestroyDeviceInfoListFunc setupDestroyDeviceInfoList = (SetupDiDestroyDeviceInfoListFunc)
|
||||
GetProcAddress(setupapi, "SetupDiDestroyDeviceInfoList");
|
||||
|
||||
SetupDiDestroyDeviceInfoList(devinfo);
|
||||
}
|
||||
if (setupGetClassDevs &&
|
||||
setupEnumDeviceInfo &&
|
||||
setupGetDeviceRegistryProperty &&
|
||||
setupDestroyDeviceInfoList) {
|
||||
/* create a device information set composed of the current display device */
|
||||
HDEVINFO devinfo = setupGetClassDevs(NULL, mDeviceID.get(), NULL,
|
||||
DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
|
||||
|
||||
mAdapterVendorID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "VEN_", 4));
|
||||
mAdapterDeviceID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "&DEV_", 4));
|
||||
mAdapterSubsysID = ParseIDFromDeviceID(mDeviceID, "&SUBSYS_", 8);
|
||||
if (devinfo != INVALID_HANDLE_VALUE) {
|
||||
HKEY key;
|
||||
LONG result;
|
||||
WCHAR value[255];
|
||||
DWORD dwcbData;
|
||||
SP_DEVINFO_DATA devinfoData;
|
||||
DWORD memberIndex = 0;
|
||||
|
||||
// We now check for second display adapter.
|
||||
|
||||
// Device interface class for display adapters.
|
||||
CLSID GUID_DISPLAY_DEVICE_ARRIVAL;
|
||||
HRESULT hresult = CLSIDFromString(L"{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}",
|
||||
&GUID_DISPLAY_DEVICE_ARRIVAL);
|
||||
if (hresult == NOERROR) {
|
||||
devinfo = SetupDiGetClassDevsW(&GUID_DISPLAY_DEVICE_ARRIVAL, NULL, NULL,
|
||||
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
|
||||
|
||||
if (devinfo != INVALID_HANDLE_VALUE) {
|
||||
HKEY key;
|
||||
LONG result;
|
||||
WCHAR value[255];
|
||||
DWORD dwcbData;
|
||||
SP_DEVINFO_DATA devinfoData;
|
||||
DWORD memberIndex = 0;
|
||||
devinfoData.cbSize = sizeof(devinfoData);
|
||||
|
||||
nsAutoString adapterDriver2;
|
||||
nsAutoString deviceID2;
|
||||
nsAutoString driverVersion2;
|
||||
nsAutoString driverDate2;
|
||||
PRUint32 adapterVendorID2;
|
||||
PRUint32 adapterDeviceID2;
|
||||
|
||||
NS_NAMED_LITERAL_STRING(driverKeyPre, "System\\CurrentControlSet\\Control\\Class\\");
|
||||
/* enumerate device information elements in the device information set */
|
||||
while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) {
|
||||
/* get a string that identifies the device's driver key */
|
||||
if (SetupDiGetDeviceRegistryPropertyW(devinfo,
|
||||
&devinfoData,
|
||||
SPDRP_DRIVER,
|
||||
NULL,
|
||||
(PBYTE)value,
|
||||
sizeof(value),
|
||||
NULL)) {
|
||||
nsAutoString driverKey2(driverKeyPre);
|
||||
driverKey2 += value;
|
||||
result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey2.BeginReading(), 0, KEY_QUERY_VALUE, &key);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"MatchingDeviceId", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
deviceID2 = value;
|
||||
nsAutoString adapterVendorID2String;
|
||||
nsAutoString adapterDeviceID2String;
|
||||
adapterVendorID2 = ParseIDFromDeviceID(deviceID2, "VEN_", 4);
|
||||
adapterVendorID2String.AppendPrintf("0x%04x", adapterVendorID2);
|
||||
adapterDeviceID2 = ParseIDFromDeviceID(deviceID2, "&DEV_", 4);
|
||||
adapterDeviceID2String.AppendPrintf("0x%04x", adapterDeviceID2);
|
||||
if (mAdapterVendorID == adapterVendorID2String &&
|
||||
mAdapterDeviceID == adapterDeviceID2String) {
|
||||
RegCloseKey(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this device is missing driver information, it is unlikely to
|
||||
// be a real display adapter.
|
||||
if (NS_FAILED(GetKeyValue(driverKey2.BeginReading(), L"InstalledDisplayDrivers",
|
||||
adapterDriver2, REG_MULTI_SZ))) {
|
||||
RegCloseKey(key);
|
||||
continue;
|
||||
}
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"DriverVersion", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
RegCloseKey(key);
|
||||
continue;
|
||||
}
|
||||
driverVersion2 = value;
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"DriverDate", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
RegCloseKey(key);
|
||||
continue;
|
||||
}
|
||||
driverDate2 = value;
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"Device Description", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
RegCloseKey(key);
|
||||
devinfoData.cbSize = sizeof(devinfoData);
|
||||
NS_NAMED_LITERAL_STRING(driverKeyPre, "System\\CurrentControlSet\\Control\\Class\\");
|
||||
/* enumerate device information elements in the device information set */
|
||||
while (setupEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) {
|
||||
/* get a string that identifies the device's driver key */
|
||||
if (setupGetDeviceRegistryProperty(devinfo,
|
||||
&devinfoData,
|
||||
SPDRP_DRIVER,
|
||||
NULL,
|
||||
(PBYTE)value,
|
||||
sizeof(value),
|
||||
NULL)) {
|
||||
nsAutoString driverKey(driverKeyPre);
|
||||
driverKey += value;
|
||||
result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey.BeginReading(), 0, KEY_QUERY_VALUE, &key);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
mHasDualGPU = true;
|
||||
mDeviceString2 = value;
|
||||
mDeviceID2 = deviceID2;
|
||||
mDeviceKey2 = driverKey2;
|
||||
mDriverVersion2 = driverVersion2;
|
||||
mDriverDate2 = driverDate2;
|
||||
mAdapterVendorID2.AppendPrintf("0x%04x", adapterVendorID2);
|
||||
mAdapterDeviceID2.AppendPrintf("0x%04x", adapterDeviceID2);
|
||||
mAdapterSubsysID2 = ParseIDFromDeviceID(mDeviceID2, "&SUBSYS_", 8);
|
||||
/* we've found the driver we're looking for */
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"DriverVersion", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result == ERROR_SUCCESS)
|
||||
mDriverVersion = value;
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"DriverDate", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result == ERROR_SUCCESS)
|
||||
mDriverDate = value;
|
||||
RegCloseKey(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupDestroyDeviceInfoList(devinfo);
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList(devinfo);
|
||||
mAdapterVendorID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "VEN_", 4));
|
||||
mAdapterDeviceID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "&DEV_", 4));
|
||||
mAdapterSubsysID = ParseIDFromDeviceID(mDeviceID, "&SUBSYS_", 8);
|
||||
|
||||
// We now check for second display adapter.
|
||||
|
||||
// Device interface class for display adapters.
|
||||
CLSID GUID_DISPLAY_DEVICE_ARRIVAL;
|
||||
HRESULT hresult = CLSIDFromString(L"{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}",
|
||||
&GUID_DISPLAY_DEVICE_ARRIVAL);
|
||||
if (hresult == NOERROR) {
|
||||
devinfo = setupGetClassDevs(&GUID_DISPLAY_DEVICE_ARRIVAL, NULL, NULL,
|
||||
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
|
||||
|
||||
if (devinfo != INVALID_HANDLE_VALUE) {
|
||||
HKEY key;
|
||||
LONG result;
|
||||
WCHAR value[255];
|
||||
DWORD dwcbData;
|
||||
SP_DEVINFO_DATA devinfoData;
|
||||
DWORD memberIndex = 0;
|
||||
devinfoData.cbSize = sizeof(devinfoData);
|
||||
|
||||
nsAutoString adapterDriver2;
|
||||
nsAutoString deviceID2;
|
||||
nsAutoString driverVersion2;
|
||||
nsAutoString driverDate2;
|
||||
PRUint32 adapterVendorID2;
|
||||
PRUint32 adapterDeviceID2;
|
||||
|
||||
NS_NAMED_LITERAL_STRING(driverKeyPre, "System\\CurrentControlSet\\Control\\Class\\");
|
||||
/* enumerate device information elements in the device information set */
|
||||
while (setupEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) {
|
||||
/* get a string that identifies the device's driver key */
|
||||
if (setupGetDeviceRegistryProperty(devinfo,
|
||||
&devinfoData,
|
||||
SPDRP_DRIVER,
|
||||
NULL,
|
||||
(PBYTE)value,
|
||||
sizeof(value),
|
||||
NULL)) {
|
||||
nsAutoString driverKey2(driverKeyPre);
|
||||
driverKey2 += value;
|
||||
result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey2.BeginReading(), 0, KEY_QUERY_VALUE, &key);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"MatchingDeviceId", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
deviceID2 = value;
|
||||
nsAutoString adapterVendorID2String;
|
||||
nsAutoString adapterDeviceID2String;
|
||||
adapterVendorID2 = ParseIDFromDeviceID(deviceID2, "VEN_", 4);
|
||||
adapterVendorID2String.AppendPrintf("0x%04x", adapterVendorID2);
|
||||
adapterDeviceID2 = ParseIDFromDeviceID(deviceID2, "&DEV_", 4);
|
||||
adapterDeviceID2String.AppendPrintf("0x%04x", adapterDeviceID2);
|
||||
if (mAdapterVendorID == adapterVendorID2String &&
|
||||
mAdapterDeviceID == adapterDeviceID2String) {
|
||||
RegCloseKey(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this device is missing driver information, it is unlikely to
|
||||
// be a real display adapter.
|
||||
if (NS_FAILED(GetKeyValue(driverKey2.BeginReading(), L"InstalledDisplayDrivers",
|
||||
adapterDriver2, REG_MULTI_SZ))) {
|
||||
RegCloseKey(key);
|
||||
continue;
|
||||
}
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"DriverVersion", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
RegCloseKey(key);
|
||||
continue;
|
||||
}
|
||||
driverVersion2 = value;
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"DriverDate", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
RegCloseKey(key);
|
||||
continue;
|
||||
}
|
||||
driverDate2 = value;
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"Device Description", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
RegCloseKey(key);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
mHasDualGPU = true;
|
||||
mDeviceString2 = value;
|
||||
mDeviceID2 = deviceID2;
|
||||
mDeviceKey2 = driverKey2;
|
||||
mDriverVersion2 = driverVersion2;
|
||||
mDriverDate2 = driverDate2;
|
||||
mAdapterVendorID2.AppendPrintf("0x%04x", adapterVendorID2);
|
||||
mAdapterDeviceID2.AppendPrintf("0x%04x", adapterDeviceID2);
|
||||
mAdapterSubsysID2 = ParseIDFromDeviceID(mDeviceID2, "&SUBSYS_", 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupDestroyDeviceInfoList(devinfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
FreeLibrary(setupapi);
|
||||
}
|
||||
|
||||
const char *spoofedDriverVersionString = PR_GetEnv("MOZ_GFX_SPOOF_DRIVER_VERSION");
|
||||
@ -758,6 +806,8 @@ static OperatingSystem
|
||||
WindowsVersionToOperatingSystem(PRInt32 aWindowsVersion)
|
||||
{
|
||||
switch(aWindowsVersion) {
|
||||
case gfxWindowsPlatform::kWindows2000:
|
||||
return DRIVER_OS_WINDOWS_2000;
|
||||
case gfxWindowsPlatform::kWindowsXP:
|
||||
return DRIVER_OS_WINDOWS_XP;
|
||||
case gfxWindowsPlatform::kWindowsServer2003:
|
||||
@ -942,6 +992,13 @@ GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aFeature == FEATURE_DIRECT3D_9_LAYERS &&
|
||||
mWindowsVersion < gfxWindowsPlatform::kWindowsXP)
|
||||
{
|
||||
*aStatus = FEATURE_BLOCKED_OS_VERSION;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// ANGLE currently uses D3D10 <-> D3D9 interop, which crashes on Optimus
|
||||
// machines.
|
||||
if (aFeature == FEATURE_WEBGL_ANGLE &&
|
||||
|
@ -61,6 +61,7 @@ namespace widget {
|
||||
class WinUtils {
|
||||
public:
|
||||
enum WinVersion {
|
||||
WIN2K_VERSION = 0x500,
|
||||
WINXP_VERSION = 0x501,
|
||||
WIN2K3_VERSION = 0x502,
|
||||
VISTA_VERSION = 0x600,
|
||||
|
@ -46,9 +46,10 @@
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsUXThemeData.h"
|
||||
#include "nsUXThemeConstants.h"
|
||||
#include "WinUtils.h"
|
||||
|
||||
using namespace mozilla::widget;
|
||||
typedef UINT (CALLBACK *SHAppBarMessagePtr)(DWORD, PAPPBARDATA);
|
||||
SHAppBarMessagePtr gSHAppBarMessage = NULL;
|
||||
static HINSTANCE gShell32DLLInst = NULL;
|
||||
|
||||
static nsresult GetColorFromTheme(nsUXThemeClass cls,
|
||||
PRInt32 aPart,
|
||||
@ -57,7 +58,7 @@ static nsresult GetColorFromTheme(nsUXThemeClass cls,
|
||||
nscolor &aColor)
|
||||
{
|
||||
COLORREF color;
|
||||
HRESULT hr = GetThemeColor(nsUXThemeData::GetTheme(cls), aPart, aState, aPropId, &color);
|
||||
HRESULT hr = nsUXThemeData::GetThemeColor(cls, aPart, aState, aPropId, &color);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
aColor = COLOREF_2_NSRGB(color);
|
||||
@ -74,10 +75,22 @@ static PRInt32 GetSystemParam(long flag, PRInt32 def)
|
||||
|
||||
nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel()
|
||||
{
|
||||
gShell32DLLInst = LoadLibraryW(L"Shell32.dll");
|
||||
if (gShell32DLLInst)
|
||||
{
|
||||
gSHAppBarMessage = (SHAppBarMessagePtr) GetProcAddress(gShell32DLLInst,
|
||||
"SHAppBarMessage");
|
||||
}
|
||||
}
|
||||
|
||||
nsLookAndFeel::~nsLookAndFeel()
|
||||
{
|
||||
if (gShell32DLLInst)
|
||||
{
|
||||
FreeLibrary(gShell32DLLInst);
|
||||
gShell32DLLInst = NULL;
|
||||
gSHAppBarMessage = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -186,8 +199,8 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
|
||||
idx = COLOR_HIGHLIGHT;
|
||||
break;
|
||||
case eColorID__moz_menubarhovertext:
|
||||
if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION ||
|
||||
!IsAppThemed()) {
|
||||
if (!nsUXThemeData::sIsVistaOrLater || !nsUXThemeData::isAppThemed())
|
||||
{
|
||||
idx = nsUXThemeData::sFlatMenus ?
|
||||
COLOR_HIGHLIGHTTEXT :
|
||||
COLOR_MENUTEXT;
|
||||
@ -195,8 +208,8 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
|
||||
}
|
||||
// Fall through
|
||||
case eColorID__moz_menuhovertext:
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
|
||||
IsAppThemed()) {
|
||||
if (nsUXThemeData::IsAppThemed() && nsUXThemeData::sIsVistaOrLater)
|
||||
{
|
||||
res = ::GetColorFromTheme(eUXMenu,
|
||||
MENU_POPUPITEM, MPI_HOT, TMT_TEXTCOLOR, aColor);
|
||||
if (NS_SUCCEEDED(res))
|
||||
@ -271,8 +284,7 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
|
||||
idx = COLOR_3DFACE;
|
||||
break;
|
||||
case eColorID__moz_win_mediatext:
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
|
||||
IsAppThemed()) {
|
||||
if (nsUXThemeData::IsAppThemed() && nsUXThemeData::sIsVistaOrLater) {
|
||||
res = ::GetColorFromTheme(eUXMediaToolbar,
|
||||
TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor);
|
||||
if (NS_SUCCEEDED(res))
|
||||
@ -282,8 +294,8 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
|
||||
idx = COLOR_WINDOWTEXT;
|
||||
break;
|
||||
case eColorID__moz_win_communicationstext:
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
|
||||
IsAppThemed()) {
|
||||
if (nsUXThemeData::IsAppThemed() && nsUXThemeData::sIsVistaOrLater)
|
||||
{
|
||||
res = ::GetColorFromTheme(eUXCommunicationsToolbar,
|
||||
TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor);
|
||||
if (NS_SUCCEEDED(res))
|
||||
@ -393,7 +405,7 @@ nsLookAndFeel::GetIntImpl(IntID aID, PRInt32 &aResult)
|
||||
aResult = 3;
|
||||
break;
|
||||
case eIntID_WindowsClassic:
|
||||
aResult = !IsAppThemed();
|
||||
aResult = !nsUXThemeData::IsAppThemed();
|
||||
break;
|
||||
case eIntID_TouchEnabled:
|
||||
aResult = 0;
|
||||
@ -421,6 +433,7 @@ nsLookAndFeel::GetIntImpl(IntID aID, PRInt32 &aResult)
|
||||
break;
|
||||
case eIntID_AlertNotificationOrigin:
|
||||
aResult = 0;
|
||||
if (gSHAppBarMessage)
|
||||
{
|
||||
// Get task bar window handle
|
||||
HWND shellWindow = FindWindowW(L"Shell_TrayWnd", NULL);
|
||||
@ -431,7 +444,7 @@ nsLookAndFeel::GetIntImpl(IntID aID, PRInt32 &aResult)
|
||||
APPBARDATA appBarData;
|
||||
appBarData.hWnd = shellWindow;
|
||||
appBarData.cbSize = sizeof(appBarData);
|
||||
if (SHAppBarMessage(ABM_GETTASKBARPOS, &appBarData))
|
||||
if (gSHAppBarMessage(ABM_GETTASKBARPOS, &appBarData))
|
||||
{
|
||||
// Set alert origin as a bit field - see LookAndFeel.h
|
||||
// 0 represents bottom right, sliding vertically.
|
||||
@ -506,5 +519,11 @@ PRUnichar
|
||||
nsLookAndFeel::GetPasswordCharacterImpl()
|
||||
{
|
||||
#define UNICODE_BLACK_CIRCLE_CHAR 0x25cf
|
||||
return UNICODE_BLACK_CIRCLE_CHAR;
|
||||
static PRUnichar passwordCharacter = 0;
|
||||
if (!passwordCharacter) {
|
||||
passwordCharacter = '*';
|
||||
if (nsUXThemeData::sIsXPOrLater)
|
||||
passwordCharacter = UNICODE_BLACK_CIRCLE_CHAR;
|
||||
}
|
||||
return passwordCharacter;
|
||||
}
|
||||
|
@ -166,13 +166,13 @@ static bool IsTopLevelMenu(nsIFrame *aFrame)
|
||||
static MARGINS GetCheckboxMargins(HANDLE theme, HDC hdc)
|
||||
{
|
||||
MARGINS checkboxContent = {0};
|
||||
GetThemeMargins(theme, hdc, MENU_POPUPCHECK, MCB_NORMAL, TMT_CONTENTMARGINS, NULL, &checkboxContent);
|
||||
nsUXThemeData::getThemeMargins(theme, hdc, MENU_POPUPCHECK, MCB_NORMAL, TMT_CONTENTMARGINS, NULL, &checkboxContent);
|
||||
return checkboxContent;
|
||||
}
|
||||
static SIZE GetCheckboxBGSize(HANDLE theme, HDC hdc)
|
||||
{
|
||||
SIZE checkboxSize;
|
||||
GetThemePartSize(theme, hdc, MENU_POPUPCHECK, MC_CHECKMARKNORMAL, NULL, TS_TRUE, &checkboxSize);
|
||||
nsUXThemeData::getThemePartSize(theme, hdc, MENU_POPUPCHECK, MC_CHECKMARKNORMAL, NULL, TS_TRUE, &checkboxSize);
|
||||
|
||||
MARGINS checkboxMargins = GetCheckboxMargins(theme, hdc);
|
||||
|
||||
@ -192,8 +192,8 @@ static SIZE GetCheckboxBGBounds(HANDLE theme, HDC hdc)
|
||||
{
|
||||
MARGINS checkboxBGSizing = {0};
|
||||
MARGINS checkboxBGContent = {0};
|
||||
GetThemeMargins(theme, hdc, MENU_POPUPCHECKBACKGROUND, MCB_NORMAL, TMT_SIZINGMARGINS, NULL, &checkboxBGSizing);
|
||||
GetThemeMargins(theme, hdc, MENU_POPUPCHECKBACKGROUND, MCB_NORMAL, TMT_CONTENTMARGINS, NULL, &checkboxBGContent);
|
||||
nsUXThemeData::getThemeMargins(theme, hdc, MENU_POPUPCHECKBACKGROUND, MCB_NORMAL, TMT_SIZINGMARGINS, NULL, &checkboxBGSizing);
|
||||
nsUXThemeData::getThemeMargins(theme, hdc, MENU_POPUPCHECKBACKGROUND, MCB_NORMAL, TMT_CONTENTMARGINS, NULL, &checkboxBGContent);
|
||||
|
||||
#define posdx(d) ((d) > 0 ? d : 0)
|
||||
|
||||
@ -210,12 +210,12 @@ static SIZE GetCheckboxBGBounds(HANDLE theme, HDC hdc)
|
||||
static SIZE GetGutterSize(HANDLE theme, HDC hdc)
|
||||
{
|
||||
SIZE gutterSize;
|
||||
GetThemePartSize(theme, hdc, MENU_POPUPGUTTER, 0, NULL, TS_TRUE, &gutterSize);
|
||||
nsUXThemeData::getThemePartSize(theme, hdc, MENU_POPUPGUTTER, 0, NULL, TS_TRUE, &gutterSize);
|
||||
|
||||
SIZE checkboxBGSize(GetCheckboxBGBounds(theme, hdc));
|
||||
|
||||
SIZE itemSize;
|
||||
GetThemePartSize(theme, hdc, MENU_POPUPITEM, MPI_NORMAL, NULL, TS_TRUE, &itemSize);
|
||||
nsUXThemeData::getThemePartSize(theme, hdc, MENU_POPUPITEM, MPI_NORMAL, NULL, TS_TRUE, &itemSize);
|
||||
|
||||
int width = NS_MAX(itemSize.cx, checkboxBGSize.cx + gutterSize.cx);
|
||||
int height = NS_MAX(itemSize.cy, checkboxBGSize.cy);
|
||||
@ -276,7 +276,7 @@ static HRESULT DrawThemeBGRTLAware(HANDLE theme, HDC hdc, int part, int state,
|
||||
}
|
||||
|
||||
SetLayout(hdc, LAYOUT_RTL);
|
||||
HRESULT hr = DrawThemeBackground(theme, hdc, part, state, &newWRect, newCRectPtr);
|
||||
HRESULT hr = nsUXThemeData::drawThemeBG(theme, hdc, part, state, &newWRect, newCRectPtr);
|
||||
SetLayout(hdc, 0);
|
||||
|
||||
if (hr == S_OK)
|
||||
@ -285,7 +285,7 @@ static HRESULT DrawThemeBGRTLAware(HANDLE theme, HDC hdc, int part, int state,
|
||||
}
|
||||
|
||||
// Draw normally if LTR or if anything went wrong
|
||||
return DrawThemeBackground(theme, hdc, part, state, widgetRect, clipRect);
|
||||
return nsUXThemeData::drawThemeBG(theme, hdc, part, state, widgetRect, clipRect);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -383,7 +383,7 @@ static void AddPaddingRect(nsIntSize* aSize, CaptionButton button) {
|
||||
if (!aSize)
|
||||
return;
|
||||
RECT offset;
|
||||
if (!IsAppThemed())
|
||||
if (!nsUXThemeData::IsAppThemed())
|
||||
offset = buttonData[CAPTION_CLASSIC].hotPadding[button];
|
||||
else if (WinUtils::GetWindowsVersion() == WinUtils::WINXP_VERSION)
|
||||
offset = buttonData[CAPTION_XPTHEME].hotPadding[button];
|
||||
@ -397,7 +397,7 @@ static void AddPaddingRect(nsIntSize* aSize, CaptionButton button) {
|
||||
// the area we draw into to compensate.
|
||||
static void OffsetBackgroundRect(RECT& rect, CaptionButton button) {
|
||||
RECT offset;
|
||||
if (!IsAppThemed())
|
||||
if (!nsUXThemeData::IsAppThemed())
|
||||
offset = buttonData[CAPTION_CLASSIC].hotPadding[button];
|
||||
else if (WinUtils::GetWindowsVersion() == WinUtils::WINXP_VERSION)
|
||||
offset = buttonData[CAPTION_XPTHEME].hotPadding[button];
|
||||
@ -412,7 +412,7 @@ static void OffsetBackgroundRect(RECT& rect, CaptionButton button) {
|
||||
HANDLE
|
||||
nsNativeThemeWin::GetTheme(PRUint8 aWidgetType)
|
||||
{
|
||||
if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) {
|
||||
if (!nsUXThemeData::sIsVistaOrLater) {
|
||||
// On XP or earlier, render dropdowns as textfields;
|
||||
// doing it the right way works fine with the MS themes,
|
||||
// but breaks on a lot of custom themes (presumably because MS
|
||||
@ -431,9 +431,8 @@ nsNativeThemeWin::GetTheme(PRUint8 aWidgetType)
|
||||
case NS_THEME_TEXTFIELD_MULTILINE:
|
||||
return nsUXThemeData::GetTheme(eUXEdit);
|
||||
case NS_THEME_TOOLTIP:
|
||||
// XP/2K3 should force a classic treatment of tooltips
|
||||
return WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION ?
|
||||
NULL : nsUXThemeData::GetTheme(eUXTooltip);
|
||||
// BUG #161600: XP/2K3 should force a classic treatment of tooltips
|
||||
return nsUXThemeData::sIsVistaOrLater ? nsUXThemeData::GetTheme(eUXTooltip) : NULL;
|
||||
case NS_THEME_TOOLBOX:
|
||||
return nsUXThemeData::GetTheme(eUXRebar);
|
||||
case NS_THEME_WIN_MEDIA_TOOLBOX:
|
||||
@ -558,7 +557,7 @@ nsresult
|
||||
nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
PRInt32& aPart, PRInt32& aState)
|
||||
{
|
||||
if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION) {
|
||||
if (!nsUXThemeData::sIsVistaOrLater) {
|
||||
// See GetTheme
|
||||
if (aWidgetType == NS_THEME_DROPDOWN)
|
||||
aWidgetType = NS_THEME_TEXTFIELD;
|
||||
@ -635,7 +634,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
case NS_THEME_TEXTFIELD_MULTILINE: {
|
||||
nsEventStates eventState = GetContentState(aFrame, aWidgetType);
|
||||
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
|
||||
if (nsUXThemeData::sIsVistaOrLater) {
|
||||
/* Note: the NOSCROLL type has a rounded corner in each
|
||||
* corner. The more specific HSCROLL, VSCROLL, HVSCROLL types
|
||||
* have side and/or top/bottom edges rendered as straight
|
||||
@ -702,11 +701,9 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
// we have to return aPart = -1.
|
||||
aPart = -1;
|
||||
} else if (IsVerticalProgress(stateFrame)) {
|
||||
aPart = WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION ?
|
||||
PP_FILLVERT : PP_CHUNKVERT;
|
||||
aPart = nsUXThemeData::sIsVistaOrLater ? PP_FILLVERT : PP_CHUNKVERT;
|
||||
} else {
|
||||
aPart = WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION ?
|
||||
PP_FILL : PP_CHUNK;
|
||||
aPart = nsUXThemeData::sIsVistaOrLater ? PP_FILL : PP_CHUNK;
|
||||
}
|
||||
|
||||
aState = TS_NORMAL;
|
||||
@ -779,8 +776,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
aState += TS_ACTIVE;
|
||||
else if (eventState.HasState(NS_EVENT_STATE_HOVER))
|
||||
aState += TS_HOVER;
|
||||
else if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
|
||||
parentState.HasState(NS_EVENT_STATE_HOVER))
|
||||
else if (nsUXThemeData::sIsVistaOrLater && parentState.HasState(NS_EVENT_STATE_HOVER))
|
||||
aState = (aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP) + SP_BUTTON_IMPLICIT_HOVER_BASE;
|
||||
else
|
||||
aState += TS_NORMAL;
|
||||
@ -868,7 +864,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
case NS_THEME_SCROLLBAR:
|
||||
case NS_THEME_SCROLLBAR_SMALL: {
|
||||
aState = 0;
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
|
||||
if (nsUXThemeData::sIsVistaOrLater) {
|
||||
// On vista, they have a part
|
||||
aPart = RP_BACKGROUND;
|
||||
} else {
|
||||
@ -1000,8 +996,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
aFrame = parentFrame;
|
||||
|
||||
nsEventStates eventState = GetContentState(aFrame, aWidgetType);
|
||||
aPart = WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION ?
|
||||
CBP_DROPMARKER_VISTA : CBP_DROPMARKER;
|
||||
aPart = nsUXThemeData::sIsVistaOrLater ? CBP_DROPMARKER_VISTA : CBP_DROPMARKER;
|
||||
|
||||
// For HTML controls with author styling, we should fall
|
||||
// back to the old dropmarker style to avoid clashes with
|
||||
@ -1021,7 +1016,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
else
|
||||
isOpen = IsOpenButton(aFrame);
|
||||
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
|
||||
if (nsUXThemeData::sIsVistaOrLater) {
|
||||
if (isHTML || IsMenuListEditable(aFrame)) {
|
||||
if (isOpen) {
|
||||
/* Hover is propagated, but we need to know whether we're
|
||||
@ -1217,6 +1212,9 @@ nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
if (!theme)
|
||||
return ClassicDrawWidgetBackground(aContext, aFrame, aWidgetType, aRect, aDirtyRect);
|
||||
|
||||
if (!nsUXThemeData::drawThemeBG)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
// ^^ without the right sdk, assume xp theming and fall through.
|
||||
if (nsUXThemeData::CheckForCompositor()) {
|
||||
@ -1355,10 +1353,10 @@ RENDER_AGAIN:
|
||||
if (aWidgetType == NS_THEME_SCALE_HORIZONTAL ||
|
||||
aWidgetType == NS_THEME_SCALE_VERTICAL) {
|
||||
RECT contentRect;
|
||||
GetThemeBackgroundContentRect(theme, hdc, part, state, &widgetRect, &contentRect);
|
||||
nsUXThemeData::getThemeContentRect(theme, hdc, part, state, &widgetRect, &contentRect);
|
||||
|
||||
SIZE siz;
|
||||
GetThemePartSize(theme, hdc, part, state, &widgetRect, TS_TRUE, &siz);
|
||||
nsUXThemeData::getThemePartSize(theme, hdc, part, state, &widgetRect, 1, &siz);
|
||||
|
||||
if (aWidgetType == NS_THEME_SCALE_HORIZONTAL) {
|
||||
PRInt32 adjustment = (contentRect.bottom - contentRect.top - siz.cy) / 2 + 1;
|
||||
@ -1373,7 +1371,7 @@ RENDER_AGAIN:
|
||||
contentRect.right -= adjustment;
|
||||
}
|
||||
|
||||
DrawThemeBackground(theme, hdc, part, state, &contentRect, &clipRect);
|
||||
nsUXThemeData::drawThemeBG(theme, hdc, part, state, &contentRect, &clipRect);
|
||||
}
|
||||
else if (aWidgetType == NS_THEME_MENUCHECKBOX || aWidgetType == NS_THEME_MENURADIO)
|
||||
{
|
||||
@ -1402,7 +1400,7 @@ RENDER_AGAIN:
|
||||
checkBGRect.top += (checkBGRect.bottom - checkBGRect.top)/2 - checkboxBGSize.cy/2;
|
||||
checkBGRect.bottom = checkBGRect.top + checkboxBGSize.cy;
|
||||
|
||||
DrawThemeBackground(theme, hdc, MENU_POPUPCHECKBACKGROUND, bgState, &checkBGRect, &clipRect);
|
||||
nsUXThemeData::drawThemeBG(theme, hdc, MENU_POPUPCHECKBACKGROUND, bgState, &checkBGRect, &clipRect);
|
||||
|
||||
MARGINS checkMargins = GetCheckboxMargins(theme, hdc);
|
||||
RECT checkRect = checkBGRect;
|
||||
@ -1410,14 +1408,14 @@ RENDER_AGAIN:
|
||||
checkRect.right -= checkMargins.cxRightWidth;
|
||||
checkRect.top += checkMargins.cyTopHeight;
|
||||
checkRect.bottom -= checkMargins.cyBottomHeight;
|
||||
DrawThemeBackground(theme, hdc, MENU_POPUPCHECK, state, &checkRect, &clipRect);
|
||||
nsUXThemeData::drawThemeBG(theme, hdc, MENU_POPUPCHECK, state, &checkRect, &clipRect);
|
||||
}
|
||||
}
|
||||
else if (aWidgetType == NS_THEME_MENUPOPUP)
|
||||
{
|
||||
DrawThemeBackground(theme, hdc, MENU_POPUPBORDERS, /* state */ 0, &widgetRect, &clipRect);
|
||||
nsUXThemeData::drawThemeBG(theme, hdc, MENU_POPUPBORDERS, /* state */ 0, &widgetRect, &clipRect);
|
||||
SIZE borderSize;
|
||||
GetThemePartSize(theme, hdc, MENU_POPUPBORDERS, 0, NULL, TS_TRUE, &borderSize);
|
||||
nsUXThemeData::getThemePartSize(theme, hdc, MENU_POPUPBORDERS, 0, NULL, TS_TRUE, &borderSize);
|
||||
|
||||
RECT bgRect = widgetRect;
|
||||
bgRect.top += borderSize.cy;
|
||||
@ -1425,7 +1423,7 @@ RENDER_AGAIN:
|
||||
bgRect.left += borderSize.cx;
|
||||
bgRect.right -= borderSize.cx;
|
||||
|
||||
DrawThemeBackground(theme, hdc, MENU_POPUPBACKGROUND, /* state */ 0, &bgRect, &clipRect);
|
||||
nsUXThemeData::drawThemeBG(theme, hdc, MENU_POPUPBACKGROUND, /* state */ 0, &bgRect, &clipRect);
|
||||
|
||||
SIZE gutterSize(GetGutterSize(theme, hdc));
|
||||
|
||||
@ -1453,7 +1451,7 @@ RENDER_AGAIN:
|
||||
else
|
||||
sepRect.left += gutterSize.cx;
|
||||
|
||||
DrawThemeBackground(theme, hdc, MENU_POPUPSEPARATOR, /* state */ 0, &sepRect, &clipRect);
|
||||
nsUXThemeData::drawThemeBG(theme, hdc, MENU_POPUPSEPARATOR, /* state */ 0, &sepRect, &clipRect);
|
||||
}
|
||||
// The following widgets need to be RTL-aware
|
||||
else if (aWidgetType == NS_THEME_MENUARROW ||
|
||||
@ -1466,7 +1464,7 @@ RENDER_AGAIN:
|
||||
// If part is negative, the element wishes us to not render a themed
|
||||
// background, instead opting to be drawn specially below.
|
||||
else if (part >= 0) {
|
||||
DrawThemeBackground(theme, hdc, part, state, &widgetRect, &clipRect);
|
||||
nsUXThemeData::drawThemeBG(theme, hdc, part, state, &widgetRect, &clipRect);
|
||||
}
|
||||
|
||||
// Draw focus rectangles for XP HTML checkboxes and radio buttons
|
||||
@ -1489,8 +1487,7 @@ RENDER_AGAIN:
|
||||
|
||||
// On vista, choose our own colors and draw an XP style half focus rect
|
||||
// for focused checkboxes and a full rect when active.
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
|
||||
aWidgetType == NS_THEME_CHECKBOX) {
|
||||
if (nsUXThemeData::sIsVistaOrLater && aWidgetType == NS_THEME_CHECKBOX) {
|
||||
LOGBRUSH lb;
|
||||
lb.lbStyle = BS_SOLID;
|
||||
lb.lbColor = RGB(255,255,255);
|
||||
@ -1528,7 +1525,7 @@ RENDER_AGAIN:
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
widgetRect.bottom = widgetRect.top + TB_SEPARATOR_HEIGHT;
|
||||
DrawThemeEdge(theme, hdc, RP_BAND, 0, &widgetRect, EDGE_ETCHED, BF_TOP, NULL);
|
||||
nsUXThemeData::drawThemeEdge(theme, hdc, RP_BAND, 0, &widgetRect, EDGE_ETCHED, BF_TOP, NULL);
|
||||
}
|
||||
else if (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL ||
|
||||
aWidgetType == NS_THEME_SCROLLBAR_THUMB_VERTICAL)
|
||||
@ -1540,12 +1537,12 @@ RENDER_AGAIN:
|
||||
int gripPart = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL) ?
|
||||
SP_GRIPPERHOR : SP_GRIPPERVERT;
|
||||
|
||||
if (GetThemePartSize(theme, hdc, gripPart, state, NULL, TS_TRUE, &gripSize) == S_OK &&
|
||||
GetThemeMargins(theme, hdc, part, state, TMT_CONTENTMARGINS, NULL, &thumbMgns) == S_OK &&
|
||||
if (nsUXThemeData::getThemePartSize(theme, hdc, gripPart, state, NULL, TS_TRUE, &gripSize) == S_OK &&
|
||||
nsUXThemeData::getThemeMargins(theme, hdc, part, state, TMT_CONTENTMARGINS, NULL, &thumbMgns) == S_OK &&
|
||||
gripSize.cx + thumbMgns.cxLeftWidth + thumbMgns.cxRightWidth <= widgetRect.right - widgetRect.left &&
|
||||
gripSize.cy + thumbMgns.cyTopHeight + thumbMgns.cyBottomHeight <= widgetRect.bottom - widgetRect.top)
|
||||
{
|
||||
DrawThemeBackground(theme, hdc, gripPart, state, &widgetRect, &clipRect);
|
||||
nsUXThemeData::drawThemeBG(theme, hdc, gripPart, state, &widgetRect, &clipRect);
|
||||
}
|
||||
}
|
||||
else if ((aWidgetType == NS_THEME_WINDOW_BUTTON_BOX ||
|
||||
@ -1599,8 +1596,7 @@ RENDER_AGAIN:
|
||||
bool indeterminate = IsIndeterminateProgress(stateFrame, eventStates);
|
||||
bool vertical = IsVerticalProgress(stateFrame);
|
||||
|
||||
if (indeterminate ||
|
||||
WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
|
||||
if (indeterminate || nsUXThemeData::sIsVistaOrLater) {
|
||||
if (!QueueAnimatedContentForRefresh(aFrame->GetContent(), 30)) {
|
||||
NS_WARNING("unable to animate progress widget!");
|
||||
}
|
||||
@ -1612,7 +1608,7 @@ RENDER_AGAIN:
|
||||
* indeterminate progress bars.
|
||||
*/
|
||||
PRInt32 overlaySize;
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
|
||||
if (nsUXThemeData::sIsVistaOrLater) {
|
||||
if (vertical) {
|
||||
overlaySize = indeterminate ? kProgressVerticalIndeterminateOverlaySize
|
||||
: kProgressVerticalOverlaySize;
|
||||
@ -1656,17 +1652,16 @@ RENDER_AGAIN:
|
||||
|
||||
PRInt32 overlayPart;
|
||||
if (vertical) {
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
|
||||
if (nsUXThemeData::sIsVistaOrLater) {
|
||||
overlayPart = indeterminate ? PP_MOVEOVERLAY : PP_MOVEOVERLAYVERT;
|
||||
} else {
|
||||
overlayPart = PP_CHUNKVERT;
|
||||
}
|
||||
} else {
|
||||
overlayPart = WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION ?
|
||||
PP_MOVEOVERLAY : PP_CHUNK;
|
||||
overlayPart = nsUXThemeData::sIsVistaOrLater ? PP_MOVEOVERLAY : PP_CHUNK;
|
||||
}
|
||||
|
||||
DrawThemeBackground(theme, hdc, overlayPart, state, &overlayRect,
|
||||
nsUXThemeData::drawThemeBG(theme, hdc, overlayPart, state, &overlayRect,
|
||||
&clipRect);
|
||||
}
|
||||
}
|
||||
@ -1712,6 +1707,9 @@ nsNativeThemeWin::GetWidgetBorder(nsDeviceContext* aContext,
|
||||
aWidgetType == NS_THEME_WIN_GLASS || aWidgetType == NS_THEME_WIN_BORDERLESS_GLASS)
|
||||
return NS_OK; // Don't worry about it.
|
||||
|
||||
if (!nsUXThemeData::getThemeContentRect)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRInt32 part, state;
|
||||
nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
|
||||
if (NS_FAILED(rv))
|
||||
@ -1729,7 +1727,7 @@ nsNativeThemeWin::GetWidgetBorder(nsDeviceContext* aContext,
|
||||
outerRect.top = outerRect.left = 100;
|
||||
outerRect.right = outerRect.bottom = 200;
|
||||
RECT contentRect(outerRect);
|
||||
HRESULT res = GetThemeBackgroundContentRect(theme, NULL, part, state, &outerRect, &contentRect);
|
||||
HRESULT res = nsUXThemeData::getThemeContentRect(theme, NULL, part, state, &outerRect, &contentRect);
|
||||
|
||||
if (FAILED(res))
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -1819,13 +1817,13 @@ nsNativeThemeWin::GetWidgetPadding(nsDeviceContext* aContext,
|
||||
if (aWidgetType == NS_THEME_MENUPOPUP)
|
||||
{
|
||||
SIZE popupSize;
|
||||
GetThemePartSize(theme, NULL, MENU_POPUPBORDERS, /* state */ 0, NULL, TS_TRUE, &popupSize);
|
||||
nsUXThemeData::getThemePartSize(theme, NULL, MENU_POPUPBORDERS, /* state */ 0, NULL, TS_TRUE, &popupSize);
|
||||
aResult->top = aResult->bottom = popupSize.cy;
|
||||
aResult->left = aResult->right = popupSize.cx;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
|
||||
if (nsUXThemeData::sIsVistaOrLater) {
|
||||
if (aWidgetType == NS_THEME_TEXTFIELD ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
|
||||
aWidgetType == NS_THEME_DROPDOWN)
|
||||
@ -1918,7 +1916,7 @@ nsNativeThemeWin::GetWidgetOverflow(nsDeviceContext* aContext,
|
||||
* a border only shows up if the widget is being hovered.
|
||||
*/
|
||||
#if 0
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
|
||||
if (nsUXThemeData::sIsVistaOrLater) {
|
||||
/* We explicitly draw dropdown buttons in HTML content 1px bigger
|
||||
* up, right, and bottom so that they overlap the dropdown's border
|
||||
* like they're supposed to.
|
||||
@ -1977,10 +1975,13 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsRenderingContext* aContext, nsIFrame* a
|
||||
if (aWidgetType == NS_THEME_MENUITEM && IsTopLevelMenu(aFrame))
|
||||
return NS_OK; // Don't worry about it for top level menus
|
||||
|
||||
if (!nsUXThemeData::getThemePartSize)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Call GetSystemMetrics to determine size for WinXP scrollbars
|
||||
// (GetThemeSysSize API returns the optimal size for the theme, but
|
||||
// Windows appears to always use metrics when drawing standard scrollbars)
|
||||
THEMESIZE sizeReq = TS_TRUE; // Best-fit size
|
||||
PRInt32 sizeReq = TS_TRUE; // Best-fit size
|
||||
switch (aWidgetType) {
|
||||
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
||||
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
||||
@ -2041,7 +2042,7 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsRenderingContext* aContext, nsIFrame* a
|
||||
*aIsOverridable = false;
|
||||
// on Vista, GetThemePartAndState returns odd values for
|
||||
// scale thumbs, so use a hardcoded size instead.
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION) {
|
||||
if (nsUXThemeData::sIsVistaOrLater) {
|
||||
if (aWidgetType == NS_THEME_SCALE_THUMB_HORIZONTAL) {
|
||||
aResult->width = 12;
|
||||
aResult->height = 20;
|
||||
@ -2154,7 +2155,7 @@ nsNativeThemeWin::GetMinimumWidgetSize(nsRenderingContext* aContext, nsIFrame* a
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
SIZE sz;
|
||||
GetThemePartSize(theme, hdc, part, state, NULL, sizeReq, &sz);
|
||||
nsUXThemeData::getThemePartSize(theme, hdc, part, state, NULL, sizeReq, &sz);
|
||||
aResult->width = sz.cx;
|
||||
aResult->height = sz.cy;
|
||||
|
||||
@ -2216,7 +2217,7 @@ nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
}
|
||||
|
||||
// On Vista, the scrollbar buttons need to change state when the track has/doesn't have hover
|
||||
if (WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION &&
|
||||
if (!nsUXThemeData::sIsVistaOrLater &&
|
||||
(aWidgetType == NS_THEME_SCROLLBAR_TRACK_VERTICAL ||
|
||||
aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL)) {
|
||||
*aShouldRepaint = false;
|
||||
@ -2225,7 +2226,7 @@ nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
|
||||
// We need to repaint the dropdown arrow in vista HTML combobox controls when
|
||||
// the control is closed to get rid of the hover effect.
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
|
||||
if (nsUXThemeData::sIsVistaOrLater &&
|
||||
(aWidgetType == NS_THEME_DROPDOWN || aWidgetType == NS_THEME_DROPDOWN_BUTTON) &&
|
||||
IsHTMLContent(aFrame))
|
||||
{
|
||||
@ -2348,12 +2349,12 @@ nsNativeThemeWin::GetWidgetTransparency(nsIFrame* aFrame, PRUint8 aWidgetType)
|
||||
NS_ENSURE_SUCCESS(rv, eUnknownTransparency);
|
||||
|
||||
if (part <= 0) {
|
||||
// Not a real part code, so IsThemeBackgroundPartiallyTransparent may
|
||||
// Not a real part code, so isThemeBackgroundPartiallyTransparent may
|
||||
// not work, so don't call it.
|
||||
return eUnknownTransparency;
|
||||
}
|
||||
|
||||
if (IsThemeBackgroundPartiallyTransparent(theme, part, state))
|
||||
if (nsUXThemeData::isThemeBackgroundPartiallyTransparent(theme, part, state))
|
||||
return eTransparent;
|
||||
return eOpaque;
|
||||
}
|
||||
|
@ -184,6 +184,14 @@
|
||||
#define MSM_NORMAL 1
|
||||
#define MSM_DISABLED 2
|
||||
|
||||
// Theme size constants
|
||||
// minimum size
|
||||
#define TS_MIN 0
|
||||
// size without stretching
|
||||
#define TS_TRUE 1
|
||||
// size that theme mgr will use to draw part
|
||||
#define TS_DRAW 2
|
||||
|
||||
// From tmschema.h in the Vista SDK
|
||||
#define TMT_TEXTCOLOR 3803
|
||||
#define TMT_SIZINGMARGINS 3601
|
||||
|
@ -67,13 +67,32 @@ HMODULE
|
||||
nsUXThemeData::sDwmDLL = NULL;
|
||||
#endif
|
||||
|
||||
BOOL
|
||||
nsUXThemeData::sFlatMenus = FALSE;
|
||||
bool
|
||||
nsUXThemeData::sFlatMenus = false;
|
||||
nsUXThemeData::sIsXPOrLater = false;
|
||||
bool
|
||||
nsUXThemeData::sIsVistaOrLater = false;
|
||||
|
||||
bool nsUXThemeData::sTitlebarInfoPopulatedAero = false;
|
||||
bool nsUXThemeData::sTitlebarInfoPopulatedThemed = false;
|
||||
SIZE nsUXThemeData::sCommandButtons[4];
|
||||
|
||||
nsUXThemeData::OpenThemeDataPtr nsUXThemeData::openTheme = NULL;
|
||||
nsUXThemeData::CloseThemeDataPtr nsUXThemeData::closeTheme = NULL;
|
||||
nsUXThemeData::DrawThemeBackgroundPtr nsUXThemeData::drawThemeBG = NULL;
|
||||
nsUXThemeData::DrawThemeEdgePtr nsUXThemeData::drawThemeEdge = NULL;
|
||||
nsUXThemeData::GetThemeContentRectPtr nsUXThemeData::getThemeContentRect = NULL;
|
||||
nsUXThemeData::GetThemeBackgroundRegionPtr nsUXThemeData::getThemeBackgroundRegion = NULL;
|
||||
nsUXThemeData::GetThemePartSizePtr nsUXThemeData::getThemePartSize = NULL;
|
||||
nsUXThemeData::GetThemeSysFontPtr nsUXThemeData::getThemeSysFont = NULL;
|
||||
nsUXThemeData::GetThemeColorPtr nsUXThemeData::getThemeColor = NULL;
|
||||
nsUXThemeData::GetThemeMarginsPtr nsUXThemeData::getThemeMargins = NULL;
|
||||
nsUXThemeData::IsAppThemedPtr nsUXThemeData::isAppThemed = NULL;
|
||||
nsUXThemeData::GetCurrentThemeNamePtr nsUXThemeData::getCurrentThemeName = NULL;
|
||||
nsUXThemeData::GetThemeSysColorPtr nsUXThemeData::getThemeSysColor = NULL;
|
||||
nsUXThemeData::IsThemeBackgroundPartiallyTransparentPtr nsUXThemeData::isThemeBackgroundPartiallyTransparent = NULL;
|
||||
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
nsUXThemeData::DwmExtendFrameIntoClientAreaProc nsUXThemeData::dwmExtendFrameIntoClientAreaPtr = NULL;
|
||||
nsUXThemeData::DwmIsCompositionEnabledProc nsUXThemeData::dwmIsCompositionEnabledPtr = NULL;
|
||||
@ -102,6 +121,26 @@ nsUXThemeData::Initialize()
|
||||
::ZeroMemory(sThemes, sizeof(sThemes));
|
||||
NS_ASSERTION(!sThemeDLL, "nsUXThemeData being initialized twice!");
|
||||
|
||||
WinUtils::WinVersion version = WinUtils::GetWindowsVersion();
|
||||
sIsXPOrLater = version >= WinUtils::WINXP_VERSION;
|
||||
sIsVistaOrLater = version >= WinUtils::VISTA_VERSION;
|
||||
|
||||
if (GetThemeDLL()) {
|
||||
openTheme = (OpenThemeDataPtr)GetProcAddress(sThemeDLL, "OpenThemeData");
|
||||
closeTheme = (CloseThemeDataPtr)GetProcAddress(sThemeDLL, "CloseThemeData");
|
||||
drawThemeBG = (DrawThemeBackgroundPtr)GetProcAddress(sThemeDLL, "DrawThemeBackground");
|
||||
drawThemeEdge = (DrawThemeEdgePtr)GetProcAddress(sThemeDLL, "DrawThemeEdge");
|
||||
getThemeContentRect = (GetThemeContentRectPtr)GetProcAddress(sThemeDLL, "GetThemeBackgroundContentRect");
|
||||
getThemeBackgroundRegion = (GetThemeBackgroundRegionPtr)GetProcAddress(sThemeDLL, "GetThemeBackgroundRegion");
|
||||
getThemePartSize = (GetThemePartSizePtr)GetProcAddress(sThemeDLL, "GetThemePartSize");
|
||||
getThemeSysFont = (GetThemeSysFontPtr)GetProcAddress(sThemeDLL, "GetThemeSysFont");
|
||||
getThemeColor = (GetThemeColorPtr)GetProcAddress(sThemeDLL, "GetThemeColor");
|
||||
getThemeMargins = (GetThemeMarginsPtr)GetProcAddress(sThemeDLL, "GetThemeMargins");
|
||||
isAppThemed = (IsAppThemedPtr)GetProcAddress(sThemeDLL, "IsAppThemed");
|
||||
getCurrentThemeName = (GetCurrentThemeNamePtr)GetProcAddress(sThemeDLL, "GetCurrentThemeName");
|
||||
getThemeSysColor = (GetThemeSysColorPtr)GetProcAddress(sThemeDLL, "GetThemeSysColor");
|
||||
isThemeBackgroundPartiallyTransparent = (IsThemeBackgroundPartiallyTransparentPtr)GetProcAddress(sThemeDLL, "IsThemeBackgroundPartiallyTransparent");
|
||||
}
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
if (GetDwmDLL()) {
|
||||
dwmExtendFrameIntoClientAreaPtr = (DwmExtendFrameIntoClientAreaProc)::GetProcAddress(sDwmDLL, "DwmExtendFrameIntoClientArea");
|
||||
@ -123,28 +162,38 @@ void
|
||||
nsUXThemeData::Invalidate() {
|
||||
for(int i = 0; i < eUXNumClasses; i++) {
|
||||
if(sThemes[i]) {
|
||||
CloseThemeData(sThemes[i]);
|
||||
closeTheme(sThemes[i]);
|
||||
sThemes[i] = NULL;
|
||||
}
|
||||
}
|
||||
BOOL useFlat = false;
|
||||
sFlatMenus = ::SystemParametersInfo(SPI_GETFLATMENU, 0, &useFlat, 0) ?
|
||||
useFlat : false;
|
||||
if (sIsXPOrLater) {
|
||||
BOOL useFlat = false;
|
||||
sFlatMenus = ::SystemParametersInfo(SPI_GETFLATMENU, 0, &useFlat, 0) ?
|
||||
useFlat : false;
|
||||
} else {
|
||||
// Contrary to Microsoft's documentation, SPI_GETFLATMENU will not fail
|
||||
// on Windows 2000, and it is also possible (though unlikely) for WIN2K
|
||||
// to be misconfigured in such a way that it would return true, so we
|
||||
// shall give WIN2K special treatment
|
||||
sFlatMenus = false;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE
|
||||
nsUXThemeData::GetTheme(nsUXThemeClass cls) {
|
||||
NS_ASSERTION(cls < eUXNumClasses, "Invalid theme class!");
|
||||
if(!sThemeDLL)
|
||||
return NULL;
|
||||
if(!sThemes[cls])
|
||||
{
|
||||
sThemes[cls] = OpenThemeData(NULL, GetClassName(cls));
|
||||
sThemes[cls] = openTheme(NULL, GetClassName(cls));
|
||||
}
|
||||
return sThemes[cls];
|
||||
}
|
||||
|
||||
HMODULE
|
||||
nsUXThemeData::GetThemeDLL() {
|
||||
if (!sThemeDLL)
|
||||
if (!sThemeDLL && sIsXPOrLater)
|
||||
sThemeDLL = ::LoadLibraryW(kThemeLibraryName);
|
||||
return sThemeDLL;
|
||||
}
|
||||
@ -152,7 +201,7 @@ nsUXThemeData::GetThemeDLL() {
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
HMODULE
|
||||
nsUXThemeData::GetDwmDLL() {
|
||||
if (!sDwmDLL && WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION)
|
||||
if (!sDwmDLL && sIsVistaOrLater)
|
||||
sDwmDLL = ::LoadLibraryW(kDwmLibraryName);
|
||||
return sDwmDLL;
|
||||
}
|
||||
@ -358,14 +407,14 @@ nsUXThemeData::UpdateNativeThemeInfo()
|
||||
sIsDefaultWindowsTheme = false;
|
||||
sThemeId = LookAndFeel::eWindowsTheme_Generic;
|
||||
|
||||
if (!IsAppThemed()) {
|
||||
if (!IsAppThemed() || !getCurrentThemeName) {
|
||||
sThemeId = LookAndFeel::eWindowsTheme_Classic;
|
||||
return;
|
||||
}
|
||||
|
||||
WCHAR themeFileName[MAX_PATH + 1];
|
||||
WCHAR themeColor[MAX_PATH + 1];
|
||||
if (FAILED(GetCurrentThemeName(themeFileName,
|
||||
if (FAILED(getCurrentThemeName(themeFileName,
|
||||
MAX_PATH,
|
||||
themeColor,
|
||||
MAX_PATH,
|
||||
|
@ -127,7 +127,9 @@ public:
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
static const PRUnichar kDwmLibraryName[];
|
||||
#endif
|
||||
static bool sFlatMenus;
|
||||
static BOOL sFlatMenus;
|
||||
static bool sIsXPOrLater;
|
||||
static bool sIsVistaOrLater;
|
||||
static bool sTitlebarInfoPopulatedAero;
|
||||
static bool sTitlebarInfoPopulatedThemed;
|
||||
static SIZE sCommandButtons[4];
|
||||
@ -151,6 +153,64 @@ public:
|
||||
static mozilla::LookAndFeel::WindowsTheme GetNativeThemeId();
|
||||
static bool IsDefaultWindowTheme();
|
||||
|
||||
static inline BOOL IsAppThemed() {
|
||||
return isAppThemed && isAppThemed();
|
||||
}
|
||||
|
||||
static inline HRESULT GetThemeColor(nsUXThemeClass cls, int iPartId, int iStateId,
|
||||
int iPropId, OUT COLORREF* pFont) {
|
||||
if(!getThemeColor)
|
||||
return E_FAIL;
|
||||
return getThemeColor(GetTheme(cls), iPartId, iStateId, iPropId, pFont);
|
||||
}
|
||||
|
||||
// UXTheme.dll Function typedefs and declarations
|
||||
typedef HANDLE (WINAPI*OpenThemeDataPtr)(HWND hwnd, LPCWSTR pszClassList);
|
||||
typedef HRESULT (WINAPI*CloseThemeDataPtr)(HANDLE hTheme);
|
||||
typedef HRESULT (WINAPI*DrawThemeBackgroundPtr)(HANDLE hTheme, HDC hdc, int iPartId,
|
||||
int iStateId, const RECT *pRect,
|
||||
const RECT* pClipRect);
|
||||
typedef HRESULT (WINAPI*DrawThemeEdgePtr)(HANDLE hTheme, HDC hdc, int iPartId,
|
||||
int iStateId, const RECT *pDestRect,
|
||||
uint uEdge, uint uFlags,
|
||||
const RECT* pContentRect);
|
||||
typedef HRESULT (WINAPI*GetThemeContentRectPtr)(HANDLE hTheme, HDC hdc, int iPartId,
|
||||
int iStateId, const RECT* pRect,
|
||||
RECT* pContentRect);
|
||||
typedef HRESULT (WINAPI*GetThemeBackgroundRegionPtr)(HANDLE hTheme, HDC hdc, int iPartId,
|
||||
int iStateId, const RECT* pRect,
|
||||
HRGN *pRegion);
|
||||
typedef HRESULT (WINAPI*GetThemePartSizePtr)(HANDLE hTheme, HDC hdc, int iPartId,
|
||||
int iStateId, RECT* prc, int ts,
|
||||
SIZE* psz);
|
||||
typedef HRESULT (WINAPI*GetThemeSysFontPtr)(HANDLE hTheme, int iFontId, OUT LOGFONT* pFont);
|
||||
typedef HRESULT (WINAPI*GetThemeColorPtr)(HANDLE hTheme, int iPartId,
|
||||
int iStateId, int iPropId, OUT COLORREF* pFont);
|
||||
typedef HRESULT (WINAPI*GetThemeMarginsPtr)(HANDLE hTheme, HDC hdc, int iPartId,
|
||||
int iStateid, int iPropId,
|
||||
LPRECT prc, MARGINS *pMargins);
|
||||
typedef BOOL (WINAPI*IsAppThemedPtr)(VOID);
|
||||
typedef HRESULT (WINAPI*GetCurrentThemeNamePtr)(LPWSTR pszThemeFileName, int dwMaxNameChars,
|
||||
LPWSTR pszColorBuff, int cchMaxColorChars,
|
||||
LPWSTR pszSizeBuff, int cchMaxSizeChars);
|
||||
typedef COLORREF (WINAPI*GetThemeSysColorPtr)(HANDLE hTheme, int iColorID);
|
||||
typedef BOOL (WINAPI*IsThemeBackgroundPartiallyTransparentPtr)(HANDLE hTheme, int iPartId, int iStateId);
|
||||
|
||||
static OpenThemeDataPtr openTheme;
|
||||
static CloseThemeDataPtr closeTheme;
|
||||
static DrawThemeBackgroundPtr drawThemeBG;
|
||||
static DrawThemeEdgePtr drawThemeEdge;
|
||||
static GetThemeContentRectPtr getThemeContentRect;
|
||||
static GetThemeBackgroundRegionPtr getThemeBackgroundRegion;
|
||||
static GetThemePartSizePtr getThemePartSize;
|
||||
static GetThemeSysFontPtr getThemeSysFont;
|
||||
static GetThemeColorPtr getThemeColor;
|
||||
static GetThemeMarginsPtr getThemeMargins;
|
||||
static IsAppThemedPtr isAppThemed;
|
||||
static GetCurrentThemeNamePtr getCurrentThemeName;
|
||||
static GetThemeSysColorPtr getThemeSysColor;
|
||||
static IsThemeBackgroundPartiallyTransparentPtr isThemeBackgroundPartiallyTransparent;
|
||||
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
// dwmapi.dll function typedefs and declarations
|
||||
typedef HRESULT (WINAPI*DwmExtendFrameIntoClientAreaProc)(HWND hWnd, const MARGINS *pMarInset);
|
||||
|
@ -113,7 +113,6 @@
|
||||
#include <process.h>
|
||||
#include <commctrl.h>
|
||||
#include <unknwn.h>
|
||||
#include <psapi.h>
|
||||
|
||||
#include "prlog.h"
|
||||
#include "prtime.h"
|
||||
@ -1274,8 +1273,7 @@ NS_METHOD nsWindow::IsVisible(bool & bState)
|
||||
// transparency. These routines are called on size and move operations.
|
||||
void nsWindow::ClearThemeRegion()
|
||||
{
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
|
||||
!HasGlass() &&
|
||||
if (nsUXThemeData::sIsVistaOrLater && !HasGlass() &&
|
||||
(mWindowType == eWindowType_popup && !IsPopupWithTitleBar() &&
|
||||
(mPopupType == ePopupTypeTooltip || mPopupType == ePopupTypePanel))) {
|
||||
SetWindowRgn(mWnd, NULL, false);
|
||||
@ -1289,15 +1287,14 @@ void nsWindow::SetThemeRegion()
|
||||
// so default constants are used for part and state. At some point we might need part and
|
||||
// state values from nsNativeThemeWin's GetThemePartAndState, but currently windows that
|
||||
// change shape based on state haven't come up.
|
||||
if (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION &&
|
||||
!HasGlass() &&
|
||||
if (nsUXThemeData::sIsVistaOrLater && !HasGlass() &&
|
||||
(mWindowType == eWindowType_popup && !IsPopupWithTitleBar() &&
|
||||
(mPopupType == ePopupTypeTooltip || mPopupType == ePopupTypePanel))) {
|
||||
HRGN hRgn = nsnull;
|
||||
RECT rect = {0,0,mBounds.width,mBounds.height};
|
||||
|
||||
HDC dc = ::GetDC(mWnd);
|
||||
GetThemeBackgroundRegion(nsUXThemeData::GetTheme(eUXTooltip), dc, TTP_STANDARD, TS_NORMAL, &rect, &hRgn);
|
||||
nsUXThemeData::getThemeBackgroundRegion(nsUXThemeData::GetTheme(eUXTooltip), dc, TTP_STANDARD, TS_NORMAL, &rect, &hRgn);
|
||||
if (hRgn) {
|
||||
if (!SetWindowRgn(mWnd, hRgn, false)) // do not delete or alter hRgn if accepted.
|
||||
DeleteObject(hRgn);
|
||||
@ -6360,7 +6357,7 @@ nsWindow::InitMouseWheelScrollData()
|
||||
|
||||
if (!::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0,
|
||||
&sMouseWheelScrollChars, 0)) {
|
||||
NS_ASSERTION(WinUtils::GetWindowsVersion() < WinUtils::VISTA_VERSION,
|
||||
NS_ASSERTION(!nsUXThemeData::sIsVistaOrLater,
|
||||
"Failed to get SPI_GETWHEELSCROLLCHARS");
|
||||
sMouseWheelScrollChars = 1;
|
||||
} else if (sMouseWheelScrollChars > WHEEL_DELTA) {
|
||||
@ -7461,12 +7458,22 @@ bool nsWindow::OnHotKey(WPARAM wParam, LPARAM lParam)
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef DWORD (WINAPI *GetProcessImageFileNameProc)(HANDLE, LPWSTR, DWORD);
|
||||
|
||||
// Determine whether the given HWND is the handle for the Elantech helper
|
||||
// window. The helper window cannot be distinguished based on its
|
||||
// window class, so we need to check if it is owned by the helper process,
|
||||
// ETDCtrl.exe.
|
||||
static bool IsElantechHelperWindow(HWND aHWND)
|
||||
{
|
||||
static HMODULE hPSAPI = ::LoadLibraryW(L"psapi.dll");
|
||||
static GetProcessImageFileNameProc pGetProcessImageFileName =
|
||||
reinterpret_cast<GetProcessImageFileNameProc>(::GetProcAddress(hPSAPI, "GetProcessImageFileNameW"));
|
||||
|
||||
if (!pGetProcessImageFileName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const PRUnichar* filenameSuffix = L"\\etdctrl.exe";
|
||||
const int filenameSuffixLength = 12;
|
||||
|
||||
@ -7478,7 +7485,7 @@ static bool IsElantechHelperWindow(HWND aHWND)
|
||||
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
|
||||
if (hProcess) {
|
||||
PRUnichar path[256] = {L'\0'};
|
||||
if (GetProcessImageFileName(hProcess, path, ArrayLength(path))) {
|
||||
if (pGetProcessImageFileName(hProcess, path, ArrayLength(path))) {
|
||||
int pathLength = lstrlenW(path);
|
||||
if (pathLength >= filenameSuffixLength) {
|
||||
if (lstrcmpiW(path + pathLength - filenameSuffixLength, filenameSuffix) == 0) {
|
||||
|
@ -758,9 +758,23 @@ PRUint8* nsWindowGfx::Data32BitTo1Bit(PRUint8* aImageData,
|
||||
return outData;
|
||||
}
|
||||
|
||||
bool nsWindowGfx::IsCursorTranslucencySupported()
|
||||
{
|
||||
static bool didCheck = false;
|
||||
static bool isSupported = false;
|
||||
if (!didCheck) {
|
||||
didCheck = true;
|
||||
// Cursor translucency is supported on Windows XP and newer
|
||||
isSupported = WinUtils::GetWindowsVersion() >= WinUtils::WINXP_VERSION;
|
||||
}
|
||||
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given image data to a HBITMAP. If the requested depth is
|
||||
* 32 bit, a bitmap with an alpha channel will be returned.
|
||||
* 32 bit and the OS supports translucency, a bitmap with an alpha channel
|
||||
* will be returned.
|
||||
*
|
||||
* @param aImageData The image data to convert. Must use the format accepted
|
||||
* by CreateDIBitmap.
|
||||
@ -779,7 +793,7 @@ HBITMAP nsWindowGfx::DataToBitmap(PRUint8* aImageData,
|
||||
{
|
||||
HDC dc = ::GetDC(NULL);
|
||||
|
||||
if (aDepth == 32) {
|
||||
if (aDepth == 32 && IsCursorTranslucencySupported()) {
|
||||
// Alpha channel. We need the new header.
|
||||
BITMAPV4HEADER head = { 0 };
|
||||
head.bV4Size = sizeof(head);
|
||||
|
@ -72,6 +72,7 @@ private:
|
||||
* Cursor helpers
|
||||
*/
|
||||
static PRUint8* Data32BitTo1Bit(PRUint8* aImageData, PRUint32 aWidth, PRUint32 aHeight);
|
||||
static bool IsCursorTranslucencySupported();
|
||||
static HBITMAP DataToBitmap(PRUint8* aImageData, PRUint32 aWidth, PRUint32 aHeight, PRUint32 aDepth);
|
||||
};
|
||||
|
||||
|
@ -54,6 +54,7 @@ namespace widget {
|
||||
|
||||
enum OperatingSystem {
|
||||
DRIVER_OS_UNKNOWN = 0,
|
||||
DRIVER_OS_WINDOWS_2000,
|
||||
DRIVER_OS_WINDOWS_XP,
|
||||
DRIVER_OS_WINDOWS_SERVER_2003,
|
||||
DRIVER_OS_WINDOWS_VISTA,
|
||||
|
@ -287,7 +287,9 @@ BlacklistNodeToTextValue(nsIDOMNode *aBlacklistNode, nsAString& aValue)
|
||||
static OperatingSystem
|
||||
BlacklistOSToOperatingSystem(const nsAString& os)
|
||||
{
|
||||
if (os == NS_LITERAL_STRING("WINNT 5.1"))
|
||||
if (os == NS_LITERAL_STRING("WINNT 5.0"))
|
||||
return DRIVER_OS_WINDOWS_2000;
|
||||
else if (os == NS_LITERAL_STRING("WINNT 5.1"))
|
||||
return DRIVER_OS_WINDOWS_XP;
|
||||
else if (os == NS_LITERAL_STRING("WINNT 5.2"))
|
||||
return DRIVER_OS_WINDOWS_SERVER_2003;
|
||||
|
@ -70,6 +70,22 @@ static void SanitizeEnvironmentVariables()
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the directory from which DLLs can be loaded if the SetDllDirectory OS
|
||||
// API is available.
|
||||
// You must call SanitizeEnvironmentVariables before this function when calling
|
||||
// it the first time.
|
||||
static inline void NS_SetDllDirectory(const WCHAR *aDllDirectory)
|
||||
{
|
||||
typedef BOOL
|
||||
(WINAPI *pfnSetDllDirectory) (LPCWSTR);
|
||||
pfnSetDllDirectory setDllDirectory = nsnull;
|
||||
setDllDirectory = reinterpret_cast<pfnSetDllDirectory>
|
||||
(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDllDirectoryW"));
|
||||
if (setDllDirectory) {
|
||||
setDllDirectory(aDllDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -205,12 +205,14 @@ StackWalkInitCriticalAddress()
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
|
||||
#include "nspr.h"
|
||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||
#include <imagehlp.h>
|
||||
// We need a way to know if we are building for WXP (or later), as if we are, we
|
||||
// need to use the newer 64-bit APIs. API_VERSION_NUMBER seems to fit the bill.
|
||||
// A value of 9 indicates we want to use the new APIs.
|
||||
#if API_VERSION_NUMBER < 9
|
||||
#error Too old imagehlp.h
|
||||
#if API_VERSION_NUMBER >= 9
|
||||
#define USING_WXP_VERSION 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
@ -223,12 +225,116 @@ using namespace mozilla;
|
||||
//
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
typedef DWORD (__stdcall *SYMSETOPTIONSPROC)(DWORD);
|
||||
extern SYMSETOPTIONSPROC _SymSetOptions;
|
||||
|
||||
typedef BOOL (__stdcall *SYMINITIALIZEPROC)(HANDLE, LPSTR, BOOL);
|
||||
extern SYMINITIALIZEPROC _SymInitialize;
|
||||
|
||||
typedef BOOL (__stdcall *SYMCLEANUPPROC)(HANDLE);
|
||||
extern SYMCLEANUPPROC _SymCleanup;
|
||||
|
||||
typedef BOOL (__stdcall *STACKWALKPROC)(DWORD,
|
||||
HANDLE,
|
||||
HANDLE,
|
||||
LPSTACKFRAME,
|
||||
LPVOID,
|
||||
PREAD_PROCESS_MEMORY_ROUTINE,
|
||||
PFUNCTION_TABLE_ACCESS_ROUTINE,
|
||||
PGET_MODULE_BASE_ROUTINE,
|
||||
PTRANSLATE_ADDRESS_ROUTINE);
|
||||
extern STACKWALKPROC _StackWalk;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
typedef BOOL (__stdcall *STACKWALKPROC64)(DWORD,
|
||||
HANDLE,
|
||||
HANDLE,
|
||||
LPSTACKFRAME64,
|
||||
PVOID,
|
||||
PREAD_PROCESS_MEMORY_ROUTINE64,
|
||||
PFUNCTION_TABLE_ACCESS_ROUTINE64,
|
||||
PGET_MODULE_BASE_ROUTINE64,
|
||||
PTRANSLATE_ADDRESS_ROUTINE64);
|
||||
extern STACKWALKPROC64 _StackWalk64;
|
||||
#endif
|
||||
|
||||
typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)(HANDLE, DWORD);
|
||||
extern SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC64)(HANDLE, DWORD64);
|
||||
extern SYMFUNCTIONTABLEACCESSPROC64 _SymFunctionTableAccess64;
|
||||
#endif
|
||||
|
||||
typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)(HANDLE, DWORD);
|
||||
extern SYMGETMODULEBASEPROC _SymGetModuleBase;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
typedef DWORD64 (__stdcall *SYMGETMODULEBASEPROC64)(HANDLE, DWORD64);
|
||||
extern SYMGETMODULEBASEPROC64 _SymGetModuleBase64;
|
||||
#endif
|
||||
|
||||
typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL);
|
||||
extern SYMGETSYMFROMADDRPROC _SymGetSymFromAddr;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
typedef BOOL (__stdcall *SYMFROMADDRPROC)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO);
|
||||
extern SYMFROMADDRPROC _SymFromAddr;
|
||||
#endif
|
||||
|
||||
typedef DWORD ( __stdcall *SYMLOADMODULE)(HANDLE, HANDLE, PSTR, PSTR, DWORD, DWORD);
|
||||
extern SYMLOADMODULE _SymLoadModule;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
typedef DWORD ( __stdcall *SYMLOADMODULE64)(HANDLE, HANDLE, PCSTR, PCSTR, DWORD64, DWORD);
|
||||
extern SYMLOADMODULE64 _SymLoadModule64;
|
||||
#endif
|
||||
|
||||
typedef DWORD ( __stdcall *SYMUNDNAME)(PIMAGEHLP_SYMBOL, PSTR, DWORD);
|
||||
extern SYMUNDNAME _SymUnDName;
|
||||
|
||||
typedef DWORD ( __stdcall *SYMGETMODULEINFO)( HANDLE, DWORD, PIMAGEHLP_MODULE);
|
||||
extern SYMGETMODULEINFO _SymGetModuleInfo;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
typedef BOOL ( __stdcall *SYMGETMODULEINFO64)( HANDLE, DWORD64, PIMAGEHLP_MODULE64);
|
||||
extern SYMGETMODULEINFO64 _SymGetModuleInfo64;
|
||||
#endif
|
||||
|
||||
typedef BOOL ( __stdcall *ENUMLOADEDMODULES)( HANDLE, PENUMLOADED_MODULES_CALLBACK, PVOID);
|
||||
extern ENUMLOADEDMODULES _EnumerateLoadedModules;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
typedef BOOL ( __stdcall *ENUMLOADEDMODULES64)( HANDLE, PENUMLOADED_MODULES_CALLBACK64, PVOID);
|
||||
extern ENUMLOADEDMODULES64 _EnumerateLoadedModules64;
|
||||
#endif
|
||||
|
||||
typedef BOOL (__stdcall *SYMGETLINEFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE);
|
||||
extern SYMGETLINEFROMADDRPROC _SymGetLineFromAddr;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
typedef BOOL (__stdcall *SYMGETLINEFROMADDRPROC64)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64);
|
||||
extern SYMGETLINEFROMADDRPROC64 _SymGetLineFromAddr64;
|
||||
#endif
|
||||
|
||||
extern HANDLE hStackWalkMutex;
|
||||
|
||||
bool EnsureSymInitialized();
|
||||
|
||||
bool EnsureImageHlpInitialized();
|
||||
|
||||
/*
|
||||
* SymGetModuleInfoEspecial
|
||||
*
|
||||
* Attempt to determine the module information.
|
||||
* Bug 112196 says this DLL may not have been loaded at the time
|
||||
* SymInitialize was called, and thus the module information
|
||||
* and symbol information is not available.
|
||||
* This code rectifies that problem.
|
||||
* Line information is optional.
|
||||
*/
|
||||
BOOL SymGetModuleInfoEspecial(HANDLE aProcess, DWORD aAddr, PIMAGEHLP_MODULE aModuleInfo, PIMAGEHLP_LINE aLineInfo);
|
||||
|
||||
struct WalkStackData {
|
||||
PRUint32 skipFrames;
|
||||
HANDLE thread;
|
||||
@ -244,8 +350,82 @@ struct WalkStackData {
|
||||
void PrintError(char *prefix, WalkStackData* data);
|
||||
unsigned int WINAPI WalkStackThread(void* data);
|
||||
void WalkStackMain64(struct WalkStackData* data);
|
||||
#if !defined(_WIN64)
|
||||
void WalkStackMain(struct WalkStackData* data);
|
||||
#endif
|
||||
|
||||
|
||||
// Define these as static pointers so that we can load the DLL on the
|
||||
// fly (and not introduce a link-time dependency on it). Tip o' the
|
||||
// hat to Matt Pietrick for this idea. See:
|
||||
//
|
||||
// http://msdn.microsoft.com/library/periodic/period97/F1/D3/S245C6.htm
|
||||
//
|
||||
|
||||
SYMSETOPTIONSPROC _SymSetOptions;
|
||||
|
||||
SYMINITIALIZEPROC _SymInitialize;
|
||||
|
||||
SYMCLEANUPPROC _SymCleanup;
|
||||
|
||||
STACKWALKPROC _StackWalk;
|
||||
#ifdef USING_WXP_VERSION
|
||||
STACKWALKPROC64 _StackWalk64;
|
||||
#else
|
||||
#define _StackWalk64 0
|
||||
#endif
|
||||
|
||||
SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess;
|
||||
#ifdef USING_WXP_VERSION
|
||||
SYMFUNCTIONTABLEACCESSPROC64 _SymFunctionTableAccess64;
|
||||
#else
|
||||
#define _SymFunctionTableAccess64 0
|
||||
#endif
|
||||
|
||||
SYMGETMODULEBASEPROC _SymGetModuleBase;
|
||||
#ifdef USING_WXP_VERSION
|
||||
SYMGETMODULEBASEPROC64 _SymGetModuleBase64;
|
||||
#else
|
||||
#define _SymGetModuleBase64 0
|
||||
#endif
|
||||
|
||||
SYMGETSYMFROMADDRPROC _SymGetSymFromAddr;
|
||||
#ifdef USING_WXP_VERSION
|
||||
SYMFROMADDRPROC _SymFromAddr;
|
||||
#else
|
||||
#define _SymFromAddr 0
|
||||
#endif
|
||||
|
||||
SYMLOADMODULE _SymLoadModule;
|
||||
#ifdef USING_WXP_VERSION
|
||||
SYMLOADMODULE64 _SymLoadModule64;
|
||||
#else
|
||||
#define _SymLoadModule64 0
|
||||
#endif
|
||||
|
||||
SYMUNDNAME _SymUnDName;
|
||||
|
||||
SYMGETMODULEINFO _SymGetModuleInfo;
|
||||
#ifdef USING_WXP_VERSION
|
||||
SYMGETMODULEINFO64 _SymGetModuleInfo64;
|
||||
#else
|
||||
#define _SymGetModuleInfo64 0
|
||||
#endif
|
||||
|
||||
ENUMLOADEDMODULES _EnumerateLoadedModules;
|
||||
#ifdef USING_WXP_VERSION
|
||||
ENUMLOADEDMODULES64 _EnumerateLoadedModules64;
|
||||
#else
|
||||
#define _EnumerateLoadedModules64 0
|
||||
#endif
|
||||
|
||||
SYMGETLINEFROMADDRPROC _SymGetLineFromAddr;
|
||||
#ifdef USING_WXP_VERSION
|
||||
SYMGETLINEFROMADDRPROC64 _SymGetLineFromAddr64;
|
||||
#else
|
||||
#define _SymGetLineFromAddr64 0
|
||||
#endif
|
||||
|
||||
DWORD gStackWalkThread;
|
||||
CRITICAL_SECTION gDbgHelpCS;
|
||||
|
||||
@ -304,12 +484,79 @@ EnsureImageHlpInitialized()
|
||||
|
||||
::InitializeCriticalSection(&gDbgHelpCS);
|
||||
|
||||
HMODULE module = ::LoadLibraryW(L"DBGHELP.DLL");
|
||||
if (!module) {
|
||||
module = ::LoadLibraryW(L"IMAGEHLP.DLL");
|
||||
if (!module) return false;
|
||||
}
|
||||
|
||||
_SymSetOptions = (SYMSETOPTIONSPROC) ::GetProcAddress(module, "SymSetOptions");
|
||||
if (!_SymSetOptions) return false;
|
||||
|
||||
_SymInitialize = (SYMINITIALIZEPROC) ::GetProcAddress(module, "SymInitialize");
|
||||
if (!_SymInitialize) return false;
|
||||
|
||||
_SymCleanup = (SYMCLEANUPPROC)GetProcAddress(module, "SymCleanup");
|
||||
if (!_SymCleanup) return false;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
_StackWalk64 = (STACKWALKPROC64)GetProcAddress(module, "StackWalk64");
|
||||
#endif
|
||||
_StackWalk = (STACKWALKPROC)GetProcAddress(module, "StackWalk");
|
||||
if (!_StackWalk64 && !_StackWalk) return false;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
_SymFunctionTableAccess64 = (SYMFUNCTIONTABLEACCESSPROC64) GetProcAddress(module, "SymFunctionTableAccess64");
|
||||
#endif
|
||||
_SymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC) GetProcAddress(module, "SymFunctionTableAccess");
|
||||
if (!_SymFunctionTableAccess64 && !_SymFunctionTableAccess) return false;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
_SymGetModuleBase64 = (SYMGETMODULEBASEPROC64)GetProcAddress(module, "SymGetModuleBase64");
|
||||
#endif
|
||||
_SymGetModuleBase = (SYMGETMODULEBASEPROC)GetProcAddress(module, "SymGetModuleBase");
|
||||
if (!_SymGetModuleBase64 && !_SymGetModuleBase) return false;
|
||||
|
||||
_SymGetSymFromAddr = (SYMGETSYMFROMADDRPROC)GetProcAddress(module, "SymGetSymFromAddr");
|
||||
#ifdef USING_WXP_VERSION
|
||||
_SymFromAddr = (SYMFROMADDRPROC)GetProcAddress(module, "SymFromAddr");
|
||||
#endif
|
||||
if (!_SymFromAddr && !_SymGetSymFromAddr) return false;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
_SymLoadModule64 = (SYMLOADMODULE64)GetProcAddress(module, "SymLoadModule64");
|
||||
#endif
|
||||
_SymLoadModule = (SYMLOADMODULE)GetProcAddress(module, "SymLoadModule");
|
||||
if (!_SymLoadModule64 && !_SymLoadModule) return false;
|
||||
|
||||
_SymUnDName = (SYMUNDNAME)GetProcAddress(module, "SymUnDName");
|
||||
if (!_SymUnDName) return false;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
_SymGetModuleInfo64 = (SYMGETMODULEINFO64)GetProcAddress(module, "SymGetModuleInfo64");
|
||||
#endif
|
||||
_SymGetModuleInfo = (SYMGETMODULEINFO)GetProcAddress(module, "SymGetModuleInfo");
|
||||
if (!_SymGetModuleInfo64 && !_SymGetModuleInfo) return false;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
_EnumerateLoadedModules64 = (ENUMLOADEDMODULES64)GetProcAddress(module, "EnumerateLoadedModules64");
|
||||
#endif
|
||||
_EnumerateLoadedModules = (ENUMLOADEDMODULES)GetProcAddress(module, "EnumerateLoadedModules");
|
||||
if (!_EnumerateLoadedModules64 && !_EnumerateLoadedModules) return false;
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
_SymGetLineFromAddr64 = (SYMGETLINEFROMADDRPROC64)GetProcAddress(module, "SymGetLineFromAddr64");
|
||||
#endif
|
||||
_SymGetLineFromAddr = (SYMGETLINEFROMADDRPROC)GetProcAddress(module, "SymGetLineFromAddr");
|
||||
if (!_SymGetLineFromAddr64 && !_SymGetLineFromAddr) return false;
|
||||
|
||||
return gInitialized = true;
|
||||
}
|
||||
|
||||
void
|
||||
WalkStackMain64(struct WalkStackData* data)
|
||||
{
|
||||
#ifdef USING_WXP_VERSION
|
||||
// Get the context information for the thread. That way we will
|
||||
// know where our sp, fp, pc, etc. are and can fill in the
|
||||
// STACKFRAME64 with the initial values.
|
||||
@ -357,7 +604,7 @@ WalkStackMain64(struct WalkStackData* data)
|
||||
|
||||
// debug routines are not threadsafe, so grab the lock.
|
||||
EnterCriticalSection(&gDbgHelpCS);
|
||||
ok = StackWalk64(
|
||||
ok = _StackWalk64(
|
||||
#ifdef _M_AMD64
|
||||
IMAGE_FILE_MACHINE_AMD64,
|
||||
#elif defined _M_IA64
|
||||
@ -372,8 +619,8 @@ WalkStackMain64(struct WalkStackData* data)
|
||||
&frame64,
|
||||
&context,
|
||||
NULL,
|
||||
SymFunctionTableAccess64, // function table access routine
|
||||
SymGetModuleBase64, // module base routine
|
||||
_SymFunctionTableAccess64, // function table access routine
|
||||
_SymGetModuleBase64, // module base routine
|
||||
0
|
||||
);
|
||||
LeaveCriticalSection(&gDbgHelpCS);
|
||||
@ -401,9 +648,106 @@ WalkStackMain64(struct WalkStackData* data)
|
||||
break;
|
||||
}
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !defined(_WIN64)
|
||||
void
|
||||
WalkStackMain(struct WalkStackData* data)
|
||||
{
|
||||
// Get the context information for the thread. That way we will
|
||||
// know where our sp, fp, pc, etc. are and can fill in the
|
||||
// STACKFRAME with the initial values.
|
||||
CONTEXT context;
|
||||
HANDLE myProcess = data->process;
|
||||
HANDLE myThread = data->thread;
|
||||
DWORD addr;
|
||||
STACKFRAME frame;
|
||||
int skip = data->skipFrames; // skip our own stack walking frames
|
||||
BOOL ok;
|
||||
|
||||
// Get a context for the specified thread.
|
||||
memset(&context, 0, sizeof(CONTEXT));
|
||||
context.ContextFlags = CONTEXT_FULL;
|
||||
if (!GetThreadContext(myThread, &context)) {
|
||||
PrintError("GetThreadContext");
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup initial stack frame to walk from
|
||||
#if defined _M_IX86
|
||||
memset(&frame, 0, sizeof(frame));
|
||||
frame.AddrPC.Offset = context.Eip;
|
||||
frame.AddrPC.Mode = AddrModeFlat;
|
||||
frame.AddrStack.Offset = context.Esp;
|
||||
frame.AddrStack.Mode = AddrModeFlat;
|
||||
frame.AddrFrame.Offset = context.Ebp;
|
||||
frame.AddrFrame.Mode = AddrModeFlat;
|
||||
#else
|
||||
PrintError("Unknown platform. No stack walking.");
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Now walk the stack
|
||||
while (1) {
|
||||
|
||||
// debug routines are not threadsafe, so grab the lock.
|
||||
EnterCriticalSection(&gDbgHelpCS);
|
||||
ok = _StackWalk(
|
||||
IMAGE_FILE_MACHINE_I386,
|
||||
myProcess,
|
||||
myThread,
|
||||
&frame,
|
||||
&context,
|
||||
0, // read process memory routine
|
||||
_SymFunctionTableAccess, // function table access routine
|
||||
_SymGetModuleBase, // module base routine
|
||||
0 // translate address routine
|
||||
);
|
||||
LeaveCriticalSection(&gDbgHelpCS);
|
||||
|
||||
if (ok)
|
||||
addr = frame.AddrPC.Offset;
|
||||
else {
|
||||
addr = 0;
|
||||
PrintError("WalkStack");
|
||||
}
|
||||
|
||||
if (!ok || (addr == 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (skip-- > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (data->pc_count < data->pc_size)
|
||||
data->pcs[data->pc_count] = (void*)addr;
|
||||
++data->pc_count;
|
||||
|
||||
if (frame.AddrReturn.Offset == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
void PerformStackWalk(struct WalkStackData* data)
|
||||
{
|
||||
#if defined(_WIN64)
|
||||
WalkStackMain64(data);
|
||||
#else
|
||||
if (_StackWalk64)
|
||||
WalkStackMain64(data);
|
||||
else
|
||||
WalkStackMain(data);
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int WINAPI
|
||||
WalkStackThread(void* aData)
|
||||
{
|
||||
@ -441,7 +785,7 @@ WalkStackThread(void* aData)
|
||||
PrintError("ThreadSuspend");
|
||||
}
|
||||
else {
|
||||
WalkStackMain64(data);
|
||||
PerformStackWalk(data);
|
||||
|
||||
ret = ::ResumeThread(data->thread);
|
||||
if (ret == -1) {
|
||||
@ -515,7 +859,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, PRUint32 aSkipFrames,
|
||||
if (aThread) {
|
||||
// If we're walking the stack of another thread, we don't need to
|
||||
// use a separate walker thread.
|
||||
WalkStackMain64(&data);
|
||||
PerformStackWalk(&data);
|
||||
} else {
|
||||
data.eventStart = ::CreateEvent(NULL, FALSE /* auto-reset*/,
|
||||
FALSE /* initially non-signaled */, NULL);
|
||||
@ -556,12 +900,44 @@ NS_StackWalk(NS_WalkStackCallback aCallback, PRUint32 aSkipFrames,
|
||||
}
|
||||
|
||||
|
||||
static BOOL CALLBACK callbackEspecial(
|
||||
PCSTR aModuleName,
|
||||
ULONG aModuleBase,
|
||||
ULONG aModuleSize,
|
||||
PVOID aUserContext)
|
||||
{
|
||||
BOOL retval = TRUE;
|
||||
DWORD addr = *(DWORD*)aUserContext;
|
||||
|
||||
/*
|
||||
* You'll want to control this if we are running on an
|
||||
* architecture where the addresses go the other direction.
|
||||
* Not sure this is even a realistic consideration.
|
||||
*/
|
||||
const BOOL addressIncreases = TRUE;
|
||||
|
||||
/*
|
||||
* If it falls inside the known range, load the symbols.
|
||||
*/
|
||||
if (addressIncreases
|
||||
? (addr >= aModuleBase && addr <= (aModuleBase + aModuleSize))
|
||||
: (addr <= aModuleBase && addr >= (aModuleBase - aModuleSize))
|
||||
) {
|
||||
retval = _SymLoadModule(GetCurrentProcess(), NULL, (PSTR)aModuleName, NULL, aModuleBase, aModuleSize);
|
||||
if (!retval)
|
||||
PrintError("SymLoadModule");
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK callbackEspecial64(
|
||||
PCSTR aModuleName,
|
||||
DWORD64 aModuleBase,
|
||||
ULONG aModuleSize,
|
||||
PVOID aUserContext)
|
||||
{
|
||||
#ifdef USING_WXP_VERSION
|
||||
BOOL retval = TRUE;
|
||||
DWORD64 addr = *(DWORD64*)aUserContext;
|
||||
|
||||
@ -579,12 +955,15 @@ static BOOL CALLBACK callbackEspecial64(
|
||||
? (addr >= aModuleBase && addr <= (aModuleBase + aModuleSize))
|
||||
: (addr <= aModuleBase && addr >= (aModuleBase - aModuleSize))
|
||||
) {
|
||||
retval = SymLoadModule64(GetCurrentProcess(), NULL, (PSTR)aModuleName, NULL, aModuleBase, aModuleSize);
|
||||
retval = _SymLoadModule64(GetCurrentProcess(), NULL, (PSTR)aModuleName, NULL, aModuleBase, aModuleSize);
|
||||
if (!retval)
|
||||
PrintError("SymLoadModule64");
|
||||
}
|
||||
|
||||
return retval;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -596,6 +975,61 @@ static BOOL CALLBACK callbackEspecial64(
|
||||
* and symbol information is not available.
|
||||
* This code rectifies that problem.
|
||||
*/
|
||||
BOOL SymGetModuleInfoEspecial(HANDLE aProcess, DWORD aAddr, PIMAGEHLP_MODULE aModuleInfo, PIMAGEHLP_LINE aLineInfo)
|
||||
{
|
||||
BOOL retval = FALSE;
|
||||
|
||||
/*
|
||||
* Init the vars if we have em.
|
||||
*/
|
||||
aModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE);
|
||||
if (nsnull != aLineInfo) {
|
||||
aLineInfo->SizeOfStruct = sizeof(IMAGEHLP_LINE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Give it a go.
|
||||
* It may already be loaded.
|
||||
*/
|
||||
retval = _SymGetModuleInfo(aProcess, aAddr, aModuleInfo);
|
||||
|
||||
if (FALSE == retval) {
|
||||
BOOL enumRes = FALSE;
|
||||
|
||||
/*
|
||||
* Not loaded, here's the magic.
|
||||
* Go through all the modules.
|
||||
*/
|
||||
// Need to cast to PENUMLOADED_MODULES_CALLBACK because the
|
||||
// constness of the first parameter of
|
||||
// PENUMLOADED_MODULES_CALLBACK varies over SDK versions (from
|
||||
// non-const to const over time). See bug 391848 and bug
|
||||
// 415426.
|
||||
enumRes = _EnumerateLoadedModules(aProcess, (PENUMLOADED_MODULES_CALLBACK)callbackEspecial, (PVOID)&aAddr);
|
||||
if (FALSE != enumRes)
|
||||
{
|
||||
/*
|
||||
* One final go.
|
||||
* If it fails, then well, we have other problems.
|
||||
*/
|
||||
retval = _SymGetModuleInfo(aProcess, aAddr, aModuleInfo);
|
||||
if (!retval)
|
||||
PrintError("SymGetModuleInfo");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we got module info, we may attempt line info as well.
|
||||
* We will not report failure if this does not work.
|
||||
*/
|
||||
if (FALSE != retval && nsnull != aLineInfo && nsnull != _SymGetLineFromAddr) {
|
||||
DWORD displacement = 0;
|
||||
BOOL lineRes = FALSE;
|
||||
lineRes = _SymGetLineFromAddr(aProcess, aAddr, &displacement, aLineInfo);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// New members were added to IMAGEHLP_MODULE64 (that show up in the
|
||||
// Platform SDK that ships with VC8, but not the Platform SDK that ships
|
||||
@ -612,6 +1046,7 @@ static BOOL CALLBACK callbackEspecial64(
|
||||
#define NS_IMAGEHLP_MODULE64_SIZE sizeof(IMAGEHLP_MODULE64)
|
||||
#endif
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
BOOL SymGetModuleInfoEspecial64(HANDLE aProcess, DWORD64 aAddr, PIMAGEHLP_MODULE64 aModuleInfo, PIMAGEHLP_LINE64 aLineInfo)
|
||||
{
|
||||
BOOL retval = FALSE;
|
||||
@ -628,7 +1063,7 @@ BOOL SymGetModuleInfoEspecial64(HANDLE aProcess, DWORD64 aAddr, PIMAGEHLP_MODULE
|
||||
* Give it a go.
|
||||
* It may already be loaded.
|
||||
*/
|
||||
retval = SymGetModuleInfo64(aProcess, aAddr, aModuleInfo);
|
||||
retval = _SymGetModuleInfo64(aProcess, aAddr, aModuleInfo);
|
||||
|
||||
if (FALSE == retval) {
|
||||
BOOL enumRes = FALSE;
|
||||
@ -642,14 +1077,14 @@ BOOL SymGetModuleInfoEspecial64(HANDLE aProcess, DWORD64 aAddr, PIMAGEHLP_MODULE
|
||||
// PENUMLOADED_MODULES_CALLBACK64 varies over SDK versions (from
|
||||
// non-const to const over time). See bug 391848 and bug
|
||||
// 415426.
|
||||
enumRes = EnumerateLoadedModules64(aProcess, (PENUMLOADED_MODULES_CALLBACK64)callbackEspecial64, (PVOID)&aAddr);
|
||||
enumRes = _EnumerateLoadedModules64(aProcess, (PENUMLOADED_MODULES_CALLBACK64)callbackEspecial64, (PVOID)&aAddr);
|
||||
if (FALSE != enumRes)
|
||||
{
|
||||
/*
|
||||
* One final go.
|
||||
* If it fails, then well, we have other problems.
|
||||
*/
|
||||
retval = SymGetModuleInfo64(aProcess, aAddr, aModuleInfo);
|
||||
retval = _SymGetModuleInfo64(aProcess, aAddr, aModuleInfo);
|
||||
if (!retval)
|
||||
PrintError("SymGetModuleInfo64");
|
||||
}
|
||||
@ -659,10 +1094,10 @@ BOOL SymGetModuleInfoEspecial64(HANDLE aProcess, DWORD64 aAddr, PIMAGEHLP_MODULE
|
||||
* If we got module info, we may attempt line info as well.
|
||||
* We will not report failure if this does not work.
|
||||
*/
|
||||
if (FALSE != retval && nsnull != aLineInfo) {
|
||||
if (FALSE != retval && nsnull != aLineInfo && nsnull != _SymGetLineFromAddr64) {
|
||||
DWORD displacement = 0;
|
||||
BOOL lineRes = FALSE;
|
||||
lineRes = SymGetLineFromAddr64(aProcess, aAddr, &displacement, aLineInfo);
|
||||
lineRes = _SymGetLineFromAddr64(aProcess, aAddr, &displacement, aLineInfo);
|
||||
if (!lineRes) {
|
||||
// Clear out aLineInfo to indicate that it's not valid
|
||||
memset(aLineInfo, 0, sizeof(*aLineInfo));
|
||||
@ -671,6 +1106,7 @@ BOOL SymGetModuleInfoEspecial64(HANDLE aProcess, DWORD64 aAddr, PIMAGEHLP_MODULE
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
EnsureSymInitialized()
|
||||
@ -686,13 +1122,13 @@ EnsureSymInitialized()
|
||||
if (!EnsureImageHlpInitialized())
|
||||
return false;
|
||||
|
||||
SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
|
||||
retStat = SymInitialize(GetCurrentProcess(), NULL, TRUE);
|
||||
_SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
|
||||
retStat = _SymInitialize(GetCurrentProcess(), NULL, TRUE);
|
||||
if (!retStat)
|
||||
PrintError("SymInitialize");
|
||||
|
||||
gInitialized = retStat;
|
||||
/* XXX At some point we need to arrange to call SymCleanup */
|
||||
/* XXX At some point we need to arrange to call _SymCleanup */
|
||||
|
||||
return retStat;
|
||||
}
|
||||
@ -717,42 +1153,97 @@ NS_DescribeCodeAddress(void *aPC, nsCodeAddressDetails *aDetails)
|
||||
// debug routines are not threadsafe, so grab the lock.
|
||||
EnterCriticalSection(&gDbgHelpCS);
|
||||
|
||||
//
|
||||
// Attempt to load module info before we attempt to resolve the symbol.
|
||||
// This just makes sure we get good info if available.
|
||||
//
|
||||
#ifdef USING_WXP_VERSION
|
||||
if (_StackWalk64) {
|
||||
//
|
||||
// Attempt to load module info before we attempt to resolve the symbol.
|
||||
// This just makes sure we get good info if available.
|
||||
//
|
||||
|
||||
DWORD64 addr = (DWORD64)aPC;
|
||||
IMAGEHLP_MODULE64 modInfo;
|
||||
IMAGEHLP_LINE64 lineInfo;
|
||||
BOOL modInfoRes;
|
||||
modInfoRes = SymGetModuleInfoEspecial64(myProcess, addr, &modInfo, &lineInfo);
|
||||
DWORD64 addr = (DWORD64)aPC;
|
||||
IMAGEHLP_MODULE64 modInfo;
|
||||
IMAGEHLP_LINE64 lineInfo;
|
||||
BOOL modInfoRes;
|
||||
modInfoRes = SymGetModuleInfoEspecial64(myProcess, addr, &modInfo, &lineInfo);
|
||||
|
||||
if (modInfoRes) {
|
||||
PL_strncpyz(aDetails->library, modInfo.ModuleName,
|
||||
sizeof(aDetails->library));
|
||||
aDetails->loffset = (char*) aPC - (char*) modInfo.BaseOfImage;
|
||||
|
||||
if (lineInfo.FileName) {
|
||||
if (modInfoRes) {
|
||||
PL_strncpyz(aDetails->library, modInfo.ModuleName,
|
||||
sizeof(aDetails->library));
|
||||
aDetails->loffset = (char*) aPC - (char*) modInfo.BaseOfImage;
|
||||
|
||||
if (lineInfo.FileName) {
|
||||
PL_strncpyz(aDetails->filename, lineInfo.FileName,
|
||||
sizeof(aDetails->filename));
|
||||
aDetails->lineno = lineInfo.LineNumber;
|
||||
}
|
||||
}
|
||||
|
||||
ULONG64 buffer[(sizeof(SYMBOL_INFO) +
|
||||
MAX_SYM_NAME*sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
|
||||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_SYM_NAME;
|
||||
|
||||
DWORD64 displacement;
|
||||
ok = _SymFromAddr && _SymFromAddr(myProcess, addr, &displacement, pSymbol);
|
||||
|
||||
if (ok) {
|
||||
PL_strncpyz(aDetails->function, pSymbol->Name,
|
||||
sizeof(aDetails->function));
|
||||
aDetails->foffset = displacement;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
//
|
||||
// Attempt to load module info before we attempt to resolve the symbol.
|
||||
// This just makes sure we get good info if available.
|
||||
//
|
||||
|
||||
DWORD_PTR addr = (DWORD_PTR)aPC;
|
||||
IMAGEHLP_MODULE modInfo;
|
||||
IMAGEHLP_LINE lineInfo;
|
||||
BOOL modInfoRes;
|
||||
modInfoRes = SymGetModuleInfoEspecial(myProcess, addr, &modInfo, &lineInfo);
|
||||
|
||||
if (modInfoRes) {
|
||||
PL_strncpyz(aDetails->library, modInfo.ModuleName,
|
||||
sizeof(aDetails->library));
|
||||
aDetails->loffset = (char*) aPC - (char*) modInfo.BaseOfImage;
|
||||
PL_strncpyz(aDetails->filename, lineInfo.FileName,
|
||||
sizeof(aDetails->filename));
|
||||
aDetails->lineno = lineInfo.LineNumber;
|
||||
}
|
||||
}
|
||||
|
||||
ULONG64 buffer[(sizeof(SYMBOL_INFO) +
|
||||
MAX_SYM_NAME*sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
|
||||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_SYM_NAME;
|
||||
#ifdef USING_WXP_VERSION
|
||||
ULONG64 buffer[(sizeof(SYMBOL_INFO) +
|
||||
MAX_SYM_NAME*sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
|
||||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_SYM_NAME;
|
||||
|
||||
DWORD64 displacement;
|
||||
ok = SymFromAddr(myProcess, addr, &displacement, pSymbol);
|
||||
DWORD64 displacement;
|
||||
|
||||
if (ok) {
|
||||
PL_strncpyz(aDetails->function, pSymbol->Name,
|
||||
sizeof(aDetails->function));
|
||||
aDetails->foffset = displacement;
|
||||
ok = _SymFromAddr && _SymFromAddr(myProcess, addr, &displacement, pSymbol);
|
||||
#else
|
||||
char buf[sizeof(IMAGEHLP_SYMBOL) + 512];
|
||||
PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL) buf;
|
||||
pSymbol->SizeOfStruct = sizeof(buf);
|
||||
pSymbol->MaxNameLength = 512;
|
||||
|
||||
DWORD displacement;
|
||||
|
||||
ok = _SymGetSymFromAddr(myProcess,
|
||||
frame.AddrPC.Offset,
|
||||
&displacement,
|
||||
pSymbol);
|
||||
#endif
|
||||
|
||||
if (ok) {
|
||||
PL_strncpyz(aDetails->function, pSymbol->Name,
|
||||
sizeof(aDetails->function));
|
||||
aDetails->foffset = displacement;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&gDbgHelpCS); // release our lock
|
||||
@ -763,12 +1254,23 @@ EXPORT_XPCOM_API(nsresult)
|
||||
NS_FormatCodeAddressDetails(void *aPC, const nsCodeAddressDetails *aDetails,
|
||||
char *aBuffer, PRUint32 aBufferSize)
|
||||
{
|
||||
if (aDetails->function[0])
|
||||
_snprintf(aBuffer, aBufferSize, "%s!%s+0x%016lX",
|
||||
aDetails->library, aDetails->function, aDetails->foffset);
|
||||
else
|
||||
_snprintf(aBuffer, aBufferSize, "0x%016lX", aPC);
|
||||
|
||||
#ifdef USING_WXP_VERSION
|
||||
if (_StackWalk64) {
|
||||
if (aDetails->function[0])
|
||||
_snprintf(aBuffer, aBufferSize, "%s!%s+0x%016lX",
|
||||
aDetails->library, aDetails->function, aDetails->foffset);
|
||||
else
|
||||
_snprintf(aBuffer, aBufferSize, "0x%016lX", aPC);
|
||||
} else {
|
||||
#endif
|
||||
if (aDetails->function[0])
|
||||
_snprintf(aBuffer, aBufferSize, "%s!%s+0x%08lX",
|
||||
aDetails->library, aDetails->function, aDetails->foffset);
|
||||
else
|
||||
_snprintf(aBuffer, aBufferSize, "0x%08lX", aPC);
|
||||
#ifdef USING_WXP_VERSION
|
||||
}
|
||||
#endif
|
||||
aBuffer[aBufferSize - 1] = '\0';
|
||||
|
||||
PRUint32 len = strlen(aBuffer);
|
||||
|
@ -673,7 +673,7 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
||||
GUID folderid_downloads = {0x374de290, 0x123f, 0x4565, {0x91, 0x64,
|
||||
0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b}};
|
||||
nsresult rv = GetKnownFolder(&folderid_downloads, aFile);
|
||||
// On WinXP, there is no downloads folder, default
|
||||
// On WinXP and 2k, there is no downloads folder, default
|
||||
// to 'Desktop'.
|
||||
if(NS_ERROR_FAILURE == rv)
|
||||
{
|
||||
|
@ -110,6 +110,9 @@ unsigned char *_mbsstr( const unsigned char *str,
|
||||
#define DRIVE_REMOTE 4
|
||||
#endif
|
||||
|
||||
ILCreateFromPathWPtr nsLocalFile::sILCreateFromPathW = NULL;
|
||||
SHOpenFolderAndSelectItemsPtr nsLocalFile::sSHOpenFolderAndSelectItems = NULL;
|
||||
|
||||
class nsDriveEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
@ -2713,6 +2716,19 @@ nsLocalFile::SetPersistentDescriptor(const nsACString &aPersistentDescriptor)
|
||||
}
|
||||
|
||||
/* attrib unsigned long fileAttributesWin; */
|
||||
static bool IsXPOrGreater()
|
||||
{
|
||||
OSVERSIONINFO osvi;
|
||||
|
||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
|
||||
GetVersionEx(&osvi);
|
||||
|
||||
return ((osvi.dwMajorVersion > 5) ||
|
||||
((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1)));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::GetFileAttributesWin(PRUint32 *aAttribs)
|
||||
{
|
||||
@ -2734,31 +2750,85 @@ nsLocalFile::SetFileAttributesWin(PRUint32 aAttribs)
|
||||
if (dwAttrs == INVALID_FILE_ATTRIBUTES)
|
||||
return NS_ERROR_FILE_INVALID_PATH;
|
||||
|
||||
if (aAttribs & WFA_SEARCH_INDEXED) {
|
||||
dwAttrs &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
|
||||
} else {
|
||||
dwAttrs |= FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
|
||||
if (IsXPOrGreater()) {
|
||||
if (aAttribs & WFA_SEARCH_INDEXED) {
|
||||
dwAttrs &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
|
||||
} else {
|
||||
dwAttrs |= FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
|
||||
}
|
||||
}
|
||||
|
||||
if (SetFileAttributesW(mWorkingPath.get(), dwAttrs) == 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::Reveal()
|
||||
{
|
||||
// make sure mResolvedPath is set
|
||||
bool isDirectory = false;
|
||||
// make sure mResolvedPath is set
|
||||
nsresult rv = ResolveAndStat();
|
||||
if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND)
|
||||
return rv;
|
||||
|
||||
// First try revealing with the shell, and if that fails fall back
|
||||
// to the classic way using explorer.exe command line parameters
|
||||
rv = RevealUsingShell();
|
||||
if (NS_FAILED(rv)) {
|
||||
rv = RevealClassic();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLocalFile::RevealClassic()
|
||||
{
|
||||
// use the full path to explorer for security
|
||||
nsCOMPtr<nsILocalFile> winDir;
|
||||
nsresult rv = GetSpecialSystemDirectory(Win_WindowsDirectory, getter_AddRefs(winDir));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsAutoString explorerPath;
|
||||
rv = winDir->GetPath(explorerPath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
explorerPath.AppendLiteral("\\explorer.exe");
|
||||
|
||||
// Always open a new window for files because Win2K doesn't appear to select
|
||||
// the file if a window showing that folder was already open. If the resolved
|
||||
// path is a directory then instead of opening the parent and selecting it,
|
||||
// we open the directory itself.
|
||||
nsAutoString explorerParams;
|
||||
if (mFileInfo64.type != PR_FILE_DIRECTORY) // valid because we ResolveAndStat above
|
||||
explorerParams.AppendLiteral("/n,/select,");
|
||||
explorerParams.Append(L'\"');
|
||||
explorerParams.Append(mResolvedPath);
|
||||
explorerParams.Append(L'\"');
|
||||
|
||||
if (::ShellExecuteW(NULL, L"open", explorerPath.get(), explorerParams.get(),
|
||||
NULL, SW_SHOWNORMAL) <= (HINSTANCE) 32)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLocalFile::RevealUsingShell()
|
||||
{
|
||||
// All of these shell32.dll related pointers should be non NULL
|
||||
// on XP and later.
|
||||
if (!sILCreateFromPathW || !sSHOpenFolderAndSelectItems) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
bool isDirectory;
|
||||
nsresult rv = IsDirectory(&isDirectory);
|
||||
if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND)
|
||||
return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
HRESULT hr;
|
||||
if (isDirectory) {
|
||||
// We have a directory so we should open the directory itself.
|
||||
ITEMIDLIST *dir = ILCreateFromPathW(mResolvedPath.get());
|
||||
ITEMIDLIST *dir = sILCreateFromPathW(mResolvedPath.get());
|
||||
if (!dir) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -2767,7 +2837,7 @@ nsLocalFile::Reveal()
|
||||
UINT count = ArrayLength(selection);
|
||||
|
||||
//Perform the open of the directory.
|
||||
hr = SHOpenFolderAndSelectItems(dir, count, selection, 0);
|
||||
hr = sSHOpenFolderAndSelectItems(dir, count, selection, 0);
|
||||
CoTaskMemFree(dir);
|
||||
}
|
||||
else {
|
||||
@ -2780,13 +2850,13 @@ nsLocalFile::Reveal()
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We have a file so we should open the parent directory.
|
||||
ITEMIDLIST *dir = ILCreateFromPathW(parentDirectoryPath.get());
|
||||
ITEMIDLIST *dir = sILCreateFromPathW(parentDirectoryPath.get());
|
||||
if (!dir) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Set the item in the directory to select to the file we want to reveal.
|
||||
ITEMIDLIST *item = ILCreateFromPathW(mResolvedPath.get());
|
||||
ITEMIDLIST *item = sILCreateFromPathW(mResolvedPath.get());
|
||||
if (!item) {
|
||||
CoTaskMemFree(dir);
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -2796,7 +2866,7 @@ nsLocalFile::Reveal()
|
||||
UINT count = ArrayLength(selection);
|
||||
|
||||
//Perform the selection of the file.
|
||||
hr = SHOpenFolderAndSelectItems(dir, count, selection, 0);
|
||||
hr = sSHOpenFolderAndSelectItems(dir, count, selection, 0);
|
||||
|
||||
CoTaskMemFree(dir);
|
||||
CoTaskMemFree(item);
|
||||
@ -3105,6 +3175,21 @@ nsLocalFile::GlobalInit()
|
||||
{
|
||||
nsresult rv = NS_CreateShortcutResolver();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Shortcut resolver could not be created");
|
||||
|
||||
// shell32.dll should be loaded already, so we are not actually
|
||||
// loading the library here.
|
||||
HMODULE hLibShell = GetModuleHandleW(L"shell32.dll");
|
||||
if (hLibShell) {
|
||||
// ILCreateFromPathW is available in XP and up.
|
||||
sILCreateFromPathW = (ILCreateFromPathWPtr)
|
||||
GetProcAddress(hLibShell,
|
||||
"ILCreateFromPathW");
|
||||
|
||||
// SHOpenFolderAndSelectItems is available in XP and up.
|
||||
sSHOpenFolderAndSelectItems = (SHOpenFolderAndSelectItemsPtr)
|
||||
GetProcAddress(hLibShell,
|
||||
"SHOpenFolderAndSelectItems");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -56,6 +56,11 @@
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
typedef LPITEMIDLIST (WINAPI *ILCreateFromPathWPtr)(PCWSTR);
|
||||
typedef HRESULT (WINAPI *SHOpenFolderAndSelectItemsPtr)(PCIDLIST_ABSOLUTE, UINT,
|
||||
PCUITEMID_CHILD_ARRAY,
|
||||
DWORD);
|
||||
|
||||
class nsLocalFile : public nsILocalFileWin,
|
||||
public nsIHashable
|
||||
{
|
||||
@ -123,6 +128,11 @@ private:
|
||||
nsresult HasFileAttribute(DWORD fileAttrib, bool *_retval);
|
||||
nsresult AppendInternal(const nsAFlatString &node,
|
||||
bool multipleComponents);
|
||||
nsresult RevealClassic(); // Reveals the path using explorer.exe cmdline
|
||||
nsresult RevealUsingShell(); // Uses newer shell API to reveal the path
|
||||
|
||||
static ILCreateFromPathWPtr sILCreateFromPathW;
|
||||
static SHOpenFolderAndSelectItemsPtr sSHOpenFolderAndSelectItems;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -103,6 +103,7 @@ private:
|
||||
// protected with mLock.
|
||||
PRInt32 mExitValue;
|
||||
#if defined(PROCESSMODEL_WINAPI)
|
||||
typedef DWORD (WINAPI*GetProcessIdPtr)(HANDLE process);
|
||||
HANDLE mProcess;
|
||||
#elif !defined(XP_MACOSX)
|
||||
PRProcess *mProcess;
|
||||
|
@ -500,7 +500,13 @@ nsProcess::RunProcess(bool blocking, char **my_argv, nsIObserver* observer,
|
||||
if (cmdLine)
|
||||
PR_Free(cmdLine);
|
||||
|
||||
mPid = GetProcessId(mProcess);
|
||||
HMODULE kernelDLL = ::LoadLibraryW(L"kernel32.dll");
|
||||
if (kernelDLL) {
|
||||
GetProcessIdPtr getProcessId = (GetProcessIdPtr)GetProcAddress(kernelDLL, "GetProcessId");
|
||||
if (getProcessId)
|
||||
mPid = getProcessId(mProcess);
|
||||
FreeLibrary(kernelDLL);
|
||||
}
|
||||
#elif defined(XP_MACOSX)
|
||||
// Initialize spawn attributes.
|
||||
posix_spawnattr_t spawnattr;
|
||||
|
Loading…
Reference in New Issue
Block a user