Ejemplo n.º 1
1
void RenamePrinter(const std::tstring& currentPrinterName, const std::tstring& newPrinterName)
{
   HANDLE printer = 0;
   PRINTER_INFO_2 *printerInfo = 0;
   DEVMODE *pDevMode = 0;
   
   try
   {
      // get the printer and it's info structure...
      PRINTER_DEFAULTS printerDefaults;
      ZeroMemory(&printerDefaults, sizeof(printerDefaults));
      printerDefaults.DesiredAccess = PRINTER_ALL_ACCESS;

      BOOL result = OpenPrinter((LPTSTR)currentPrinterName.c_str(), &printer, &printerDefaults);
      if (!result || (0 == printer))
         throw Workshare::Exception(_T("Failed to open printer."));

      DWORD bufferSize = 0;
      SetLastError(0);
      result = GetPrinter(printer, 2, 0, 0, &bufferSize);
      if ((!result) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (bufferSize == 0))
         throw Workshare::Exception(_T("Failed to get printer info buffer size."));

      printerInfo = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, bufferSize);
      if (0 == printerInfo)
         throw Workshare::System::SystemException(_T("Failed to allocate printer info buffer."));

      result = GetPrinter(printer, 2, (LPBYTE)printerInfo, bufferSize, &bufferSize);
      if (!result)
         throw Workshare::Exception(_T("Failed to get printer info."));

      // If GetPrinter didn't fill in the DEVMODE, try to get it by calling DocumentProperties...
      LONG lFlag;

      if (0 == printerInfo->pDevMode)
      {
         bufferSize = DocumentProperties(0, printer, (LPTSTR)currentPrinterName.c_str(), 0, 0, 0);
         if (bufferSize <= 0)
            throw Workshare::Exception(_T("Failed to get document properties buffer size."));

         pDevMode = (DEVMODE *)GlobalAlloc(GPTR, bufferSize);
         if (0 == pDevMode)
            throw Workshare::System::SystemException(_T("Failed to allocate document properties buffer."));

         lFlag = DocumentProperties(0, printer, (LPTSTR)currentPrinterName.c_str(), pDevMode, 0, DM_OUT_BUFFER);
         if (lFlag != IDOK || 0 == pDevMode)
            throw Workshare::Exception(_T("Failed to get document properties."));

         printerInfo->pDevMode = pDevMode;
      }

      if (!(printerInfo->pDevMode->dmFields & DM_ORIENTATION))
         throw Workshare::Exception(_T("Printer does not support the required name change."));

      // Specify the new printer name...
      printerInfo->pPrinterName = (LPTSTR)newPrinterName.c_str() ;

      // Do not attempt to set security descriptor...
      printerInfo->pSecurityDescriptor = 0;

      lFlag = DocumentProperties(0, printer, (LPTSTR)currentPrinterName.c_str(), printerInfo->pDevMode,
                                 printerInfo->pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
      if (IDOK != lFlag)
         throw Workshare::Exception(_T("Failed to update the devmode part of document properties."));

      result = SetPrinter(printer, 2, (LPBYTE)printerInfo, 0);
      if (!result)
         throw Workshare::Exception(_T("Failed to update printer information."));

      // Tell other apps that there was a change...
      SendMessageTimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0L,
                        (LPARAM)(LPCTSTR)(LPTSTR)currentPrinterName.c_str(), SMTO_NORMAL, 1000, 0);

      return;
   }
   catch(...)
   {
      if (printerInfo)
         GlobalFree(printerInfo);
      if (printer)
         ClosePrinter(printer);
      if (pDevMode)
         GlobalFree(pDevMode);

      throw;
   }
}
Ejemplo n.º 2
0
static LPDEVMODE getDevmode(HANDLE hPrinter, const QString &printerId)
{
    LPWSTR printerIdUtf16 = const_cast<LPWSTR>(reinterpret_cast<LPCWSTR>(printerId.utf16()));
    // Allocate the required DEVMODE buffer
    LONG dmSize = DocumentProperties(NULL, hPrinter, printerIdUtf16, NULL, NULL, 0);
    if (dmSize < 0)
        return Q_NULLPTR;
    LPDEVMODE pDevMode = reinterpret_cast<LPDEVMODE>(malloc(dmSize));
     // Get the default DevMode
    LONG result = DocumentProperties(NULL, hPrinter, printerIdUtf16, pDevMode, NULL, DM_OUT_BUFFER);
    if (result != IDOK) {
        free(pDevMode);
        pDevMode = Q_NULLPTR;
    }
    return pDevMode;
}
Ejemplo n.º 3
0
Bool
apc_prn_setup( Handle self)
{
   void * lph;
   LONG sz, ret;
   DEVMODE * dm;
   HWND who = GetActiveWindow();
   HDC dc;

   objCheck false;
   if ( !OpenPrinter( sys s. prn. ppi. pPrinterName, &lph, nil))
      apiErrRet;
   sz = DocumentProperties( nil, lph, sys s. prn. ppi. pPrinterName, nil, nil, 0);
   if ( sz <= 0) {
      apiErr;
      ClosePrinter( lph);
      return false;
   }
   dm  = ( DEVMODE * ) malloc( sz);
   if ( !dm) {
      ClosePrinter( lph);
      return false;
   }

   sys s. prn. ppi. pDevMode-> dmFields = -1;
   ret = DocumentProperties( hwnd_to_view( who) ? who : nil, lph, sys s. prn. ppi. pPrinterName,
       dm, sys s. prn. ppi. pDevMode, DM_IN_BUFFER|DM_IN_PROMPT|DM_OUT_BUFFER);
   ClosePrinter( lph);
   if ( ret != IDOK) {
      free( dm);
      return false;
   }
   free( sys s. prn. ppi. pDevMode);
   sys s. prn. ppi. pDevMode = dm;

   if ( !( dc = prn_info_dc( self))) return false;
   sys res.      x = ( float) GetDeviceCaps( dc, LOGPIXELSX);
   sys res.      y = ( float) GetDeviceCaps( dc, LOGPIXELSY);
   sys lastSize. x = GetDeviceCaps( dc, HORZRES);
   sys lastSize. y = GetDeviceCaps( dc, VERTRES);
   if ( !DeleteDC( dc)) apiErr;

   return true;
}
Ejemplo n.º 4
0
void getDefaultDevmodeC(char *printSetup, LPHANDLE phPrinter,  char **device)
{
	int		size,r1;

	size		= ((int*)printSetup)[0];
	printSetup	+=4;
	r1 = DocumentProperties(NULL,phPrinter,((char*)device)+4,
							(DEVMODE*)printSetup,NULL,DM_OUT_BUFFER);
	ClosePrinter(phPrinter);
}
Ejemplo n.º 5
0
QPageSize QWindowsPrintDevice::defaultPageSize() const
{
    if (!m_havePageSizes)
        loadPageSizes();

    QPageSize pageSize;

    // Allocate the required DEVMODE buffer
    DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0);
    LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize);

     // Get the default DevMode
    DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER);

    // Get the default paper size
    if (result == IDOK && pDevMode->dmFields & DM_PAPERSIZE) {
        // Find the supported page size that matches, in theory default should be one of them
        foreach (const QPageSize &ps, m_pageSizes) {
            if (ps.windowsId() == pDevMode->dmPaperSize) {
                pageSize = ps;
                break;
            }
        }
    }
Ejemplo n.º 6
0
void getDevmodeSizeC(int *size, HANDLE *phPrinter,
					 char **device, char **driver,  char **output)
{
	char	szPrinter[80];
	char	*szDevice, *szDriver, *szOutput;

	GetProfileString("windows", "device", ",,,", szPrinter, 80);
	szDevice = strtok(szPrinter,",");
	szDriver = strtok(NULL,", ");
	szOutput = strtok(NULL,", ");
	*device	= PassString(szDevice);
	*driver	= PassString(szDriver);
	*output	= PassString(szOutput);
	if (*szDevice=='\0' || *szDriver=='\0' || *szOutput=='\0')
	{
		*size	= 0;
		return;
	};
	OpenPrinter(szDevice,phPrinter,NULL);
	*size = DocumentProperties(NULL,*phPrinter,szDevice,NULL,NULL,0);
}
Ejemplo n.º 7
0
bool PrintFile(const WCHAR *fileName, const WCHAR *printerName, bool displayErrors, const WCHAR *settings)
{
    if (!HasPermission(Perm_PrinterAccess))
        return false;

    ScopedMem<WCHAR> fileName2(path::Normalize(fileName));
    BaseEngine *engine = EngineManager::CreateEngine(!gUseEbookUI, fileName2);
    if (!engine || !engine->AllowsPrinting()) {
        if (displayErrors)
            MessageBox(NULL, _TR("Cannot print this file"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0));
        return false;
    }

    HANDLE printer;
    bool ok = OpenPrinter((WCHAR *)printerName, &printer, NULL);
    if (!ok) {
        if (displayErrors)
            MessageBox(NULL, _TR("Printer with given name doesn't exist"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0));
        return false;
    }

    // get printer driver information
    DWORD needed = 0;
    GetPrinter(printer, 2, NULL, 0, &needed);
    ScopedMem<PRINTER_INFO_2> infoData((PRINTER_INFO_2 *)AllocArray<BYTE>(needed));
    if (infoData)
        ok = GetPrinter(printer, 2, (LPBYTE)infoData.Get(), needed, &needed);
    if (!ok || !infoData || needed <= sizeof(PRINTER_INFO_2)) goto Exit;

    LONG structSize = DocumentProperties(NULL,
        printer,                /* Handle to our printer. */
        (WCHAR *)printerName,   /* Name of the printer. */ 
        NULL,                   /* Asking for size, so */
        NULL,                   /* these are not used. */
        0);                     /* Zero returns buffer size. */
    if (structSize < sizeof(DEVMODE)) {
        // If failure, inform the user, cleanup and return failure.
        if (displayErrors)
            MessageBox(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0));
        goto Exit;
    }
    LPDEVMODE devMode = (LPDEVMODE)malloc(structSize);
    if (!devMode) goto Exit;

    // Get the default DevMode for the printer and modify it for your needs.
    LONG returnCode = DocumentProperties(NULL,
        printer,
        (WCHAR *)printerName,
        devMode,        /* The address of the buffer to fill. */
        NULL,           /* Not using the input buffer. */
        DM_OUT_BUFFER); /* Have the output buffer filled. */
    if (IDOK != returnCode) {
        // If failure, inform the user, cleanup and return failure.
        if (displayErrors)
            MessageBox(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem."), MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0));
        goto Exit;
    }

    ClosePrinter(printer);
    printer = NULL;

    {
        Print_Advanced_Data advanced;
        Vec<PRINTPAGERANGE> ranges;
        ApplyPrintSettings(settings, engine->PageCount(), ranges, advanced);

        PrintData pd(engine, infoData, devMode, ranges, advanced);
        ok = PrintToDevice(pd);
        if (!ok && displayErrors)
            MessageBox(NULL, _TR("Couldn't initialize printer"), _TR("Printing problem."),
                MB_ICONEXCLAMATION | MB_OK | (IsUIRightToLeft() ? MB_RTLREADING : 0));
    }

Exit:
    free(devMode);
    if (printer)
        ClosePrinter(printer);
    delete engine;
    return ok;
}
Ejemplo n.º 8
0
bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
{
    WinPrinter printer;
    LPTSTR szPrinterName = wxMSW_CONV_LPTSTR(data.GetPrinterName());

    if (!m_devMode)
        InitializeDevMode(data.GetPrinterName(), &printer);

    HGLOBAL hDevMode = static_cast<HGLOBAL>(m_devMode);

    if ( hDevMode )
    {
        GlobalPtrLock lockDevMode(hDevMode);
        DEVMODE * const devMode = static_cast<DEVMODE *>(lockDevMode.Get());

        //// Orientation
        devMode->dmOrientation = (short)data.GetOrientation();

        //// Collation
        devMode->dmCollate = (data.GetCollate() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE);
        devMode->dmFields |= DM_COLLATE;

        //// Number of copies
        devMode->dmCopies = (short)data.GetNoCopies();
        devMode->dmFields |= DM_COPIES;

        //// Printer name
        wxString name = data.GetPrinterName();
        if (!name.empty())
        {
            // NB: the cast is needed in the ANSI build, strangely enough
            //     dmDeviceName is BYTE[] and not char[] there
            wxStrlcpy(reinterpret_cast<wxChar *>(devMode->dmDeviceName),
                      name.t_str(),
                      WXSIZEOF(devMode->dmDeviceName));
        }

        //// Colour
        if (data.GetColour())
            devMode->dmColor = DMCOLOR_COLOR;
        else
            devMode->dmColor = DMCOLOR_MONOCHROME;
        devMode->dmFields |= DM_COLOR;

        //// Paper size

        // Paper id has priority over paper size. If id is specified, then size
        // is ignored (as it can be filled in even for standard paper sizes)

        wxPrintPaperType *paperType = NULL;

        const wxPaperSize paperId = data.GetPaperId();
        if ( paperId != wxPAPER_NONE && wxThePrintPaperDatabase )
        {
            paperType = wxThePrintPaperDatabase->FindPaperType(paperId);
        }

        if ( paperType )
        {
            devMode->dmPaperSize = (short)paperType->GetPlatformId();
            devMode->dmFields |= DM_PAPERSIZE;
        }
        else // custom (or no) paper size
        {
            const wxSize paperSize = data.GetPaperSize();
            if ( paperSize != wxDefaultSize )
            {
                // Fall back on specifying the paper size explicitly
                if(m_customWindowsPaperId != 0)
                    devMode->dmPaperSize = m_customWindowsPaperId;
                else
                    devMode->dmPaperSize = DMPAPER_USER;
                devMode->dmPaperWidth = (short)(paperSize.x * 10);
                devMode->dmPaperLength = (short)(paperSize.y * 10);
                devMode->dmFields |= DM_PAPERWIDTH;
                devMode->dmFields |= DM_PAPERLENGTH;

                // A printer driver may or may not also want DM_PAPERSIZE to
                // be specified. Also, if the printer driver doesn't implement the DMPAPER_USER
                // size, then this won't work, and even if you found the correct id by
                // enumerating the driver's paper sizes, it probably won't change the actual size,
                // it'll just select that custom paper type with its own current setting.
                // For a discussion on this, see http://www.codeguru.com/forum/showthread.php?threadid=458617
                // Although m_customWindowsPaperId is intended to work around this, it's
                // unclear how it can help you set the custom paper size programmatically.
            }
            //else: neither paper type nor size specified, don't fill DEVMODE
            //      at all so that the system defaults are used
        }

        //// Duplex
        short duplex;
        switch (data.GetDuplex())
        {
            case wxDUPLEX_HORIZONTAL:
                duplex = DMDUP_HORIZONTAL;
                break;
            case wxDUPLEX_VERTICAL:
                duplex = DMDUP_VERTICAL;
                break;
            default:
            // in fact case wxDUPLEX_SIMPLEX:
                duplex = DMDUP_SIMPLEX;
                break;
        }
        devMode->dmDuplex = duplex;
        devMode->dmFields |= DM_DUPLEX;

        //// Quality

        short quality;
        switch (data.GetQuality())
        {
            case wxPRINT_QUALITY_MEDIUM:
                quality = DMRES_MEDIUM;
                break;
            case wxPRINT_QUALITY_LOW:
                quality = DMRES_LOW;
                break;
            case wxPRINT_QUALITY_DRAFT:
                quality = DMRES_DRAFT;
                break;
            case wxPRINT_QUALITY_HIGH:
                quality = DMRES_HIGH;
                break;
            default:
                quality = (short)data.GetQuality();
                devMode->dmYResolution = quality;
                devMode->dmFields |= DM_YRESOLUTION;
                break;
        }
        devMode->dmPrintQuality = quality;
        devMode->dmFields |= DM_PRINTQUALITY;

        if (data.GetPrivDataLen() > 0)
        {
            memcpy( (char *)devMode+devMode->dmSize, data.GetPrivData(), data.GetPrivDataLen() );
            devMode->dmDriverExtra = (WXWORD)data.GetPrivDataLen();
        }

        if (data.GetBin() != wxPRINTBIN_DEFAULT)
        {
            switch (data.GetBin())
            {
                case wxPRINTBIN_ONLYONE:        devMode->dmDefaultSource = DMBIN_ONLYONE;       break;
                case wxPRINTBIN_LOWER:          devMode->dmDefaultSource = DMBIN_LOWER;         break;
                case wxPRINTBIN_MIDDLE:         devMode->dmDefaultSource = DMBIN_MIDDLE;        break;
                case wxPRINTBIN_MANUAL:         devMode->dmDefaultSource = DMBIN_MANUAL;        break;
                case wxPRINTBIN_ENVELOPE:       devMode->dmDefaultSource = DMBIN_ENVELOPE;      break;
                case wxPRINTBIN_ENVMANUAL:      devMode->dmDefaultSource = DMBIN_ENVMANUAL;     break;
                case wxPRINTBIN_AUTO:           devMode->dmDefaultSource = DMBIN_AUTO;          break;
                case wxPRINTBIN_TRACTOR:        devMode->dmDefaultSource = DMBIN_TRACTOR;       break;
                case wxPRINTBIN_SMALLFMT:       devMode->dmDefaultSource = DMBIN_SMALLFMT;      break;
                case wxPRINTBIN_LARGEFMT:       devMode->dmDefaultSource = DMBIN_LARGEFMT;      break;
                case wxPRINTBIN_LARGECAPACITY:  devMode->dmDefaultSource = DMBIN_LARGECAPACITY; break;
                case wxPRINTBIN_CASSETTE:       devMode->dmDefaultSource = DMBIN_CASSETTE;      break;
                case wxPRINTBIN_FORMSOURCE:     devMode->dmDefaultSource = DMBIN_FORMSOURCE;    break;

                default:
                    devMode->dmDefaultSource = (short)(DMBIN_USER + data.GetBin() - wxPRINTBIN_USER); // 256 + data.GetBin() - 14 = 242 + data.GetBin()
                    break;
            }

            devMode->dmFields |= DM_DEFAULTSOURCE;
        }
        if (data.GetMedia() != wxPRINTMEDIA_DEFAULT)
        {
            devMode->dmMediaType = data.GetMedia();
            devMode->dmFields |= DM_MEDIATYPE;
        }

        if( printer )
        {
            // Step 3:
            // Merge the new settings with the old.
            // This gives the driver an opportunity to update any private
            // portions of the DevMode structure.
            DocumentProperties( NULL,
                printer,
                szPrinterName,
                (LPDEVMODE)hDevMode, // Reuse our buffer for output.
                (LPDEVMODE)hDevMode, // Pass the driver our changes
                DM_IN_BUFFER |       // Commands to Merge our changes and
                DM_OUT_BUFFER );     // write the result.
        }
    }

    if ( m_devNames )
    {
        ::GlobalFree(static_cast<HGLOBAL>(m_devNames));
    }

    // TODO: I hope it's OK to pass some empty strings to DEVNAMES.
    m_devNames = wxCreateDevNames(wxEmptyString, data.GetPrinterName(), wxEmptyString);

    return true;
}
Ejemplo n.º 9
0
void wxWindowsPrintNativeData::InitializeDevMode(const wxString& printerName, WinPrinter* printer)
{
    if (m_devMode)
        return;

    LPTSTR szPrinterName = wxMSW_CONV_LPTSTR(printerName);

    // From MSDN: How To Modify Printer Settings with the DocumentProperties() Function
    // The purpose of this is to fill the DEVMODE with privdata from printer driver.
    // If we have a printer name and OpenPrinter successfully returns
    // this replaces the PrintDlg function which creates the DEVMODE filled only with data from default printer.
    if ( !m_devMode && !printerName.IsEmpty() )
    {
        // Open printer
        if ( printer && printer->Open( printerName ) == TRUE )
        {
            DWORD dwNeeded, dwRet;

            // Step 1:
            // Allocate a buffer of the correct size.
            dwNeeded = DocumentProperties( NULL,
                *printer,        // Handle to our printer.
                szPrinterName,   // Name of the printer.
                NULL,            // Asking for size, so
                NULL,            // these are not used.
                0 );             // Zero returns buffer size.

            LPDEVMODE tempDevMode = static_cast<LPDEVMODE>( GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, dwNeeded ) );

            // Step 2:
            // Get the default DevMode for the printer
            dwRet = DocumentProperties( NULL,
                *printer,
                szPrinterName,
                tempDevMode,     // The address of the buffer to fill.
                NULL,            // Not using the input buffer.
                DM_OUT_BUFFER ); // Have the output buffer filled.

            if ( dwRet != IDOK )
            {
                // If failure, cleanup
                GlobalFree( tempDevMode );
                printer->Close();
            }
            else
            {
                m_devMode = tempDevMode;
                tempDevMode = NULL;
            }
        }
    }

    if ( !m_devMode )
    {
        // Use PRINTDLG as a way of creating a DEVMODE object
        PRINTDLG pd;

        memset(&pd, 0, sizeof(PRINTDLG));
#ifdef __WXWINCE__
        pd.cbStruct    = sizeof(PRINTDLG);
#else
        pd.lStructSize    = sizeof(PRINTDLG);
#endif

        pd.hwndOwner      = NULL;
        pd.hDevMode       = NULL; // Will be created by PrintDlg
        pd.hDevNames      = NULL; // Ditto

        pd.Flags          = PD_RETURNDEFAULT;
        pd.nCopies        = 1;

        // Fill out the DEVMODE structure
        // so we can use it as input in the 'real' PrintDlg
        if (!PrintDlg(&pd))
        {
            if ( pd.hDevMode )
                GlobalFree(pd.hDevMode);
            if ( pd.hDevNames )
                GlobalFree(pd.hDevNames);
            pd.hDevMode = NULL;
            pd.hDevNames = NULL;

#if wxDEBUG_LEVEL
            wxLogDebug(wxT("Printing error: ") + wxGetPrintDlgError());
#endif // wxDEBUG_LEVEL
        }
        else
        {
            m_devMode = pd.hDevMode;
            pd.hDevMode = NULL;

            // We'll create a new DEVNAMEs structure below.
            if ( pd.hDevNames )
                GlobalFree(pd.hDevNames);
            pd.hDevNames = NULL;

            // hDevNames = pd->hDevNames;
            // m_devNames = (void*)(long) hDevNames;
            // pd->hDevnames = NULL;

        }
    }

}
Ejemplo n.º 10
0
static HANDLE LoadCustomPrinterHDEVMODE(HWND hWnd, const char *filepath)
{
  char device[MAX_PATH];
  HANDLE hPrinter = NULL;
  int sizeof_devmode;
  HGLOBAL hDevMode = NULL;
  DEVMODE *devmode = NULL;
  int res;
  FILE *fp = NULL;
  int block_size;
  int block_read;

  if ((fp = fopen(filepath, "rb")) == NULL)
    return NULL;

  if (fread(device, 1, dmDeviceNameSize, fp) != dmDeviceNameSize)
    goto err_exit;

  if (!OpenPrinter(device, &hPrinter, NULL))
    goto err_exit;

  sizeof_devmode = (int) DocumentProperties(hWnd, hPrinter, device,
					    NULL, NULL, 0);

  if (!sizeof_devmode)
    goto err_exit;

  hDevMode = GlobalAlloc(GHND, sizeof_devmode);
  if (!hDevMode)
    goto err_exit;

  devmode = (DEVMODE *) GlobalLock(hDevMode);
  if (!devmode)
    goto err_exit;

  res = DocumentProperties(hWnd, hPrinter, device, devmode, NULL,
			   DM_OUT_BUFFER);
  if (res != IDOK)
    goto err_exit;

  block_size = devmode->dmSize + devmode->dmDriverExtra;
  block_read = fread(devmode, 1, block_size, fp);
  if (block_size != block_read)
    goto err_exit;
  fclose(fp);

  res = DocumentProperties(hWnd, hPrinter, device, devmode, devmode,
			   DM_IN_BUFFER | DM_OUT_BUFFER);
  if (res != IDOK)
    goto err_exit;

  GlobalUnlock(hDevMode);
  ClosePrinter(hPrinter);
  return hDevMode;

err_exit:
  if (fp)
    fclose(fp);
  if (devmode)
    GlobalUnlock(hDevMode);
  if (hDevMode)
    GlobalFree(hDevMode);
  if (hPrinter)
    ClosePrinter(hPrinter);
  return NULL;
}
Ejemplo n.º 11
0
bool PrintFile(BaseEngine *engine, WCHAR *printerName, bool displayErrors, const WCHAR *settings)
{
    bool ok = false;
    if (!HasPermission(Perm_PrinterAccess))
        return false;

#ifndef DISABLE_DOCUMENT_RESTRICTIONS
    if (engine && !engine->AllowsPrinting())
        engine = NULL;
#endif
    if (!engine) {
        if (displayErrors)
            MessageBoxWarning(NULL, _TR("Cannot print this file"), _TR("Printing problem."));
        return false;
    }

    ScopedMem<WCHAR> defaultPrinter;
    if (!printerName) {
        defaultPrinter.Set(GetDefaultPrinterName());
        printerName = defaultPrinter;
    }

    HANDLE printer;
    BOOL res = OpenPrinter(printerName, &printer, NULL);
    if (!res) {
        if (displayErrors)
            MessageBoxWarning(NULL, _TR("Printer with given name doesn't exist"), _TR("Printing problem."));
        return false;
    }

    LPDEVMODE devMode = NULL;
    // get printer driver information
    DWORD needed = 0;
    GetPrinter(printer, 2, NULL, 0, &needed);
    ScopedMem<PRINTER_INFO_2> infoData((PRINTER_INFO_2 *)AllocArray<BYTE>(needed));
    if (infoData)
        res = GetPrinter(printer, 2, (LPBYTE)infoData.Get(), needed, &needed);
    if (!res || !infoData || needed <= sizeof(PRINTER_INFO_2))
        goto Exit;

    LONG structSize = DocumentProperties(NULL,
        printer,
        printerName,
        NULL,                   /* Asking for size, so */
        NULL,                   /* not used. */
        0);                     /* Zero returns buffer size. */
    if (structSize < sizeof(DEVMODE)) {
        // If failure, inform the user, cleanup and return failure.
        if (displayErrors)
            MessageBoxWarning(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem."));
        goto Exit;
    }
    devMode = (LPDEVMODE)malloc(structSize);
    if (!devMode)
        goto Exit;

    // Get the default DevMode for the printer and modify it for your needs.
    LONG returnCode = DocumentProperties(NULL,
        printer,
        printerName,
        devMode,        /* The address of the buffer to fill. */
        NULL,           /* Not using the input buffer. */
        DM_OUT_BUFFER); /* Have the output buffer filled. */
    if (IDOK != returnCode) {
        // If failure, inform the user, cleanup and return failure.
        if (displayErrors)
            MessageBoxWarning(NULL, _TR("Could not obtain Printer properties"), _TR("Printing problem."));
        goto Exit;
    }

    ClosePrinter(printer);
    printer = NULL;

    {
        Print_Advanced_Data advanced;
        Vec<PRINTPAGERANGE> ranges;
        ApplyPrintSettings(settings, engine->PageCount(), ranges, advanced, devMode);

        PrintData pd(engine, infoData, devMode, ranges, advanced);
        ok = PrintToDevice(pd);
        if (!ok && displayErrors)
            MessageBoxWarning(NULL, _TR("Couldn't initialize printer"), _TR("Printing problem."));
    }

Exit:
    free(devMode);
    if (printer)
        ClosePrinter(printer);
    return ok;
}
Ejemplo n.º 12
0
int _tmain(int argc, _TCHAR* argv[])
{
	// Before we can do anything, we need to unlock the DLL
	// NOTE: If you are evaluating FOXIT READER SDK, you don’t need unlock the DLL,
	// then evaluation marks will be shown with all rendered pages.
	FPDF_UnlockDLL("license_id", "unlock_code");

	// first, load the document (no password specified)
	pdf_doc = FPDF_LoadDocument("testdoc.pdf", NULL);

	// error handling
	if (pdf_doc == NULL) 
	{
		fprintf(stderr, "ERROR - doc\n");
		exit(1);
	}

	// Open the out file
	
	fopen_s(&out, "test.spl", "wb");

	// Send the StartDoc header
	
	wchar_t* dname = L"desktop.ini - Editor";
	wchar_t* prn = L"c:\\output.prn";
	
	{

	if (wcsnlen(dname, 255) == 255)
		ErrorExit(L"dname too long");
	if (wcsnlen(prn, 255) == 255)
		ErrorExit(L"prn too long");

	SPL_HEADER spl;

	spl.SIGNATURE=SPLMETA_SIGNATURE;
	spl.nSize=(DWORD)sizeof(spl)+wcslen(dname)*2+wcslen(prn)*2+4; // +4, because \0\0 is after dname and prn
	spl.offDocumentName=(DWORD)sizeof(spl);
	spl.offPort=(DWORD)sizeof(spl)+wcslen(dname)*2+2; // +2 because \0\0 is after dname
	
	fwrite(&spl, sizeof(spl), 1, out);
	
	fwrite(dname, wcslen(dname)*2, 1, out);
	fwrite("\0\0", 2, 1, out);

	fwrite(prn, wcslen(prn)*2, 1, out);
	fwrite("\0\0", 2, 1, out);
	}

	// Load the first page and calculate the bbox
	// based on the printer margins

	pdf_page = FPDF_LoadPage(pdf_doc, 0);
	if (pdf_page == NULL)
		ErrorExit(L"FPDF_LoadPage");

	double page_width, page_height;
    
	page_width = FPDF_GetPageWidth(pdf_page);
    page_height = FPDF_GetPageHeight(pdf_page);

#ifdef EXT_PRINT
#ifdef EXT_PRNDLG
	PRINTDLG pd;
	HWND hwnd = NULL;

	// Initialize PRINTDLG
	ZeroMemory(&pd, sizeof(pd));
	pd.lStructSize = sizeof(pd);
	pd.hwndOwner   = hwnd;
	pd.hDevMode    = NULL;     // Don't forget to free or store hDevMode
	pd.hDevNames   = NULL;     // Don't forget to free or store hDevNames
	pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC; 
	pd.nCopies     = 1;
	pd.nFromPage   = 0xFFFF; 
	pd.nToPage     = 0xFFFF; 
	pd.nMinPage    = 1; 
	pd.nMaxPage    = 0xFFFF; 
	

	if (PrintDlg(&pd) != TRUE)
		ErrorExit(L"PrintDialog\n");

	hDC = pd.hDC;
#else
	wchar_t* printer=L"FF";
	if (!OpenPrinter(printer, &hPrinter, NULL))
		ErrorExit(L"OpenPrinter\n");
    DWORD dwNeeded = DocumentProperties(NULL, hPrinter, printer, NULL, NULL, 0);
    lpDevMode = (LPDEVMODE)malloc(dwNeeded);
	
	DocumentProperties(NULL, hPrinter, printer, lpDevMode, NULL, DM_OUT_BUFFER);
	/* Try to set a higher print quality */
	lpDevMode->dmPrintQuality=1200;
	lpDevMode->dmFields|=DM_PRINTQUALITY;
	DocumentProperties(NULL, hPrinter, printer, lpDevMode, lpDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
#ifdef EXT_PRNOPTS
	DocumentProperties(NULL, hPrinter, printer, lpDevMode, lpDevMode, DM_IN_BUFFER | DM_PROMPT | DM_OUT_BUFFER);
#endif
	hDC = CreateDC(L"WINEPS.DRV", printer, NULL, lpDevMode);

	ClosePrinter(&hPrinter);
#endif
#else
	hDC = CreateDC(L"WINEPS.DRV", L"FF", NULL, lpDevMode);
#endif

	
#ifdef PRINT
	DOCINFO doc_info;

	doc_info.cbSize=sizeof(DOCINFO)+12;
	doc_info.lpszDocName=dname;
	doc_info.lpszOutput=prn;
	doc_info.lpszDatatype=NULL;
	doc_info.fwType=0;

	// Start a printer job
	StartDoc(hDC, &doc_info);
#endif
	
	// get number of pixels per inch (horizontally and vertically)
	logpixelsx = GetDeviceCaps(hDC, LOGPIXELSX);
	logpixelsy = GetDeviceCaps(hDC, LOGPIXELSY);
	
	// convert points into pixels
	size_x = (int)page_width / 72 * logpixelsx;
	size_y = (int)page_height / 72 * logpixelsy;

	DWORD p_width =GetDeviceCaps(hDC, HORZSIZE)*100;
	DWORD p_height=GetDeviceCaps(hDC, VERTSIZE)*100;

	SetRect( &rect, 0, 0, p_width, p_height );

#ifdef DEBUG
	//fprintf(stderr, "x=%u, y=%u, pw=%u, ph=%u,sx=%u,sy=%u,lpx=%u,lpy=%u,size_x=%u,size_y=%u\n",x,y,page_width,page_height,sx,sy,logpixelsx,logpixelsy,size_x,size_y);
#endif

	// now load the pages one after another

	for (i=0; i < FPDF_GetPageCount(pdf_doc); i++)
	{
#ifdef DEBUG
		fprintf(stderr, "Load page %d/%d\n", i, FPDF_GetPageCount(pdf_doc));
#endif

		// Load the next page

		pdf_page = FPDF_LoadPage(pdf_doc, i);
		
		if (pdf_page == NULL)
			ErrorExit(L"FPDF_LoadPage");
	
		fbuf=NULL;
#ifdef DEBUG
		sprintf_s(buf, 255, "test-%d.emf", i);
		//fbuf=buf;
#endif

		// Create a metafile to render to

		hMeta = CreateEnhMetaFileA(hDC, 
	          fbuf, 
	          &rect, "SPLFilter.exe\0Created by Fabian\0\0");

		if (hMeta == NULL)
			ErrorExit(L"CreateEnhMetaFileA");

	 	// Call FPDF_RenderPage function to render the whole page
		FPDF_RenderPage(hMeta, pdf_page, 0, 0, size_x, size_y, 0, 0);

#ifdef PRINT
		// Start a new printing page
		StartPage(hDC);
		FPDF_RenderPage(hDC, pdf_page, 0, 0, size_x, size_y, 0, 0);
		EndPage(hDC);
#endif

		// Close PDF page

		FPDF_ClosePage(pdf_page);

		efile=CloseEnhMetaFile(hMeta);

		if (efile == NULL)
			ErrorExit(L"CloseEnhMetaFile");

		// Write EMF data - via enumeration, because we want to embed fonts later
	    EnumEnhMetaFile(hDC, efile, enum_it, NULL, &rect);

		// Write EndPage() record
		{
		SMR_EOPAGE smr_eopage;
		
		smr_eopage.smrext.smr.iType=SRT_EXT_EOPAGE_VECTOR;
		smr_eopage.smrext.smr.nSize=sizeof(smr_eopage)-sizeof(smr_eopage.smrext.smr);

		/* FIXME: Need to calcualte low and high correctly */
		smr_eopage.smrext.DistanceLow=bufSize+smr_eopage.smrext.smr.nSize;
		smr_eopage.smrext.DistanceHigh=0;

		fwrite(&smr_eopage, sizeof(smr_eopage), 1, out);
		}
		
		DeleteEnhMetaFile(efile);
	}
#ifdef PRINT
	EndDoc(hDC);
#endif

	fclose(out);
	out=NULL;
	DeleteDC(hDC);
	FPDF_CloseDocument(pdf_doc);

#ifdef DEBUG
	fprintf(stderr, "SPLFilter: Conversion successful!\n");
#endif
	exit(0);
}
Ejemplo n.º 13
0
/* Get Device Context for printer */
static int
win_pr2_getdc(gx_device_win_pr2 * wdev)
{
    char *device;
    char *devices;
    char *p;
    char driverbuf[512];
    char *driver;
    char *output;
    char *devcap;
    int devcapsize;
    int devmode_size;

    int i, n;
    POINT *pp;
    int paperindex;
    int paperwidth, paperheight;
    int orientation;
    int papersize;
    char papername[64];
    LPDEVMODE podevmode, pidevmode;
    HANDLE hprinter;

    /* first try to derive the printer name from -sOutputFile= */
    /* is printer if name prefixed by \\spool\ or by %printer% */
    if (is_spool(wdev->fname)) {
	device = wdev->fname + 8;	/* skip over \\spool\ */
	wdev->use_old_spool_name = true;
    } else if (strncmp("%printer%",wdev->fname,9) == 0) {
	device = wdev->fname + 9;	/* skip over %printer% */
	wdev->use_old_spool_name = false;
    } else {
	return FALSE;
    }

    /* now try to match the printer name against the [Devices] section */
    if ((devices = gs_malloc(wdev->memory, 4096, 1, "win_pr2_getdc")) == (char *)NULL)
	return FALSE;
    GetProfileString("Devices", NULL, "", devices, 4096);
    p = devices;
    while (*p) {
	if (stricmp(p, device) == 0)
	    break;
	p += strlen(p) + 1;
    }
    if (*p == '\0')
	p = NULL;
    gs_free(wdev->memory, devices, 4096, 1, "win_pr2_getdc");
    if (p == NULL)
	return FALSE;		/* doesn't match an available printer */

    /* the printer exists, get the remaining information from win.ini */
    GetProfileString("Devices", device, "", driverbuf, sizeof(driverbuf));
    driver = strtok(driverbuf, ",");
    output = strtok(NULL, ",");

    if (!OpenPrinter(device, &hprinter, NULL))
	return FALSE;
    devmode_size = DocumentProperties(NULL, hprinter, device, NULL, NULL, 0);
    if ((podevmode = gs_malloc(wdev->memory, devmode_size, 1, "win_pr2_getdc"))
	== (LPDEVMODE) NULL) {
	ClosePrinter(hprinter);
	return FALSE;
    }
    if ((pidevmode = gs_malloc(wdev->memory, devmode_size, 1, "win_pr2_getdc"))		== (LPDEVMODE) NULL) {
	gs_free(wdev->memory, podevmode, devmode_size, 1, "win_pr2_getdc");
	ClosePrinter(hprinter);
	return FALSE;
    }
    DocumentProperties(NULL, hprinter, device, podevmode, NULL, DM_OUT_BUFFER);

    /* now find out what paper sizes are available */
    devcapsize = DeviceCapabilities(device, output, DC_PAPERSIZE, NULL, NULL);
    devcapsize *= sizeof(POINT);
    if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
	return FALSE;
    n = DeviceCapabilities(device, output, DC_PAPERSIZE, devcap, NULL);
    paperwidth = (int)(wdev->MediaSize[0] * 254 / 72);
    paperheight = (int)(wdev->MediaSize[1] * 254 / 72);
    papername[0] = '\0';
    papersize = 0;
    paperindex = -1;
    orientation = 0;
    pp = (POINT *) devcap;
    for (i = 0; i < n; i++, pp++) {
	if ((pp->x < paperwidth + 20) && (pp->x > paperwidth - 20) &&
	    (pp->y < paperheight + 20) && (pp->y > paperheight - 20)) {
	    paperindex = i;
	    paperwidth = pp->x;
	    paperheight = pp->y;
	    orientation = DMORIENT_PORTRAIT;
	    break;
	}
    }
    if (paperindex < 0) {
	/* try again in landscape */
	pp = (POINT *) devcap;
	for (i = 0; i < n; i++, pp++) {
	    if ((pp->x < paperheight + 20) && (pp->x > paperheight - 20) &&
		(pp->y < paperwidth + 20) && (pp->y > paperwidth - 20)) {
		paperindex = i;
		paperwidth = pp->x;
		paperheight = pp->y;
		orientation = DMORIENT_LANDSCAPE;
		break;
	    }
	}
    }
    gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc");
    
    /* get the dmPaperSize */
    devcapsize = DeviceCapabilities(device, output, DC_PAPERS, NULL, NULL);
    devcapsize *= sizeof(WORD);
    if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
	return FALSE;
    n = DeviceCapabilities(device, output, DC_PAPERS, devcap, NULL);
    if ((paperindex >= 0) && (paperindex < n))
	papersize = ((WORD *) devcap)[paperindex];
    gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc");

    /* get the paper name */
    devcapsize = DeviceCapabilities(device, output, DC_PAPERNAMES, NULL, NULL);
    devcapsize *= 64;
    if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
	return FALSE;
    n = DeviceCapabilities(device, output, DC_PAPERNAMES, devcap, NULL);
    if ((paperindex >= 0) && (paperindex < n))
	strcpy(papername, devcap + paperindex * 64);
    gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc");

    memcpy(pidevmode, podevmode, devmode_size);

    pidevmode->dmFields = 0;
    
    wdev->paper_name[0] = 0;

    if ( (wdev->user_paper)
      && (wdev->user_paper != papersize) ) {
	papersize = wdev->user_paper;
	paperheight = 0;
	paperwidth = 0;
	papername[0] = 0;
    }
    if (wdev->user_orient) {
	orientation = wdev->user_orient;
    }
    
    pidevmode->dmFields &= ~(DM_PAPERSIZE | DM_ORIENTATION | DM_COLOR | DM_PAPERLENGTH | DM_PAPERWIDTH | DM_DUPLEX);
    pidevmode->dmFields |= DM_DEFAULTSOURCE;
    pidevmode->dmDefaultSource = 0;
    
    if (orientation) {
	wdev->user_orient = orientation;
    }
    if (papersize) {
	wdev->user_paper = papersize;
	strcpy (wdev->paper_name, papername);
    }
    
    if (paperheight && paperwidth) {
	pidevmode->dmFields |= (DM_PAPERLENGTH | DM_PAPERWIDTH);
	pidevmode->dmPaperWidth = paperwidth;
	pidevmode->dmPaperLength = paperheight;
        wdev->user_media_size[0] = paperwidth / 254.0 * 72.0;
	wdev->user_media_size[1] = paperheight / 254.0 * 72.0;
    }
    
    if (DeviceCapabilities(device, output, DC_DUPLEX, NULL, NULL)) {
	wdev->Duplex_set = 1;
    }
    
    win_pr2_update_win(wdev, pidevmode);
    
    /* merge the entries */
    DocumentProperties(NULL, hprinter, device, podevmode, pidevmode, DM_IN_BUFFER | DM_OUT_BUFFER);
    ClosePrinter(hprinter);
    
    /* now get a DC */
    wdev->hdcprn = CreateDC(driver, device, NULL, podevmode);
    
    if (wdev->win32_hdevmode == NULL)
	wdev->win32_hdevmode = GlobalAlloc(0, devmode_size);
    
    if (wdev->win32_hdevmode) {
	LPDEVMODE pdevmode = (LPDEVMODE) GlobalLock(wdev->win32_hdevmode);
	if (pdevmode) {
	    memcpy(pdevmode, podevmode, devmode_size);
	    GlobalUnlock(wdev->win32_hdevmode);
	}
    }

    gs_free(wdev->memory, pidevmode, devmode_size, 1, "win_pr2_getdc");
    gs_free(wdev->memory, podevmode, devmode_size, 1, "win_pr2_getdc");

    if (wdev->hdcprn != (HDC) NULL)
	return TRUE;		/* success */

    /* fall back to prompting user */
    return FALSE;
}
Ejemplo n.º 14
0
void setAttributes(const char *printer, const int pdcID, AttributesUnion attributes) {
    HDC pdc = printerDCs[pdcID];
    if (pdc != NULL) {
        DEVMODE *pDevMode = NULL;
        HANDLE hPrinter;
        if (OpenPrinter((LPTSTR)printer, &hPrinter, NULL) != 0) {
            int size = DocumentProperties(NULL, hPrinter, NULL, pDevMode, NULL, 0);
            pDevMode = (DEVMODE *)malloc(size);
            if (DocumentProperties(NULL, hPrinter, NULL, pDevMode, NULL, DM_OUT_BUFFER) == IDOK) {
                pDevMode->dmFields = 0;
                if (attributes.fields.PaperID > 0) {
                    pDevMode->dmPaperSize = (short)attributes.fields.PaperID;
                    pDevMode->dmFields |= DM_PAPERSIZE;
                }

                if (attributes.fields.Copies > 0) {
                    pDevMode->dmCopies = (short)attributes.fields.Copies;
                    pDevMode->dmFields |= DM_COPIES;
                }

                if (attributes.fields.Collate > 0) {
                    if (attributes.fields.Collate == 1) {
                        pDevMode->dmCollate = DMCOLLATE_TRUE;
                    } else {
                        pDevMode->dmCollate = DMCOLLATE_FALSE;
                    }
                    pDevMode->dmFields |= DM_COLLATE;
                }

                if (attributes.fields.Sides > 0) {
                    pDevMode->dmDuplex = (short)attributes.fields.Sides;
                    pDevMode->dmFields |= DM_DUPLEX;
                }

                if (attributes.fields.Chromaticity > 0) {
                    if (attributes.fields.Chromaticity == 1) {
                        pDevMode->dmColor = DMCOLOR_MONOCHROME;
                    } else {
                        pDevMode->dmColor = DMCOLOR_COLOR;
                    }
                    pDevMode->dmFields |= DM_COLOR;
                }

                if (attributes.fields.Orientation > 0) {
                    if (attributes.fields.Orientation == 2) {
                        pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
                    } else {
                        pDevMode->dmOrientation = DMORIENT_PORTRAIT;
                    }
                    pDevMode->dmFields |= DM_ORIENTATION;
                }

                if (attributes.fields.XResolution > 0) {
                    pDevMode->dmPrintQuality = (short)attributes.fields.XResolution;
                    pDevMode->dmFields |= DM_PRINTQUALITY;
                }

                if (attributes.fields.YResolution > 0) {
                    pDevMode->dmYResolution = (short)attributes.fields.YResolution;
                    pDevMode->dmFields |= DM_YRESOLUTION;
                }

                if (pDevMode->dmFields != 0) {
#ifdef PRINTING_DEBUG
                    printf("Setting up print attributes.\n");
#endif /* PRINTING_DEBUG */
                    ResetDC(pdc, pDevMode);
                }
            }
            ClosePrinter(hPrinter);
        }
    }
}
Ejemplo n.º 15
0
JNIEXPORT jint JNICALL Java_org_apache_harmony_x_print_GDIClient_startDocPrinter
(JNIEnv *env, jclass owner, jstring printerName, jintArray printAttributes, jstring jobName, jstring destination) {
    const char *printer = env->GetStringUTFChars(printerName, 0);
    const char *jn = env->GetStringUTFChars(jobName, 0);
    char *jname = new char[strlen(jn) + 1];
    char *fname = NULL;
    strcpy(jname, jn);
    if (destination != NULL) {
        const char *fn = env->GetStringUTFChars(destination, 0);
        fname = new char[strlen(fn) + 1];
        strcpy(fname, fn);
    }
    AttributesUnion attributes;
    jboolean isCopy = JNI_FALSE;
    int *numbers = (int *)env->GetIntArrayElements(printAttributes, &isCopy);
    for (int i = 0; i < ATTRIBUTE_UNION_SIZE; i++) {
        attributes.numbers[i] = numbers[i];
    }

    jint res = 0;
    HANDLE hPrinter = NULL;

    if (OpenPrinter((LPTSTR)printer, &hPrinter, NULL) != 0) {
        DOC_INFO_1 dinfo;
        dinfo.pDocName = jname;
        dinfo.pDatatype = "RAW";
        dinfo.pOutputFile = fname;

        DEVMODE *pDevMode = NULL;
        int size = DocumentProperties(NULL, hPrinter, NULL, pDevMode, NULL, 0);
        pDevMode = (DEVMODE *)malloc(size);
//        if (DocumentProperties(NULL, hPrinter, NULL, pDevMode, NULL, DM_PROMPT) == IDOK) {
        if (DocumentProperties(NULL, hPrinter, NULL, pDevMode, NULL, DM_OUT_BUFFER) == IDOK) {

#ifdef PRINTING_DEBUG
            printf("DEVMODE received successfuly!\n");
#endif /* PRINTING_DEBUG */

            if (attributes.fields.Copies > 0) {
                pDevMode->dmCopies = (short)attributes.fields.Copies;
                pDevMode->dmFields |= DM_COPIES;
            }
            if (attributes.fields.Sides > 0) {
                pDevMode->dmDuplex = (short)attributes.fields.Sides;
                pDevMode->dmFields |= DM_DUPLEX;
            }
            if (attributes.fields.PaperID > 0) {
                pDevMode->dmPaperSize = (short)attributes.fields.PaperID;
                pDevMode->dmFields |= DM_PAPERSIZE;
            }
            if (DocumentProperties(NULL, hPrinter, NULL,
                                   pDevMode, pDevMode,
                                   DM_IN_BUFFER | DM_OUT_BUFFER) == IDOK) {
            }
        } else {

#ifdef PRINTING_DEBUG
            printf("Can't get initial DEVMODE.\n");
#endif /* PRINTING_DEBUG */

        }

        if (StartDocPrinter(hPrinter, 1, (LPBYTE)&dinfo) != 0) {
            res = *((int *)&hPrinter);
        }
    }

#ifdef PRINTING_DEBUG
    if (res == 0) {
        DWORD error = GetLastError();
        printf("Error occurred while starting: %d.\n", error);
    }
    if (res != 0) {
        file = fopen("C:\\from_Native.ps", "wb+");
    }
#endif /* PRINTING_DEBUG */

    return res;
}