Windows NT 4.0 source code leak
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.

281 lines
8.0 KiB

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