|
|
/*****************************************************************************\
* MODULE: spljob.c * * This module contains the routines to deal with spooling a job to file. * * * Copyright (C) 1996-1997 Microsoft Corporation * Copyright (C) 1996-1997 Hewlett Packard * * History: * 07-Oct-1996 HWP-Guys Initiated port from win95 to winNT * 14-Nov-1997 ChrisWil Added local-spooling functionality. * \*****************************************************************************/
#include "precomp.h"
#include "priv.h"
/*****************************************************************************\
* Spl_GetCurDir * * Returns string indicating current-directory. * \*****************************************************************************/ LPTSTR Spl_GetCurDir(VOID) { DWORD cbSize; LPTSTR lpszDir = NULL;
cbSize = GetCurrentDirectory(0, NULL);
if (cbSize && (lpszDir = (LPTSTR)memAlloc((cbSize * sizeof(TCHAR))))) GetCurrentDirectory(cbSize, lpszDir);
return lpszDir; }
/*****************************************************************************\
* Spl_GetDir * * Returns the spooler-directory where print-jobs are processed. * \*****************************************************************************/ LPTSTR Spl_GetDir(VOID) { DWORD cbSize; LPTSTR lpszDir = NULL;
if (*g_szDefSplDir) { size_t uSize = lstrlen (g_szDefSplDir) + 1;
lpszDir = (LPTSTR) memAlloc(sizeof (TCHAR) * uSize);
if (lpszDir) { StringCchCopy(lpszDir, uSize, g_szDefSplDir); } }
return lpszDir; }
/*****************************************************************************\
* Spl_MemCheck (Local Routine) * * This routine checks for out-of-disk-space and out-of-memory conditions. * \*****************************************************************************/ VOID Spl_MemCheck( LPCTSTR lpszDir) { ULARGE_INTEGER i64FreeBytesToCaller; ULARGE_INTEGER i64TotalBytes; LPTSTR lpszRoot; LPTSTR lpszPtr;
// Look for out-of-diskspace
//
if (lpszRoot = memAllocStr(lpszDir)) {
// Set the path to be only a root-drive-path.
//
if (lpszPtr = utlStrChr(lpszRoot, TEXT('\\'))) {
lpszPtr++;
if (*lpszPtr != TEXT('\0')) *lpszPtr = TEXT('\0'); }
// Get the drive-space information.
//
if (GetDiskFreeSpaceEx (lpszRoot, &i64FreeBytesToCaller, &i64TotalBytes, NULL)) {
// We'll assume out-of-disk-space for anything less
// then MIN_DISK_SPACE.
//
if (i64FreeBytesToCaller.QuadPart <= MIN_DISK_SPACE) {
DBG_MSG(DBG_LEV_ERROR, (TEXT("Err : _inet_MemCheck : Out of disk space.")));
SetLastError(ERROR_DISK_FULL); } }
memFreeStr(lpszRoot);
} else {
DBG_MSG(DBG_LEV_ERROR, (TEXT("Err : _inet_MemCheck : Out of memory.")));
SetLastError(ERROR_OUTOFMEMORY); } }
/*****************************************************************************\
* Spl_OpnFile (Local Routine) * * This routine creates/opens a spool-file. * \*****************************************************************************/ HANDLE spl_OpnFile( LPCTSTR lpszFile) { HANDLE hFile;
hFile = CreateFile(lpszFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
return ((hFile && (hFile != INVALID_HANDLE_VALUE)) ? hFile : NULL); }
/*****************************************************************************\
* Spl_BldFile (Local Routine) * * This routine builds a spool-file-name. The returned file name is of the form. * c:\windows\system32\spool\printers\splnnn.tmp or * c:\windows\system32\spool\printers\tmpnnn.tmp * * The idJob argument is not used, it was previously used when the file * name was derived from the job id. This is not done anymore because it * leads to file name squatting issues in the spool directory. * \*****************************************************************************/ LPTSTR spl_BldFile( DWORD idJob, DWORD dwType) { static CONST TCHAR s_szSpl[] = TEXT("spl"); static CONST TCHAR s_szTmp[] = TEXT("tmp");
HRESULT hRetval = E_FAIL; LPTSTR pszDir = NULL; LPTSTR pszFile = NULL; LPTSTR pszSplFile = NULL; UINT cchSize = 0; LPCTSTR pszPrefix = dwType == SPLFILE_TMP ? s_szTmp : s_szSpl; TCHAR szBuffer[MAX_PATH] = {0};
pszDir = Spl_GetDir();
hRetval = pszDir ? S_OK : GetLastErrorAsHResultAndFail();
if (SUCCEEDED(hRetval)) { hRetval = GetTempFileName(pszDir, pszPrefix, 0, szBuffer) ? S_OK : GetLastErrorAsHResult(); }
if (SUCCEEDED(hRetval)) { cchSize = _tcslen(szBuffer) + 1;
pszFile = (LPTSTR)memAlloc(cchSize * sizeof(TCHAR));
hRetval = pszFile ? S_OK : E_OUTOFMEMORY; }
if (SUCCEEDED(hRetval)) { hRetval = StringCchCopy(pszFile, cchSize, szBuffer); }
if (SUCCEEDED(hRetval)) { pszSplFile = pszFile; pszFile = NULL; }
if (pszFile) { memFreeStr(pszFile); }
if (pszDir) { memFreeStr(pszDir); }
if (FAILED(hRetval)) { SetLastError(HRESULT_CODE(hRetval)); }
return pszSplFile; }
/*****************************************************************************\
* SplLock * * Open a stream interface to the spool file * \*****************************************************************************/ CFileStream* SplLock( HANDLE hSpl) { PSPLFILE pSpl; CFileStream *pStream = NULL;
if (pSpl = (PSPLFILE)hSpl) { pStream = new CFileStream (pSpl->hFile); pSpl->pStream = pStream; }
return pStream; }
/*****************************************************************************\
* SplUnlock * * Close our file-mapping. * \*****************************************************************************/ BOOL SplUnlock( HANDLE hSpl) { PSPLFILE pSpl; BOOL bRet = FALSE;
if (pSpl = (PSPLFILE)hSpl) {
if (pSpl->pStream) { delete pSpl->pStream;
pSpl->pStream = NULL; } }
return bRet; }
/*****************************************************************************\
* SplWrite * * Write data to our spool-file. * \*****************************************************************************/ BOOL SplWrite( HANDLE hSpl, LPBYTE lpData, DWORD cbData, LPDWORD lpcbWr) { PSPLFILE pSpl; BOOL bRet = FALSE; HANDLE hToken = RevertToPrinterSelf();
if (hToken) {
if (pSpl = (PSPLFILE)hSpl) {
// Write the data to our spool-file.
//
bRet = WriteFile(pSpl->hFile, lpData, cbData, lpcbWr, NULL);
// If we failed, or our bytes written aren't what we
// expected, then we need to check for out-of-memory.
//
if (!bRet || (cbData != *lpcbWr)) Spl_MemCheck(pSpl->lpszFile); }
if (!ImpersonatePrinterClient(hToken)) { bRet = FALSE; } }
return bRet; }
/*****************************************************************************\
* SplWrite * * Write data to our spool-file. * \*****************************************************************************/ BOOL SplWrite( HANDLE hSpl, CStream *pStream) { PSPLFILE pSpl; BOOL bRet = FALSE; static DWORD cbBufSize = 32 * 1024; //Copy size is 32K
PBYTE pBuf; DWORD cbTotal;
HANDLE hToken = RevertToPrinterSelf();
if (hToken) {
if (pSpl = (PSPLFILE)hSpl) {
pBuf = new BYTE[cbBufSize];
if (pBuf && pStream->GetTotalSize (&cbTotal)) {
DWORD cbRemain = cbTotal;
while (cbRemain > 0 && bRet) {
DWORD cbToRead = cbRemain > cbBufSize? cbBufSize:cbRemain; DWORD cbRead, cbWritten;
if (pStream->Read (pBuf, cbToRead, &cbRead) && cbToRead == cbRead) {
// Write the data to our spool-file.
//
bRet = WriteFile(pSpl->hFile, pBuf, cbRead, &cbWritten, NULL) && cbWritten == cbRead;
if (bRet) { cbRemain -= cbToRead; }
} else bRet = FALSE; }
// If we failed, or our bytes written aren't what we
// expected, then we need to check for out-of-memory.
//
if (!bRet) Spl_MemCheck(pSpl->lpszFile);
}
if (pBuf) { delete [] pBuf; }
}
if (!ImpersonatePrinterClient(hToken)) { bRet = FALSE; } }
return bRet; }
BOOL PrivateSplFree( HANDLE hSpl) { BOOL bRet = FALSE; PSPLFILE pSpl;
if (pSpl = (PSPLFILE)hSpl) {
if (pSpl->pStream) delete pSpl->pStream;
if (pSpl->hFile) CloseHandle(pSpl->hFile);
bRet = DeleteFile(pSpl->lpszFile);
if (pSpl->lpszFile) memFreeStr(pSpl->lpszFile);
memFree(pSpl, sizeof(SPLFILE)); } return bRet; }
/*****************************************************************************\
* SplFree (Local Routine) * * Free our spool-file. This will delete all information regarding the * file. * \*****************************************************************************/ BOOL SplFree( HANDLE hSpl) { PSPLFILE pSpl; BOOL bRet = FALSE; HANDLE hToken = RevertToPrinterSelf();
if (hToken) { bRet = PrivateSplFree (hSpl);
if (!ImpersonatePrinterClient(hToken)) { bRet = FALSE; } }
return bRet; }
/*****************************************************************************\
* SplCreate (Local Routine) * * Create a unique file for processing our spool-file. * \*****************************************************************************/ HANDLE SplCreate( DWORD idJob, DWORD dwType) { PSPLFILE pSpl = NULL; HANDLE hToken = RevertToPrinterSelf();
if (hToken) {
if (pSpl = (PSPLFILE) memAlloc(sizeof(SPLFILE))) {
if (pSpl->lpszFile = spl_BldFile(idJob, dwType)) {
if (pSpl->hFile = spl_OpnFile(pSpl->lpszFile)) {
pSpl->pStream = NULL;
} else {
memFreeStr(pSpl->lpszFile);
goto SplFail; }
} else {
SplFail: memFree(pSpl, sizeof(SPLFILE)); pSpl = NULL; } }
if (!ImpersonatePrinterClient(hToken)) { (VOID)PrivateSplFree (pSpl); pSpl = NULL; } }
return (HANDLE)pSpl; }
/*****************************************************************************\
* SplOpen (Local Routine) * * Open the handle to our spool-file. * \*****************************************************************************/ BOOL SplOpen( HANDLE hSpl) { PSPLFILE pSpl; BOOL bRet = FALSE; HANDLE hToken = RevertToPrinterSelf();
if (hToken) {
if (pSpl = (PSPLFILE)hSpl) {
if (pSpl->hFile == NULL) {
// Open the file and store it in the object.
//
pSpl->hFile = CreateFile(pSpl->lpszFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (!pSpl->hFile || (pSpl->hFile == INVALID_HANDLE_VALUE)) pSpl->hFile = NULL; else bRet = TRUE;
} else {
// Already open.
//
bRet = TRUE; } }
if (!ImpersonatePrinterClient(hToken)) { bRet = FALSE; } }
return bRet; }
/*****************************************************************************\
* SplClose * * Close the spool-file. * \*****************************************************************************/ BOOL SplClose( HANDLE hSpl) { PSPLFILE pSpl; BOOL bRet = FALSE; HANDLE hToken = RevertToPrinterSelf();
if (hToken) {
if (pSpl = (PSPLFILE)hSpl) {
if (pSpl->hFile) {
bRet = CloseHandle(pSpl->hFile); pSpl->hFile = NULL;
} else {
// Already closed.
//
bRet = TRUE; } }
if (!ImpersonatePrinterClient(hToken)) { bRet = FALSE; } }
return bRet; }
/*****************************************************************************\
* SplClean * * Cleans out all spool-files in the spool-directory. * \*****************************************************************************/ VOID SplClean(VOID) { LPTSTR lpszDir; LPTSTR lpszCur; LPTSTR lpszFiles; HANDLE hFind; DWORD cbSize; WIN32_FIND_DATA wfd;
static CONST TCHAR s_szFmt[] = TEXT("%s\\%s*.*");
// Get the spool-directory where our splipp files reside.
//
if (lpszDir = Spl_GetDir()) {
if (lpszCur = Spl_GetCurDir()) {
cbSize = utlStrSize(lpszDir) + utlStrSize(g_szSplPfx) + utlStrSize(s_szFmt);
if (lpszFiles = (LPTSTR)memAlloc(cbSize)) {
StringCbPrintf(lpszFiles, cbSize, s_szFmt, lpszDir, g_szSplPfx);
if (SetCurrentDirectory(lpszDir)) {
// Delete all the files that pertain to our criteria.
//
hFind = FindFirstFile(lpszFiles, &wfd);
if (hFind && (hFind != INVALID_HANDLE_VALUE)) {
do {
DeleteFile(wfd.cFileName);
} while (FindNextFile(hFind, &wfd));
FindClose(hFind); }
SetCurrentDirectory(lpszCur); }
memFreeStr(lpszFiles); }
memFreeStr(lpszCur); }
memFreeStr(lpszDir); } }
|