BOOL IrdaStartDocPort( _Inout_ PLCMINIPORT pIniPort ) { HANDLE hToken = NULL; DWORD dwLastError = ERROR_SUCCESS; // // If remote guest is the first user to print, then the connect fails. // Thus we need to revert to system context before calling IrdaConnect // hToken = RevertToPrinterSelf(); if (!hToken) { return FALSE; } dwLastError = IrdaConnect(pIniPort); ImpersonatePrinterClient(hToken); if ( dwLastError ) { SetLastError(dwLastError); return FALSE; } else return TRUE; }
/** * @name _HandleSetDefaultCommConfig * * Sets the default configuration of a legacy port. Checks for granted SERVER_ACCESS_ADMINISTER access. * You have to supply the port name (with colon!) in XcvOpenPort. * The opposite function is _HandleGetDefaultCommConfig. * * @param pXcv * Pointer to the LOCALMON_XCV structure of the currently opened Xcv port. * * @param pInputData * Pointer to the COMMCONFIG structure that shall be passed to SetDefaultCommConfigW. * * @param pcbOutputNeeded * Pointer to a DWORD that will be zeroed on return. * * @return * An error code indicating success or failure. */ static DWORD _HandleSetDefaultCommConfig(PLOCALMON_XCV pXcv, PBYTE pInputData, PDWORD pcbOutputNeeded) { DWORD dwErrorCode; HANDLE hToken = NULL; LPCOMMCONFIG pCommConfig; PWSTR pwszPortNameWithoutColon = NULL; // Sanity checks // pwszObject needs to be at least 2 characters long to be a port name with a trailing colon. if (!pXcv || !pXcv->pwszObject || !pXcv->pwszObject[0] || !pXcv->pwszObject[1] || !pInputData || !pcbOutputNeeded) { dwErrorCode = ERROR_INVALID_PARAMETER; goto Cleanup; } *pcbOutputNeeded = 0; // This action can only happen at SERVER_ACCESS_ADMINISTER access level. if (!(pXcv->GrantedAccess & SERVER_ACCESS_ADMINISTER)) { dwErrorCode = ERROR_ACCESS_DENIED; goto Cleanup; } // SetDefaultCommConfigW needs the port name without colon. dwErrorCode = GetPortNameWithoutColon(pXcv->pwszObject, &pwszPortNameWithoutColon); if (dwErrorCode != ERROR_SUCCESS) goto Cleanup; // Switch to the SYSTEM context for setting the port configuration. hToken = RevertToPrinterSelf(); if (!hToken) { dwErrorCode = GetLastError(); ERR("RevertToPrinterSelf failed with error %lu!\n", dwErrorCode); goto Cleanup; } // Finally pass the parameters to SetDefaultCommConfigW. pCommConfig = (LPCOMMCONFIG)pInputData; if (!SetDefaultCommConfigW(pwszPortNameWithoutColon, pCommConfig, pCommConfig->dwSize)) { dwErrorCode = GetLastError(); ERR("SetDefaultCommConfigW failed with error %lu!\n", dwErrorCode); goto Cleanup; } dwErrorCode = ERROR_SUCCESS; Cleanup: if (hToken) ImpersonatePrinterClient(hToken); if (pwszPortNameWithoutColon) DllFreeSplMem(pwszPortNameWithoutColon); return dwErrorCode; }
/** * @name _HandleConfigureLPTPortCommandOK * * Writes the value for "TransmissionRetryTimeout" to the registry. Checks for granted SERVER_ACCESS_ADMINISTER access. * Actually the opposite of _HandleGetTransmissionRetryTimeout, but name kept for compatibility. * * @param pXcv * Pointer to the LOCALMON_XCV structure of the currently opened Xcv port. * * @param pInputData * Pointer to a Unicode string containing the value to be written to the registry. * * @param pcbOutputNeeded * Pointer to a DWORD that will be zeroed on return. * * @return * An error code indicating success or failure. */ static DWORD _HandleConfigureLPTPortCommandOK(PLOCALMON_XCV pXcv, PBYTE pInputData, PDWORD pcbOutputNeeded) { DWORD cbBuffer; DWORD dwErrorCode; HKEY hKey = NULL; HKEY hToken = NULL; // Sanity checks if (!pXcv || !pInputData || !pcbOutputNeeded) { dwErrorCode = ERROR_INVALID_PARAMETER; goto Cleanup; } *pcbOutputNeeded = 0; // This action can only happen at SERVER_ACCESS_ADMINISTER access level. if (!(pXcv->GrantedAccess & SERVER_ACCESS_ADMINISTER)) { dwErrorCode = ERROR_ACCESS_DENIED; goto Cleanup; } // Switch to the SYSTEM context for modifying the registry. hToken = RevertToPrinterSelf(); if (!hToken) { dwErrorCode = GetLastError(); ERR("RevertToPrinterSelf failed with error %lu!\n", dwErrorCode); goto Cleanup; } // Open the key where our value is stored. dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows", 0, KEY_SET_VALUE, &hKey); if (dwErrorCode != ERROR_SUCCESS) { ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode); goto Cleanup; } // We don't use cbInputData here, because the buffer pInputData could be bigger than the data it contains. cbBuffer = (wcslen((PWSTR)pInputData) + 1) * sizeof(WCHAR); // Write the value to the registry. dwErrorCode = (DWORD)RegSetValueExW(hKey, L"TransmissionRetryTimeout", 0, REG_SZ, pInputData, cbBuffer); if (dwErrorCode != ERROR_SUCCESS) { ERR("RegSetValueExW failed with status %lu!\n", dwErrorCode); goto Cleanup; } Cleanup: if (hKey) RegCloseKey(hKey); if (hToken) ImpersonatePrinterClient(hToken); return dwErrorCode; }
DWORD CheckPrinterJobToken( LPCWSTR string, LPCWSTR pSecondPart, PDWORD pTypeofHandle, PINIPRINTER* ppIniPrinter, PINIJOB* ppIniJob, PHANDLE phReadFile, const PINISPOOLER pIniSpooler ) { HANDLE hImpersonationToken; DWORD Position; DWORD JobId; PINIPRINTER pIniPrinter; PINIJOB pIniJob, pCurrentIniJob; if( wcsncmp( pSecondPart, L"Job ", 4 ) != STRINGS_ARE_EQUAL || !( pIniPrinter = FindPrinter( string ))){ return ROUTER_UNKNOWN; } // // Get the Job ID ",Job xxxx" // pSecondPart += 4; JobId = Myatol( (LPWSTR)pSecondPart ); pIniJob = FindJob( pIniPrinter, JobId, &Position ); if( pIniJob == NULL ) { DBGMSG( DBG_WARN, ("OpenPrinter failed to find Job %d\n", JobId )); return ROUTER_UNKNOWN; } DBGMSG( DBG_TRACE, ("OpenPrinter: pIniJob->cRef = %d\n", pIniJob->cRef)); if( pIniJob->Status & JOB_DIRECT ) { SplInSem(); INCJOBREF( pIniJob ); *pTypeofHandle |= PRINTER_HANDLE_JOB | PRINTER_HANDLE_DIRECT; goto Success; } // // If this job is assigned to a port // Then pick up the correct chained jobid file instead of the master // JobId. // if ( pIniJob->pCurrentIniJob != NULL ) { SPLASSERT( pIniJob->pCurrentIniJob->signature == IJ_SIGNATURE ); DBGMSG( DBG_TRACE,("CheckPrinterJobToken pIniJob %x JobId %d using chain JobId %d\n", pIniJob, pIniJob->JobId, pIniJob->pCurrentIniJob->JobId )); pCurrentIniJob = pIniJob->pCurrentIniJob; SPLASSERT( pCurrentIniJob->signature == IJ_SIGNATURE ); } else { pCurrentIniJob = pIniJob; } GetFullNameFromId( pCurrentIniJob->pIniPrinter, pCurrentIniJob->JobId, TRUE, (LPWSTR)string, FALSE ); // !! BUGBUG !! // Even a user without previledge can open a ", JOB #" // if he is physically running on the machine. hImpersonationToken = RevertToPrinterSelf(); *phReadFile = CreateFile( string, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL ); ImpersonatePrinterClient( hImpersonationToken ); if( *phReadFile != INVALID_HANDLE_VALUE ) { DBGMSG( DBG_TRACE, ("OpenPrinter JobID %d pIniJob %x CreateFile( %ws ), hReadFile %x success", JobId, pIniJob, string, *phReadFile )); SplInSem(); INCJOBREF( pIniJob ); *pTypeofHandle |= PRINTER_HANDLE_JOB; goto Success; } DBGMSG( DBG_WARNING, ("LocalOpenPrinter CreateFile(%ws) GENERIC_READ failed : %d\n", string, GetLastError())); SPLASSERT( GetLastError( )); return ROUTER_STOP_ROUTING; Success: *ppIniJob = pIniJob; *ppIniPrinter = pIniPrinter; return ROUTER_SUCCESS; }