|
|
/*++
Copyright (c) 1994 - 1996 Microsoft Corporation
Module Name:
Files.c
Abstract:
This module contains routines for copying files specified under the CopyFiles key of a print queue
Author:
Muhunthan Sivapragasam (Muhunthan Sivapragasam) Nov-27-96
Revision History:
--*/
#include <precomp.h>
WCHAR *szSpoolDirectory = L"\\spool";
extern SPLCLIENT_INFO_1 gSplClientInfo1;
#define PRINTER_ENUM_KEY_SIZE 400
BOOL ProcessACopyFileKey( PWSPOOL pSpool, LPWSTR pszKey, LPWSTR pszModule, LPWSTR pszDir, LPWSTR ppszFiles, LPWSTR pszSourceDir, LPWSTR pszTargetDir, PSPLCLIENT_INFO_1 pSplClientInfo1 ) { BOOL bRet = FALSE, bFilesUpdated; DWORD dwLen, dwCount, dwTemp, dwSourceDirSize, dwTargetDirSize; LPWSTR *ppszFileNames = NULL, pszBuf = NULL, p1, p2; HINSTANCE hModule = NULL; DWORD (*pfn)(LPWSTR pszPrinterName, LPCWSTR pszDirectory, LPBYTE pSplClientInfo, DWORD dwLevel, LPWSTR pszSourceDir, LPDWORD pcchSourceDirSize, LPWSTR pszTargetDir, LPDWORD pcchTargetDirSize, DWORD dwFlags );
//
// If a module is given we need to call into to "correct" the path
// We will first try LoadLibrary on the module, if we can't find the module
// we will look in the driver directory for it
//
if ( pszModule && *pszModule ) {
if ( !(hModule = SplLoadLibraryTheCopyFileModule(pSpool, pszModule)) || !((FARPROC)pfn = GetProcAddress(hModule, "GenerateCopyFilePaths")) ) goto Cleanup;
dwSourceDirSize = dwTargetDirSize = MAX_PATH;
#if DBG
#else
try { #endif
//
// On free builds we do not want spooler to crash
//
if ( ERROR_SUCCESS != pfn(pSpool->pName, pszDir, (LPVOID)pSplClientInfo1, 1, pszSourceDir, &dwSourceDirSize, pszTargetDir, &dwTargetDirSize, COPYFILE_FLAG_CLIENT_SPOOLER) ) #if DBG
goto Cleanup; #else
leave; #endif
bRet = TRUE; #if DBG
#else
} except(1) { } #endif
if ( !bRet ) goto Cleanup;
} else {
bRet = TRUE; }
dwSourceDirSize = wcslen(pszSourceDir); dwTargetDirSize = wcslen(pszTargetDir);
pszSourceDir[dwSourceDirSize] = L'\\';
pszSourceDir[++dwSourceDirSize] = L'\0'; pszTargetDir[dwTargetDirSize] = L'\0';
//
// First find out number of files and size of one long buffer to put
// all filenames. We need to build fully qualified filenames in the source
// directory
//
for ( dwCount = dwLen = 0, p1 = ppszFiles ; *p1 ; p1 += dwTemp, ++dwCount ) {
dwTemp = wcslen(p1) + 1; dwLen += dwTemp + dwSourceDirSize; }
pszBuf = (LPWSTR) AllocSplMem(dwLen * sizeof(WCHAR)); ppszFileNames = (LPWSTR *) AllocSplMem(dwCount * sizeof(LPWSTR));
if ( !pszBuf || !ppszFileNames ) goto Cleanup;
for ( p1 = ppszFiles, p2 = pszBuf, dwCount = dwTemp = 0 ; *p1 ; p1 += wcslen(p1) + 1, ++dwCount ) {
StringCchCopyW(p2, dwLen, pszSourceDir); StringCchCopyW(p2 + dwSourceDirSize, dwLen - dwSourceDirSize, p1);
ppszFileNames[dwCount] = p2;
dwTemp += dwSourceDirSize + wcslen(p1) + 1; p2 = pszBuf + dwTemp; }
SPLASSERT(dwTemp == dwLen);
bRet = SplCopyNumberOfFiles(pSpool->pName, ppszFileNames, dwCount, pszTargetDir, &bFilesUpdated);
if ( bFilesUpdated ) (VOID) SplCopyFileEvent(pSpool->hSplPrinter, pszKey, COPYFILE_EVENT_FILES_CHANGED); Cleanup: if ( hModule ) FreeLibrary(hModule);
FreeSplMem(pszBuf); FreeSplMem(ppszFileNames);
return bRet; }
BOOL CopyFilesUnderAKey( PWSPOOL pSpool, LPWSTR pszSubKey, PSPLCLIENT_INFO_1 pSplClientInfo1 ) { BOOL bRet = FALSE; DWORD dwSize, dwLen, dwType, dwNeeded; WCHAR szSourceDir[MAX_PATH], szTargetDir[MAX_PATH]; LPWSTR pszDir, ppszFiles, pszModule;
pszDir = ppszFiles = pszModule = NULL;
dwSize = sizeof(szSourceDir);
if ( SplGetPrinterDataEx(pSpool->hSplPrinter, pszSubKey, L"Directory", &dwType, (LPBYTE)szSourceDir, dwSize, &dwNeeded) || dwType != REG_SZ || !(pszDir = AllocSplStr(szSourceDir)) || SplGetPrinterDataEx(pSpool->hSplPrinter, pszSubKey, L"SourceDir", &dwType, (LPBYTE)szSourceDir, dwSize, &dwNeeded) || dwType != REG_SZ || dwNeeded + sizeof(WCHAR) > dwSize || SplGetPrinterDataEx(pSpool->hSplPrinter, pszSubKey, L"Files", &dwType, (LPBYTE)szTargetDir, // Can't pass NULL
0, &dwNeeded) != ERROR_MORE_DATA || !(ppszFiles = (LPWSTR) AllocSplMem(dwNeeded)) || SplGetPrinterDataEx(pSpool->hSplPrinter, pszSubKey, L"Files", &dwType, (LPBYTE)ppszFiles, dwNeeded, &dwNeeded) || dwType != REG_MULTI_SZ ) {
goto Cleanup; }
//
// Module name is optional
//
dwLen = SplGetPrinterDataEx(pSpool->hSplPrinter, pszSubKey, L"Module", &dwType, (LPBYTE)szTargetDir, dwSize, &dwNeeded);
if ( dwLen == ERROR_SUCCESS ) {
if ( dwType != REG_SZ || !(pszModule = AllocSplStr(szTargetDir)) ) {
goto Cleanup; } } else if ( dwLen != ERROR_FILE_NOT_FOUND ) {
goto Cleanup; }
dwLen = dwSize; //
// Target directory we got from the server is relative to print$.
// We need to convert it to a fully qualified path now
//
if ( !SplGetDriverDir(pSpool->hIniSpooler, szTargetDir, &dwLen) ) goto Cleanup;
szTargetDir[dwLen-1] = L'\\';
dwSize -= dwLen * sizeof(WCHAR); if ( SplGetPrinterDataEx(pSpool->hSplPrinter, pszSubKey, L"TargetDir", &dwType, (LPBYTE)(szTargetDir + dwLen), dwSize, &dwNeeded) || dwType != REG_SZ ) {
goto Cleanup; }
bRet = ProcessACopyFileKey(pSpool, pszSubKey, pszModule, pszDir, ppszFiles, szSourceDir, szTargetDir, pSplClientInfo1);
Cleanup: FreeSplStr(pszDir); FreeSplStr(ppszFiles); FreeSplStr(pszModule);
return bRet; }
BOOL RefreshPrinterCopyFiles( PWSPOOL pSpool ) { DWORD dwNeeded, dwSize = 0, dwLastError; LPWSTR pszBuf = NULL, pszSubKey; WCHAR szUserName[MAX_PATH+1], szKey[MAX_PATH]; SPLCLIENT_INFO_1 SplClientInfo;
if ( pSpool->Type != SJ_WIN32HANDLE ) return TRUE;
SYNCRPCHANDLE(pSpool);
SPLASSERT(pSpool->Status & WSPOOL_STATUS_USE_CACHE);
//
// If it is a 3x server it is not going to support the rpc calls we need
// so there is nothing to copy
//
if ( pSpool->bNt3xServer ) return TRUE;
Retry:
dwLastError = SplEnumPrinterKey(pSpool->hSplPrinter, L"CopyFiles", pszBuf, dwSize, &dwNeeded);
//
// If first time size was not enough we will try once more with dwNeeded
//
if ( dwLastError == ERROR_MORE_DATA && dwSize == 0 && dwNeeded != 0 ) {
dwSize = dwNeeded; pszBuf = AllocSplMem(dwSize);
if ( !pszBuf ) goto Cleanup;
goto Retry; }
//
// If the call failed, or there was no sub key we are done
//
if ( dwLastError != ERROR_SUCCESS ) goto Cleanup;
CopyMemory((LPBYTE)&SplClientInfo, (LPBYTE)&gSplClientInfo1, sizeof(SplClientInfo));
SplClientInfo.pMachineName = SplClientInfo.pUserName = NULL;
for ( pszSubKey = pszBuf ; *pszSubKey ; pszSubKey += wcslen(pszSubKey) + 1 ) {
if ( sizeof(szKey)/sizeof(szKey[0]) > wcslen(L"CopyFiles") + wcslen(pszSubKey) ) {
StringCchPrintf(szKey, COUNTOF(szKey), L"%ws\\%ws", L"CopyFiles", pszSubKey);
CopyFilesUnderAKey(pSpool, szKey, &SplClientInfo); } else {
SPLASSERT(sizeof(szKey)/sizeof(szKey[0]) > wcslen(L"CopyFiles") + wcslen(pszSubKey)); } }
Cleanup: FreeSplMem(pszBuf);
return dwLastError == ERROR_SUCCESS; }
|