зеркало из https://github.com/mozilla/pjs.git
changed all the DEVMODE allocating and freeing to native Windows calls HeapAlloc and HeapFree
nsPrintSettingsWin.cpp was creating and copying only the non-platform specific data by using the "sizeof" of the DEVMODE struct, instead of checking the struct size with dmSize and the size of the private (device-specific) data with dmDriverExtra. Now it creates the correct size of memory and copies all the non-private data and private data. Bug 156318 r=dcone sr=kin,waterson,rpotts a=asa
This commit is contained in:
Родитель
e213cbb8e9
Коммит
27586e9402
|
@ -780,21 +780,26 @@ static HGLOBAL CreateGlobalDevModeAndInit(LPTSTR aPrintName, nsIPrintSettings* a
|
|||
prtName.AssignWithConversion((char*)aPrintName);
|
||||
#endif
|
||||
|
||||
// Allocate a buffer of the correct size.
|
||||
// Get the buffer size
|
||||
dwNeeded = ::DocumentProperties(gParentWnd, hPrinter, aPrintName, NULL, NULL, 0);
|
||||
if (dwNeeded == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pNewDevMode = (LPDEVMODE)malloc(dwNeeded);
|
||||
// Allocate a buffer of the correct size.
|
||||
pNewDevMode = (LPDEVMODE)::HeapAlloc (::GetProcessHeap(), HEAP_ZERO_MEMORY, dwNeeded);
|
||||
if (!pNewDevMode) return NULL;
|
||||
|
||||
hGlobalDevMode = (HGLOBAL)::GlobalAlloc(GHND, dwNeeded);
|
||||
if (!hGlobalDevMode) {
|
||||
free(pNewDevMode);
|
||||
::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dwRet = ::DocumentProperties(gParentWnd, hPrinter, aPrintName, pNewDevMode, NULL, DM_OUT_BUFFER);
|
||||
|
||||
if (dwRet != IDOK) {
|
||||
free(pNewDevMode);
|
||||
::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
|
||||
::GlobalFree(hGlobalDevMode);
|
||||
::ClosePrinter(hPrinter);
|
||||
return NULL;
|
||||
|
@ -813,7 +818,7 @@ static HGLOBAL CreateGlobalDevModeAndInit(LPTSTR aPrintName, nsIPrintSettings* a
|
|||
hGlobalDevMode = NULL;
|
||||
}
|
||||
|
||||
free(pNewDevMode);
|
||||
::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
|
||||
|
||||
::ClosePrinter(hPrinter);
|
||||
|
||||
|
|
|
@ -45,8 +45,41 @@
|
|||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#if 0
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsPrintProgress);
|
||||
NS_IMPL_THREADSAFE_RELEASE(nsPrintProgress);
|
||||
#else
|
||||
NS_IMETHODIMP_(nsrefcnt) nsPrintProgress::AddRef(void)
|
||||
{
|
||||
NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
|
||||
nsrefcnt count;
|
||||
count = PR_AtomicIncrement((PRInt32*)&mRefCnt);
|
||||
//NS_LOG_ADDREF(this, count, #_class, sizeof(*this));
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this macro to implement the Release method for a given <i>_class</i>
|
||||
* @param _class The name of the class implementing the method
|
||||
*/
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt) nsPrintProgress::Release(void)
|
||||
{
|
||||
nsrefcnt count;
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||
count = PR_AtomicDecrement((PRInt32 *)&mRefCnt);
|
||||
//NS_LOG_RELEASE(this, count, #_class);
|
||||
if (0 == count) {
|
||||
mRefCnt = 1; /* stabilize */
|
||||
/* enable this to find non-threadsafe destructors: */
|
||||
/* NS_ASSERT_OWNINGTHREAD(_class); */
|
||||
NS_DELETEXPCOM(this);
|
||||
return 0;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsPrintProgress)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintStatusFeedback)
|
||||
|
|
|
@ -169,8 +169,6 @@ nsDeviceContextSpecWin::nsDeviceContextSpecWin()
|
|||
mDriverName = nsnull;
|
||||
mDeviceName = nsnull;
|
||||
mDevMode = NULL;
|
||||
mGlobalDevMode = NULL;
|
||||
mIsDEVMODEGlobalHandle = PR_FALSE;
|
||||
|
||||
}
|
||||
|
||||
|
@ -183,7 +181,6 @@ nsDeviceContextSpecWin::~nsDeviceContextSpecWin()
|
|||
SetDeviceName(nsnull);
|
||||
SetDriverName(nsnull);
|
||||
SetDevMode(NULL);
|
||||
SetGlobalDevMode(NULL);
|
||||
|
||||
nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(mPrintSettings));
|
||||
if (psWin) {
|
||||
|
@ -219,12 +216,14 @@ static PRUnichar * GetDefaultPrinterNameFromGlobalPrinters()
|
|||
static nsresult
|
||||
EnumerateNativePrinters(DWORD aWhichPrinters, LPTSTR aPrinterName, PRBool& aIsFound, PRBool& aIsFile)
|
||||
{
|
||||
DWORD dwSizeNeeded;
|
||||
DWORD dwNumItems;
|
||||
LPPRINTER_INFO_2 lpInfo = NULL;
|
||||
DWORD dwSizeNeeded = 0;
|
||||
DWORD dwNumItems = 0;
|
||||
LPPRINTER_INFO_2 lpInfo = NULL;
|
||||
|
||||
// Get buffer size
|
||||
::EnumPrinters ( aWhichPrinters, NULL, 2, NULL, 0, &dwSizeNeeded, &dwNumItems );
|
||||
if (::EnumPrinters ( aWhichPrinters, NULL, 2, NULL, 0, &dwSizeNeeded, &dwNumItems )) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// allocate memory
|
||||
lpInfo = (LPPRINTER_INFO_2)HeapAlloc ( GetProcessHeap (), HEAP_ZERO_MEMORY, dwSizeNeeded );
|
||||
|
@ -233,6 +232,7 @@ EnumerateNativePrinters(DWORD aWhichPrinters, LPTSTR aPrinterName, PRBool& aIsFo
|
|||
}
|
||||
|
||||
if (::EnumPrinters ( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)lpInfo, dwSizeNeeded, &dwSizeNeeded, &dwNumItems) == 0 ) {
|
||||
::HeapFree(GetProcessHeap (), 0, lpInfo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ EnumerateNativePrinters(DWORD aWhichPrinters, LPTSTR aPrinterName, PRBool& aIsFo
|
|||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap (), 0, lpInfo);
|
||||
::HeapFree(GetProcessHeap (), 0, lpInfo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -417,7 +417,11 @@ NS_IMETHODIMP nsDeviceContextSpecWin::Init(nsIWidget* aWidget,
|
|||
|
||||
if (!aIsPrintPreview) {
|
||||
rv = CheckForPrintToFile(mPrintSettings, deviceName, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
nsCRT::free(deviceName);
|
||||
nsCRT::free(driverName);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// clean up
|
||||
|
@ -429,7 +433,7 @@ NS_IMETHODIMP nsDeviceContextSpecWin::Init(nsIWidget* aWidget,
|
|||
PR_PL(("***** nsDeviceContextSpecWin::Init - deviceName/driverName/devMode was NULL!\n"));
|
||||
if (deviceName) nsCRT::free(deviceName);
|
||||
if (driverName) nsCRT::free(driverName);
|
||||
if (devMode) free(devMode);
|
||||
if (devMode) ::HeapFree(::GetProcessHeap(), 0, devMode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -490,39 +494,21 @@ void nsDeviceContextSpecWin::SetDriverName(char* aDriverName)
|
|||
CleanAndCopyString(mDriverName, aDriverName);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void nsDeviceContextSpecWin::SetGlobalDevMode(HGLOBAL aHGlobal)
|
||||
{
|
||||
if (mGlobalDevMode) {
|
||||
::GlobalFree(mGlobalDevMode);
|
||||
mGlobalDevMode = NULL;
|
||||
}
|
||||
mGlobalDevMode = aHGlobal;
|
||||
mIsDEVMODEGlobalHandle = PR_TRUE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
void nsDeviceContextSpecWin::SetDevMode(LPDEVMODE aDevMode)
|
||||
{
|
||||
if (mDevMode) free(mDevMode);
|
||||
if (mDevMode) {
|
||||
::HeapFree(::GetProcessHeap(), 0, mDevMode);
|
||||
}
|
||||
|
||||
mDevMode = aDevMode;
|
||||
mIsDEVMODEGlobalHandle = PR_FALSE;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
nsDeviceContextSpecWin::GetDevMode(LPDEVMODE &aDevMode)
|
||||
{
|
||||
if (mIsDEVMODEGlobalHandle) {
|
||||
if (mGlobalDevMode) {
|
||||
aDevMode = (DEVMODE *)::GlobalLock(mGlobalDevMode);
|
||||
} else {
|
||||
aDevMode = NULL;
|
||||
}
|
||||
} else {
|
||||
aDevMode = mDevMode;
|
||||
}
|
||||
aDevMode = mDevMode;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -667,14 +653,15 @@ nsDeviceContextSpecWin::GetDataFromPrinter(const PRUnichar * aName, nsIPrintSett
|
|||
dwNeeded = DocumentProperties(gParentWnd, hPrinter, (char*)NS_ConvertUCS2toUTF8(aName).get(),
|
||||
NULL, NULL, 0);
|
||||
|
||||
pDevMode = (LPDEVMODE)malloc(dwNeeded);
|
||||
pDevMode = (LPDEVMODE)::HeapAlloc (::GetProcessHeap(), HEAP_ZERO_MEMORY, dwNeeded);
|
||||
if (!pDevMode) return NS_ERROR_FAILURE;
|
||||
|
||||
// Get the default DevMode for the printer and modify it for our needs.
|
||||
dwRet = DocumentProperties(gParentWnd, hPrinter, (char*)NS_ConvertUCS2toUTF8(aName).get(),
|
||||
pDevMode, NULL, DM_OUT_BUFFER);
|
||||
|
||||
if (dwRet != IDOK) {
|
||||
free(pDevMode);
|
||||
::HeapFree(::GetProcessHeap(), 0, pDevMode);
|
||||
::ClosePrinter(hPrinter);
|
||||
PR_PL(("***** nsDeviceContextSpecWin::GetDataFromPrinter - DocumentProperties call failed code: %d/0x%x\n", dwRet, dwRet));
|
||||
DISPLAY_LAST_ERROR
|
||||
|
@ -724,7 +711,6 @@ nsDeviceContextSpecWin::SetupPaperInfoFromSettings()
|
|||
if (devMode) {
|
||||
SetupDevModeFromSettings(devMode, mPrintSettings);
|
||||
}
|
||||
UnlockDevMode();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -854,7 +840,6 @@ nsPrinterEnumeratorWin::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterNa
|
|||
if (devmode) {
|
||||
nsDeviceContextSpecWin::SetPrintSettingsFromDevMode(aPrintSettings, devmode);
|
||||
}
|
||||
devSpecWin->UnlockDevMode();
|
||||
|
||||
// Free them, we won't need them for a while
|
||||
GlobalPrinters::GetInstance()->FreeGlobalPrinters();
|
||||
|
@ -926,29 +911,33 @@ NS_IMETHODIMP nsPrinterEnumeratorWin::DisplayPropertiesDlg(const PRUnichar *aPri
|
|||
LPDEVMODE pNewDevMode;
|
||||
DWORD dwNeeded, dwRet;
|
||||
|
||||
// Allocate a buffer of the correct size.
|
||||
// Get the buffer correct buffer size
|
||||
dwNeeded = ::DocumentProperties(gParentWnd, hPrinter,
|
||||
(char*)NS_ConvertUCS2toUTF8(aPrinterName).get(), NULL, NULL, 0);
|
||||
|
||||
pNewDevMode = (LPDEVMODE)malloc(dwNeeded);
|
||||
// Allocate a buffer of the correct size.
|
||||
pNewDevMode = (LPDEVMODE)::HeapAlloc (::GetProcessHeap(), HEAP_ZERO_MEMORY, dwNeeded);
|
||||
if (!pNewDevMode) return NS_ERROR_FAILURE;
|
||||
|
||||
dwRet = ::DocumentProperties(gParentWnd, hPrinter, (char*)NS_ConvertUCS2toUTF8(aPrinterName).get(),
|
||||
pNewDevMode, NULL, DM_OUT_BUFFER);
|
||||
|
||||
if (dwRet != IDOK) {
|
||||
free(pNewDevMode);
|
||||
::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
|
||||
::ClosePrinter(hPrinter);
|
||||
PR_PL(("***** nsDeviceContextSpecWin::DisplayPropertiesDlg - Couldn't get DocumentProperties (pNewDevMode) for [%s]\n", NS_ConvertUCS2toUTF8(aPrinterName).get()));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
pDevMode = (LPDEVMODE)malloc(dwNeeded);
|
||||
pDevMode = (LPDEVMODE)::HeapAlloc (::GetProcessHeap(), HEAP_ZERO_MEMORY, dwNeeded);
|
||||
if (!pDevMode) return NS_ERROR_FAILURE;
|
||||
|
||||
dwRet = ::DocumentProperties(gParentWnd, hPrinter, (char*)NS_ConvertUCS2toUTF8(aPrinterName).get(),
|
||||
pDevMode, NULL, DM_OUT_BUFFER);
|
||||
|
||||
if (dwRet != IDOK) {
|
||||
free(pDevMode);
|
||||
free(pNewDevMode);
|
||||
::HeapFree(::GetProcessHeap(), 0, pDevMode);
|
||||
::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
|
||||
::ClosePrinter(hPrinter);
|
||||
PR_PL(("***** nsDeviceContextSpecWin::DisplayPropertiesDlg - Couldn't get DocumentProperties (pDevMode) for [%s]\n", NS_ConvertUCS2toUTF8(aPrinterName).get()));
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -969,8 +958,8 @@ NS_IMETHODIMP nsPrinterEnumeratorWin::DisplayPropertiesDlg(const PRUnichar *aPri
|
|||
// Now set the print options from the native Page Setup
|
||||
nsDeviceContextSpecWin::SetPrintSettingsFromDevMode(aPrintSettings, pDevMode);
|
||||
}
|
||||
free(pDevMode);
|
||||
free(pNewDevMode);
|
||||
::HeapFree(::GetProcessHeap(), 0, pDevMode);
|
||||
::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
|
||||
rv = NS_OK;
|
||||
} else {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
|
|
@ -61,7 +61,6 @@ public:
|
|||
// To get the DevMode from the Global memory Handle it must lock it
|
||||
// So this call must be paired with a call to UnlockGlobalHandle
|
||||
void GetDevMode(LPDEVMODE &aDevMode);
|
||||
void UnlockDevMode() { if (mIsDEVMODEGlobalHandle && mGlobalDevMode) ::GlobalUnlock(mGlobalDevMode); }
|
||||
|
||||
// helper functions
|
||||
nsresult GetDataFromPrinter(const PRUnichar * aName, nsIPrintSettings* aPS = nsnull);
|
||||
|
@ -73,7 +72,6 @@ protected:
|
|||
|
||||
void SetDeviceName(char* aDeviceName);
|
||||
void SetDriverName(char* aDriverName);
|
||||
void SetGlobalDevMode(HGLOBAL aHGlobal);
|
||||
void SetDevMode(LPDEVMODE aDevMode);
|
||||
|
||||
void SetupPaperInfoFromSettings();
|
||||
|
@ -82,9 +80,7 @@ protected:
|
|||
|
||||
char* mDriverName;
|
||||
char* mDeviceName;
|
||||
HGLOBAL mGlobalDevMode;
|
||||
LPDEVMODE mDevMode;
|
||||
PRBool mIsDEVMODEGlobalHandle;
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> mPrintSettings;
|
||||
};
|
||||
|
|
|
@ -737,7 +737,6 @@ NS_IMETHODIMP nsDeviceContextWin :: GetDeviceContextFor(nsIDeviceContextSpec *aD
|
|||
if (devmode) {
|
||||
dc = ::CreateDC(drivername, devicename, NULL, devmode);
|
||||
}
|
||||
devSpecWin->UnlockDevMode();
|
||||
|
||||
return devConWin->Init(dc, this); // take ownership of the DC
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ nsPrintSettingsWin::~nsPrintSettingsWin()
|
|||
{
|
||||
if (mDeviceName) nsMemory::Free(mDeviceName);
|
||||
if (mDriverName) nsMemory::Free(mDriverName);
|
||||
if (mDevMode) free(mDevMode);
|
||||
if (mDevMode) ::HeapFree(::GetProcessHeap(), 0, mDevMode);
|
||||
}
|
||||
|
||||
/* [noscript] attribute charPtr deviceName; */
|
||||
|
@ -110,15 +110,24 @@ NS_IMETHODIMP nsPrintSettingsWin::GetDriverName(char * *aDriverName)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsPrintSettingsWin::CopyDevMode(DEVMODE* aInDevMode, DEVMODE *& aOutDevMode)
|
||||
{
|
||||
aOutDevMode = nsnull;
|
||||
size_t size = aInDevMode->dmSize + aInDevMode->dmDriverExtra;
|
||||
aOutDevMode = (LPDEVMODE)::HeapAlloc (::GetProcessHeap(), HEAP_ZERO_MEMORY, size);
|
||||
if (aOutDevMode) {
|
||||
memcpy(aOutDevMode, aInDevMode, size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* [noscript] attribute nsDevMode devMode; */
|
||||
NS_IMETHODIMP nsPrintSettingsWin::GetDevMode(DEVMODE * *aDevMode)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDevMode);
|
||||
|
||||
if (mDevMode) {
|
||||
size_t size = sizeof(*mDevMode);
|
||||
*aDevMode = (LPDEVMODE)malloc(size);
|
||||
memcpy(*aDevMode, mDevMode, size);
|
||||
CopyDevMode(mDevMode, *aDevMode);
|
||||
} else {
|
||||
*aDevMode = nsnull;
|
||||
}
|
||||
|
@ -128,14 +137,12 @@ NS_IMETHODIMP nsPrintSettingsWin::GetDevMode(DEVMODE * *aDevMode)
|
|||
NS_IMETHODIMP nsPrintSettingsWin::SetDevMode(DEVMODE * aDevMode)
|
||||
{
|
||||
if (mDevMode) {
|
||||
free(mDevMode);
|
||||
::HeapFree(::GetProcessHeap(), 0, mDevMode);
|
||||
mDevMode = NULL;
|
||||
}
|
||||
|
||||
if (aDevMode) {
|
||||
size_t size = sizeof(*aDevMode);
|
||||
mDevMode = (LPDEVMODE)malloc(size);
|
||||
memcpy(mDevMode, aDevMode, size);
|
||||
CopyDevMode(aDevMode, mDevMode);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -167,16 +174,14 @@ nsPrintSettingsWin& nsPrintSettingsWin::operator=(const nsPrintSettingsWin& rhs)
|
|||
|
||||
// Use free because we used the native malloc to create the memory
|
||||
if (mDevMode) {
|
||||
free(mDevMode);
|
||||
::HeapFree(::GetProcessHeap(), 0, mDevMode);
|
||||
}
|
||||
|
||||
mDeviceName = rhs.mDeviceName?nsCRT::strdup(rhs.mDeviceName):nsnull;
|
||||
mDriverName = rhs.mDriverName?nsCRT::strdup(rhs.mDriverName):nsnull;
|
||||
|
||||
if (rhs.mDevMode) {
|
||||
size_t size = sizeof(*rhs.mDevMode);
|
||||
mDevMode = (LPDEVMODE)malloc(size);
|
||||
memcpy(mDevMode, rhs.mDevMode, size);
|
||||
CopyDevMode(rhs.mDevMode, mDevMode);
|
||||
} else {
|
||||
mDevMode = nsnull;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,8 @@ public:
|
|||
nsPrintSettingsWin& operator=(const nsPrintSettingsWin& rhs);
|
||||
|
||||
protected:
|
||||
void CopyDevMode(DEVMODE* aInDevMode, DEVMODE *& aOutDevMode);
|
||||
|
||||
char* mDeviceName;
|
||||
char* mDriverName;
|
||||
LPDEVMODE mDevMode;
|
||||
|
|
Загрузка…
Ссылка в новой задаче