1498 lines
37 KiB
C++
Executable File
1498 lines
37 KiB
C++
Executable File
#include "wxinc.h"
|
|
#include <wx/filename.h>
|
|
#include <wx/print.h>
|
|
#include <wx/snglinst.h>
|
|
#include <wx/tokenzr.h>
|
|
|
|
#include "xvt.h"
|
|
#include "xvtart.h"
|
|
|
|
#ifdef __WXMSW__
|
|
#include "wx/dcps.h"
|
|
#include "wx/msw/printdlg.h"
|
|
#include "oswin32.h"
|
|
#else
|
|
#include "wx/setup.h"
|
|
#include "wx/dcps.h"
|
|
#include "oslinux.h"
|
|
#include "incstr.h"
|
|
#endif
|
|
|
|
#include "xvtpdf.h"
|
|
#include "xvtwin.h"
|
|
|
|
#pragma pack(4)
|
|
|
|
struct TPRINT_RCD : public PRINT_RCD
|
|
{
|
|
#ifdef __WXMSW__
|
|
unsigned char m_data[16*1024];
|
|
unsigned int m_size; // Dimensione della struct DEVMODE
|
|
|
|
void SetData(void * data, unsigned int nSize);
|
|
#else
|
|
wxPrintNativeDataBase* m_data;
|
|
unsigned int m_size; // Dimensione di wxPostScriptPrintNativeData
|
|
|
|
void GetData(wxPrintNativeDataBase* data) const;
|
|
void SetData(void * data);
|
|
#endif
|
|
|
|
unsigned int GetSize() const { return m_size; }
|
|
|
|
TPRINT_RCD();
|
|
~TPRINT_RCD();
|
|
};
|
|
|
|
#pragma pack()
|
|
|
|
#ifdef __WXMSW__
|
|
|
|
void TPRINT_RCD::SetData(void* data, unsigned int nSize)
|
|
{
|
|
if (nSize <= sizeof(m_data))
|
|
{
|
|
memset(m_data, 0, sizeof(m_data)); // Azzero per bene anche tutto quanto segue nSize
|
|
memcpy(m_data, data, nSize);
|
|
m_size = nSize;
|
|
}
|
|
else
|
|
xvt_dm_post_error("Printer info exceeds 16K");
|
|
}
|
|
|
|
TPRINT_RCD::TPRINT_RCD() : m_size(0)
|
|
{
|
|
pr = NULL;
|
|
memset(m_data, 0, sizeof(m_data));
|
|
}
|
|
|
|
TPRINT_RCD::~TPRINT_RCD()
|
|
{
|
|
memset(m_data, 0, sizeof(m_data));
|
|
m_size = 0;
|
|
}
|
|
|
|
#else
|
|
|
|
void TPRINT_RCD::GetData(wxPrintNativeDataBase * data) const
|
|
{
|
|
memcpy(data, m_data, GetSize());
|
|
}
|
|
|
|
void TPRINT_RCD::SetData(void* data)
|
|
{
|
|
memcpy(m_data, data, GetSize());
|
|
}
|
|
|
|
wxNativePrintFactory __factory;
|
|
|
|
TPRINT_RCD::TPRINT_RCD()
|
|
{
|
|
m_data = __factory.CreatePrintNativeData();
|
|
m_size = sizeof(*m_data);
|
|
}
|
|
|
|
TPRINT_RCD::~TPRINT_RCD()
|
|
{
|
|
delete m_data;
|
|
}
|
|
|
|
#endif
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TwxPrintOut
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TwxPrintOut : public wxPrintout
|
|
{
|
|
protected:
|
|
const TPRINT_RCD* m_prcd;
|
|
bool m_bBadDriver;
|
|
|
|
virtual bool HasPage(int pageNum);
|
|
virtual bool OnPrintPage(int pageNum);
|
|
void ResetDC();
|
|
|
|
wxDC* CreateDC(const TPRINT_RCD* prcd, const char* title);
|
|
|
|
public:
|
|
void SetBadDriver(bool bd) { m_bBadDriver = bd; }
|
|
bool HasBadDriver() const { return m_bBadDriver; }
|
|
|
|
wxString PrinterName() const;
|
|
bool IsPDF() const { return !HasBadDriver() && xvt_print_is_pdf(m_prcd) != 0; }
|
|
|
|
bool InitDC(const TPRINT_RCD* prcd, const char* title);
|
|
TwxPrintOut(const TPRINT_RCD* prcd = NULL);
|
|
|
|
virtual ~TwxPrintOut() {}
|
|
};
|
|
|
|
wxString TwxPrintOut::PrinterName() const
|
|
{
|
|
char strName[MAX_PATH] = "";
|
|
xvt_print_get_name(m_prcd, strName, sizeof(strName));
|
|
return wxString(strName);
|
|
}
|
|
|
|
bool TwxPrintOut::HasPage(int WXUNUSED(pageNum))
|
|
{ return true; }
|
|
|
|
bool TwxPrintOut::OnPrintPage(int WXUNUSED(pageNum))
|
|
{ return false; }
|
|
|
|
void TwxPrintOut::ResetDC()
|
|
{
|
|
wxDC* dc = GetDC();
|
|
if (dc != NULL)
|
|
{
|
|
delete dc;
|
|
SetDC(NULL);
|
|
}
|
|
}
|
|
|
|
static void RCD2data(const TPRINT_RCD* prcd, wxPrintData& data)
|
|
{
|
|
#ifdef WIN32
|
|
wxWindowsPrintNativeData ndb;
|
|
ndb.SetDevMode(OsWin32_ConvertToNativePrinterInfo((void*)prcd->m_data, prcd->m_size));
|
|
ndb.TransferTo(data);
|
|
|
|
// in assenza di PDEVNAMES aggiorno il nome in questo modo
|
|
char strName[MAX_PATH] = "";
|
|
xvt_print_get_name(prcd, strName, sizeof(strName));
|
|
data.SetPrinterName(strName);
|
|
#else
|
|
prcd->GetData(data.GetNativeData());
|
|
data.ConvertFromNative();
|
|
#endif
|
|
}
|
|
|
|
static void data2RCD(const wxPrintData& data, TPRINT_RCD* prcd)
|
|
{
|
|
#ifdef WIN32
|
|
wxWindowsPrintNativeData* pNative = (wxWindowsPrintNativeData*)data.GetNativeData();
|
|
unsigned int nSize = 0;
|
|
void* ptr = OsWin32_ConvertFromNativePrinterInfo(pNative->GetDevMode(), nSize);
|
|
prcd->SetData(ptr, nSize);
|
|
delete ptr;
|
|
#else
|
|
((wxPrintData&)data).ConvertToNative();
|
|
prcd->SetData(data.GetNativeData());
|
|
#endif
|
|
}
|
|
|
|
wxDC* TwxPrintOut::CreateDC(const TPRINT_RCD* prcd, const char* title)
|
|
{
|
|
m_prcd = prcd;
|
|
wxDC* dc = NULL;
|
|
|
|
if (m_prcd == NULL)
|
|
{
|
|
wxPrinter printer;
|
|
#ifdef WIN32
|
|
dc = new wxPrinterDC(printer.GetPrintDialogData().GetPrintData());
|
|
#else
|
|
dc = new wxPostScriptDC(printer.GetPrintDialogData().GetPrintData());
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
wxPrintData data;
|
|
RCD2data(prcd, data);
|
|
|
|
const bool ispdf = IsPDF();
|
|
if (ispdf)
|
|
dc = new TwxPDFDC(data, title);
|
|
else
|
|
#ifdef WIN32
|
|
dc = new wxPrinterDC(data);
|
|
#else
|
|
dc = new wxPostScriptDC(data);
|
|
#endif
|
|
}
|
|
|
|
if (dc->IsOk())
|
|
{
|
|
wxSize s = dc->GetPPI();
|
|
SetPPIPrinter(s.x, s.y);
|
|
|
|
s = dc->GetSize();
|
|
SetPageSizePixels(s.x, s.y);
|
|
|
|
SetDC(dc);
|
|
|
|
wxWindow* pAbort = wxPrinterBase::sm_abortWindow;
|
|
if (pAbort != NULL)
|
|
{
|
|
wxWindow* pStatic = pAbort->FindWindow(wxID_STATIC);
|
|
if (pStatic != NULL)
|
|
{
|
|
wxString strPrompt;
|
|
if (IsPDF())
|
|
{
|
|
const wxFileName fn(title);
|
|
strPrompt << wxT("Generazione di ") << fn.GetFullName();
|
|
}
|
|
else
|
|
strPrompt << wxT("Stampa su ") << PrinterName();
|
|
pStatic->SetLabel(strPrompt);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// delete dc;
|
|
dc = NULL;
|
|
}
|
|
return dc;
|
|
}
|
|
|
|
bool TwxPrintOut::InitDC(const TPRINT_RCD* prcd, const char* title)
|
|
{
|
|
ResetDC();
|
|
wxDC* dc = CreateDC(prcd, title);
|
|
if (dc != NULL)
|
|
{
|
|
wxSize s = dc->GetPPI();
|
|
if (s.x > 0)
|
|
SetPPIPrinter(s.x, s.y);
|
|
|
|
s = dc->GetSize();
|
|
if (s.x > 0)
|
|
SetPageSizePixels(s.x, s.y);
|
|
SetDC(dc);
|
|
}
|
|
m_bBadDriver = dc == NULL;
|
|
return !m_bBadDriver;
|
|
}
|
|
|
|
TwxPrintOut::TwxPrintOut(const TPRINT_RCD* prcd)
|
|
: wxPrintout(_GetAppTitle()), m_bBadDriver(false)
|
|
{
|
|
InitDC(prcd, _GetAppTitle());
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TwxPrintOutCache
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TwxPrintOutCache
|
|
{
|
|
unsigned long m_signature;
|
|
TwxPrintOut* m_po;
|
|
bool m_bLocked;
|
|
|
|
protected:
|
|
unsigned long Signature(const TPRINT_RCD* prcd) const;
|
|
|
|
public:
|
|
TwxPrintOut& Get(const TPRINT_RCD* prcd);
|
|
void Reset();
|
|
|
|
void Lock() { m_bLocked = true; }
|
|
void Unlock() { m_bLocked = false; }
|
|
|
|
bool Ok() const { return m_po != NULL; }
|
|
bool Locked() const { return m_bLocked; }
|
|
bool Printing() const { return Ok() && Locked(); }
|
|
|
|
TwxPrintOutCache();
|
|
~TwxPrintOutCache();
|
|
} m_PrintoutCache;
|
|
|
|
unsigned long TwxPrintOutCache::Signature(const TPRINT_RCD* prcd) const
|
|
{
|
|
unsigned long h = 0;
|
|
if (prcd != NULL)
|
|
{
|
|
const unsigned char* data = (const unsigned char*)prcd;
|
|
const size_t sz = prcd->GetSize();
|
|
for (size_t c = 0; c < sz; c++)
|
|
{
|
|
h = (h << 2) + data[c];
|
|
const unsigned long i = h & 0xC0000000;
|
|
if (i) h = (h ^ (i >> 12)) & 0x3FFFFFFF;
|
|
}
|
|
}
|
|
return h;
|
|
}
|
|
|
|
void TwxPrintOutCache::Reset()
|
|
{
|
|
wxASSERT(!Locked());
|
|
if (m_po != NULL)
|
|
{
|
|
delete m_po;
|
|
m_po = NULL;
|
|
|
|
// Marca come non valido anche il puntatore al DC contenuto nel defunto m_po
|
|
TDCMapper& m = GetTDCMapper();
|
|
if (m.HasValidDC(PRINTER_WIN))
|
|
m.GetTDC(PRINTER_WIN).KillDC();
|
|
}
|
|
}
|
|
|
|
TwxPrintOut& TwxPrintOutCache::Get(const TPRINT_RCD* prcd)
|
|
{
|
|
if (!Locked())
|
|
{
|
|
if (prcd == NULL)
|
|
{
|
|
if (m_po == NULL)
|
|
m_po = new TwxPrintOut;
|
|
}
|
|
else
|
|
{
|
|
unsigned long signature = Signature(prcd);
|
|
if (m_po != NULL && m_signature == signature)
|
|
return *m_po;
|
|
Reset();
|
|
m_po = new TwxPrintOut(prcd);
|
|
m_signature = signature;
|
|
}
|
|
}
|
|
wxASSERT(m_po != NULL);
|
|
return *m_po;
|
|
}
|
|
|
|
TwxPrintOutCache::TwxPrintOutCache() : m_signature(0), m_po(NULL)
|
|
{ }
|
|
|
|
TwxPrintOutCache::~TwxPrintOutCache()
|
|
{
|
|
// Reset(); // Essendo un oggetto statico la delete m_po non funziona!
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPrintDC
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Flag di reset ad inizio pagina
|
|
bool TPrintDC::_page_start = false;
|
|
|
|
void TPrintDC::SetPageStart()
|
|
{ _page_start = true; }
|
|
|
|
wxDC& TPrintDC::GetDC(bool)
|
|
{
|
|
_dc = m_PrintoutCache.Get(NULL).GetDC(); // Forza display context corrente
|
|
if (_page_start)
|
|
{
|
|
_dirty = -1;
|
|
_page_start = false;
|
|
}
|
|
return TDC::GetDC(false);
|
|
}
|
|
|
|
void TPrintDC::KillDC()
|
|
{
|
|
_dc = NULL; // _dc is owned by wxPrintout
|
|
}
|
|
|
|
TPrintDC::TPrintDC(wxWindow* owner) : TDC(owner)
|
|
{
|
|
_page_start = false;
|
|
}
|
|
|
|
TPrintDC::~TPrintDC()
|
|
{
|
|
KillDC();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Printing management :-(((((
|
|
///////////////////////////////////////////////////////////
|
|
|
|
BOOLEAN xvt_app_escape(int esc_code, PRINT_RCD* rcd, long* ph, long* pw, long* pvr, long* phr)
|
|
{
|
|
switch (esc_code)
|
|
{
|
|
case XVT_ESC_GET_PRINTER_INFO:
|
|
if (ph) *ph = *pw = 0;
|
|
if (pvr) *pvr = *phr = 0;
|
|
if (rcd == NULL || xvt_print_is_valid(rcd))
|
|
{
|
|
const TwxPrintOut& po = m_PrintoutCache.Get((TPRINT_RCD*)rcd);
|
|
int w, h;
|
|
if (ph)
|
|
{
|
|
po.GetPageSizePixels(&w, &h);
|
|
*pw = w; *ph = h;
|
|
}
|
|
if (pvr)
|
|
{
|
|
po.GetPPIPrinter(&w, &h);
|
|
*phr = w; *pvr = h;
|
|
}
|
|
return TRUE;
|
|
}
|
|
break;
|
|
case XVT_ESC_SET_PRINTER_INFO:
|
|
if (xvt_print_is_valid(rcd) && ph != NULL && pw != NULL)
|
|
{
|
|
TPRINT_RCD* prcd = (TPRINT_RCD*)rcd;
|
|
wxPrintData data;
|
|
|
|
RCD2data(prcd, data);
|
|
data.SetOrientation(*ph >= *pw ? wxPORTRAIT : wxLANDSCAPE);
|
|
data.ConvertToNative();
|
|
data2RCD(data, prcd);
|
|
|
|
TwxPrintOut& po = m_PrintoutCache.Get((TPRINT_RCD*)rcd);
|
|
po.InitDC(prcd, _GetAppTitle());
|
|
|
|
return true;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN xvt_dm_post_page_setup(PRINT_RCD* precp)
|
|
{
|
|
wxPageSetupDialog dlg((wxWindow*)TASK_WIN);
|
|
TPRINT_RCD* rcd = (TPRINT_RCD*)precp;
|
|
|
|
wxPageSetupData& pdd = dlg.GetPageSetupData();
|
|
wxPrintData& data = pdd.GetPrintData();
|
|
|
|
RCD2data(rcd, data);
|
|
|
|
pdd.EnableMargins(false);
|
|
|
|
const BOOLEAN ok = dlg.ShowModal() == wxID_OK;
|
|
if (ok)
|
|
{
|
|
data2RCD(data, rcd);
|
|
m_PrintoutCache.Reset();
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
static wxBitmap& GetCachedBitmap(const wxString& strName, const wxRect& dst)
|
|
{
|
|
static wxString _strName;
|
|
static wxRect _dst;
|
|
static wxBitmap _bmp;
|
|
|
|
if (strName != _strName || dst.GetSize() != _dst.GetSize())
|
|
{
|
|
wxImage img;
|
|
if (img.LoadFile(strName))
|
|
{
|
|
if (img.HasAlpha() || img.HasMask())
|
|
img.Rescale(dst.width, dst.height, wxIMAGE_QUALITY_NORMAL);
|
|
else
|
|
img.Rescale(dst.width, dst.height, wxIMAGE_QUALITY_HIGH);
|
|
_bmp = wxBitmap(img);
|
|
_strName = strName;
|
|
_dst = dst;
|
|
}
|
|
else
|
|
{
|
|
_bmp = wxNullBitmap;
|
|
_strName = "";
|
|
_dst.width = _dst.height = 0;
|
|
}
|
|
}
|
|
|
|
return _bmp;
|
|
}
|
|
|
|
void xvt_dwin_draw_image_on_pdf(WINDOW win, const char* name, const RCT* dest)
|
|
{
|
|
const wxRect dst = RCT2Rect(dest);
|
|
wxDC& dc = GetTDCMapper().GetDC(win);
|
|
if (win == PRINTER_WIN)
|
|
{
|
|
TwxPDFDC* pPDF = wxDynamicCast(&dc, TwxPDFDC);
|
|
if (pPDF != NULL)
|
|
{
|
|
pPDF->DrawImage(name, dst);
|
|
return;
|
|
}
|
|
}
|
|
|
|
wxString strName(name); strName.MakeLower();
|
|
wxBitmap& bmp = GetCachedBitmap(strName, dst);
|
|
if (bmp.IsOk())
|
|
{
|
|
//wxIcon ico; ico.CopyFromBitmap(bmp);
|
|
//dc.DrawIcon(ico, dst.x, dst.y);
|
|
wxMemoryDC mem(bmp);
|
|
dc.Blit(dst.x, dst.y, dst.width, dst.height, &mem, 0, 0, wxCOPY, true);
|
|
}
|
|
}
|
|
|
|
long xvt_fmap_get_family_sizes(PRINT_RCD *precp, char *family, long *size_array, BOOLEAN *scalable, long max_sizes)
|
|
{
|
|
long size = 0;
|
|
*scalable = FALSE;
|
|
|
|
#ifdef __WXMSW__
|
|
if (xvt_print_is_valid(precp))
|
|
{
|
|
const TwxPrintOut& po = m_PrintoutCache.Get((TPRINT_RCD*)precp);
|
|
if (!po.HasBadDriver())
|
|
size = OsWin32_EnumerateSizes(po.GetDC()->GetHDC(), family, size_array, scalable, max_sizes);
|
|
}
|
|
else
|
|
{
|
|
size = OsWin32_EnumerateSizes(NULL, family, size_array, scalable, max_sizes);
|
|
}
|
|
#else
|
|
size = OsLinux_EnumerateSizes(family, size_array, scalable, max_sizes);
|
|
#endif
|
|
|
|
return size;
|
|
}
|
|
|
|
long xvt_fmap_get_families(PRINT_RCD *precp, char **family_array, long max_families)
|
|
{
|
|
long size = 0;
|
|
family_array[0] = NULL;
|
|
|
|
#ifdef __WXMSW__
|
|
if (xvt_print_is_valid(precp))
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get((TPRINT_RCD*)precp);
|
|
if (!po.HasBadDriver())
|
|
{
|
|
size = OsWin32_EnumerateFamilies(po.GetDC()->GetHDC(), family_array, max_families);
|
|
if (size == 0)
|
|
po.SetBadDriver(true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wxFrame* tw = (wxFrame*)TASK_WIN;
|
|
wxClientDC dc(tw);
|
|
size = OsWin32_EnumerateFamilies(dc.GetHDC(), family_array, max_families);
|
|
}
|
|
#else
|
|
size = OsLinux_EnumerateFamilies(family_array, max_families);
|
|
#endif
|
|
|
|
return size;
|
|
}
|
|
|
|
void xvt_print_close(void)
|
|
{
|
|
// Nothing to do ?
|
|
m_PrintoutCache.Reset();
|
|
}
|
|
|
|
BOOLEAN xvt_print_close_page(PRINT_RCD* WXUNUSED(precp))
|
|
{
|
|
BOOLEAN ok = m_PrintoutCache.Printing();
|
|
if (ok)
|
|
{
|
|
const TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
wxDC* dc = po.GetDC();
|
|
dc->EndPage();
|
|
|
|
//GetTDCMapper().DestroyTDC(PRINTER_WIN); // Elimina dalla lista dei display context
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
PRINT_RCD* xvt_print_create(int *sizep)
|
|
{
|
|
return xvt_print_create_by_name(sizep, NULL);
|
|
}
|
|
|
|
// Impone il nome ad un PRINT_RCD.
|
|
// Utilizzato per la definiz. della stamp. virtuale PDF predefinita
|
|
int xvt_print_set_name(PRINT_RCD* precp, const char* name)
|
|
{
|
|
if (precp == NULL)
|
|
return 0;
|
|
|
|
if (name == NULL || !*name)
|
|
return 0;
|
|
|
|
wxString n = name;
|
|
|
|
#ifdef __WXMSW__
|
|
wxStrncpy(((char*)precp) + 4, name, 32);
|
|
#else
|
|
TPRINT_RCD* rcd = (TPRINT_RCD*)precp;
|
|
wxPrintData data;
|
|
|
|
rcd->GetData(data);
|
|
data.SetPrinterName(n);
|
|
rcd->SetData(data);
|
|
#endif
|
|
|
|
return n.Length();
|
|
}
|
|
|
|
// Nuova funzione inventata da Aga
|
|
PRINT_RCD* xvt_print_create_by_name(int* sizep, const char* name)
|
|
{
|
|
TPRINT_RCD* pr = NULL;
|
|
*sizep = 0;
|
|
|
|
const bool ispdf = name != NULL && xvt_str_same(name, XVT_PDF_PRINTER_NAME);
|
|
if (ispdf)
|
|
name = NULL;
|
|
|
|
#ifdef __WXMSW__
|
|
void* data = OsWin32_GetPrinterInfo(*sizep, name);
|
|
if (data == NULL)
|
|
{
|
|
SLIST plist = xvt_print_list_devices();
|
|
SLIST_ELT pitem = xvt_slist_get_first(plist);
|
|
name = xvt_slist_get(plist, pitem, NULL);
|
|
data = OsWin32_GetPrinterInfo(*sizep, name);
|
|
xvt_slist_destroy(plist);
|
|
}
|
|
if (data != NULL)
|
|
{
|
|
pr = new TPRINT_RCD;
|
|
pr->SetData(data, *sizep);
|
|
*sizep += 4; // Spazio per puntatore iniziale
|
|
delete data;
|
|
}
|
|
#else
|
|
wxPrintData data;
|
|
|
|
data.SetPrinterName(name == NULL ? "" : name);
|
|
pr = new TPRINT_RCD;
|
|
data2RCD(data, pr);
|
|
*sizep = pr->GetSize();
|
|
#endif
|
|
|
|
if (ispdf)
|
|
xvt_print_set_name(pr, XVT_PDF_PRINTER_NAME);
|
|
|
|
return pr;
|
|
}
|
|
|
|
WINDOW xvt_print_create_win(PRINT_RCD* precp, const char* title)
|
|
{
|
|
bool ok = xvt_print_is_valid(precp) != FALSE;
|
|
if (ok)
|
|
{
|
|
TPRINT_RCD* rcd = (TPRINT_RCD*)precp;
|
|
if (m_PrintoutCache.Printing())
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
ok = po.InitDC(rcd, title);
|
|
if (ok)
|
|
{
|
|
po.OnBeginPrinting();
|
|
po.OnBeginDocument(1, 32000);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get(rcd);
|
|
ok = po.InitDC(rcd, title);
|
|
}
|
|
}
|
|
return ok ? PRINTER_WIN : NULL_WIN;
|
|
}
|
|
|
|
void xvt_print_destroy(PRINT_RCD* precp)
|
|
{
|
|
if (precp != NULL)
|
|
delete precp;
|
|
}
|
|
|
|
RCT* xvt_print_get_next_band(void)
|
|
{
|
|
static bool yes = false;
|
|
static RCT rct;
|
|
yes = !yes;
|
|
|
|
if (!yes)
|
|
return NULL;
|
|
|
|
const TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
int w = 0, h = 0;
|
|
po.GetPageSizePixels(&w, &h);
|
|
rct.left = rct.top = 0;
|
|
rct.right = w;
|
|
rct.bottom = h;
|
|
|
|
return &rct;
|
|
}
|
|
|
|
BOOLEAN xvt_print_is_pdf(const PRINT_RCD* precp)
|
|
{
|
|
bool yes = precp != NULL;
|
|
if (yes)
|
|
{
|
|
char strName[MAX_PATH];
|
|
xvt_print_get_name(precp, strName, sizeof(strName));
|
|
yes = xvt_str_same(strName, XVT_PDF_PRINTER_NAME) != 0;
|
|
}
|
|
return yes;
|
|
}
|
|
|
|
BOOLEAN xvt_print_pdf_version(char* version, int size)
|
|
{
|
|
const BOOLEAN ok = version && size > 12;
|
|
if (ok)
|
|
{
|
|
wxString str = "PDFlib ";
|
|
str += PDFLIB_VERSIONSTRING;
|
|
wxStrncpy(version, str, size);
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
BOOLEAN xvt_print_is_valid(const PRINT_RCD* precp)
|
|
{
|
|
BOOLEAN ok = precp != NULL && precp->pr == NULL;
|
|
if (ok)
|
|
{
|
|
const TPRINT_RCD* rcd = (const TPRINT_RCD*)precp;
|
|
|
|
#ifdef __WXMSW__
|
|
ok = OsWin32_CheckPrinterInfo(rcd->m_data, rcd->m_size);
|
|
#else
|
|
wxPrintData data;
|
|
RCD2data(rcd, data);
|
|
ok = data.Ok();
|
|
#endif
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
int xvt_print_get_name(const PRINT_RCD* precp, char* name, int sz_s)
|
|
{
|
|
if (!xvt_print_is_valid(precp))
|
|
return 0;
|
|
|
|
#ifdef __WXMSW__
|
|
wxString n = ((const char*)precp) + 4;
|
|
if (n.Length() >= 30)
|
|
{
|
|
double dBest = 0.0;
|
|
wxString strBest = n;
|
|
SLIST plist = xvt_print_list_devices();
|
|
for (SLIST_ELT pitem = xvt_slist_get_first(plist);
|
|
pitem != NULL; pitem = xvt_slist_get_next(plist, pitem))
|
|
{
|
|
const char* pname = xvt_slist_get(plist, pitem, NULL);
|
|
const double dScore = xvt_str_fuzzy_compare_ignoring_case(n, pname);
|
|
if (dScore > dBest)
|
|
{
|
|
dBest = dScore;
|
|
strBest = pname;
|
|
if (dScore >= 1.0)
|
|
break;
|
|
}
|
|
}
|
|
xvt_slist_destroy(plist);
|
|
n = strBest;
|
|
}
|
|
#else
|
|
TPRINT_RCD* rcd = (TPRINT_RCD*)precp;
|
|
wxPrintData data;
|
|
|
|
RCD2data(rcd, data);
|
|
wxString n = data.GetPrinterName();
|
|
#endif
|
|
if (name != NULL && sz_s > 0)
|
|
{
|
|
wxStrncpy(name, n, sz_s);
|
|
name[sz_s-1] = '\0';
|
|
}
|
|
return n.Length();
|
|
}
|
|
|
|
BOOLEAN xvt_print_open(void)
|
|
{
|
|
return m_PrintoutCache.Ok();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TwxPrintAbortDialog : public wxPrintAbortDialog
|
|
{
|
|
public:
|
|
void Pulse();
|
|
TwxPrintAbortDialog();
|
|
};
|
|
|
|
void TwxPrintAbortDialog::Pulse()
|
|
{
|
|
wxGauge* pGauge = wxStaticCast(FindWindow(wxID_FORWARD), wxGauge);
|
|
pGauge->Pulse();
|
|
}
|
|
|
|
TwxPrintAbortDialog::TwxPrintAbortDialog()
|
|
: wxPrintAbortDialog(NULL, _("Stampa"),
|
|
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
|
|
{
|
|
wxBoxSizer *button_sizer = new wxBoxSizer( wxVERTICAL );
|
|
|
|
button_sizer->Add(new wxStaticText(this, wxID_STATIC, _("Stampa in corso..."),
|
|
wxDefaultPosition, wxSize(480,-1)), 0, wxALL, 10 );
|
|
button_sizer->Add(new wxGauge(this, wxID_FORWARD, 1, wxDefaultPosition, wxSize(480,-1)), 0, wxALL, 10 );
|
|
|
|
//button_sizer->Add(new wxButton(this, wxID_CANCEL, wxT("Annulla") ), 0, wxALL | wxALIGN_CENTER, 10 );
|
|
button_sizer->Add(new wxBitmapButton(this, wxID_CANCEL, xvtart_GetToolResource(102,32) ), 0, wxALL | wxALIGN_CENTER, 10 );
|
|
|
|
SetAutoLayout(true);
|
|
SetSizer(button_sizer);
|
|
|
|
button_sizer->Fit(this);
|
|
button_sizer->SetSizeHints(this);
|
|
|
|
Show();
|
|
Update();
|
|
}
|
|
|
|
void CreateAbortWindow()
|
|
{
|
|
wxPrinterBase::sm_abortWindow = new TwxPrintAbortDialog;
|
|
}
|
|
|
|
void DestroyAbortWindow()
|
|
{
|
|
if (wxPrinterBase::sm_abortWindow != NULL)
|
|
{
|
|
wxPrinterBase::sm_abortWindow->Hide();
|
|
delete wxPrinterBase::sm_abortWindow;
|
|
wxPrinterBase::sm_abortWindow = NULL;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
BOOLEAN xvt_print_start_thread(BOOLEAN(*print_fcn)(long), long data)
|
|
{
|
|
const wxString strDir = ::wxGetCwd(); // Memorizzo la directory corrente (Acrobat la cambia)
|
|
|
|
wxBeginBusyCursor();
|
|
m_PrintoutCache.Reset(); // Forza nuovo contesto di stampa
|
|
TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
m_PrintoutCache.Lock();
|
|
wxEndBusyCursor();
|
|
|
|
CreateAbortWindow();
|
|
const BOOLEAN success = print_fcn(data);
|
|
DestroyAbortWindow();
|
|
|
|
if (!po.HasBadDriver())
|
|
{
|
|
po.OnEndDocument();
|
|
po.OnEndPrinting();
|
|
}
|
|
|
|
m_PrintoutCache.Unlock();
|
|
m_PrintoutCache.Reset();
|
|
|
|
::wxSetWorkingDirectory(strDir); // Ripristino la directory corrente (Acrobat l'ha cambiata)
|
|
|
|
return success;
|
|
}
|
|
|
|
BOOLEAN xvt_print_suspend_thread()
|
|
{
|
|
BOOLEAN ok = m_PrintoutCache.Printing();
|
|
if (ok)
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
po.OnEndDocument(); // Sembra generare una pagina vuota indesiderata
|
|
po.OnEndPrinting();
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
BOOLEAN xvt_print_restart_thread()
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
po.OnBeginPrinting();
|
|
return po.OnBeginDocument(1, 32000);
|
|
}
|
|
|
|
BOOLEAN xvt_print_open_page(PRINT_RCD* WXUNUSED(precp))
|
|
{
|
|
BOOLEAN ok = m_PrintoutCache.Printing();
|
|
if (ok)
|
|
{
|
|
if (wxPrinterBase::sm_abortIt)
|
|
ok = FALSE;
|
|
else
|
|
{
|
|
TwxPrintOut& po = m_PrintoutCache.Get(NULL);
|
|
po.GetDC()->StartPage();
|
|
TPrintDC::SetPageStart(); // Flag per azzeramento dati DC
|
|
|
|
// Aggiorna barra di attesa
|
|
TwxPrintAbortDialog* pad = wxDynamicCast(wxPrinterBase::sm_abortWindow, TwxPrintAbortDialog);
|
|
if (pad != NULL)
|
|
{
|
|
pad->Pulse();
|
|
wxWakeUpIdle();
|
|
}
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Added by XVAGA
|
|
///////////////////////////////////////////////////////////
|
|
|
|
SLIST xvt_print_list_devices()
|
|
{
|
|
SLIST list = xvt_slist_create();
|
|
|
|
const DWORD dwFlags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS;
|
|
const int level = xvt_sys_get_os_version() >= XVT_WS_WIN_NT ? 4 : 5;
|
|
DWORD dwSize = 0, dwPrinters = 0;
|
|
::EnumPrinters (dwFlags, NULL, level, NULL, 0, &dwSize, &dwPrinters);
|
|
if (dwSize > 0)
|
|
{
|
|
BYTE* pBuffer = new BYTE[dwSize];
|
|
::EnumPrinters (dwFlags, NULL, level, pBuffer, dwSize, &dwSize, &dwPrinters);
|
|
if (level == 4)
|
|
{
|
|
const PRINTER_INFO_4* pPrnInfo = (const PRINTER_INFO_4*)pBuffer;
|
|
for (UINT i=0; i < dwPrinters; i++)
|
|
{
|
|
xvt_slist_add_at_elt(list, NULL, pPrnInfo->pPrinterName, NULL);
|
|
pPrnInfo++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const PRINTER_INFO_5* pPrnInfo = (const PRINTER_INFO_5*)pBuffer;
|
|
for (UINT i=0; i < dwPrinters; i++)
|
|
{
|
|
xvt_slist_add_at_elt(list, NULL, pPrnInfo->pPrinterName, NULL);
|
|
pPrnInfo++;
|
|
}
|
|
}
|
|
delete[] pBuffer;
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
BOOLEAN xvt_print_set_default_device(const char* name)
|
|
{
|
|
BOOLEAN ok = name != NULL && *name > ' ';
|
|
if (ok)
|
|
{
|
|
wxString pdev(name);
|
|
if (pdev.Find(',') < 0)
|
|
{
|
|
char szDevice[_MAX_PATH];
|
|
::GetProfileString ("devices", pdev, "", szDevice, sizeof(szDevice));
|
|
pdev << ',' << szDevice;
|
|
}
|
|
ok = ::WriteProfileString("windows", "device", pdev) != 0;
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
BOOLEAN xvt_print_get_default_device(char* name, int namesize)
|
|
{
|
|
return ::GetProfileString ("windows", "device", ",,,", name, namesize) != 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Gestione files di configurazione
|
|
///////////////////////////////////////////////////////////
|
|
|
|
int xvt_fsys_get_campo_stp_value(const char* name, char* value, int valsize)
|
|
{
|
|
BOOLEAN bFound = FALSE;
|
|
|
|
const char* const stpfile = "c:/campo.stp";
|
|
int p;
|
|
DIRECTORY dir;
|
|
char exedir[_MAX_PATH], path[_MAX_PATH];
|
|
xvt_fsys_get_default_dir(&dir);
|
|
xvt_fsys_convert_dir_to_str(&dir, exedir, sizeof(exedir));
|
|
|
|
for (p = 1; ; p++)
|
|
{
|
|
char para[4]; sprintf(para, "%d", p);
|
|
int len = xvt_sys_get_profile_string(stpfile, para, "Program", "", path, sizeof(path));
|
|
if (len <= 0)
|
|
break;
|
|
if (wxEndsWithPathSeparator(path))
|
|
{
|
|
len--;
|
|
path[len] = '\0';
|
|
}
|
|
if (xvt_str_same(path, exedir))
|
|
{
|
|
xvt_sys_get_profile_string(stpfile, para, name, "", value, valsize);
|
|
bFound = *value > ' ';
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bFound;
|
|
}
|
|
|
|
/*
|
|
@($) CGetCampoIni FILES
|
|
|
|
@(ID)
|
|
Restituisce il nome del file che contiene il prefisso corrente.
|
|
@(FD)
|
|
|
|
@(ISV)
|
|
s,s1 = stringhe di lavoro.
|
|
|
|
Versione WIN32 e LINUX.
|
|
@(FSV)
|
|
*/
|
|
const char* xvt_fsys_get_campo_ini()
|
|
{
|
|
static wxString prawin;
|
|
if (prawin.IsEmpty())
|
|
{
|
|
BOOLEAN bFound = FALSE;
|
|
char exedir[_MAX_PATH], path[_MAX_PATH];
|
|
// Nelle installazioni sfigate con programmi in rete cerca di stabilire il percorso locale di Campo.ini
|
|
DIRECTORY dir;
|
|
|
|
xvt_fsys_get_default_dir(&dir);
|
|
xvt_fsys_convert_dir_to_str(&dir, exedir, sizeof(exedir));
|
|
|
|
if (xvt_fsys_is_network_drive(exedir))
|
|
bFound = xvt_fsys_get_campo_stp_value("CampoIni", path, sizeof(path));
|
|
|
|
if (!bFound)
|
|
{
|
|
if (OsWin32_IsWindowsServer())
|
|
{
|
|
xvt_fsys_build_pathname(path, NULL, wxGetHomeDir(), "campo", "ini", NULL);
|
|
bFound = xvt_fsys_file_exists(path);
|
|
if (!bFound)
|
|
{
|
|
char pathstd[_MAX_PATH];
|
|
xvt_fsys_build_pathname(pathstd, NULL, exedir, "campo", "ini", NULL);
|
|
if (xvt_fsys_file_exists(pathstd))
|
|
wxCopyFile(pathstd, path);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bFound)
|
|
xvt_fsys_build_pathname(path, NULL, exedir, "campo", "ini", NULL);
|
|
|
|
if (!xvt_fsys_file_exists(path))
|
|
{
|
|
char msg[_MAX_PATH];
|
|
sprintf(msg, _("Impossibile aprire '%s'"), path);
|
|
xvt_dm_post_fatal_exit(msg);
|
|
}
|
|
prawin = path;
|
|
}
|
|
return prawin;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Gestione MD5
|
|
///////////////////////////////////////////////////////////
|
|
|
|
#include "MD5Checksum.h"
|
|
|
|
BOOLEAN xvt_str_md5(const char* instr, char* outstr)
|
|
{
|
|
wxASSERT(outstr != NULL);
|
|
BOOLEAN ok = instr && *instr && outstr;
|
|
if (ok)
|
|
{
|
|
wxStrcpy(outstr, wxMD5Checksum::GetMD5((unsigned char*)instr, strlen(instr)));
|
|
ok = *outstr != '\0';
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
BOOLEAN xvt_fsys_file_md5(const char* path, char* outstr)
|
|
{
|
|
wxASSERT(outstr != NULL);
|
|
BOOLEAN ok = path && *path && outstr;
|
|
if (ok)
|
|
{
|
|
wxStrcpy(outstr, wxMD5Checksum::GetMD5(wxString(path)));
|
|
ok = *outstr != '\0';
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Gestione firma digitale
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TwxSignatureDlg : public wxDialog
|
|
{
|
|
private:
|
|
virtual bool TransferDataToWindow();
|
|
virtual bool TransferDataFromWindow();
|
|
|
|
protected:
|
|
wxTextCtrl* AddString(wxSizer* ctlSizer, int id, const char* label,
|
|
wxString* str, int nFlags = 0);
|
|
|
|
public:
|
|
wxString m_strUser, m_strPIN;
|
|
bool m_bMark;
|
|
|
|
TwxSignatureDlg();
|
|
};
|
|
|
|
bool TwxSignatureDlg::TransferDataToWindow()
|
|
{
|
|
FindWindowById(1001, this)->SetLabel(m_strUser);
|
|
// FindWindowById(1002, this)->SetLabel(m_strPin); // Non riproporre
|
|
wxCheckBox* cb = wxStaticCast(FindWindowById(1003, this), wxCheckBox);
|
|
cb->SetValue(m_bMark);
|
|
return true;
|
|
}
|
|
|
|
bool TwxSignatureDlg::TransferDataFromWindow()
|
|
{
|
|
m_strUser = FindWindowById(1001, this)->GetLabel();
|
|
m_strPIN = FindWindowById(1002, this)->GetLabel();
|
|
wxCheckBox* cb = wxStaticCast(FindWindowById(1003, this), wxCheckBox);
|
|
m_bMark = cb->IsEnabled() && cb->GetValue();
|
|
return !m_strUser.IsEmpty() && !m_strPIN.IsEmpty();
|
|
}
|
|
|
|
wxTextCtrl* TwxSignatureDlg::AddString(wxSizer* ctlSizer, int id, const char* label, wxString* str, int nFlags)
|
|
{
|
|
wxStaticText* lbl = new wxStaticText(this, wxID_ANY, label);
|
|
wxTextCtrl* txt = new wxTextCtrl(this, id, wxEmptyString, wxDefaultPosition, wxSize(120, -1),
|
|
nFlags, wxTextValidator(wxFILTER_ASCII, str));
|
|
ctlSizer->Add(lbl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 4);
|
|
ctlSizer->Add(txt, 1, wxALIGN_LEFT | wxALL, 4);
|
|
|
|
return txt;
|
|
}
|
|
|
|
TwxSignatureDlg::TwxSignatureDlg() : wxDialog(NULL, wxID_ANY, "ESigner", wxDefaultPosition)
|
|
{
|
|
wxSizer* ctlSizer = new wxFlexGridSizer(4, 2, 4, 4);
|
|
AddString(ctlSizer, 1001, "Utente", &m_strUser);
|
|
AddString(ctlSizer, 1002, "PIN", &m_strPIN, wxTE_PASSWORD);
|
|
|
|
wxCheckBox* ctlMark = new wxCheckBox(this, 1003, "Marcatura temporale");
|
|
if (xvt_net_get_status() <= 0)
|
|
ctlMark->Disable();
|
|
ctlSizer->AddSpacer(4);
|
|
ctlSizer->Add(ctlMark, 0, wxALIGN_LEFT | wxALL, 4);
|
|
|
|
wxSizer* ctlButtonSizer = CreateButtonSizer(wxOK | wxCANCEL);
|
|
|
|
wxBoxSizer* ctlTopSizer = new wxBoxSizer(wxVERTICAL);
|
|
ctlTopSizer->Add(ctlSizer, 0, wxALIGN_CENTER);
|
|
ctlTopSizer->Add(ctlButtonSizer, 0, wxALIGN_CENTER);
|
|
|
|
SetSizer(ctlTopSizer);
|
|
ctlTopSizer->SetSizeHints(this);
|
|
}
|
|
|
|
typedef
|
|
int (*dllSignMethod) (
|
|
char *operation, //operazione : S (firma file),
|
|
// S+D (firma directory),
|
|
// S+T (firma + marca file),
|
|
// S+T+D (firma + marca directory)
|
|
char *method, //metodo : F (file cert), P (file PFX), T (token/smartcard)
|
|
char *inputFile, //percorso file di input
|
|
char *outputFile, //percorso file di output (senza estensione)
|
|
char *timestampOutputFile, //percorso file di output TSR (marca temporale separata)
|
|
char *extension, //estensione in caso di input PDF
|
|
char *certificateFile, //nome file .cer o .crt contenente il certificato
|
|
char *kprivFile, //nome file .pem contenente la chiave privata
|
|
char *pfxFile, //nome file pfx contenente certificato e chiave privata
|
|
char *pkcs11Dll, //nome dll PKCS11
|
|
char *pin_passphrase, //passphrase o PIN (per chiave privata, pfx o token)
|
|
char *directoryTokenCache, //directory cache certificati estratti da token
|
|
char *indexCertificateOnToken, //numero certificato del token
|
|
char *tsaURI, //URI della TSA (http:\\....)
|
|
char *tsaUsername, //Username TSA
|
|
char *tsaPassword, //Password TSA
|
|
char *tsaPolicy, //Policy TSA
|
|
char *tsaCoding, //Codifica TSA: binary o base64
|
|
char *rootCADir) //percorso directory contenente i certificati della rootca
|
|
;
|
|
|
|
typedef int (*dllVerifyMethod) (
|
|
char *operation, //operazione : V (verifica file),
|
|
// V+D (verifica directory),
|
|
char *inputFileName, //percorso file di input
|
|
char *responseFileName, //percorso file di esito
|
|
char *rootCADir, //percorso directory contenente i certificati della rootca
|
|
char *rootTSADir, //percorso directory contenente i certificati delle rootTSA
|
|
char *resultDescription //parametro di output contenente l'esito della verifica
|
|
);
|
|
|
|
class TEsigner
|
|
{
|
|
#ifdef WIN32
|
|
HMODULE m_hESigner;
|
|
dllSignMethod _SignPDF;
|
|
dllVerifyMethod _VerifyPDF;
|
|
#endif
|
|
|
|
wxString m_strUser, m_strPin, m_strDllFile, m_strCertificate;
|
|
wxString m_strTSAuri, m_strTSAuser, m_strTSApwd, m_strPolicy, m_strTSAcoding;
|
|
bool m_bMark;
|
|
|
|
public:
|
|
bool Init(bool on);
|
|
bool Sign(const wxString& strInput, wxString& strOutput);
|
|
bool Verify(const wxString& strInput);
|
|
|
|
TEsigner();
|
|
~TEsigner();
|
|
} __TheSigner;
|
|
|
|
TEsigner::TEsigner() : m_bMark(false)
|
|
#ifdef WIN32
|
|
, m_hESigner(NULL), _SignPDF(NULL), _VerifyPDF(NULL)
|
|
#endif
|
|
{}
|
|
|
|
TEsigner::~TEsigner()
|
|
{ Init(false); }
|
|
|
|
bool TEsigner::Init(bool bLoad)
|
|
{
|
|
bool ok = false;
|
|
#ifdef WIN32
|
|
if (bLoad)
|
|
{
|
|
char str[_MAX_PATH] = "";
|
|
xvt_sys_get_profile_string(NULL, NULL, "Study", "", str, sizeof(str));
|
|
wxString strConfig; strConfig = str;
|
|
if (!wxEndsWithPathSeparator(strConfig))
|
|
strConfig << wxFILE_SEP_PATH;
|
|
strConfig << "config" << wxFILE_SEP_PATH << wxGetHostName() << ".ini";
|
|
|
|
if (m_hESigner == NULL)
|
|
{
|
|
m_hESigner = ::LoadLibrary("esigner.dll");
|
|
if (m_hESigner != NULL)
|
|
{
|
|
_SignPDF = (dllSignMethod)::GetProcAddress(m_hESigner, "Sign");
|
|
_VerifyPDF = (dllVerifyMethod)::GetProcAddress(m_hESigner, "Verify");
|
|
m_strPin.Empty();
|
|
|
|
TwxSignatureDlg dlg;
|
|
if (m_strUser.IsEmpty())
|
|
m_strUser = wxGetUserId();
|
|
dlg.m_strUser = m_strUser;
|
|
dlg.m_bMark = m_bMark;
|
|
if (dlg.ShowModal() == wxID_OK)
|
|
{
|
|
m_strUser = dlg.m_strUser;
|
|
m_strPin= dlg.m_strPIN;
|
|
m_bMark = dlg.m_bMark;
|
|
}
|
|
else
|
|
return ok = false;
|
|
|
|
xvt_sys_get_profile_string(strConfig, "fd", "Cert_"+m_strUser, "", str, sizeof(str));
|
|
if (*str == '\0') // Se non trova l'utente corrente di riprova con Guest
|
|
xvt_sys_get_profile_string(strConfig, "fd", "Cert_Guest", "", str, sizeof(str));
|
|
|
|
wxStringTokenizer strDllCert(str, ",");
|
|
m_strDllFile = strDllCert.GetNextToken(); m_strDllFile.MakeLower();
|
|
m_strCertificate = strDllCert.GetNextToken();
|
|
if (m_strCertificate.IsEmpty() && m_strDllFile.EndsWith(".dll"))
|
|
m_strCertificate = "0";
|
|
|
|
if (m_bMark)
|
|
{
|
|
m_strTSAuri = strDllCert.GetNextToken();
|
|
m_strTSAuser = strDllCert.GetNextToken();
|
|
m_strTSApwd = strDllCert.GetNextToken();
|
|
m_strPolicy = strDllCert.GetNextToken();
|
|
m_strTSAcoding = strDllCert.GetNextToken();
|
|
|
|
if (m_strTSAcoding.IsEmpty())
|
|
m_strTSAcoding = wxT("binary");
|
|
|
|
if (m_strTSAuri.IsEmpty())
|
|
{
|
|
wxString msg;
|
|
msg << "Mancano i parametri per la marcatura temporale"
|
|
<< "\nControllare Cert_" << m_strUser
|
|
<< " nel paragrafo [fd]\ndel file " << strConfig;
|
|
xvt_dm_post_warning(msg);
|
|
m_bMark = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ok = m_hESigner != NULL && _SignPDF != NULL && _VerifyPDF != NULL;
|
|
if (ok)
|
|
{
|
|
ok = wxFileExists(m_strDllFile);
|
|
if (!ok)
|
|
{
|
|
wxString msg;
|
|
msg << "Impossibile caricare il certificato/driver " << m_strDllFile
|
|
<< "\nControllare Cert_" << m_strUser
|
|
<< " nel paragrafo [fd]\ndel file " << strConfig;
|
|
xvt_dm_post_error(msg);
|
|
}
|
|
}
|
|
else
|
|
xvt_dm_post_error("Impossibile caricare 'ESigner.dll'");
|
|
}
|
|
else
|
|
{
|
|
if (m_hESigner != NULL)
|
|
{
|
|
::FreeLibrary(m_hESigner);
|
|
m_hESigner = NULL;
|
|
_SignPDF = NULL;
|
|
_VerifyPDF = NULL;
|
|
m_strPin.Empty();
|
|
}
|
|
}
|
|
#endif
|
|
return ok;
|
|
}
|
|
|
|
bool TEsigner::Sign(const wxString& strInput, wxString& strOutput)
|
|
{
|
|
if ((m_strPin.IsEmpty() || m_strDllFile.IsEmpty()) && !Init(true))
|
|
return false;
|
|
|
|
const char* ext = strInput.Lower().EndsWith(".pdf") ? ".pdf.p7m" : "";
|
|
|
|
if (strOutput.IsEmpty())
|
|
strOutput = strInput + ".p7m";
|
|
::wxRemoveFile(strOutput); // Altrimenti la fantastica dll s'incazza come una biscia
|
|
|
|
const wxString strFile = strOutput.BeforeFirst('.');
|
|
|
|
int res = 0;
|
|
if (m_strDllFile.Lower().EndsWith(".dll"))
|
|
{
|
|
if (m_bMark && !m_strTSAuri.IsEmpty()) // Firma con marcatura temporale
|
|
{
|
|
res = _SignPDF("S", "T", // "S"ignature with "T"oken or smartcard
|
|
(char*)(const char*)strInput, (char*)(const char*)strFile,
|
|
NULL, (char*)ext, NULL, NULL, NULL, (char*)(const char*)m_strDllFile,
|
|
(char*)(const char*)m_strPin, NULL, (char*)(const char*)m_strCertificate,
|
|
(char*)(const char*)m_strTSAuri, (char*)(const char*)m_strTSAuser,
|
|
(char*)(const char*)m_strTSApwd, (char*)(const char*)m_strPolicy,
|
|
(char*)(const char*)m_strTSAcoding, NULL);
|
|
}
|
|
else // Firma normale
|
|
{
|
|
res = _SignPDF("S", "T", // "S"ignature with "T"oken or smartcard
|
|
(char*)(const char*)strInput, (char*)(const char*)strFile,
|
|
NULL, (char*)ext, NULL, NULL, NULL, (char*)(const char*)m_strDllFile,
|
|
(char*)(const char*)m_strPin, NULL, (char*)(const char*)m_strCertificate,
|
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_bMark && !m_strTSAuri.IsEmpty()) // Firma con marcatura temporale
|
|
{
|
|
res = _SignPDF("S", "P", // "S"ignature with "P"fx file
|
|
(char*)(const char*)strInput, (char*)(const char*)strFile,
|
|
NULL, (char*)ext, NULL, NULL, (char*)(const char*)m_strDllFile, NULL,
|
|
(char*)(const char*)m_strPin, NULL, NULL,
|
|
(char*)(const char*)m_strTSAuri, (char*)(const char*)m_strTSAuser,
|
|
(char*)(const char*)m_strTSApwd, (char*)(const char*)m_strPolicy,
|
|
(char*)(const char*)m_strTSAcoding, NULL);
|
|
}
|
|
else
|
|
{
|
|
res = _SignPDF("S", "P", // "S"ignature with "P"fx file
|
|
(char*)(const char*)strInput, (char*)(const char*)strFile,
|
|
NULL, (char*)ext, NULL, NULL, (char*)(const char*)m_strDllFile, NULL,
|
|
(char*)(const char*)m_strPin, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
|
}
|
|
}
|
|
|
|
if (res == 0)
|
|
{
|
|
if (!xvt_fsys_file_exists(strOutput))
|
|
{
|
|
wxString str = "ESigner.dll can't create " + strOutput;
|
|
xvt_dm_post_error(str);
|
|
res = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wxString str;
|
|
str.Printf("ESigner.dll error %d", res);
|
|
xvt_dm_post_error(str);
|
|
}
|
|
|
|
return res == 0;
|
|
}
|
|
|
|
bool TEsigner::Verify(const wxString& strInput)
|
|
{
|
|
int res = -1;
|
|
if (Init(!strInput.IsEmpty()))
|
|
{
|
|
char file[_MAX_PATH], result[_MAX_PATH];
|
|
wxStrncpy(file, strInput, _MAX_PATH);
|
|
res = _VerifyPDF("V", file, NULL, NULL, NULL, result);
|
|
}
|
|
return res == 0;
|
|
}
|
|
|
|
BOOLEAN xvt_sign_start()
|
|
{
|
|
return __TheSigner.Init(true);
|
|
}
|
|
|
|
BOOLEAN xvt_sign_stop()
|
|
{
|
|
__TheSigner.Init(false);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN xvt_sign_file(const char* input_name, char* output_name)
|
|
{
|
|
wxString strInput = input_name, strOutput = output_name;
|
|
if (strInput.IsEmpty())
|
|
{
|
|
FILE_SPEC fs;
|
|
xvt_fsys_convert_str_to_fspec(strInput, &fs);
|
|
if (xvt_dm_post_file_open(&fs, "File") != FL_OK)
|
|
return false;
|
|
}
|
|
strInput.MakeLower();
|
|
BOOLEAN ok = __TheSigner.Sign(strInput, strOutput);
|
|
if (ok && output_name != NULL)
|
|
wxStrncpy(output_name, strOutput, _MAX_PATH);
|
|
return ok;
|
|
}
|
|
|
|
|
|
BOOLEAN xvt_sign_test(const char* input_name)
|
|
{
|
|
wxString strInput = input_name;
|
|
if (strInput.IsEmpty())
|
|
{
|
|
FILE_SPEC fs;
|
|
xvt_fsys_convert_str_to_fspec(strInput, &fs);
|
|
if (xvt_dm_post_file_open(&fs, "File") != FL_OK)
|
|
return FALSE;
|
|
}
|
|
return __TheSigner.Verify(strInput);
|
|
}
|