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.

353 lines
11 KiB

  1. //
  2. // prnwrap.cpp
  3. //
  4. // Unicode printer function wrappers
  5. //
  6. // Copyright(C) Microsoft Corporation 2000
  7. //
  8. // Nadim Abdo (nadima)
  9. //
  10. #include "stdafx.h"
  11. #include "uniwrap.h"
  12. #include "cstrinout.h"
  13. //Just include wrap function prototypes
  14. //no wrappers (it would be silly to wrap wrappers)
  15. #define DONOT_REPLACE_WITH_WRAPPERS
  16. #include "uwrap.h"
  17. //
  18. // Printer wrappers.
  19. //
  20. BOOL
  21. WINAPI
  22. EnumPrintersWrapW(
  23. IN DWORD Flags,
  24. IN LPWSTR Name,
  25. IN DWORD Level,
  26. OUT LPBYTE pPrinterEnum,
  27. IN DWORD cbBuf,
  28. OUT LPDWORD pcbNeeded,
  29. OUT LPDWORD pcReturned)
  30. {
  31. BOOL fRet;
  32. if (g_bRunningOnNT)
  33. {
  34. return EnumPrintersW(Flags, Name, Level,
  35. pPrinterEnum, cbBuf,
  36. pcbNeeded, pcReturned);
  37. }
  38. else
  39. {
  40. ASSERT(Level == 2); //only supported level
  41. if(2 == Level)
  42. {
  43. CStrIn strName(Name);
  44. LPBYTE pPrinterEnumA = NULL;
  45. if(pPrinterEnum && cbBuf)
  46. {
  47. pPrinterEnumA = (LPBYTE)LocalAlloc( LPTR, cbBuf );
  48. if(!pPrinterEnumA)
  49. {
  50. return FALSE;
  51. }
  52. }
  53. fRet = EnumPrintersA(Flags,
  54. strName,
  55. Level,
  56. pPrinterEnumA,
  57. cbBuf,
  58. pcbNeeded,
  59. pcReturned);
  60. if(fRet || (!fRet && GetLastError() == ERROR_INSUFFICIENT_BUFFER))
  61. {
  62. if(!pPrinterEnumA)
  63. {
  64. //
  65. // This is a size query double the requested space
  66. // so the caller allocates a buffer with enough space
  67. // for UNICODE converted sub strings.
  68. //
  69. *pcbNeeded = *pcbNeeded * 2;
  70. return TRUE;
  71. }
  72. else
  73. {
  74. //Convert the ANSI structures in the temporary
  75. //output buffer to UNICODE structures in the caller's
  76. //buffer.
  77. memset( pPrinterEnum, 0, cbBuf );
  78. PBYTE pStartStrings = pPrinterEnum +
  79. (*pcReturned * sizeof(PRINTER_INFO_2W));
  80. PBYTE pEndUserBuf = pPrinterEnum + cbBuf;
  81. LPWSTR szCurOutputString = (LPWSTR)pStartStrings;
  82. UINT i =0;
  83. //Strings go after the array of structures
  84. //compute the string start address
  85. for(i = 0 ; i < *pcReturned; i++)
  86. {
  87. PPRINTER_INFO_2A ppi2a =
  88. &(((PRINTER_INFO_2A *)pPrinterEnumA)[i]);
  89. PPRINTER_INFO_2W ppi2w =
  90. &(((PRINTER_INFO_2W *)pPrinterEnum)[i]);
  91. //
  92. // First copy over all the static fields
  93. //
  94. ppi2w->Attributes = ppi2a->Attributes;
  95. ppi2w->Priority = ppi2a->Priority;
  96. ppi2w->DefaultPriority = ppi2a->DefaultPriority;
  97. ppi2w->StartTime = ppi2a->StartTime;
  98. ppi2w->UntilTime = ppi2a->UntilTime;
  99. ppi2w->Status = ppi2a->Status;
  100. ppi2w->cJobs = ppi2a->cJobs;
  101. ppi2w->AveragePPM = ppi2a->AveragePPM;
  102. //Win9x has no security descriptors
  103. ppi2w->pSecurityDescriptor = NULL;
  104. //WARN: RDPDR currently doesn't use DEVMODE
  105. //so we don't bother converting it (it's huge)
  106. ppi2w->pDevMode = NULL;
  107. //
  108. // Now convert the strings
  109. // for perf reasons we only handle the
  110. // strings RDPDR currently uses. The others are set
  111. // to null when we memset above.
  112. //
  113. int cchLen = lstrlenA( ppi2a->pPortName );
  114. SHAnsiToUnicode( ppi2a->pPortName,
  115. szCurOutputString,
  116. cchLen + 1 );
  117. ppi2w->pPortName = szCurOutputString;
  118. szCurOutputString += (cchLen + 2);
  119. cchLen = lstrlenA( ppi2a->pPrinterName );
  120. SHAnsiToUnicode( ppi2a->pPrinterName,
  121. szCurOutputString,
  122. cchLen + 1 );
  123. ppi2w->pPrinterName = szCurOutputString;
  124. szCurOutputString += (cchLen + 2);
  125. cchLen = lstrlenA( ppi2a->pDriverName );
  126. SHAnsiToUnicode( ppi2a->pDriverName,
  127. szCurOutputString,
  128. cchLen + 1 );
  129. ppi2w->pDriverName = szCurOutputString;
  130. szCurOutputString += (cchLen + 2);
  131. }
  132. LocalFree(pPrinterEnumA);
  133. pPrinterEnumA = NULL;
  134. return TRUE;
  135. }
  136. }
  137. else
  138. {
  139. LocalFree(pPrinterEnumA);
  140. return FALSE;
  141. }
  142. }
  143. else
  144. {
  145. //We only support level2 for now. Add more if needed.
  146. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  147. return FALSE;
  148. }
  149. }
  150. }
  151. BOOL
  152. WINAPI
  153. OpenPrinterWrapW(
  154. IN LPWSTR pPrinterName,
  155. OUT LPHANDLE phPrinter,
  156. IN LPPRINTER_DEFAULTSW pDefault)
  157. {
  158. //We don't support converting the pDev because RDPDR doesn't use
  159. //it. If you add code that needs it modify this wrapper.
  160. if(pDefault)
  161. {
  162. ASSERT(pDefault->pDevMode == NULL);
  163. }
  164. if(g_bRunningOnNT)
  165. {
  166. return OpenPrinterW( pPrinterName, phPrinter, pDefault);
  167. }
  168. else
  169. {
  170. PRINTER_DEFAULTSA pdefa;
  171. CStrIn strPrinterName(pPrinterName);
  172. if(pDefault)
  173. {
  174. CStrIn strInDataType(pDefault->pDatatype);
  175. pdefa.DesiredAccess = pDefault->DesiredAccess;
  176. pdefa.pDevMode = NULL; //UNSUPPORTED conversion see above
  177. pdefa.pDatatype = strInDataType;
  178. return OpenPrinterA( strPrinterName,
  179. phPrinter,
  180. &pdefa );
  181. }
  182. else
  183. {
  184. return OpenPrinterA( strPrinterName,
  185. phPrinter,
  186. NULL );
  187. }
  188. }
  189. }
  190. DWORD
  191. WINAPI
  192. StartDocPrinterWrapW(
  193. IN HANDLE hPrinter,
  194. IN DWORD Level,
  195. IN LPBYTE pDocInfo)
  196. {
  197. if(g_bRunningOnNT)
  198. {
  199. return StartDocPrinterW( hPrinter, Level, pDocInfo );
  200. }
  201. else
  202. {
  203. ASSERT(Level == 1); //we only support this level
  204. DOC_INFO_1A docinf1a;
  205. CStrIn strDocName( ((PDOC_INFO_1)pDocInfo)->pDocName );
  206. CStrIn strOutputFile( ((PDOC_INFO_1)pDocInfo)->pOutputFile );
  207. CStrIn strDataType( ((PDOC_INFO_1)pDocInfo)->pDatatype );
  208. docinf1a.pDocName = strDocName;
  209. docinf1a.pOutputFile = strOutputFile;
  210. docinf1a.pDatatype = strDataType;
  211. return StartDocPrinterA( hPrinter, Level, (PBYTE)&docinf1a );
  212. }
  213. }
  214. DWORD
  215. WINAPI
  216. GetPrinterDataWrapW(
  217. IN HANDLE hPrinter,
  218. IN LPWSTR pValueName,
  219. OUT LPDWORD pType,
  220. OUT LPBYTE pData,
  221. IN DWORD nSize,
  222. OUT LPDWORD pcbNeeded)
  223. {
  224. if(g_bRunningOnNT)
  225. {
  226. return GetPrinterDataW( hPrinter, pValueName, pType,
  227. pData, nSize, pcbNeeded );
  228. }
  229. else
  230. {
  231. CStrIn strValueName(pValueName);
  232. DWORD ret = 0;
  233. if(!pData)
  234. {
  235. //This is a size query
  236. ret = GetPrinterDataA( hPrinter,
  237. strValueName,
  238. pType,
  239. NULL,
  240. nSize,
  241. pcbNeeded );
  242. *pcbNeeded = *pcbNeeded * 2; //double for UNICODE
  243. return ret;
  244. }
  245. else
  246. {
  247. CStrOut strDataOut( (LPWSTR)pData, nSize/sizeof(TCHAR));
  248. //ASSUMPTION is that we get back string data
  249. ret = GetPrinterDataA( hPrinter,
  250. strValueName,
  251. pType,
  252. (LPBYTE)((LPSTR)strDataOut),
  253. nSize,
  254. pcbNeeded );
  255. return ret;
  256. }
  257. }
  258. }
  259. BOOL
  260. WINAPI
  261. GetPrinterDriverWrapW(
  262. HANDLE hPrinter, // printer object
  263. LPTSTR pEnvironment, // environment name. NULL is supported.
  264. DWORD Level, // information level
  265. LPBYTE pDriverInfo, // driver data buffer
  266. DWORD cbBuf, // size of buffer
  267. LPDWORD pcbNeeded // bytes received or required
  268. )
  269. {
  270. BOOL ret;
  271. // Level 1 is supported at this time.
  272. ASSERT(Level == 1);
  273. // pEnvironment better be NULL.
  274. ASSERT(pEnvironment == NULL);
  275. if (g_bRunningOnNT) {
  276. return GetPrinterDriverW(
  277. hPrinter, pEnvironment, Level,
  278. pDriverInfo, cbBuf,
  279. pcbNeeded
  280. );
  281. }
  282. else {
  283. if (!pDriverInfo) {
  284. //
  285. // This is a size query
  286. //
  287. ret = GetPrinterDriverA(
  288. hPrinter, NULL, Level,
  289. NULL, cbBuf, pcbNeeded
  290. );
  291. *pcbNeeded = *pcbNeeded * 2; //double for UNICODE
  292. return ret;
  293. }
  294. else {
  295. PDRIVER_INFO_1 srcP1 = (PDRIVER_INFO_1)LocalAlloc(LPTR, cbBuf);
  296. if (srcP1 == NULL) {
  297. return FALSE;
  298. }
  299. else {
  300. ret = GetPrinterDriverA(
  301. hPrinter, NULL, Level,
  302. (LPBYTE)srcP1, cbBuf, pcbNeeded
  303. );
  304. if (ret) {
  305. int cchLen = lstrlenA((LPCSTR)srcP1->pName);
  306. PDRIVER_INFO_1 dstP1 = (PDRIVER_INFO_1)pDriverInfo;
  307. dstP1->pName = (LPWSTR)(dstP1 + 1);
  308. SHAnsiToUnicode((LPCSTR)srcP1->pName, dstP1->pName, cchLen + 1);
  309. }
  310. LocalFree(srcP1);
  311. return ret;
  312. }
  313. }
  314. }
  315. }