|
|
//
// prnwrap.cpp
//
// Unicode printer function wrappers
//
// Copyright(C) Microsoft Corporation 2000
//
// Nadim Abdo (nadima)
//
#include "stdafx.h"
#include "uniwrap.h"
#include "cstrinout.h"
//Just include wrap function prototypes
//no wrappers (it would be silly to wrap wrappers)
#define DONOT_REPLACE_WITH_WRAPPERS
#include "uwrap.h"
//
// Printer wrappers.
//
BOOL WINAPI EnumPrintersWrapW( IN DWORD Flags, IN LPWSTR Name, IN DWORD Level, OUT LPBYTE pPrinterEnum, IN DWORD cbBuf, OUT LPDWORD pcbNeeded, OUT LPDWORD pcReturned) { BOOL fRet;
if (g_bRunningOnNT) { return EnumPrintersW(Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned); } else { ASSERT(Level == 2); //only supported level
if(2 == Level) { CStrIn strName(Name);
LPBYTE pPrinterEnumA = NULL; if(pPrinterEnum && cbBuf) { pPrinterEnumA = (LPBYTE)LocalAlloc( LPTR, cbBuf ); if(!pPrinterEnumA) { return FALSE; } } fRet = EnumPrintersA(Flags, strName, Level, pPrinterEnumA, cbBuf, pcbNeeded, pcReturned);
if(fRet || (!fRet && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { if(!pPrinterEnumA) { //
// This is a size query double the requested space
// so the caller allocates a buffer with enough space
// for UNICODE converted sub strings.
//
*pcbNeeded = *pcbNeeded * 2; return TRUE; } else { //Convert the ANSI structures in the temporary
//output buffer to UNICODE structures in the caller's
//buffer.
memset( pPrinterEnum, 0, cbBuf ); PBYTE pStartStrings = pPrinterEnum + (*pcReturned * sizeof(PRINTER_INFO_2W)); PBYTE pEndUserBuf = pPrinterEnum + cbBuf; LPWSTR szCurOutputString = (LPWSTR)pStartStrings;
UINT i =0; //Strings go after the array of structures
//compute the string start address
for(i = 0 ; i < *pcReturned; i++) { PPRINTER_INFO_2A ppi2a = &(((PRINTER_INFO_2A *)pPrinterEnumA)[i]); PPRINTER_INFO_2W ppi2w = &(((PRINTER_INFO_2W *)pPrinterEnum)[i]); //
// First copy over all the static fields
//
ppi2w->Attributes = ppi2a->Attributes; ppi2w->Priority = ppi2a->Priority; ppi2w->DefaultPriority = ppi2a->DefaultPriority; ppi2w->StartTime = ppi2a->StartTime; ppi2w->UntilTime = ppi2a->UntilTime; ppi2w->Status = ppi2a->Status; ppi2w->cJobs = ppi2a->cJobs; ppi2w->AveragePPM = ppi2a->AveragePPM; //Win9x has no security descriptors
ppi2w->pSecurityDescriptor = NULL; //WARN: RDPDR currently doesn't use DEVMODE
//so we don't bother converting it (it's huge)
ppi2w->pDevMode = NULL;
//
// Now convert the strings
// for perf reasons we only handle the
// strings RDPDR currently uses. The others are set
// to null when we memset above.
//
int cchLen = lstrlenA( ppi2a->pPortName ); SHAnsiToUnicode( ppi2a->pPortName, szCurOutputString, cchLen + 1 ); ppi2w->pPortName = szCurOutputString; szCurOutputString += (cchLen + 2);
cchLen = lstrlenA( ppi2a->pPrinterName ); SHAnsiToUnicode( ppi2a->pPrinterName, szCurOutputString, cchLen + 1 ); ppi2w->pPrinterName = szCurOutputString; szCurOutputString += (cchLen + 2);
cchLen = lstrlenA( ppi2a->pDriverName ); SHAnsiToUnicode( ppi2a->pDriverName, szCurOutputString, cchLen + 1 ); ppi2w->pDriverName = szCurOutputString; szCurOutputString += (cchLen + 2); }
LocalFree(pPrinterEnumA); pPrinterEnumA = NULL;
return TRUE; } } else { LocalFree(pPrinterEnumA); return FALSE; } } else { //We only support level2 for now. Add more if needed.
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } } }
BOOL WINAPI OpenPrinterWrapW( IN LPWSTR pPrinterName, OUT LPHANDLE phPrinter, IN LPPRINTER_DEFAULTSW pDefault) { //We don't support converting the pDev because RDPDR doesn't use
//it. If you add code that needs it modify this wrapper.
if(pDefault) { ASSERT(pDefault->pDevMode == NULL); } if(g_bRunningOnNT) { return OpenPrinterW( pPrinterName, phPrinter, pDefault); } else { PRINTER_DEFAULTSA pdefa; CStrIn strPrinterName(pPrinterName); if(pDefault) { CStrIn strInDataType(pDefault->pDatatype); pdefa.DesiredAccess = pDefault->DesiredAccess; pdefa.pDevMode = NULL; //UNSUPPORTED conversion see above
pdefa.pDatatype = strInDataType; return OpenPrinterA( strPrinterName, phPrinter, &pdefa ); } else { return OpenPrinterA( strPrinterName, phPrinter, NULL ); } } }
DWORD WINAPI StartDocPrinterWrapW( IN HANDLE hPrinter, IN DWORD Level, IN LPBYTE pDocInfo) { if(g_bRunningOnNT) { return StartDocPrinterW( hPrinter, Level, pDocInfo ); } else { ASSERT(Level == 1); //we only support this level
DOC_INFO_1A docinf1a; CStrIn strDocName( ((PDOC_INFO_1)pDocInfo)->pDocName ); CStrIn strOutputFile( ((PDOC_INFO_1)pDocInfo)->pOutputFile ); CStrIn strDataType( ((PDOC_INFO_1)pDocInfo)->pDatatype );
docinf1a.pDocName = strDocName; docinf1a.pOutputFile = strOutputFile; docinf1a.pDatatype = strDataType; return StartDocPrinterA( hPrinter, Level, (PBYTE)&docinf1a ); } }
DWORD WINAPI GetPrinterDataWrapW( IN HANDLE hPrinter, IN LPWSTR pValueName, OUT LPDWORD pType, OUT LPBYTE pData, IN DWORD nSize, OUT LPDWORD pcbNeeded) { if(g_bRunningOnNT) { return GetPrinterDataW( hPrinter, pValueName, pType, pData, nSize, pcbNeeded ); } else { CStrIn strValueName(pValueName); DWORD ret = 0; if(!pData) { //This is a size query
ret = GetPrinterDataA( hPrinter, strValueName, pType, NULL, nSize, pcbNeeded ); *pcbNeeded = *pcbNeeded * 2; //double for UNICODE
return ret; } else { CStrOut strDataOut( (LPWSTR)pData, nSize/sizeof(TCHAR)); //ASSUMPTION is that we get back string data
ret = GetPrinterDataA( hPrinter, strValueName, pType, (LPBYTE)((LPSTR)strDataOut), nSize, pcbNeeded ); return ret; } } }
BOOL WINAPI GetPrinterDriverWrapW( HANDLE hPrinter, // printer object
LPTSTR pEnvironment, // environment name. NULL is supported.
DWORD Level, // information level
LPBYTE pDriverInfo, // driver data buffer
DWORD cbBuf, // size of buffer
LPDWORD pcbNeeded // bytes received or required
) { BOOL ret;
// Level 1 is supported at this time.
ASSERT(Level == 1);
// pEnvironment better be NULL.
ASSERT(pEnvironment == NULL);
if (g_bRunningOnNT) {
return GetPrinterDriverW( hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded );
} else {
if (!pDriverInfo) {
//
// This is a size query
//
ret = GetPrinterDriverA( hPrinter, NULL, Level, NULL, cbBuf, pcbNeeded ); *pcbNeeded = *pcbNeeded * 2; //double for UNICODE
return ret;
} else {
PDRIVER_INFO_1 srcP1 = (PDRIVER_INFO_1)LocalAlloc(LPTR, cbBuf); if (srcP1 == NULL) { return FALSE; } else { ret = GetPrinterDriverA( hPrinter, NULL, Level, (LPBYTE)srcP1, cbBuf, pcbNeeded ); if (ret) { int cchLen = lstrlenA((LPCSTR)srcP1->pName);
PDRIVER_INFO_1 dstP1 = (PDRIVER_INFO_1)pDriverInfo; dstP1->pName = (LPWSTR)(dstP1 + 1); SHAnsiToUnicode((LPCSTR)srcP1->pName, dstP1->pName, cchLen + 1); } LocalFree(srcP1); return ret; } } } }
|