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.

498 lines
10 KiB

  1. /*++
  2. Copyright (c) 1990-1994 Microsoft Corporation
  3. Module Name:
  4. local.c
  5. Abstract:
  6. This module provides all the public exported APIs relating to Printer
  7. and Job management for the Local Print Providor
  8. Author:
  9. Dave Snipp (DaveSn) 15-Mar-1991
  10. Revision History:
  11. 16-Jun-1992 JohnRo net print vs. UNICODE.
  12. July 1994 MattFe Caching
  13. --*/
  14. #include "precomp.h"
  15. #define NOTIFY_TIMEOUT 10000
  16. DWORD
  17. LMStartDocPrinter(
  18. HANDLE hPrinter,
  19. DWORD Level,
  20. LPBYTE pDocInfo
  21. )
  22. {
  23. PWSPOOL pSpool=(PWSPOOL)hPrinter;
  24. WCHAR szFileName[MAX_PATH];
  25. PDOC_INFO_1 pDocInfo1=(PDOC_INFO_1)pDocInfo;
  26. QUERY_PRINT_JOB_INFO JobInfo;
  27. IO_STATUS_BLOCK Iosb;
  28. VALIDATEW32HANDLE( pSpool );
  29. if (pSpool->Status) {
  30. SetLastError(ERROR_INVALID_PARAMETER);
  31. return FALSE;
  32. }
  33. pSpool->Status |= WSPOOL_STATUS_STARTDOC;
  34. if(StrNCatBuff(szFileName,
  35. COUNTOF(szFileName),
  36. pSpool->pServer,
  37. L"\\",
  38. pSpool->pShare,
  39. NULL) != ERROR_SUCCESS)
  40. {
  41. return FALSE;
  42. }
  43. pSpool->hFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL,
  44. OPEN_ALWAYS,
  45. FILE_ATTRIBUTE_NORMAL |
  46. FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  47. if (pSpool->hFile == INVALID_HANDLE_VALUE) {
  48. EnterSplSem();
  49. DeleteEntryfromLMCache(pSpool->pServer, pSpool->pShare);
  50. LeaveSplSem();
  51. DBGMSG( DBG_WARNING, ("Failed to open %ws\n", szFileName));
  52. pSpool->Status &= ~WSPOOL_STATUS_STARTDOC;
  53. SetLastError(ERROR_INVALID_NAME);
  54. return FALSE;
  55. }
  56. if (pDocInfo1 && pDocInfo1->pDocName && (wcslen(pDocInfo1->pDocName) < MAX_PATH)) {
  57. if (NtFsControlFile(pSpool->hFile,
  58. NULL,
  59. NULL,
  60. NULL,
  61. &Iosb,
  62. FSCTL_GET_PRINT_ID,
  63. NULL, 0,
  64. &JobInfo, sizeof(JobInfo)) == ERROR_SUCCESS){
  65. RxPrintJobSetInfo(pSpool->pServer,
  66. JobInfo.JobId,
  67. 3,
  68. (LPBYTE)pDocInfo1->pDocName,
  69. wcslen(pDocInfo1->pDocName)*sizeof(WCHAR) + sizeof(WCHAR),
  70. PRJ_COMMENT_PARMNUM);
  71. }
  72. else
  73. {
  74. DBGMSG( DBG_WARN, ("NtFsControlFile failed %ws\n", szFileName));
  75. }
  76. }
  77. return TRUE;
  78. }
  79. BOOL
  80. LMStartPagePrinter(
  81. HANDLE hPrinter
  82. )
  83. {
  84. PWSPOOL pSpool = (PWSPOOL)hPrinter;
  85. VALIDATEW32HANDLE( pSpool );
  86. return FALSE;
  87. }
  88. BOOL
  89. LMWritePrinter(
  90. HANDLE hPrinter,
  91. LPVOID pBuf,
  92. DWORD cbBuf,
  93. LPDWORD pcWritten
  94. )
  95. {
  96. PWSPOOL pSpool=(PWSPOOL)hPrinter;
  97. DWORD cWritten, cTotal;
  98. DWORD rc;
  99. LPBYTE pByte=pBuf;
  100. VALIDATEW32HANDLE( pSpool );
  101. if (!(pSpool->Status & WSPOOL_STATUS_STARTDOC)) {
  102. SetLastError(ERROR_INVALID_PARAMETER);
  103. return FALSE;
  104. }
  105. if (pSpool->hFile == INVALID_HANDLE_VALUE) {
  106. *pcWritten = 0;
  107. SetLastError(ERROR_INVALID_HANDLE);
  108. return FALSE;
  109. }
  110. cWritten = cTotal = 0;
  111. while (cbBuf) {
  112. rc = WriteFile(pSpool->hFile, pByte, cbBuf, &cWritten, NULL);
  113. if (!rc) {
  114. rc = GetLastError();
  115. DBGMSG(DBG_WARNING, ("Win32 Spooler: Error writing to server, Error %d\n", rc));
  116. cTotal+=cWritten;
  117. *pcWritten=cTotal;
  118. return FALSE;
  119. } else if (!cWritten) {
  120. DBGMSG(DBG_ERROR, ("Spooler: Amount written is zero !!!\n"));
  121. }
  122. cTotal+=cWritten;
  123. cbBuf-=cWritten;
  124. pByte+=cWritten;
  125. }
  126. *pcWritten = cTotal;
  127. return TRUE;
  128. }
  129. BOOL
  130. LMEndPagePrinter(
  131. HANDLE hPrinter
  132. )
  133. {
  134. PWSPOOL pSpool = (PWSPOOL)hPrinter;
  135. VALIDATEW32HANDLE( pSpool );
  136. return FALSE;
  137. }
  138. BOOL
  139. LMAbortPrinter(
  140. HANDLE hPrinter
  141. )
  142. {
  143. PWSPOOL pSpool=(PWSPOOL)hPrinter;
  144. VALIDATEW32HANDLE( pSpool );
  145. return TRUE;
  146. }
  147. BOOL
  148. LMReadPrinter(
  149. HANDLE hPrinter,
  150. LPVOID pBuf,
  151. DWORD cbBuf,
  152. LPDWORD pNoBytesRead
  153. )
  154. {
  155. PWSPOOL pSpool=(PWSPOOL)hPrinter;
  156. VALIDATEW32HANDLE( pSpool );
  157. return 0;
  158. UNREFERENCED_PARAMETER(pBuf);
  159. UNREFERENCED_PARAMETER(pNoBytesRead);
  160. }
  161. BOOL
  162. LMEndDocPrinter(
  163. HANDLE hPrinter
  164. )
  165. {
  166. PWSPOOL pSpool=(PWSPOOL)hPrinter;
  167. VALIDATEW32HANDLE( pSpool );
  168. if (!(pSpool->Status & WSPOOL_STATUS_STARTDOC)) {
  169. SetLastError(ERROR_INVALID_HANDLE);
  170. return FALSE;
  171. }
  172. pSpool->Status &= ~WSPOOL_STATUS_STARTDOC;
  173. if (pSpool->hFile != INVALID_HANDLE_VALUE) {
  174. CloseHandle(pSpool->hFile);
  175. pSpool->hFile = INVALID_HANDLE_VALUE;
  176. }
  177. return TRUE;
  178. }
  179. BOOL
  180. LMAddJob(
  181. HANDLE hPrinter,
  182. DWORD Level,
  183. LPBYTE pData,
  184. DWORD cbBuf,
  185. LPDWORD pcbNeeded
  186. )
  187. {
  188. PWSPOOL pSpool=(PWSPOOL)hPrinter;
  189. DWORD cb;
  190. WCHAR szFileName[MAX_PATH];
  191. LPBYTE pEnd;
  192. LPADDJOB_INFO_1 pAddJob=(LPADDJOB_INFO_1)pData;
  193. VALIDATEW32HANDLE( pSpool );
  194. if(StrNCatBuff(szFileName,
  195. COUNTOF(szFileName),
  196. pSpool->pServer,
  197. L"\\",
  198. pSpool->pShare,
  199. NULL) != ERROR_SUCCESS)
  200. {
  201. return(FALSE);
  202. }
  203. cb = wcslen(szFileName)*sizeof(WCHAR) + sizeof(WCHAR) + sizeof(ADDJOB_INFO_1);
  204. if (cb > cbBuf) {
  205. *pcbNeeded=cb;
  206. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  207. return(FALSE);
  208. }
  209. pEnd = (LPBYTE)pAddJob+cbBuf;
  210. cb = wcslen(szFileName)*sizeof(WCHAR)+sizeof(WCHAR);
  211. pEnd -= cb;
  212. StringCbCopy((LPWSTR)pEnd, cb, szFileName);
  213. pAddJob->Path = (LPWSTR)pEnd;
  214. pAddJob->JobId = (DWORD)-1;
  215. return TRUE;
  216. }
  217. BOOL
  218. LMScheduleJob(
  219. HANDLE hPrinter,
  220. DWORD JobId
  221. )
  222. {
  223. PWSPOOL pSpool=(PWSPOOL)hPrinter;
  224. VALIDATEW32HANDLE( pSpool );
  225. JobId = JobId;
  226. return TRUE;
  227. }
  228. DWORD
  229. LMGetPrinterData(
  230. HANDLE hPrinter,
  231. LPTSTR pValueName,
  232. LPDWORD pType,
  233. LPBYTE pData,
  234. DWORD nSize,
  235. LPDWORD pcbNeeded
  236. )
  237. {
  238. PWSPOOL pSpool=(PWSPOOL)hPrinter;
  239. VALIDATEW32HANDLE( pSpool );
  240. return FALSE;
  241. }
  242. DWORD
  243. LMSetPrinterData(
  244. HANDLE hPrinter,
  245. LPTSTR pValueName,
  246. DWORD Type,
  247. LPBYTE pData,
  248. DWORD cbData
  249. )
  250. {
  251. PWSPOOL pSpool=(PWSPOOL)hPrinter;
  252. VALIDATEW32HANDLE( pSpool );
  253. return FALSE;
  254. }
  255. BOOL
  256. LMClosePrinter(
  257. HANDLE hPrinter
  258. )
  259. {
  260. PWSPOOL pSpool=(PWSPOOL)hPrinter;
  261. PLMNOTIFY pLMNotify = &pSpool->LMNotify;
  262. BOOL bReturnValue = FALSE;
  263. VALIDATEW32HANDLE( pSpool );
  264. EnterSplSem();
  265. if (pSpool->Status & WSPOOL_STATUS_STARTDOC)
  266. EndDocPrinter(hPrinter);
  267. if (pLMNotify->ChangeEvent) {
  268. if (pLMNotify->ChangeEvent != INVALID_HANDLE_VALUE) {
  269. CloseHandle(pLMNotify->ChangeEvent);
  270. } else {
  271. LMFindClosePrinterChangeNotification(hPrinter);
  272. }
  273. }
  274. bReturnValue = TRUE;
  275. LeaveSplSem();
  276. return bReturnValue;
  277. }
  278. DWORD
  279. LMWaitForPrinterChange(
  280. HANDLE hPrinter,
  281. DWORD Flags
  282. )
  283. {
  284. PWSPOOL pSpool = (PWSPOOL)hPrinter;
  285. PLMNOTIFY pLMNotify = &pSpool->LMNotify;
  286. HANDLE ChangeEvent;
  287. DWORD bReturnValue = FALSE;
  288. EnterSplSem();
  289. if (pLMNotify->ChangeEvent) {
  290. SetLastError(ERROR_ALREADY_WAITING);
  291. goto Error;
  292. }
  293. // Allocate memory for ChangeEvent for LanMan Printers
  294. // This event is pulsed by LMSetJob and any othe LM
  295. // function that modifies the printer/job status
  296. // LMWaitForPrinterChange waits on this event
  297. // being pulsed.
  298. ChangeEvent = CreateEvent(NULL,
  299. FALSE,
  300. FALSE,
  301. NULL);
  302. if (!ChangeEvent) {
  303. DBGMSG(DBG_WARNING, ("CreateEvent( ChangeEvent ) failed: Error %d\n",
  304. GetLastError()));
  305. goto Error;
  306. }
  307. pLMNotify->ChangeEvent = ChangeEvent;
  308. LeaveSplSem();
  309. WaitForSingleObject(pLMNotify->ChangeEvent, NOTIFY_TIMEOUT);
  310. CloseHandle(ChangeEvent);
  311. //
  312. // We shouldn't return that everything changed; we should
  313. // return what did.
  314. //
  315. return Flags;
  316. Error:
  317. LeaveSplSem();
  318. return 0;
  319. }
  320. BOOL
  321. LMFindFirstPrinterChangeNotification(
  322. HANDLE hPrinter,
  323. DWORD fdwFlags,
  324. DWORD fdwOptions,
  325. HANDLE hNotify,
  326. PDWORD pfdwStatus)
  327. {
  328. PWSPOOL pSpool = (PWSPOOL)hPrinter;
  329. PLMNOTIFY pLMNotify = &pSpool->LMNotify;
  330. EnterSplSem();
  331. pLMNotify->hNotify = hNotify;
  332. pLMNotify->fdwChangeFlags = fdwFlags;
  333. pLMNotify->ChangeEvent = INVALID_HANDLE_VALUE;
  334. *pfdwStatus = PRINTER_NOTIFY_STATUS_ENDPOINT | PRINTER_NOTIFY_STATUS_POLL;
  335. LeaveSplSem();
  336. return TRUE;
  337. }
  338. BOOL
  339. LMFindClosePrinterChangeNotification(
  340. HANDLE hPrinter)
  341. {
  342. PWSPOOL pSpool = (PWSPOOL)hPrinter;
  343. PLMNOTIFY pLMNotify = &pSpool->LMNotify;
  344. SplInSem();
  345. if (pLMNotify->ChangeEvent != INVALID_HANDLE_VALUE) {
  346. SetLastError(ERROR_INVALID_HANDLE);
  347. return FALSE;
  348. }
  349. pLMNotify->hNotify = NULL;
  350. pLMNotify->ChangeEvent = NULL;
  351. return TRUE;
  352. }
  353. VOID
  354. LMSetSpoolChange(
  355. PWSPOOL pSpool)
  356. {
  357. PLMNOTIFY pLMNotify;
  358. pLMNotify = &pSpool->LMNotify;
  359. EnterSplSem();
  360. if (pLMNotify->ChangeEvent) {
  361. if (pLMNotify->ChangeEvent == INVALID_HANDLE_VALUE) {
  362. //
  363. // FindFirstPrinterChangeNotification used.
  364. //
  365. ReplyPrinterChangeNotification(pLMNotify->hNotify,
  366. pLMNotify->fdwChangeFlags,
  367. NULL,
  368. NULL);
  369. } else {
  370. SetEvent(pLMNotify->ChangeEvent);
  371. }
  372. }
  373. LeaveSplSem();
  374. }