Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
8.2 KiB

  1. /*++
  2. Copyright (c) 1990-1998 Microsoft Corporation
  3. All Rights Reserved
  4. // @@BEGIN_DDKSPLIT
  5. Module Name:
  6. windows\spooler\prtprocs\winprint\formfeed.c
  7. // @@END_DDKSPLIT
  8. Abstract:
  9. Table and routine to send formfeed to a printer.
  10. // @@BEGIN_DDKSPLIT
  11. Author:
  12. Tommy Evans (vtommye) 10-21-1993
  13. Revision History:
  14. // @@END_DDKSPLIT
  15. --*/
  16. #include <windows.h>
  17. #include <winspool.h>
  18. #include <winsplp.h>
  19. #include <wchar.h>
  20. #include "winprint.h"
  21. /** Constants for our various states **/
  22. #define ST_KEY 0x01 /** Looking for a key **/
  23. #define ST_VALUE 0x02 /** Looking for a value **/
  24. #define ST_EQUAL 0x04 /** Looking for an = sign **/
  25. #define ST_EQNODATA 0x08 /** Looking for equal w/ no data **/
  26. #define ST_DELIM 0x10 /** Looking for a ; **/
  27. #define ST_DMNODATA 0x20 /** Looking for a ; w/ no data **/
  28. /*++
  29. *******************************************************************
  30. G e t K e y V a l u e
  31. Routine Description:
  32. Returns the value for a given key in the given
  33. parameter string. The key/values are in the order of
  34. KEY = VALUE;. The spaces are optional, the ';' is
  35. required and MUST be present, directly after the value.
  36. If the call fails, the return length will be 0 and the
  37. return code will give the error. This routine is written
  38. as a state machine, driven by the current character.
  39. Arguments:
  40. pParmString => Parameter string to parse
  41. pKeyName => Key to search for
  42. ValueType = type of value to return, string or ULONG
  43. pDestLength => length of dest buffer on enter,
  44. new length on exit.
  45. pDestBuffer => area to store the key value
  46. Return Value:
  47. 0 if okay
  48. error if failed (from winerror.h)
  49. *******************************************************************
  50. --*/
  51. USHORT
  52. GetKeyValue(
  53. IN PWCHAR pParmString,
  54. IN PWCHAR pKeyName,
  55. IN USHORT ValueType,
  56. IN OUT PUSHORT pDestLength,
  57. OUT PVOID pDestBuffer)
  58. {
  59. PWCHAR pKey, pVal, pValEnd = NULL;
  60. WCHAR HoldChar;
  61. USHORT State = ST_KEY; /** Start looking for a key **/
  62. ULONG length;
  63. /** If any of the pointers are bad, return error **/
  64. if ((pParmString == NULL) ||
  65. (pKeyName == NULL) ||
  66. (pDestLength == NULL) ||
  67. (pDestBuffer == NULL)) {
  68. if (pDestLength) {
  69. *pDestLength = 0;
  70. }
  71. return ERROR_INVALID_PARAMETER;
  72. }
  73. /**
  74. If we are looking for a ULONG, make sure they passed
  75. in a big enough buffer.
  76. **/
  77. if (ValueType == VALUE_ULONG) {
  78. if (*pDestLength < sizeof(ULONG)) {
  79. *pDestLength = 0;
  80. return ERROR_INSUFFICIENT_BUFFER;
  81. }
  82. }
  83. while (pParmString && *pParmString) {
  84. /**
  85. Update our state, if necessary, depending on
  86. the current character.
  87. **/
  88. switch (*pParmString) {
  89. /**
  90. We got a white space. If we were looking for an equal
  91. sign or delimiter, then note that we got a space. If
  92. we run across more data, then we have an error.
  93. **/
  94. case (WCHAR)' ':
  95. case (WCHAR)'\t':
  96. /**
  97. If we were looking for an equal sign,
  98. check to see if this is the key they
  99. wanted. If not, jump to the next key.
  100. **/
  101. if (State == ST_EQUAL) {
  102. if (_wcsnicmp(pKey, pKeyName, lstrlen(pKeyName))) {
  103. if (pParmString = wcschr(pParmString, (WCHAR)';')) {
  104. pParmString++;
  105. }
  106. State = ST_KEY;
  107. pValEnd = NULL;
  108. break;
  109. }
  110. /** Looking for an equal sign with no more data **/
  111. State = ST_EQNODATA;
  112. }
  113. else if (State == ST_DELIM) {
  114. /** If this is the end of the value, remember it **/
  115. if (!pValEnd) {
  116. pValEnd = pParmString;
  117. }
  118. /** Now looking for a delimiter with no more data **/
  119. State = ST_DMNODATA;
  120. }
  121. pParmString++;
  122. break;
  123. /**
  124. Found an equal sign. If we were looking for one,
  125. then great - we will then be looking for a value.
  126. We will check to see if this is the key they wanted.
  127. Otherwise, this is an error and we will start over
  128. with the next key.
  129. **/
  130. case (WCHAR)'=':
  131. if (State == ST_EQUAL) {
  132. if (_wcsnicmp(pKey, pKeyName, lstrlen(pKeyName))) {
  133. /** Error - go to next key **/
  134. if (pParmString = wcschr(pParmString, (WCHAR)';')) {
  135. pParmString++;
  136. }
  137. State = ST_KEY;
  138. pValEnd = NULL;
  139. break;
  140. }
  141. pParmString++;
  142. State = ST_VALUE;
  143. }
  144. else {
  145. /** Error - go to next key **/
  146. if (pParmString = wcschr(pParmString, (WCHAR)';')) {
  147. pParmString++;
  148. }
  149. State = ST_KEY;
  150. pValEnd = NULL;
  151. }
  152. break;
  153. // @@BEGIN_DDKSPLIT
  154. /**
  155. Found a delimeter. If this is what we were looking
  156. for, great - we have a complete key/value pair.
  157. **/
  158. // @@END_DDKSPLIT
  159. case (WCHAR)';':
  160. if (State == ST_DELIM) {
  161. if (!pValEnd) {
  162. pValEnd = pParmString;
  163. }
  164. if (ValueType == VALUE_ULONG) {
  165. if (!iswdigit(*pVal)) {
  166. if (pParmString = wcschr(pParmString, (WCHAR)';')) {
  167. pParmString++;
  168. }
  169. State = ST_KEY;
  170. pValEnd = NULL;
  171. break;
  172. }
  173. *(PULONG)pDestBuffer = wcstoul(pVal, NULL, 10);
  174. return 0;
  175. }
  176. else if (ValueType == VALUE_STRING) {
  177. /**
  178. ASCIIZ the value to copy it out without
  179. any trailing spaces.
  180. **/
  181. HoldChar = *pValEnd;
  182. *pValEnd = (WCHAR)0;
  183. /** Make sure the buffer is big enough **/
  184. length = lstrlen(pVal);
  185. if (*pDestLength < length) {
  186. *pDestLength = 0;
  187. return ERROR_INSUFFICIENT_BUFFER;
  188. }
  189. /**
  190. Copy the data, restore the character where
  191. we ASCIIZ'd the string, set up the length
  192. and return.
  193. **/
  194. lstrcpy(pDestBuffer, pVal);
  195. *pValEnd = HoldChar;
  196. *(PULONG)pDestLength = length;
  197. return 0;
  198. }
  199. }
  200. else {
  201. /** We weren't looking for a delimiter - next key **/
  202. State = ST_KEY;
  203. pValEnd = NULL;
  204. pParmString++;
  205. }
  206. break;
  207. /**
  208. Found some data. If we had hit a space,
  209. and were expecting a equal sign or delimiter,
  210. this is an error.
  211. **/
  212. default:
  213. if ((State == ST_EQNODATA) ||
  214. (State == ST_DMNODATA)) {
  215. if (pParmString = wcschr(pParmString, (WCHAR)';')) {
  216. pParmString++;
  217. }
  218. State = ST_KEY;
  219. pValEnd = NULL;
  220. break;
  221. }
  222. else if (State == ST_KEY) {
  223. pKey = pParmString;
  224. State = ST_EQUAL;
  225. }
  226. else if (State == ST_VALUE) {
  227. pVal = pParmString;
  228. State = ST_DELIM;
  229. }
  230. pParmString++;
  231. break;
  232. } /* End switch */
  233. } /* While parms data */
  234. *pDestLength = 0;
  235. return ERROR_NO_DATA;
  236. }