294 lines
8.2 KiB
C
294 lines
8.2 KiB
C
/*++
|
||
|
||
Copyright (c) 1990-1998 Microsoft Corporation
|
||
All Rights Reserved
|
||
|
||
// @@BEGIN_DDKSPLIT
|
||
Module Name:
|
||
|
||
windows\spooler\prtprocs\winprint\formfeed.c
|
||
// @@END_DDKSPLIT
|
||
|
||
Abstract:
|
||
|
||
Table and routine to send formfeed to a printer.
|
||
|
||
// @@BEGIN_DDKSPLIT
|
||
Author:
|
||
|
||
Tommy Evans (vtommye) 10-21-1993
|
||
|
||
Revision History:
|
||
// @@END_DDKSPLIT
|
||
--*/
|
||
#include <windows.h>
|
||
#include <winspool.h>
|
||
#include <winsplp.h>
|
||
#include <wchar.h>
|
||
|
||
#include "winprint.h"
|
||
|
||
/** Constants for our various states **/
|
||
|
||
#define ST_KEY 0x01 /** Looking for a key **/
|
||
#define ST_VALUE 0x02 /** Looking for a value **/
|
||
#define ST_EQUAL 0x04 /** Looking for an = sign **/
|
||
#define ST_EQNODATA 0x08 /** Looking for equal w/ no data **/
|
||
#define ST_DELIM 0x10 /** Looking for a ; **/
|
||
#define ST_DMNODATA 0x20 /** Looking for a ; w/ no data **/
|
||
|
||
|
||
/*++
|
||
*******************************************************************
|
||
G e t K e y V a l u e
|
||
|
||
Routine Description:
|
||
Returns the value for a given key in the given
|
||
parameter string. The key/values are in the order of
|
||
KEY = VALUE;. The spaces are optional, the ';' is
|
||
required and MUST be present, directly after the value.
|
||
If the call fails, the return length will be 0 and the
|
||
return code will give the error. This routine is written
|
||
as a state machine, driven by the current character.
|
||
|
||
Arguments:
|
||
pParmString => Parameter string to parse
|
||
pKeyName => Key to search for
|
||
ValueType = type of value to return, string or ULONG
|
||
pDestLength => length of dest buffer on enter,
|
||
new length on exit.
|
||
pDestBuffer => area to store the key value
|
||
|
||
Return Value:
|
||
0 if okay
|
||
error if failed (from winerror.h)
|
||
*******************************************************************
|
||
--*/
|
||
USHORT
|
||
GetKeyValue(
|
||
IN PWCHAR pParmString,
|
||
IN PWCHAR pKeyName,
|
||
IN USHORT ValueType,
|
||
IN OUT PUSHORT pDestLength,
|
||
OUT PVOID pDestBuffer)
|
||
{
|
||
PWCHAR pKey, pVal, pValEnd = NULL;
|
||
WCHAR HoldChar;
|
||
USHORT State = ST_KEY; /** Start looking for a key **/
|
||
ULONG length;
|
||
|
||
/** If any of the pointers are bad, return error **/
|
||
|
||
if ((pParmString == NULL) ||
|
||
(pKeyName == NULL) ||
|
||
(pDestLength == NULL) ||
|
||
(pDestBuffer == NULL)) {
|
||
|
||
if (pDestLength) {
|
||
*pDestLength = 0;
|
||
}
|
||
|
||
return ERROR_INVALID_PARAMETER;
|
||
}
|
||
|
||
/**
|
||
If we are looking for a ULONG, make sure they passed
|
||
in a big enough buffer.
|
||
**/
|
||
|
||
if (ValueType == VALUE_ULONG) {
|
||
if (*pDestLength < sizeof(ULONG)) {
|
||
*pDestLength = 0;
|
||
return ERROR_INSUFFICIENT_BUFFER;
|
||
}
|
||
}
|
||
|
||
while (pParmString && *pParmString) {
|
||
|
||
/**
|
||
Update our state, if necessary, depending on
|
||
the current character.
|
||
**/
|
||
|
||
switch (*pParmString) {
|
||
|
||
/**
|
||
We got a white space. If we were looking for an equal
|
||
sign or delimiter, then note that we got a space. If
|
||
we run across more data, then we have an error.
|
||
**/
|
||
|
||
case (WCHAR)' ':
|
||
case (WCHAR)'\t':
|
||
|
||
/**
|
||
If we were looking for an equal sign,
|
||
check to see if this is the key they
|
||
wanted. If not, jump to the next key.
|
||
**/
|
||
|
||
if (State == ST_EQUAL) {
|
||
if (_wcsnicmp(pKey, pKeyName, lstrlen(pKeyName))) {
|
||
if (pParmString = wcschr(pParmString, (WCHAR)';')) {
|
||
pParmString++;
|
||
}
|
||
State = ST_KEY;
|
||
pValEnd = NULL;
|
||
break;
|
||
}
|
||
|
||
/** Looking for an equal sign with no more data **/
|
||
|
||
State = ST_EQNODATA;
|
||
}
|
||
else if (State == ST_DELIM) {
|
||
|
||
/** If this is the end of the value, remember it **/
|
||
|
||
if (!pValEnd) {
|
||
pValEnd = pParmString;
|
||
}
|
||
|
||
/** Now looking for a delimiter with no more data **/
|
||
|
||
State = ST_DMNODATA;
|
||
}
|
||
pParmString++;
|
||
break;
|
||
|
||
/**
|
||
Found an equal sign. If we were looking for one,
|
||
then great - we will then be looking for a value.
|
||
We will check to see if this is the key they wanted.
|
||
Otherwise, this is an error and we will start over
|
||
with the next key.
|
||
**/
|
||
|
||
case (WCHAR)'=':
|
||
if (State == ST_EQUAL) {
|
||
if (_wcsnicmp(pKey, pKeyName, lstrlen(pKeyName))) {
|
||
|
||
/** Error - go to next key **/
|
||
|
||
if (pParmString = wcschr(pParmString, (WCHAR)';')) {
|
||
pParmString++;
|
||
}
|
||
State = ST_KEY;
|
||
pValEnd = NULL;
|
||
break;
|
||
}
|
||
pParmString++;
|
||
State = ST_VALUE;
|
||
}
|
||
else {
|
||
|
||
/** Error - go to next key **/
|
||
|
||
if (pParmString = wcschr(pParmString, (WCHAR)';')) {
|
||
pParmString++;
|
||
}
|
||
State = ST_KEY;
|
||
pValEnd = NULL;
|
||
}
|
||
break;
|
||
// @@BEGIN_DDKSPLIT
|
||
/**
|
||
Found a delimeter. If this is what we were looking
|
||
for, great - we have a complete key/value pair.
|
||
**/
|
||
// @@END_DDKSPLIT
|
||
|
||
case (WCHAR)';':
|
||
if (State == ST_DELIM) {
|
||
if (!pValEnd) {
|
||
pValEnd = pParmString;
|
||
}
|
||
if (ValueType == VALUE_ULONG) {
|
||
if (!iswdigit(*pVal)) {
|
||
if (pParmString = wcschr(pParmString, (WCHAR)';')) {
|
||
pParmString++;
|
||
}
|
||
State = ST_KEY;
|
||
pValEnd = NULL;
|
||
break;
|
||
}
|
||
*(PULONG)pDestBuffer = wcstoul(pVal, NULL, 10);
|
||
return 0;
|
||
}
|
||
else if (ValueType == VALUE_STRING) {
|
||
|
||
/**
|
||
ASCIIZ the value to copy it out without
|
||
any trailing spaces.
|
||
**/
|
||
|
||
HoldChar = *pValEnd;
|
||
*pValEnd = (WCHAR)0;
|
||
|
||
/** Make sure the buffer is big enough **/
|
||
|
||
length = lstrlen(pVal);
|
||
if (*pDestLength < length) {
|
||
*pDestLength = 0;
|
||
return ERROR_INSUFFICIENT_BUFFER;
|
||
}
|
||
|
||
/**
|
||
Copy the data, restore the character where
|
||
we ASCIIZ'd the string, set up the length
|
||
and return.
|
||
**/
|
||
|
||
lstrcpy(pDestBuffer, pVal);
|
||
*pValEnd = HoldChar;
|
||
*(PULONG)pDestLength = length;
|
||
return 0;
|
||
}
|
||
}
|
||
else {
|
||
|
||
/** We weren't looking for a delimiter - next key **/
|
||
|
||
State = ST_KEY;
|
||
pValEnd = NULL;
|
||
pParmString++;
|
||
}
|
||
break;
|
||
|
||
/**
|
||
Found some data. If we had hit a space,
|
||
and were expecting a equal sign or delimiter,
|
||
this is an error.
|
||
**/
|
||
|
||
default:
|
||
if ((State == ST_EQNODATA) ||
|
||
(State == ST_DMNODATA)) {
|
||
if (pParmString = wcschr(pParmString, (WCHAR)';')) {
|
||
pParmString++;
|
||
}
|
||
State = ST_KEY;
|
||
pValEnd = NULL;
|
||
break;
|
||
}
|
||
else if (State == ST_KEY) {
|
||
pKey = pParmString;
|
||
State = ST_EQUAL;
|
||
}
|
||
else if (State == ST_VALUE) {
|
||
pVal = pParmString;
|
||
State = ST_DELIM;
|
||
}
|
||
pParmString++;
|
||
break;
|
||
} /* End switch */
|
||
} /* While parms data */
|
||
|
||
*pDestLength = 0;
|
||
return ERROR_NO_DATA;
|
||
}
|
||
|
||
|
||
|
||
|