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.

660 lines
15 KiB

  1. /*****************************************************************************\
  2. * MODULE: spljob.c
  3. *
  4. * This module contains the routines to deal with spooling a job to file.
  5. *
  6. *
  7. * Copyright (C) 1996-1997 Microsoft Corporation
  8. * Copyright (C) 1996-1997 Hewlett Packard
  9. *
  10. * History:
  11. * 07-Oct-1996 HWP-Guys Initiated port from win95 to winNT
  12. * 14-Nov-1997 ChrisWil Added local-spooling functionality.
  13. *
  14. \*****************************************************************************/
  15. #include "precomp.h"
  16. #include "priv.h"
  17. /*****************************************************************************\
  18. * Spl_GetCurDir
  19. *
  20. * Returns string indicating current-directory.
  21. *
  22. \*****************************************************************************/
  23. LPTSTR Spl_GetCurDir(VOID)
  24. {
  25. DWORD cbSize;
  26. LPTSTR lpszDir = NULL;
  27. cbSize = GetCurrentDirectory(0, NULL);
  28. if (cbSize && (lpszDir = (LPTSTR)memAlloc((cbSize * sizeof(TCHAR)))))
  29. GetCurrentDirectory(cbSize, lpszDir);
  30. return lpszDir;
  31. }
  32. /*****************************************************************************\
  33. * Spl_GetDir
  34. *
  35. * Returns the spooler-directory where print-jobs are processed.
  36. *
  37. \*****************************************************************************/
  38. LPTSTR Spl_GetDir(VOID)
  39. {
  40. DWORD cbSize;
  41. LPTSTR lpszDir = NULL;
  42. #ifdef WINNT32
  43. if (*g_szDefSplDir &&
  44. (lpszDir = (LPTSTR) memAlloc(sizeof (TCHAR) * (lstrlen (g_szDefSplDir) + 1)))) {
  45. lstrcpy (lpszDir, g_szDefSplDir);
  46. }
  47. #else
  48. cbSize = GetWindowsDirectory(NULL, 0);
  49. if (cbSize && (lpszDir = (LPTSTR)memAlloc( cbSize + lstrlen(g_szSplDir9X) ))) {
  50. if (GetWindowsDirectory(lpszDir, cbSize))
  51. lstrcat(lpszDir, g_szSplDir9X);
  52. }
  53. #endif
  54. return lpszDir;
  55. }
  56. /*****************************************************************************\
  57. * Spl_MemCheck (Local Routine)
  58. *
  59. * This routine checks for out-of-disk-space and out-of-memory conditions.
  60. *
  61. \*****************************************************************************/
  62. VOID Spl_MemCheck(
  63. LPCTSTR lpszDir)
  64. {
  65. #ifdef WINNT32
  66. ULARGE_INTEGER i64FreeBytesToCaller;
  67. ULARGE_INTEGER i64TotalBytes;
  68. #else
  69. DWORD dwSpC;
  70. DWORD dwBpS;
  71. DWORD dwNoF;
  72. DWORD dwNoC;
  73. #endif
  74. LPTSTR lpszRoot;
  75. LPTSTR lpszPtr;
  76. // Look for out-of-diskspace
  77. //
  78. if (lpszRoot = memAllocStr(lpszDir)) {
  79. // Set the path to be only a root-drive-path.
  80. //
  81. if (lpszPtr = utlStrChr(lpszRoot, TEXT('\\'))) {
  82. lpszPtr++;
  83. if (*lpszPtr != TEXT('\0'))
  84. *lpszPtr = TEXT('\0');
  85. }
  86. #ifdef WINNT32
  87. // Get the drive-space information.
  88. //
  89. if (GetDiskFreeSpaceEx (lpszRoot, &i64FreeBytesToCaller, &i64TotalBytes, NULL)) {
  90. // We'll assume out-of-disk-space for anything less
  91. // then MIN_DISK_SPACE.
  92. //
  93. if (i64FreeBytesToCaller.QuadPart <= MIN_DISK_SPACE) {
  94. DBG_MSG(DBG_LEV_ERROR, (TEXT("Err : _inet_MemCheck : Out of disk space.")));
  95. SetLastError(ERROR_DISK_FULL);
  96. }
  97. }
  98. #else
  99. // Get the drive-space information.
  100. //
  101. if (GetDiskFreeSpace(lpszRoot, &dwSpC, &dwBpS, &dwNoF, &dwNoC)) {
  102. // We'll assume out-of-disk-space for anything less
  103. // then MIN_DISK_SPACE.
  104. //
  105. if (((dwSpC * dwBpS) * dwNoF) <= MIN_DISK_SPACE) {
  106. DBG_MSG(DBG_LEV_ERROR, (TEXT("Err : _inet_MemCheck : Out of disk space.")));
  107. SetLastError(ERROR_DISK_FULL);
  108. }
  109. }
  110. #endif
  111. memFreeStr(lpszRoot);
  112. } else {
  113. DBG_MSG(DBG_LEV_ERROR, (TEXT("Err : _inet_MemCheck : Out of memory.")));
  114. SetLastError(ERROR_OUTOFMEMORY);
  115. }
  116. }
  117. /*****************************************************************************\
  118. * Spl_OpnFile (Local Routine)
  119. *
  120. * This routine creates/opens a spool-file.
  121. *
  122. \*****************************************************************************/
  123. HANDLE spl_OpnFile(
  124. LPCTSTR lpszFile)
  125. {
  126. HANDLE hFile;
  127. hFile = CreateFile(lpszFile,
  128. GENERIC_READ | GENERIC_WRITE,
  129. 0,
  130. NULL,
  131. CREATE_ALWAYS,
  132. FILE_ATTRIBUTE_NORMAL,
  133. NULL);
  134. return ((hFile && (hFile != INVALID_HANDLE_VALUE)) ? hFile : NULL);
  135. }
  136. /*****************************************************************************\
  137. * Spl_BldFile (Local Routine)
  138. *
  139. * This routine builds a spool-file-name.
  140. *
  141. \*****************************************************************************/
  142. LPTSTR spl_BldFile(
  143. DWORD idJob,
  144. DWORD dwType)
  145. {
  146. DWORD cbSize;
  147. LPTSTR lpszDir;
  148. LPTSTR lpszFile = NULL;
  149. static CONST TCHAR s_szFmt[] = TEXT("%s\\%s%05X.%s");
  150. static CONST TCHAR s_szSpl[] = TEXT("spl");
  151. static CONST TCHAR s_szTmp[] = TEXT("tmp");
  152. if (lpszDir = Spl_GetDir()) {
  153. cbSize = utlStrSize(lpszDir) +
  154. utlStrSize(g_szSplPfx) +
  155. utlStrSize(s_szFmt) +
  156. 80;
  157. if (lpszFile = (LPTSTR)memAlloc(cbSize)) {
  158. wsprintf(lpszFile,
  159. s_szFmt,
  160. lpszDir,
  161. g_szSplPfx,
  162. idJob,
  163. (dwType == SPLFILE_TMP ? s_szTmp : s_szSpl));
  164. }
  165. memFreeStr(lpszDir);
  166. }
  167. return lpszFile;
  168. }
  169. /*****************************************************************************\
  170. * SplLock
  171. *
  172. * Open a stream interface to the spool file
  173. *
  174. \*****************************************************************************/
  175. CFileStream* SplLock(
  176. HANDLE hSpl)
  177. {
  178. PSPLFILE pSpl;
  179. CFileStream *pStream = NULL;
  180. if (pSpl = (PSPLFILE)hSpl) {
  181. pStream = new CFileStream (pSpl->hFile);
  182. pSpl->pStream = pStream;
  183. }
  184. return pStream;
  185. }
  186. /*****************************************************************************\
  187. * SplUnlock
  188. *
  189. * Close our file-mapping.
  190. *
  191. \*****************************************************************************/
  192. BOOL SplUnlock(
  193. HANDLE hSpl)
  194. {
  195. PSPLFILE pSpl;
  196. BOOL bRet = FALSE;
  197. if (pSpl = (PSPLFILE)hSpl) {
  198. if (pSpl->pStream) {
  199. delete pSpl->pStream;
  200. pSpl->pStream = NULL;
  201. }
  202. }
  203. return bRet;
  204. }
  205. /*****************************************************************************\
  206. * SplWrite
  207. *
  208. * Write data to our spool-file.
  209. *
  210. \*****************************************************************************/
  211. BOOL SplWrite(
  212. HANDLE hSpl,
  213. LPBYTE lpData,
  214. DWORD cbData,
  215. LPDWORD lpcbWr)
  216. {
  217. PSPLFILE pSpl;
  218. BOOL bRet = FALSE;
  219. #ifdef WINNT32
  220. HANDLE hToken = RevertToPrinterSelf();
  221. if (hToken) {
  222. #endif
  223. if (pSpl = (PSPLFILE)hSpl) {
  224. // Write the data to our spool-file.
  225. //
  226. bRet = WriteFile(pSpl->hFile, lpData, cbData, lpcbWr, NULL);
  227. // If we failed, or our bytes written aren't what we
  228. // expected, then we need to check for out-of-memory.
  229. //
  230. if (!bRet || (cbData != *lpcbWr))
  231. Spl_MemCheck(pSpl->lpszFile);
  232. }
  233. #ifdef WINNT32
  234. if (!ImpersonatePrinterClient(hToken))
  235. {
  236. bRet = FALSE;
  237. }
  238. }
  239. #endif
  240. return bRet;
  241. }
  242. /*****************************************************************************\
  243. * SplWrite
  244. *
  245. * Write data to our spool-file.
  246. *
  247. \*****************************************************************************/
  248. BOOL SplWrite(
  249. HANDLE hSpl,
  250. CStream *pStream)
  251. {
  252. PSPLFILE pSpl;
  253. BOOL bRet = FALSE;
  254. static DWORD cbBufSize = 32 * 1024; //Copy size is 32K
  255. PBYTE pBuf;
  256. DWORD cbTotal;
  257. #ifdef WINNT32
  258. HANDLE hToken = RevertToPrinterSelf();
  259. if (hToken) {
  260. #endif
  261. if (pSpl = (PSPLFILE)hSpl) {
  262. pBuf = new BYTE[cbBufSize];
  263. if (pBuf && pStream->GetTotalSize (&cbTotal)) {
  264. DWORD cbRemain = cbTotal;
  265. while (cbRemain > 0 && bRet) {
  266. DWORD cbToRead = cbRemain > cbBufSize? cbBufSize:cbRemain;
  267. DWORD cbRead, cbWritten;
  268. if (pStream->Read (pBuf, cbToRead, &cbRead) && cbToRead == cbRead) {
  269. // Write the data to our spool-file.
  270. //
  271. bRet = WriteFile(pSpl->hFile, pBuf, cbRead, &cbWritten, NULL)
  272. && cbWritten == cbRead;
  273. if (bRet) {
  274. cbRemain -= cbToRead;
  275. }
  276. }
  277. else
  278. bRet = FALSE;
  279. }
  280. // If we failed, or our bytes written aren't what we
  281. // expected, then we need to check for out-of-memory.
  282. //
  283. if (!bRet)
  284. Spl_MemCheck(pSpl->lpszFile);
  285. }
  286. if (pBuf) {
  287. delete [] pBuf;
  288. }
  289. }
  290. #ifdef WINNT32
  291. if (!ImpersonatePrinterClient(hToken))
  292. {
  293. bRet = FALSE;
  294. }
  295. }
  296. #endif
  297. return bRet;
  298. }
  299. BOOL PrivateSplFree(
  300. HANDLE hSpl)
  301. {
  302. BOOL bRet = FALSE;
  303. PSPLFILE pSpl;
  304. if (pSpl = (PSPLFILE)hSpl) {
  305. if (pSpl->pStream)
  306. delete pSpl->pStream;
  307. if (pSpl->hFile)
  308. CloseHandle(pSpl->hFile);
  309. bRet = DeleteFile(pSpl->lpszFile);
  310. if (pSpl->lpszFile)
  311. memFreeStr(pSpl->lpszFile);
  312. memFree(pSpl, sizeof(SPLFILE));
  313. }
  314. return bRet;
  315. }
  316. /*****************************************************************************\
  317. * SplFree (Local Routine)
  318. *
  319. * Free our spool-file. This will delete all information regarding the
  320. * file.
  321. *
  322. \*****************************************************************************/
  323. BOOL SplFree(
  324. HANDLE hSpl)
  325. {
  326. PSPLFILE pSpl;
  327. BOOL bRet = FALSE;
  328. #ifdef WINNT32
  329. HANDLE hToken = RevertToPrinterSelf();
  330. if (hToken) {
  331. #endif
  332. bRet = PrivateSplFree (hSpl);
  333. #ifdef WINNT32
  334. if (!ImpersonatePrinterClient(hToken))
  335. {
  336. bRet = FALSE;
  337. }
  338. }
  339. #endif
  340. return bRet;
  341. }
  342. /*****************************************************************************\
  343. * SplCreate (Local Routine)
  344. *
  345. * Create a unique file for processing our spool-file.
  346. *
  347. \*****************************************************************************/
  348. HANDLE SplCreate(
  349. DWORD idJob,
  350. DWORD dwType)
  351. {
  352. PSPLFILE pSpl = NULL;
  353. #ifdef WINNT32
  354. HANDLE hToken = RevertToPrinterSelf();
  355. if (hToken) {
  356. #endif
  357. if (pSpl = (PSPLFILE) memAlloc(sizeof(SPLFILE))) {
  358. if (pSpl->lpszFile = spl_BldFile(idJob, dwType)) {
  359. if (pSpl->hFile = spl_OpnFile(pSpl->lpszFile)) {
  360. pSpl->pStream = NULL;
  361. } else {
  362. memFreeStr(pSpl->lpszFile);
  363. goto SplFail;
  364. }
  365. } else {
  366. SplFail:
  367. memFree(pSpl, sizeof(SPLFILE));
  368. pSpl = NULL;
  369. }
  370. }
  371. #ifdef WINNT32
  372. if (!ImpersonatePrinterClient(hToken))
  373. {
  374. (VOID)PrivateSplFree (pSpl);
  375. pSpl = NULL;
  376. }
  377. }
  378. #endif
  379. return (HANDLE)pSpl;
  380. }
  381. /*****************************************************************************\
  382. * SplOpen (Local Routine)
  383. *
  384. * Open the handle to our spool-file.
  385. *
  386. \*****************************************************************************/
  387. BOOL SplOpen(
  388. HANDLE hSpl)
  389. {
  390. PSPLFILE pSpl;
  391. BOOL bRet = FALSE;
  392. #ifdef WINNT32
  393. HANDLE hToken = RevertToPrinterSelf();
  394. if (hToken) {
  395. #endif
  396. if (pSpl = (PSPLFILE)hSpl) {
  397. if (pSpl->hFile == NULL) {
  398. // Open the file and store it in the object.
  399. //
  400. pSpl->hFile = CreateFile(pSpl->lpszFile,
  401. GENERIC_READ | GENERIC_WRITE,
  402. 0,
  403. NULL,
  404. OPEN_EXISTING,
  405. FILE_ATTRIBUTE_NORMAL,
  406. NULL);
  407. if (!pSpl->hFile || (pSpl->hFile == INVALID_HANDLE_VALUE))
  408. pSpl->hFile = NULL;
  409. else
  410. bRet = TRUE;
  411. } else {
  412. // Already open.
  413. //
  414. bRet = TRUE;
  415. }
  416. }
  417. #ifdef WINNT32
  418. if (!ImpersonatePrinterClient(hToken))
  419. {
  420. bRet = FALSE;
  421. }
  422. }
  423. #endif
  424. return bRet;
  425. }
  426. /*****************************************************************************\
  427. * SplClose
  428. *
  429. * Close the spool-file.
  430. *
  431. \*****************************************************************************/
  432. BOOL SplClose(
  433. HANDLE hSpl)
  434. {
  435. PSPLFILE pSpl;
  436. BOOL bRet = FALSE;
  437. #ifdef WINNT32
  438. HANDLE hToken = RevertToPrinterSelf();
  439. if (hToken) {
  440. #endif
  441. if (pSpl = (PSPLFILE)hSpl) {
  442. if (pSpl->hFile) {
  443. bRet = CloseHandle(pSpl->hFile);
  444. pSpl->hFile = NULL;
  445. } else {
  446. // Already closed.
  447. //
  448. bRet = TRUE;
  449. }
  450. }
  451. #ifdef WINNT32
  452. if (!ImpersonatePrinterClient(hToken))
  453. {
  454. bRet = FALSE;
  455. }
  456. }
  457. #endif
  458. return bRet;
  459. }
  460. /*****************************************************************************\
  461. * SplClean
  462. *
  463. * Cleans out all spool-files in the spool-directory.
  464. *
  465. \*****************************************************************************/
  466. VOID SplClean(VOID)
  467. {
  468. LPTSTR lpszDir;
  469. LPTSTR lpszCur;
  470. LPTSTR lpszFiles;
  471. HANDLE hFind;
  472. DWORD cbSize;
  473. WIN32_FIND_DATA wfd;
  474. static CONST TCHAR s_szFmt[] = TEXT("%s\\%s*.*");
  475. // Get the spool-directory where our splipp files reside.
  476. //
  477. if (lpszDir = Spl_GetDir()) {
  478. if (lpszCur = Spl_GetCurDir()) {
  479. cbSize = utlStrSize(lpszDir) +
  480. utlStrSize(g_szSplPfx) +
  481. utlStrSize(s_szFmt);
  482. if (lpszFiles = (LPTSTR)memAlloc(cbSize)) {
  483. wsprintf(lpszFiles, s_szFmt, lpszDir, g_szSplPfx);
  484. if (SetCurrentDirectory(lpszDir)) {
  485. // Delete all the files that pertain to our criteria.
  486. //
  487. hFind = FindFirstFile(lpszFiles, &wfd);
  488. if (hFind && (hFind != INVALID_HANDLE_VALUE)) {
  489. do {
  490. DeleteFile(wfd.cFileName);
  491. } while (FindNextFile(hFind, &wfd));
  492. FindClose(hFind);
  493. }
  494. SetCurrentDirectory(lpszCur);
  495. }
  496. memFreeStr(lpszFiles);
  497. }
  498. memFreeStr(lpszCur);
  499. }
  500. memFreeStr(lpszDir);
  501. }
  502. }