|
|
/*++
Copyright (c) 1996-1997 Microsoft Corporation
Module Name:
regdata.c
Abstract:
Functions for dealing with registry data
[Environment:]
Windows NT printer drivers
Revision History:
02/04/97 -davidx- Use REG_MULTI_SZ type where appropriate.
01/21/97 -davidx- Add functions to manipulate MultiSZ strings.
09/25/96 -davidx- Convert to Hungarian notation.
08/18/96 -davidx- Implement GetPrinterProperties.
08/13/96 -davidx- Created it.
--*/
#include "lib.h"
BOOL BGetPrinterDataDWord( IN HANDLE hPrinter, IN LPCTSTR ptstrRegKey, OUT PDWORD pdwValue )
/*++
Routine Description:
Get a DWORD value from the registry under PrinerDriverData key
Arguments:
hPrinter - Specifies the printer object ptstrRegKey - Specifies the name of registry value pdwValue - Returns the requested DWORD value in the registry
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ DWORD dwType, dwByteCount, dwStatus;
dwStatus = GetPrinterData(hPrinter, (PTSTR) ptstrRegKey, &dwType, (PBYTE) pdwValue, sizeof(DWORD), &dwByteCount);
if (dwStatus != ERROR_SUCCESS) VERBOSE(("GetPrinterData failed: %d\n", dwStatus));
return (dwStatus == ERROR_SUCCESS); }
PVOID PvGetPrinterDataBinary( IN HANDLE hPrinter, IN LPCTSTR ptstrSizeKey, IN LPCTSTR ptstrDataKey, OUT PDWORD pdwSize )
/*++
Routine Description:
Get binary data from the registry under PrinterDriverData key
Arguments:
hPrinter - Handle to the printer object ptstrSizeKey - Name of the registry value which contains the binary data size ptstrDataKey - Name of the registry value which contains the binary data itself pdwSize - Points to a variable for receiving the binary data size
Return Value:
Pointer to the binary printer data read from the registry NULL if there is an error
--*/
{ DWORD dwType, dwSize, dwByteCount; PVOID pvData = NULL;
if (GetPrinterData(hPrinter, (PTSTR) ptstrSizeKey, &dwType, (PBYTE) &dwSize, sizeof(dwSize), &dwByteCount) == ERROR_SUCCESS && dwSize > 0 && (pvData = MemAlloc(dwSize)) && GetPrinterData(hPrinter, (PTSTR) ptstrDataKey, &dwType, pvData, dwSize, &dwByteCount) == ERROR_SUCCESS && dwSize == dwByteCount) { if (pdwSize) *pdwSize = dwSize;
return pvData; }
VERBOSE(("GetPrinterData failed: %ws/%ws\n", ptstrSizeKey, ptstrDataKey)); MemFree(pvData); return NULL; }
PTSTR PtstrGetPrinterDataString( IN HANDLE hPrinter, IN LPCTSTR ptstrRegKey, OUT LPDWORD pdwSize )
/*++
Routine Description:
Get a string value from PrinerDriverData registry key
Arguments:
hPrinter - Specifies the printer object ptstrRegKey - Specifies the name of registry value pdwSize - Specifies the size
Return Value:
Pointer to the string value read from the registry NULL if there is an error
--*/
{ DWORD dwType, dwSize, dwStatus; PVOID pvData = NULL;
dwStatus = GetPrinterData(hPrinter, (PTSTR) ptstrRegKey, &dwType, NULL, 0, &dwSize);
if ((dwStatus == ERROR_MORE_DATA || dwStatus == ERROR_SUCCESS) && (dwSize > 0) && (dwType == REG_SZ || dwType == REG_MULTI_SZ) && (pvData = MemAlloc(dwSize)) != NULL && (dwStatus = GetPrinterData(hPrinter, (PTSTR) ptstrRegKey, &dwType, pvData, dwSize, &dwSize)) == ERROR_SUCCESS) { if (pdwSize) *pdwSize = dwSize;
return pvData; }
VERBOSE(("GetPrinterData '%ws' failed: %d\n", ptstrRegKey, dwStatus)); MemFree(pvData); return NULL; }
PTSTR PtstrGetPrinterDataMultiSZPair( IN HANDLE hPrinter, IN LPCTSTR ptstrRegKey, OUT PDWORD pdwSize )
/*++
Routine Description:
Get a MULTI_SZ value from PrinerDriverData registry key
Arguments:
hPrinter - Specifies the printer object ptstrRegKey - Specifies the name of registry value pdwSize - Return the size of MULTI_SZ value in bytes
Return Value:
Pointer to the MULTI_SZ value read from the registry NULL if there is an error
--*/
{ DWORD dwType, dwSize, dwStatus; PVOID pvData = NULL;
dwStatus = GetPrinterData(hPrinter, (PTSTR) ptstrRegKey, &dwType, NULL, 0, &dwSize);
if ((dwStatus == ERROR_MORE_DATA || dwStatus == ERROR_SUCCESS) && (dwSize > 0) && (pvData = MemAlloc(dwSize)) != NULL && (dwStatus = GetPrinterData(hPrinter, (PTSTR) ptstrRegKey, &dwType, pvData, dwSize, &dwSize)) == ERROR_SUCCESS && BVerifyMultiSZPair(pvData, dwSize)) { if (pdwSize) *pdwSize = dwSize;
return pvData; }
VERBOSE(("GetPrinterData '%ws' failed: %d\n", ptstrRegKey, dwStatus)); MemFree(pvData); return NULL; }
BOOL BGetDeviceHalftoneSetup( HANDLE hPrinter, DEVHTINFO *pDevHTInfo )
/*++
Routine Description:
Retrieve device halftone setup information from registry
Arguments:
hprinter - Handle to the printer pDevHTInfo - Pointer to a DEVHTINFO buffer
Return Value:
TRUE if successful, FALSE otherwise
--*/
{ DWORD dwType, dwNeeded;
return GetPrinterData(hPrinter, REGVAL_CURRENT_DEVHTINFO, &dwType, (PBYTE) pDevHTInfo, sizeof(DEVHTINFO), &dwNeeded) == ERROR_SUCCESS && dwNeeded == sizeof(DEVHTINFO); }
#ifndef KERNEL_MODE
BOOL BSavePrinterProperties( IN HANDLE hPrinter, IN PRAWBINARYDATA pRawData, IN PPRINTERDATA pPrinterData, IN DWORD dwSize ) /*++
Routine Description:
Save Printer Properites to registry
Arguments:
hPrinter - Specifies a handle to the current printer pRawData - Points to raw binary printer description data pPrinterData - Points to PRINTERDATA dwSize - Specifies the size of PRINTERDATA
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ BOOL bResult = FALSE; DWORD dwKeywordSize, dwFeatureCount = 0; PSTR pstrKeyword; POPTSELECT pCombineOptions; PUIINFO pUIInfo; PARSERINFO ParserInfo;
ParserInfo.pRawData = NULL; ParserInfo.pInfoHeader = NULL;
if (((pCombineOptions = MemAllocZ(MAX_COMBINED_OPTIONS * sizeof(OPTSELECT))) == NULL) || ((pUIInfo = PGetUIInfo(hPrinter, pRawData, pCombineOptions, pPrinterData->aOptions, &ParserInfo, &dwFeatureCount)) == NULL)) { //
// We have to fail the function if out of memory, or PGetUIInfo returns NULL (in which
// case pCombinOptions won't have valid option indices).
//
// Make sure free any allocated memory.
//
ERR(("pCombinOptions or pUIInfo is NULL\n"));
if (pCombineOptions) MemFree(pCombineOptions);
return FALSE; }
pstrKeyword = PstrConvertIndexToKeyword(hPrinter, pPrinterData->aOptions, &dwKeywordSize, pUIInfo, pCombineOptions, dwFeatureCount);
VUpdatePrivatePrinterData(hPrinter, pPrinterData, MODE_WRITE, pUIInfo, pCombineOptions );
if (pstrKeyword) { bResult = BSetPrinterDataBinary(hPrinter, REGVAL_PRINTER_DATA_SIZE, REGVAL_PRINTER_DATA, pPrinterData, dwSize) && BSetPrinterDataBinary(hPrinter, REGVAL_KEYWORD_SIZE, REGVAL_KEYWORD_NAME, pstrKeyword, dwKeywordSize); }
if (pstrKeyword) MemFree(pstrKeyword);
VFreeParserInfo(&ParserInfo);
if (pCombineOptions) MemFree(pCombineOptions);
return bResult; }
BOOL BSetPrinterDataDWord( IN HANDLE hPrinter, IN LPCTSTR ptstrRegKey, IN DWORD dwValue )
/*++
Routine Description:
Save a DWORD value to the registry under PrinerDriverData key
Arguments:
hPrinter - Specifies the printer object ptstrRegKey - Specifies the name of registry value dwValue - Specifies the value to be saved
Return Value:
TRUE if successful, FALSE otherwise
--*/
{ DWORD dwStatus;
dwStatus = SetPrinterData(hPrinter, (PTSTR) ptstrRegKey, REG_DWORD, (PBYTE) &dwValue, sizeof(dwValue));
if (dwStatus != ERROR_SUCCESS) ERR(("Couldn't save printer data '%ws': %d\n", ptstrRegKey, dwStatus));
return (dwStatus == ERROR_SUCCESS); }
BOOL BSetPrinterDataBinary( IN HANDLE hPrinter, IN LPCTSTR ptstrSizeKey, IN LPCTSTR ptstrDataKey, IN PVOID pvData, IN DWORD dwSize )
/*++
Routine Description:
Save binary data to the registry under PrinterDriverData key
Arguments:
hPrinter - Handle to the printer object ptstrSizeKey - Name of the registry value which contains the binary data size ptstrDataKey - Name of the registry value which contains the binary data itself pvData - Points to the binary data to be saved dwSize - Specifies the binary data size in bytes
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ if (SetPrinterData(hPrinter, (PTSTR) ptstrSizeKey, REG_DWORD, (PBYTE) &dwSize, sizeof(dwSize)) != ERROR_SUCCESS || SetPrinterData(hPrinter, (PTSTR) ptstrDataKey, REG_BINARY, pvData, dwSize) != ERROR_SUCCESS) { ERR(("Couldn't save printer data '%ws'/'%ws'\n", ptstrSizeKey, ptstrDataKey)); return FALSE; }
return TRUE; }
BOOL BSetPrinterDataString( IN HANDLE hPrinter, IN LPCTSTR ptstrRegKey, IN LPCTSTR ptstrValue, IN DWORD dwType )
/*++
Routine Description:
Save a string value under PrinerDriverData registry key
Arguments:
hPrinter - Specifies the printer object ptstrRegKey - Specifies the name of registry value ptstrValue - Points to string value to be saved dwType - Specifies string type: REG_SZ or REG_MULTI_SZ
Return Value:
TRUE if successful, FALSE if there is an error
Note:
If ptstrValue parameter is NULL, the specified registry value is deleted.
--*/
{ DWORD dwStatus, dwSize;
if (ptstrValue != NULL) { if (dwType == REG_SZ) dwSize = SIZE_OF_STRING(ptstrValue); else { LPCTSTR p = ptstrValue;
while (*p) p += _tcslen(p) + 1;
dwSize = ((DWORD)(p - ptstrValue) + 1) * sizeof(TCHAR); }
dwStatus = SetPrinterData(hPrinter, (PTSTR) ptstrRegKey, dwType, (PBYTE) ptstrValue, dwSize);
if (dwStatus != ERROR_SUCCESS) ERR(("Couldn't save printer data '%ws': %d\n", ptstrRegKey, dwStatus)); } else { dwStatus = DeletePrinterData(hPrinter, (PTSTR) ptstrRegKey);
if (dwStatus == ERROR_FILE_NOT_FOUND) dwStatus = ERROR_SUCCESS;
if (dwStatus != ERROR_SUCCESS) ERR(("Couldn't delete printer data '%ws': %d\n", ptstrRegKey, dwStatus)); }
return (dwStatus == ERROR_SUCCESS); }
BOOL BSetPrinterDataMultiSZPair( IN HANDLE hPrinter, IN LPCTSTR ptstrRegKey, IN LPCTSTR ptstrValue, IN DWORD dwSize )
/*++
Routine Description:
Save a MULTI_SZ value under PrinerDriverData registry key
Arguments:
hPrinter - Specifies the printer object ptstrRegKey - Specifies the name of registry value ptstrValue - Points to MULTI_SZ value to be saved dwSize - Specifies the size of the MULTI_SZ value in bytes
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ DWORD dwStatus;
ASSERT(BVerifyMultiSZPair(ptstrValue, dwSize));
dwStatus = SetPrinterData(hPrinter, (PTSTR) ptstrRegKey, REG_MULTI_SZ, (PBYTE) ptstrValue, dwSize);
if (dwStatus != ERROR_SUCCESS) ERR(("Couldn't save printer data '%ws': %d\n", ptstrRegKey, dwStatus));
return (dwStatus == ERROR_SUCCESS); }
BOOL BSaveDeviceHalftoneSetup( HANDLE hPrinter, DEVHTINFO *pDevHTInfo )
/*++
Routine Description:
Save device halftone setup information to registry
Arguments:
hPrinter - Handle to the printer pDevHTInfo - Pointer to device halftone setup information
Return Value:
TRUE if successful, FALSE otherwise
--*/
{ return SetPrinterData(hPrinter, REGVAL_CURRENT_DEVHTINFO, REG_BINARY, (PBYTE) pDevHTInfo, sizeof(DEVHTINFO)) == ERROR_SUCCESS; }
BOOL BSaveTTSubstTable( IN HANDLE hPrinter, IN TTSUBST_TABLE pTTSubstTable, IN DWORD dwSize )
/*++
Routine Description:
Save TrueType font substitution table in registry
Arguments:
hPrinter - Handle to the current printer pTTSubstTable - Pointer to font substitution table to be saved dwSize - Size of font substitution table, in bytes
Return Value:
TRUE if successful, FALSE if there is an error
Note:
Previous version pscript driver used to save font substitution table as two separate keys: one for size and the other for actual data. We only need the data key now. But we should save the size as well to be compatible with old drivers.
--*/
{ return BSetPrinterDataMultiSZPair(hPrinter, REGVAL_FONT_SUBST_TABLE, pTTSubstTable, dwSize) && BSetPrinterDataDWord(hPrinter, REGVAL_FONT_SUBST_SIZE_PS40, dwSize); }
BOOL BSaveFormTrayTable( IN HANDLE hPrinter, IN FORM_TRAY_TABLE pFormTrayTable, IN DWORD dwSize )
/*++
Routine Description:
Save form-to-tray assignment table in registry
Arguments:
hPrinter - Handle to the current printer pFormTrayTable - Pointer to the form-to-tray assignment table to be saved dwSize - Size of the form-to-tray assignment table, in bytes
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ //
// Save the table in current format and then call driver-specific
// functions to save the information in NT 4.0 format.
//
return (BSaveAsOldVersionFormTrayTable(hPrinter, pFormTrayTable, dwSize)); }
#endif // !KERNEL_MODE
FORM_TRAY_TABLE PGetFormTrayTable( IN HANDLE hPrinter, OUT PDWORD pdwSize )
/*++
Routine Description:
Retrieve form-to-tray assignment table from registry
Arguments:
hPrinter - Handle to the printer object pdwSize - Returns the form-to-tray assignment table size
Return Value:
Pointer to form-to-tray assignment table read from the registry NULL if there is an error
--*/
{ FORM_TRAY_TABLE pFormTrayTable; DWORD dwSize;
//
// Call either PSGetFormTrayTable or UniGetFormTrayTable
//
pFormTrayTable = PGetAndConvertOldVersionFormTrayTable(hPrinter, &dwSize);
if (pFormTrayTable != NULL && pdwSize != NULL) *pdwSize = dwSize;
return pFormTrayTable; }
BOOL BSearchFormTrayTable( IN FORM_TRAY_TABLE pFormTrayTable, IN PTSTR ptstrTrayName, IN PTSTR ptstrFormName, IN OUT PFINDFORMTRAY pFindData )
/*++
Routine Description:
Find the specified tray-form pair in a form-to-tray assignment table
Arguments:
pFormTrayTable - Specifies a form-to-tray assignment table to be searched ptstrTrayName - Specifies the interested tray name ptstrFormName - Specifies the interested form name pFindData - Data structure used to keep information from one call to the next
Return Value:
TRUE if the specified tray-form pair is found in the table FALSE otherwise
NOTE:
If either ptstrTrayName or ptstrFormName is NULL, they'll act as wildcard and match any tray name or form name.
The caller must call ResetFindFormTray(pFormTrayTable, pFindData) before calling this function for the very first time.
--*/
{ PTSTR ptstrNextEntry; BOOL bFound = FALSE;
//
// Make sure pFindData is properly initialized
//
ASSERT(pFindData->pvSignature == pFindData); ptstrNextEntry = pFindData->ptstrNextEntry;
while (*ptstrNextEntry) { PTSTR ptstrTrayField, ptstrFormField, ptstrPrinterFormField;
//
// Extract information from the current table entry
//
ptstrTrayField = ptstrNextEntry; ptstrNextEntry += _tcslen(ptstrNextEntry) + 1;
ptstrFormField = ptstrNextEntry; ptstrNextEntry += _tcslen(ptstrNextEntry) + 1;
//
// Check if we found a matching entry
//
if ((ptstrTrayName == NULL || _tcscmp(ptstrTrayName, ptstrTrayField) == EQUAL_STRING) && (ptstrFormName == NULL || _tcscmp(ptstrFormName, ptstrFormField) == EQUAL_STRING)) { pFindData->ptstrTrayName = ptstrTrayField; pFindData->ptstrFormName = ptstrFormField;
bFound = TRUE; break; } }
pFindData->ptstrNextEntry = ptstrNextEntry; return bFound; }
BOOL BGetPrinterProperties( IN HANDLE hPrinter, IN PRAWBINARYDATA pRawData, OUT PPRINTERDATA pPrinterData )
/*++
Routine Description:
Return the current printer-sticky property data
Arguments:
hPrinter - Specifies a handle to the current printer pRawData - Points to raw binary printer description data pPrinterData - Buffer for storing the retrieved printer property info
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ PVOID pvRegData; PSTR pstrKeyword; DWORD dwRegDataSize, dwKeywordSize, dwFeatureCount, dwVersion; POPTSELECT pCombineOptions; PUIINFO pUIInfo; PARSERINFO ParserInfo;
//
// Allocate a buffer to hold printer property data and
// read the property property data from the registry.
//
if (pvRegData = PvGetPrinterDataBinary(hPrinter, REGVAL_PRINTER_DATA_SIZE, REGVAL_PRINTER_DATA, &dwRegDataSize)) { //
// Convert the printer property data from the registry to current version
//
ZeroMemory(pPrinterData, sizeof(PRINTERDATA)); CopyMemory(pPrinterData, pvRegData, min(sizeof(PRINTERDATA), dwRegDataSize));
pPrinterData->wDriverVersion = gwDriverVersion; pPrinterData->wSize = sizeof(PRINTERDATA);
if (pPrinterData->wReserved2 != 0 || pPrinterData->dwChecksum32 != pRawData->dwChecksum32) { InitDefaultOptions(pRawData, pPrinterData->aOptions, MAX_PRINTER_OPTIONS, MODE_PRINTER_STICKY);
pPrinterData->wReserved2 = 0; pPrinterData->dwChecksum32 = pRawData->dwChecksum32; pPrinterData->dwOptions = pRawData->dwPrinterFeatures;
pPrinterData->wProtocol = PROTOCOL_ASCII; pPrinterData->dwFlags |= PFLAGS_CTRLD_AFTER; pPrinterData->wMinoutlinePPEM = DEFAULT_MINOUTLINEPPEM; pPrinterData->wMaxbitmapPPEM = DEFAULT_MAXBITMAPPPEM; }
//
// Call driver-specific conversion to give them a chance to touch up
//
(VOID) BConvertPrinterPropertiesData(hPrinter, pRawData, pPrinterData, pvRegData, dwRegDataSize); } else { if (!BGetDefaultPrinterProperties(hPrinter, pRawData, pPrinterData)) return FALSE; }
//
// At this point we should get a valid PrinterData or a
// default PrinterData. Propagate Feature.Options to
// PrinterData options array if possible
//
ParserInfo.pRawData = NULL; ParserInfo.pInfoHeader = NULL;
if (((pCombineOptions = MemAllocZ(MAX_COMBINED_OPTIONS * sizeof(OPTSELECT))) == NULL) || ((pUIInfo = PGetUIInfo(hPrinter, pRawData, pCombineOptions, pPrinterData->aOptions, &ParserInfo, &dwFeatureCount)) == NULL)) { //
// We have to fail the function if out of memory, or PGetUIInfo returns NULL (in which
// case pCombinOptions won't have valid option indices).
//
// Make sure free any allocated memory.
//
ERR(("pCombinOptions or pUIInfo is NULL\n"));
if (pvRegData) MemFree(pvRegData);
if (pCombineOptions) MemFree(pCombineOptions);
return FALSE; }
//
// set the ADD_EURO flag if it has not intentionally been set to FALSE
//
if (pUIInfo) { if (!(pPrinterData->dwFlags & PFLAGS_EURO_SET)) { if (pUIInfo->dwFlags & FLAG_ADD_EURO) pPrinterData->dwFlags |= PFLAGS_ADD_EURO; pPrinterData->dwFlags |= PFLAGS_EURO_SET; } }
VUpdatePrivatePrinterData(hPrinter, pPrinterData, MODE_READ, pUIInfo, pCombineOptions);
if ((pstrKeyword = PvGetPrinterDataBinary(hPrinter, REGVAL_KEYWORD_SIZE, REGVAL_KEYWORD_NAME, &dwKeywordSize)) && dwKeywordSize) {
//
// Skip merging in the keyword feature.option if the driver version
// is less than version 3. This is so point and print to OS version less
// than NT5 will work. REGVAL_PRINTER_INITED exists only for version 3
// or greater driver
//
if (!BGetPrinterDataDWord(hPrinter, REGVAL_PRINTER_INITED, &dwVersion)) *pstrKeyword = NUL;
//
// Convert feature.option keyword names to option indices
//
VConvertKeywordToIndex(hPrinter, pstrKeyword, dwKeywordSize, pPrinterData->aOptions, pRawData, pUIInfo, pCombineOptions, dwFeatureCount);
MemFree(pstrKeyword); } else { SeparateOptionArray(pRawData, pCombineOptions, pPrinterData->aOptions, MAX_PRINTER_OPTIONS, MODE_PRINTER_STICKY);
}
VFreeParserInfo(&ParserInfo);
if (pCombineOptions) MemFree(pCombineOptions);
if (pvRegData) MemFree(pvRegData);
return TRUE; }
BOOL BGetDefaultPrinterProperties( IN HANDLE hPrinter, IN PRAWBINARYDATA pRawData, OUT PPRINTERDATA pPrinterData )
/*++
Routine Description:
Return the default printer-sticky property data
Arguments:
hPrinter - Specifies a handle to the current printer pRawData - Points to raw binary printer description data pPrinterData - Buffer for storing the default printer property info
Return Value:
TRUE if successful, FALSE if there is an error
--*/
{ PINFOHEADER pInfoHdr; PUIINFO pUIInfo;
//
// Allocate memory to hold the default printer property data
//
ASSERT(pPrinterData && pRawData); ZeroMemory(pPrinterData, sizeof(PRINTERDATA));
pPrinterData->wDriverVersion = gwDriverVersion; pPrinterData->wSize = sizeof(PRINTERDATA);
//
// Get default printer-sticky option values
//
InitDefaultOptions(pRawData, pPrinterData->aOptions, MAX_PRINTER_OPTIONS, MODE_PRINTER_STICKY);
pPrinterData->dwChecksum32 = pRawData->dwChecksum32; pPrinterData->dwOptions = pRawData->dwPrinterFeatures;
//
// Ask the parser for a new binary data instance and
// use it to initialize the remaining fields of PRINTERDATA.
//
if (pInfoHdr = InitBinaryData(pRawData, NULL, NULL)) { pUIInfo = GET_UIINFO_FROM_INFOHEADER(pInfoHdr);
ASSERT(pUIInfo != NULL);
pPrinterData->dwFreeMem = pUIInfo->dwFreeMem; pPrinterData->dwWaitTimeout = pUIInfo->dwWaitTimeout; pPrinterData->dwJobTimeout = pUIInfo->dwJobTimeout;
if (pUIInfo->dwFlags & FLAG_TRUE_GRAY) // transfer the default into printer-sticky data
pPrinterData->dwFlags |= (PFLAGS_TRUE_GRAY_TEXT | PFLAGS_TRUE_GRAY_GRAPH);
FreeBinaryData(pInfoHdr); }
//
// Initialize any remaining fields
//
pPrinterData->wProtocol = PROTOCOL_ASCII; pPrinterData->dwFlags |= PFLAGS_CTRLD_AFTER; pPrinterData->wMinoutlinePPEM = DEFAULT_MINOUTLINEPPEM; pPrinterData->wMaxbitmapPPEM = DEFAULT_MAXBITMAPPPEM;
#ifndef KERNEL_MODE
//
// Determine whether the system is running in a metric country.
//
if (IsMetricCountry()) pPrinterData->dwFlags |= PFLAGS_METRIC;
//
// Ignore device fonts on non-1252 code page systems.
//
// NOTE: Adobe wants this to be turned off for NT4 driver.
// For NT5 driver, we need to investigate and make sure
// this doesn't break anything before turning this off.
// Specifically, watch out for NT4-client to NT5 server
// connection case.
//
// Fix MS bug #121883, Adobe bug #235417
//
#if 0
#ifndef WINNT_40
if (GetACP() != 1252) pPrinterData->dwFlags |= PFLAGS_IGNORE_DEVFONT;
#endif // !WINNT_40
#endif
#endif // !KERNEL_MODE
return TRUE; }
LPCTSTR PtstrSearchDependentFileWithExtension( LPCTSTR ptstrDependentFiles, LPCTSTR ptstrExtension )
/*++
Routine Description:
Search the list of dependent files (in REG_MULTI_SZ format) for a file with the specified extension
Arguments:
ptstrDependentFiles - Points to the list of dependent files ptstrExtension - Specifies the interested filename extension
Return Value:
Points to the first filename in the dependent file list with the specified extension
--*/
{ if (ptstrDependentFiles == NULL) { WARNING(("Driver dependent file list is NULL\n")); return NULL; }
while (*ptstrDependentFiles != NUL) { LPCTSTR ptstr, ptstrNext;
//
// Go the end of current string
//
ptstr = ptstrDependentFiles + _tcslen(ptstrDependentFiles); ptstrNext = ptstr + 1;
//
// Search backward for '.' character
//
while (--ptstr >= ptstrDependentFiles) { if (*ptstr == TEXT('.')) { //
// If the extension matches, return a pointer to
// the current string
//
if (_tcsicmp(ptstr, ptstrExtension) == EQUAL_STRING) return ptstrDependentFiles;
break; } }
ptstrDependentFiles = ptstrNext; }
return NULL; }
PTSTR PtstrGetDriverDirectory( LPCTSTR ptstrDriverDllPath )
/*++
Routine Description:
Figure out printer driver directory from the driver DLL's full pathname
Arguments:
ptstrDriverDllPath - Driver DLL's full pathname
Return Value:
Pointer to the printer driver directory string NULL if there is an error
The returned directory contains a trailing backslash. Caller is responsible for freeing the returned string.
--*/
{ PTSTR ptstr; INT iLength;
ASSERT(ptstrDriverDllPath != NULL);
if ((ptstr = _tcsrchr(ptstrDriverDllPath, TEXT(PATH_SEPARATOR))) != NULL) iLength = (INT)(ptstr - ptstrDriverDllPath) + 1; else { WARNING(("Driver DLL path is not fully qualified: %ws\n", ptstrDriverDllPath)); iLength = 0; }
if ((ptstr = MemAlloc((iLength + 1) * sizeof(TCHAR))) != NULL) { CopyMemory(ptstr, ptstrDriverDllPath, iLength * sizeof(TCHAR)); ptstr[iLength] = NUL; } else ERR(("Memory allocation failed\n"));
return ptstr; }
LPCTSTR PtstrSearchStringInMultiSZPair( LPCTSTR ptstrMultiSZ, LPCTSTR ptstrKey )
/*++
Routine Description:
Search for the specified key in MultiSZ key-value string pairs
Arguments:
ptstrMultiSZ - Points to the data to be searched ptstrKey - Specifies the key string
Return Value:
Pointer to the value string corresponding to the specified key string; NULL if the specified key string is not found
--*/
{ ASSERT(ptstrMultiSZ != NULL);
while (*ptstrMultiSZ != NUL) { //
// If the current string matches the specified key string,
// then return the corresponding value string
//
if (_tcsicmp(ptstrMultiSZ, ptstrKey) == EQUAL_STRING) return ptstrMultiSZ + _tcslen(ptstrMultiSZ) + 1;
//
// Otherwise, advance to the next string pair
//
ptstrMultiSZ += _tcslen(ptstrMultiSZ) + 1; ptstrMultiSZ += _tcslen(ptstrMultiSZ) + 1; }
return NULL; }
BOOL BVerifyMultiSZPair( LPCTSTR ptstrData, DWORD dwSize )
/*++
Routine Description:
Verify the input data block is in REG_MULTI_SZ format and it consists of multiple string pairs
Arguments:
ptstrData - Points to the data to be verified dwSize - Size of the data block in bytes
Return Value:
NONE
--*/
{ LPCTSTR ptstrEnd;
//
// Size must be even
//
ASSERTMSG(dwSize % sizeof(TCHAR) == 0, ("Size is not even: %d\n", dwSize)); dwSize /= sizeof(TCHAR);
//
// Go through one string pair during each iteration
//
ptstrEnd = ptstrData + dwSize;
while (ptstrData < ptstrEnd && *ptstrData != NUL) { while (ptstrData < ptstrEnd && *ptstrData++ != NUL) NULL;
if (ptstrData >= ptstrEnd) { ERR(("Corrupted MultiSZ pair\n")); return FALSE; }
while (ptstrData < ptstrEnd && *ptstrData++ != NUL) NULL;
if (ptstrData >= ptstrEnd) { ERR(("Corrupted MultiSZ pair\n")); return FALSE; } }
//
// Look for the last terminating NUL character
//
if (ptstrData++ >= ptstrEnd) { ERR(("Missing the last NUL terminator\n")); return FALSE; }
if (ptstrData < ptstrEnd) { ERR(("Redundant data after the last NUL terminator\n")); }
return TRUE; }
BOOL BVerifyMultiSZ( LPCTSTR ptstrData, DWORD dwSize )
/*++
Routine Description:
Verify the input data block is in REG_MULTI_SZ format
Arguments:
ptstrData - Points to the data to be verified dwSize - Size of the data block in bytes
Return Value:
NONE
--*/
{ LPCTSTR ptstrEnd;
//
// Size must be even
//
ASSERTMSG(dwSize % sizeof(TCHAR) == 0, ("Size is not even: %d\n", dwSize)); dwSize /= sizeof(TCHAR);
ptstrEnd = ptstrData + dwSize;
while (ptstrData < ptstrEnd && *ptstrData != NUL) { while (ptstrData < ptstrEnd && *ptstrData++ != NUL) NULL;
if (ptstrData >= ptstrEnd) { ERR(("Corrupted MultiSZ pair\n")); return FALSE; } }
//
// Look for the last terminating NUL character
//
if (ptstrData++ >= ptstrEnd) { ERR(("Missing the last NUL terminator\n")); return FALSE; }
if (ptstrData < ptstrEnd) { ERR(("Redundant data after the last NUL terminator\n")); }
return TRUE; }
DWORD DwCountStringsInMultiSZ( IN LPCTSTR ptstrData ) { DWORD dwCount = 0;
if (ptstrData) { while (*ptstrData) { dwCount++; ptstrData += wcslen(ptstrData); ptstrData++; } }
return dwCount; }
|