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.

312 lines
6.3 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 <windows.h>
  21. #include <winspool.h>
  22. #include <winsplp.h>
  23. #include <lm.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <rpc.h>
  27. #include "winspl.h"
  28. #include <offsets.h>
  29. #include <w32types.h>
  30. #include <local.h>
  31. #include <splcom.h>
  32. typedef struct _KEYDATA {
  33. DWORD cb;
  34. DWORD cTokens;
  35. LPWSTR pTokens[1];
  36. } KEYDATA, *PKEYDATA;
  37. WCHAR *szFilePort = L"FILE:";
  38. WCHAR *szNetPort = L"Net:";
  39. //
  40. // Function prototypes
  41. //
  42. PKEYDATA
  43. CreateTokenList(
  44. LPWSTR pKeyData
  45. );
  46. PKEYDATA
  47. GetPrinterPortList(
  48. HANDLE hPrinter
  49. );
  50. BOOL
  51. IsaFileName(
  52. LPWSTR pOutputFile
  53. );
  54. BOOL
  55. IsaPortName(
  56. PKEYDATA pKeyData,
  57. LPWSTR pOutputFile
  58. );
  59. BOOL
  60. Win32IsGoingToFile(
  61. HANDLE hPrinter,
  62. LPWSTR pOutputFile
  63. )
  64. {
  65. PKEYDATA pKeyData = NULL;
  66. BOOL bErrorCode = FALSE;
  67. if (!pOutputFile || !*pOutputFile) {
  68. return FALSE;
  69. }
  70. pKeyData = GetPrinterPortList(hPrinter);
  71. if (pKeyData) {
  72. //
  73. // If it's not a port and it is a file name,
  74. // then it is going to file.
  75. //
  76. if (!IsaPortName(pKeyData, pOutputFile) && IsaFileName(pOutputFile)) {
  77. bErrorCode = TRUE;
  78. }
  79. FreeSplMem(pKeyData);
  80. }
  81. return bErrorCode;
  82. }
  83. BOOL
  84. IsaFileName(
  85. LPWSTR pOutputFile
  86. )
  87. {
  88. HANDLE hFile = INVALID_HANDLE_VALUE;
  89. WCHAR FullPathName[MAX_PATH];
  90. LPWSTR pFileName=NULL;
  91. //
  92. // Hack for Word20c.Win
  93. //
  94. if (!_wcsicmp(pOutputFile, L"FILE")) {
  95. return(FALSE);
  96. }
  97. if (wcslen(pOutputFile) < MAX_PATH &&
  98. GetFullPathName(pOutputFile, COUNTOF(FullPathName), FullPathName, &pFileName)) {
  99. if ((hFile = CreateFile(pOutputFile,
  100. GENERIC_WRITE,
  101. FILE_SHARE_READ | FILE_SHARE_WRITE,
  102. NULL,
  103. CREATE_ALWAYS,
  104. FILE_ATTRIBUTE_NORMAL,
  105. NULL)) != INVALID_HANDLE_VALUE) {
  106. if (GetFileType(hFile) == FILE_TYPE_DISK) {
  107. CloseHandle(hFile);
  108. return(TRUE);
  109. }else {
  110. CloseHandle(hFile);
  111. return(FALSE);
  112. }
  113. }
  114. }
  115. return(FALSE);
  116. }
  117. BOOL
  118. IsaPortName(
  119. PKEYDATA pKeyData,
  120. LPWSTR pOutputFile
  121. )
  122. {
  123. DWORD i = 0;
  124. UINT uStrLen;
  125. if (!pKeyData) {
  126. return(FALSE);
  127. }
  128. for (i=0; i < pKeyData->cTokens; i++) {
  129. if (!lstrcmpi(pKeyData->pTokens[i], pOutputFile)) {
  130. return(TRUE);
  131. }
  132. }
  133. //
  134. // Hack for NeXY: ports
  135. //
  136. if (!_wcsnicmp(pOutputFile, L"Ne", 2)) {
  137. uStrLen = wcslen( pOutputFile );
  138. //
  139. // Ne00: or Ne00 if app truncates it
  140. //
  141. if ( ( uStrLen == 5 ) || ( uStrLen == 4 ) ) {
  142. // Check for two Digits
  143. if (( pOutputFile[2] >= L'0' ) && ( pOutputFile[2] <= L'9' ) &&
  144. ( pOutputFile[3] >= L'0' ) && ( pOutputFile[3] <= L'9' )) {
  145. //
  146. // Check for the final : as in Ne01:,
  147. // note some apps will truncate it.
  148. //
  149. if (( uStrLen == 5 ) && (pOutputFile[4] != L':')) {
  150. return FALSE;
  151. }
  152. return TRUE;
  153. }
  154. }
  155. }
  156. return(FALSE);
  157. }
  158. PKEYDATA
  159. GetPrinterPortList(
  160. HANDLE hPrinter
  161. )
  162. {
  163. LPBYTE pMem;
  164. LPTSTR pPort;
  165. DWORD dwPassed = 1024; //Try 1K to start with
  166. LPPRINTER_INFO_2 pPrinter;
  167. DWORD dwLevel = 2;
  168. DWORD dwNeeded;
  169. PKEYDATA pKeyData;
  170. DWORD i = 0;
  171. pMem = AllocSplMem(dwPassed);
  172. if (pMem == NULL) {
  173. return FALSE;
  174. }
  175. if (!CacheGetPrinter(hPrinter, dwLevel, pMem, dwPassed, &dwNeeded)) {
  176. DBGMSG(DBG_TRACE, ("GetPrinterPortList GetPrinter error is %d\n", GetLastError()));
  177. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
  178. return NULL;
  179. }
  180. pMem = ReallocSplMem(pMem, 0, dwNeeded);
  181. dwPassed = dwNeeded;
  182. if (!CacheGetPrinter(hPrinter, dwLevel, pMem, dwPassed, &dwNeeded)) {
  183. FreeSplMem(pMem);
  184. return (NULL);
  185. }
  186. }
  187. pPrinter = (LPPRINTER_INFO_2)pMem;
  188. //
  189. // Fixes the null pPrinter->pPortName problem where
  190. // downlevel may return null
  191. //
  192. if (!pPrinter->pPortName) {
  193. FreeSplMem(pMem);
  194. return(NULL);
  195. }
  196. pKeyData = CreateTokenList(pPrinter->pPortName);
  197. FreeSplMem(pMem);
  198. return(pKeyData);
  199. }
  200. PKEYDATA
  201. CreateTokenList(
  202. LPWSTR pKeyData
  203. )
  204. {
  205. DWORD cTokens;
  206. DWORD cb;
  207. PKEYDATA pResult;
  208. LPWSTR pDest;
  209. LPWSTR psz = pKeyData;
  210. LPWSTR *ppToken;
  211. if (!psz || !*psz)
  212. return NULL;
  213. cTokens=1;
  214. /* Scan through the string looking for commas,
  215. * ensuring that each is followed by a non-NULL character:
  216. */
  217. while ((psz = wcschr(psz, L',')) && psz[1]) {
  218. cTokens++;
  219. psz++;
  220. }
  221. cb = sizeof(KEYDATA) + (cTokens-1) * sizeof(LPWSTR) +
  222. wcslen(pKeyData)*sizeof(WCHAR) + sizeof(WCHAR);
  223. if (!(pResult = (PKEYDATA)AllocSplMem(cb)))
  224. return NULL;
  225. pResult->cb = cb;
  226. /* Initialise pDest to point beyond the token pointers:
  227. */
  228. pDest = (LPWSTR)((LPBYTE)pResult + sizeof(KEYDATA) +
  229. (cTokens-1) * sizeof(LPWSTR));
  230. /* Then copy the key data buffer there:
  231. */
  232. wcscpy(pDest, pKeyData);
  233. ppToken = pResult->pTokens;
  234. psz = pDest;
  235. do {
  236. *ppToken++ = psz;
  237. if ( psz = wcschr(psz, L',') )
  238. *psz++ = L'\0';
  239. } while (psz);
  240. pResult->cTokens = cTokens;
  241. return( pResult );
  242. }