/* We need to report failures resulting from the user having insufficient * privilege differently from other errors. * This routine allows the caller to pass the resource ID of the string * to use for each eventuality. * * It assumes that the default error string contains one replaceable %s, * which will be replaced by the error returned. * * An attempt will also be made to find a generic error message. * * The error code is returned. * */ DWORD ReportFailure( HWND hwndParent, DWORD idInsufficientPrivilege, DWORD idDefaultError ) { DWORD ErrorID; DWORD MsgType = MSG_ERROR; LPTSTR pErrorString; ErrorID = GetLastError( ); if( ( ErrorID == ERROR_ACCESS_DENIED ) && ( idInsufficientPrivilege != 0 ) ) Message( hwndParent, MsgType, IDS_PRINTMANAGER, idInsufficientPrivilege ); else { pErrorString = GetErrorString( ErrorID ); Message( hwndParent, MsgType, IDS_PRINTMANAGER, idDefaultError, pErrorString ); FreeSplStr( pErrorString ); } return ErrorID; }
LPTSTR Make8dot3Name( LPTSTR pSourceName ) { LPTSTR p, pName; TCHAR NameBuffer[MAX_PRINTER_NAME_LEN+MAX_SHARE_NAME_LEN+1]; LPTSTR p8dot3Name = NULL; pName = pSourceName; /* Skip initial blanks: */ while( *pName && ( *pName == SPACE ) ) pName++; /* Skip over all backslashes: */ if( p = _tcsrchr( pName, BACKSLASH ) ) { /* If there's another character after the backslash, * make that the first character of the name: */ if( *(p+1) ) { pName = p+1; } /* Try to find another string before the backslash: */ else { /* Back through any backslashes at the end of the name: */ while( ( *p == BACKSLASH ) && ( p > pName ) ) p--; /* Back up to any preceding backslash or the beginning * of the name: */ while( ( *p != BACKSLASH ) && ( p > pName ) ) p--; if( *p == BACKSLASH ) p++; pName = p; } } /* Copy the complete name: */ _tcscpy( NameBuffer, pName ); StripBlanks( NameBuffer ); NameBuffer[8] = NULLC; FreeSplStr( pSourceName ); return AllocSplStr( NameBuffer ); }
BOOL DeletePrinterHandle( PSPOOL pSpool ) { BOOL bRet = FALSE; SplInSem(); if (pSpool->pIniPrintProc) { pSpool->pIniPrintProc->cRef--; } if (pSpool->pDevMode) FreeSplMem(pSpool->pDevMode); FreeSplStr(pSpool->pUserName); FreeSplStr(pSpool->pMachineName); FreeSplStr(pSpool->pDatatype); SetSpoolClosingChange(pSpool); FreeSplStr(pSpool->pName); bRet = ObjectCloseAuditAlarm( szSpooler, pSpool, pSpool->GenerateOnClose ); // // If there is a WaitForPrinterChange outstanding, we can't free // the pSpool, since we may try and reference it. // if (pSpool->ChangeEvent) { pSpool->eStatus |= STATUS_PENDING_DELETION; } else { FreeSplMem(pSpool); } return TRUE; }
BOOL ReallocSplStr( LPTSTR *plpStr, LPTSTR lpStr ) { FreeSplStr(*plpStr); *plpStr=AllocSplStr(lpStr); return TRUE; }
BOOL ReallocSplStr( LPWSTR *ppStr, LPWSTR pStr ) { LPWSTR pOldStr = *ppStr; *ppStr = AllocSplStr(pStr); FreeSplStr(pOldStr); if ( *ppStr == NULL && pStr != NULL ) { return FALSE; } return TRUE; }
BOOL BReleasePPData( _In_ PPRINTPROCESSORDATA * ppData ) { PPRINTPROCESSORDATA pData = NULL; if ( NULL == ppData || NULL == *ppData) { return FALSE; } pData = *ppData; pData->signature = 0; /* Release any allocated resources */ if (pData->hPrinter) ClosePrinter(pData->hPrinter); if (pData->hDC) DeleteDC(pData->hDC); if (pData->pDevmode) FreeSplMem(pData->pDevmode); if (pData->pPrinterNameFromOpenData) FreeSplStr(pData->pPrinterNameFromOpenData); if (pData->semPaused) CloseHandle(pData->semPaused); if (pData->pPrinterName) FreeSplStr(pData->pPrinterName); if (pData->pDatatype) FreeSplStr(pData->pDatatype); if (pData->pDocument) FreeSplStr(pData->pDocument); if (pData->pOutputFile) FreeSplStr(pData->pOutputFile); if (pData->pParameters) FreeSplStr(pData->pParameters); ZeroMemory ( pData, sizeof (PRINTPROCESSORDATA) ); FreeSplMem(pData); *ppData = pData = NULL; return TRUE; }
BOOL EndDocPort( HANDLE hPort ) { PINIPORT pIniPort = (PINIPORT)hPort; CloseHandle(pIniPort->hFile); SetJob(pIniPort->hPrinter, pIniPort->JobId, 0, NULL, JOB_CONTROL_CANCEL); ClosePrinter(pIniPort->hPrinter); EnterSplSem(); FreeSplStr(pIniPort->pPrinterName); LeaveSplSem(); return TRUE; }
BOOL StartDocPort( HANDLE hPort, LPWSTR pPrinterName, DWORD JobId, DWORD Level, LPBYTE pDocInfo ) { PINIPORT pIniPort = (PINIPORT)hPort; LPWSTR pFileName; pIniPort->hFile = INVALID_HANDLE_VALUE; EnterSplSem(); if (pIniPort->pPrinterName = AllocSplStr(pPrinterName)) { if (OpenPrinter(pPrinterName, &pIniPort->hPrinter, NULL)) { pIniPort->JobId = JobId; pFileName = pIniPort->pName; pIniPort->hFile = CreateFile(pFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } else FreeSplStr(pIniPort->pPrinterName); } LeaveSplSem(); if (pIniPort->hFile == INVALID_HANDLE_VALUE) { // DbgPrint("localmon!StartDocPort FAILED %x\n", GetLastError()); return FALSE; } else { return TRUE; } }
VOID DeletePortEntry( __in PINIPORT pIniPort ) /*++ Routine Description: Deletes a port entry. Needs to be called inside monitor critical section Arguments: pIniPort : Pointer to the IniPort structure to be deleted Return Value: --*/ { SplInSem(); if ( pIniPort == pIniFirstPort ) { pIniFirstPort = pIniPort->pNext; } else { PINIPORT pPort; pPort = pIniFirstPort; while ( pPort && pPort->pNext != pIniPort ) pPort = pPort->pNext; if (pPort) { pPort->pNext = pIniPort->pNext; } else { DBG_MSG(DBG_ERROR, ("pjlmon: DeletePortEntry port not found\n")); return; } } if (pIniPort-> DoneWriting) { CloseHandle(pIniPort->DoneWriting); pIniPort->DoneWriting = NULL; } if (pIniPort-> DoneReading) { CloseHandle(pIniPort->DoneReading); pIniPort->DoneReading = NULL; } if (pIniPort-> WakeUp) { CloseHandle(pIniPort->WakeUp); pIniPort->WakeUp = NULL; } if (pIniPort-> hUstatusThread) { CloseHandle (pIniPort-> hUstatusThread); pIniPort->hUstatusThread = NULL; } FreeIniJobs(pIniPort); FreeSplStr(pIniPort->pszPortName); pIniPort->pszPortName = NULL; FreeSplMem(pIniPort); return; }
HANDLE CreatePrinterHandle( LPWSTR pPrinterName, PINIPRINTER pIniPrinter, PINIPORT pIniPort, PINIPORT pIniNetPort, PINIJOB pIniJob, DWORD TypeofHandle, HANDLE hPort, PPRINTER_DEFAULTS pDefaults, PINISPOOLER pIniSpooler, DWORD AccessRequested, LPBYTE pSplClientInfo, DWORD dwLevel, HANDLE hReadFile ) { PSPOOL pSpool = NULL; BOOL bStatus = FALSE; HANDLE hReturnHandle = NULL; LPDEVMODE pDevMode = NULL; PSPLCLIENT_INFO_1 pSplClientInfo1 = (PSPLCLIENT_INFO_1)pSplClientInfo; SPLASSERT( pIniSpooler->signature == ISP_SIGNATURE ); if ( dwLevel && ( dwLevel != 1 || !pSplClientInfo) ) { DBGMSG(DBG_ERROR, ("CreatePrintHandle: Invalid client info %x - %d\n", pSplClientInfo, dwLevel)); pSplClientInfo = NULL; } try { pSpool = (PSPOOL)AllocSplMem( SPOOL_SIZE ); if ( pSpool == NULL ) { DBGMSG( DBG_WARNING, ("CreatePrinterHandle failed to allocate SPOOL %d\n", GetLastError() )); leave; } pSpool->signature = SJ_SIGNATURE; pSpool->pIniPrinter = pIniPrinter; pSpool->hReadFile = hReadFile; // // We get other useful info like build #, client architecture // we do not need this info now -- so we do not put it in PSPOOL // if ( (TypeofHandle & PRINTER_HANDLE_REMOTE) ) { if ( !pSplClientInfo ) { TypeofHandle |= PRINTER_HANDLE_3XCLIENT; } else if ( dwLevel == 1 ) { SPLASSERT(pSplClientInfo1->pUserName && pSplClientInfo1->pMachineName); pSpool->pUserName = AllocSplStr(pSplClientInfo1->pUserName); pSpool->pMachineName = AllocSplStr(pSplClientInfo1->pMachineName); if ( !pSpool->pUserName || !pSpool->pMachineName ) { DBGMSG(DBG_WARNING, ("CreatePrinterHandle: could not allocate memory for user name or machine name\n")); } } } if ( TypeofHandle & PRINTER_HANDLE_SERVER ) { bStatus = ValidateObjectAccess( SPOOLER_OBJECT_SERVER, AccessRequested, pSpool, pIniSpooler ); } else { bStatus = ValidateObjectAccess( SPOOLER_OBJECT_PRINTER, AccessRequested, pSpool, pIniSpooler ); } if ( !bStatus ) { SetLastError(ERROR_ACCESS_DENIED); leave; } MapGenericToSpecificAccess(SPOOLER_OBJECT_PRINTER, pSpool->GrantedAccess, &pSpool->GrantedAccess); pSpool->pIniPort = pIniPort; pSpool->pIniNetPort = pIniNetPort; pSpool->pIniJob = pIniJob; pSpool->TypeofHandle = TypeofHandle; pSpool->hPort = hPort; pSpool->Status = 0; pSpool->pDevMode = NULL; pSpool->pName = AllocSplStr( pPrinterName ); if ( pSpool->pName == NULL ) { leave; } pSpool->pIniSpooler = pIniSpooler; if ( pIniPrinter ) { if ( pDefaults ) { // // Allocate DevMode // if ( pDefaults->pDevMode ) { pDevMode = pDefaults->pDevMode; } else { pDevMode = pIniPrinter->pDevMode; } if ( pDevMode != NULL ) { pSpool->pDevMode = AllocSplMem( pDevMode->dmSize + pDevMode->dmDriverExtra ); if ( pSpool->pDevMode == NULL ) { DBGMSG(DBG_WARNING, ("CreatePrinterHandle failed allocation for devmode %d\n", GetLastError() )); leave; } memcpy( pSpool->pDevMode, pDevMode, pDevMode->dmSize + pDevMode->dmDriverExtra ); } } // // Allocate Datype and Print Processor // if ( pDefaults && pDefaults->pDatatype ) { pSpool->pDatatype = AllocSplStr( pDefaults->pDatatype ); pSpool->pIniPrintProc = FindDatatype( pIniPrinter->pIniPrintProc, pSpool->pDatatype ); } else { pSpool->pDatatype = AllocSplStr( pIniPrinter->pDatatype ); pSpool->pIniPrintProc = pIniPrinter->pIniPrintProc; } if ( pSpool->pIniPrintProc == NULL ) { DBGMSG( DBG_WARNING,("CreatePrinterHandle failed to PrintProcessor for datatype %ws %d\n", pSpool->pDatatype, GetLastError() )); leave; } SPLASSERT( pSpool->pIniPrintProc->signature == IPP_SIGNATURE ); pSpool->pIniPrintProc->cRef++; if ( pSpool->pDatatype == NULL ) { DBGMSG( DBG_WARNING,("CreatePrinterHandle failed to allocate DataType %x\n", GetLastError() )); leave; } } // Add us to the linked list of handles for this printer. // This will be scanned when a change occurs on the printer, // and will be updated with a flag indicating what type of // change it was. // There is a flag for each handle, because we cannot guarantee // that all threads will have time to reference a flag in the // INIPRINTER before it is updated. if ( TypeofHandle & PRINTER_HANDLE_PRINTER ) { pSpool->pNext = pSpool->pIniPrinter->pSpool; pSpool->pIniPrinter->pSpool = pSpool; } else if ( TypeofHandle & PRINTER_HANDLE_SERVER ) { // // For server handles, hang them off the global IniSpooler: // pSpool->pNext = pIniSpooler->pSpool; pIniSpooler->pSpool = pSpool; INCSPOOLERREF( pIniSpooler ); } // Note Only PRINTER_HANDLE_PRINTER are attatched to the // pIniPrinter, since those are the handle which will require // change notifications. if ( pSpool->pIniPrinter != NULL ) { INCPRINTERREF( pSpool->pIniPrinter ); } hReturnHandle = (HANDLE)pSpool; } finally { if ( hReturnHandle == NULL ) { // Failure CleanUP if ( pSpool != NULL ) { FreeSplStr(pSpool->pUserName); FreeSplStr(pSpool->pMachineName); FreeSplStr( pSpool->pName ) ; FreeSplStr( pSpool->pDatatype ); if ( pSpool->pIniPrintProc != NULL ) pSpool->pIniPrintProc->cRef--; if ( pSpool->pDevMode ) FreeSplMem( pSpool->pDevMode ); FreeSplMem( pSpool ); pSpool = NULL; } } } return hReturnHandle; }