Leaked source code of windows server 2003
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.

336 lines
6.9 KiB

  1. /*++
  2. Copyright (c) 1994 - 1995 Microsoft Corporation
  3. Module Name:
  4. prnfile.c
  5. Abstract:
  6. This module contains all the code necessary for testing printing"
  7. to file to remote printers. There are two criteria based on which
  8. we will print to a file.
  9. Case 1:
  10. This is the true NT style print to file. One of the ports of the
  11. printer is a file port denoted as FILE: We will disregard any other
  12. port and straight away dump this job to file.
  13. Case 2:
  14. This is the "PiggyBacking" case. Apps such as WinWord, Publisher
  15. Author:
  16. Krishna Ganugapati (Krishna Ganugapati) 6-June-1994
  17. Revision History:
  18. 6-June-1994 - Created.
  19. --*/
  20. #include "precomp.h"
  21. typedef struct _KEYDATA {
  22. DWORD cb;
  23. DWORD cTokens;
  24. LPWSTR pTokens[1];
  25. } KEYDATA, *PKEYDATA;
  26. WCHAR *szFilePort = L"FILE:";
  27. WCHAR *szNetPort = L"Net:";
  28. //
  29. // Function prototypes
  30. //
  31. PKEYDATA
  32. CreateTokenList(
  33. LPWSTR pKeyData
  34. );
  35. PKEYDATA
  36. GetPrinterPortList(
  37. HANDLE hPrinter
  38. );
  39. BOOL
  40. IsaFileName(
  41. LPWSTR pOutputFile
  42. );
  43. BOOL
  44. IsaPortName(
  45. PKEYDATA pKeyData,
  46. LPWSTR pOutputFile
  47. );
  48. BOOL
  49. Win32IsGoingToFile(
  50. HANDLE hPrinter,
  51. LPWSTR pOutputFile
  52. )
  53. {
  54. PKEYDATA pKeyData = NULL;
  55. BOOL bErrorCode = FALSE;
  56. if (!pOutputFile || !*pOutputFile) {
  57. return FALSE;
  58. }
  59. pKeyData = GetPrinterPortList(hPrinter);
  60. if (pKeyData) {
  61. //
  62. // If it's not a port and it is a file name,
  63. // then it is going to file.
  64. //
  65. if (!IsaPortName(pKeyData, pOutputFile) && IsaFileName(pOutputFile)) {
  66. bErrorCode = TRUE;
  67. }
  68. FreeSplMem(pKeyData);
  69. }
  70. return bErrorCode;
  71. }
  72. BOOL
  73. IsaFileName(
  74. LPWSTR pOutputFile
  75. )
  76. {
  77. HANDLE hFile = INVALID_HANDLE_VALUE;
  78. WCHAR FullPathName[MAX_PATH];
  79. LPWSTR pFileName=NULL;
  80. //
  81. // Hack for Word20c.Win
  82. //
  83. if (!_wcsicmp(pOutputFile, L"FILE")) {
  84. return(FALSE);
  85. }
  86. if (wcslen(pOutputFile) < MAX_PATH &&
  87. GetFullPathName(pOutputFile, COUNTOF(FullPathName), FullPathName, &pFileName)) {
  88. if ((hFile = CreateFile(pOutputFile,
  89. GENERIC_WRITE,
  90. FILE_SHARE_READ | FILE_SHARE_WRITE,
  91. NULL,
  92. CREATE_ALWAYS,
  93. FILE_ATTRIBUTE_NORMAL,
  94. NULL)) != INVALID_HANDLE_VALUE) {
  95. if (GetFileType(hFile) == FILE_TYPE_DISK) {
  96. CloseHandle(hFile);
  97. return(TRUE);
  98. }else {
  99. CloseHandle(hFile);
  100. return(FALSE);
  101. }
  102. }
  103. }
  104. return(FALSE);
  105. }
  106. BOOL
  107. IsaPortName(
  108. PKEYDATA pKeyData,
  109. LPWSTR pOutputFile
  110. )
  111. {
  112. DWORD i = 0;
  113. UINT uStrLen;
  114. if (!pKeyData) {
  115. return(FALSE);
  116. }
  117. for (i=0; i < pKeyData->cTokens; i++) {
  118. if (!lstrcmpi(pKeyData->pTokens[i], pOutputFile)) {
  119. return(TRUE);
  120. }
  121. }
  122. //
  123. // Hack for NeXY: ports
  124. //
  125. if (!_wcsnicmp(pOutputFile, L"Ne", 2)) {
  126. uStrLen = wcslen( pOutputFile );
  127. //
  128. // Ne00: or Ne00 if app truncates it
  129. //
  130. if ( ( uStrLen == 5 ) || ( uStrLen == 4 ) ) {
  131. // Check for two Digits
  132. if (( pOutputFile[2] >= L'0' ) && ( pOutputFile[2] <= L'9' ) &&
  133. ( pOutputFile[3] >= L'0' ) && ( pOutputFile[3] <= L'9' )) {
  134. //
  135. // Check for the final : as in Ne01:,
  136. // note some apps will truncate it.
  137. //
  138. if (( uStrLen == 5 ) && (pOutputFile[4] != L':')) {
  139. return FALSE;
  140. }
  141. return TRUE;
  142. }
  143. }
  144. }
  145. return(FALSE);
  146. }
  147. PKEYDATA
  148. GetPrinterPortList(
  149. HANDLE hPrinter
  150. )
  151. {
  152. LPBYTE pMem;
  153. LPTSTR pPort;
  154. DWORD dwPassed = 1024; //Try 1K to start with
  155. LPPRINTER_INFO_2 pPrinter;
  156. DWORD dwLevel = 2;
  157. DWORD dwNeeded;
  158. PKEYDATA pKeyData;
  159. DWORD i = 0;
  160. pMem = AllocSplMem(dwPassed);
  161. if (pMem == NULL) {
  162. return FALSE;
  163. }
  164. if (!CacheGetPrinter(hPrinter, dwLevel, pMem, dwPassed, &dwNeeded)) {
  165. DBGMSG(DBG_TRACE, ("GetPrinterPortList GetPrinter error is %d\n", GetLastError()));
  166. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
  167. return NULL;
  168. }
  169. FreeSplMem(pMem);
  170. pMem = AllocSplMem(dwNeeded);
  171. if (pMem == NULL) {
  172. return FALSE;
  173. }
  174. dwPassed = dwNeeded;
  175. if (!CacheGetPrinter(hPrinter, dwLevel, pMem, dwPassed, &dwNeeded)) {
  176. FreeSplMem(pMem);
  177. return (NULL);
  178. }
  179. }
  180. pPrinter = (LPPRINTER_INFO_2)pMem;
  181. //
  182. // Fixes the null pPrinter->pPortName problem where
  183. // downlevel may return null
  184. //
  185. if (!pPrinter->pPortName) {
  186. FreeSplMem(pMem);
  187. return(NULL);
  188. }
  189. pKeyData = CreateTokenList(pPrinter->pPortName);
  190. FreeSplMem(pMem);
  191. return(pKeyData);
  192. }
  193. PKEYDATA
  194. CreateTokenList(
  195. LPWSTR pKeyData
  196. )
  197. {
  198. DWORD cTokens;
  199. DWORD cb;
  200. PKEYDATA pResult;
  201. LPWSTR pDest;
  202. LPWSTR psz = pKeyData;
  203. LPWSTR *ppToken;
  204. if (!psz || !*psz)
  205. {
  206. return NULL;
  207. }
  208. for (cTokens = 0; psz && *psz; )
  209. {
  210. //
  211. // We're skipping consecutive commas
  212. //
  213. while (psz && *psz == L',')
  214. {
  215. psz++;
  216. }
  217. if (psz && *psz)
  218. {
  219. cTokens++;
  220. psz = wcschr(psz, L',');
  221. }
  222. }
  223. if (!cTokens)
  224. {
  225. SetLastError(ERROR_INVALID_PARAMETER);
  226. return NULL;
  227. }
  228. cb = sizeof(KEYDATA) + (cTokens-1) * sizeof(LPWSTR) + wcslen(pKeyData)*sizeof(WCHAR) + sizeof(WCHAR);
  229. if (!(pResult = (PKEYDATA)AllocSplMem(cb)))
  230. {
  231. return NULL;
  232. }
  233. pResult->cb = cb;
  234. /* Initialise pDest to point beyond the token pointers:
  235. */
  236. pDest = (LPWSTR)((LPBYTE)pResult + sizeof(KEYDATA) + (cTokens-1) * sizeof(LPWSTR));
  237. /* Then copy the key data buffer there:
  238. */
  239. StringCbCopy(pDest, cb - ((PBYTE)pDest - (PBYTE)pResult), pKeyData);
  240. ppToken = pResult->pTokens;
  241. for (psz = pDest; psz && *psz; )
  242. {
  243. while (psz && *psz == L',')
  244. {
  245. psz++;
  246. }
  247. if (psz && *psz)
  248. {
  249. *ppToken++ = psz;
  250. psz = wcschr(psz, L',');
  251. if (psz)
  252. {
  253. *psz = L'\0';
  254. psz++;
  255. }
  256. }
  257. }
  258. pResult->cTokens = cTokens;
  259. return( pResult );
  260. }