Leaked source code of windows server 2003
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.
 
 
 
 
 
 

609 lines
14 KiB

/*++
Copyright (c) 1990-1994 Microsoft Corporation
All rights reserved
Module Name:
monitor.c
Abstract:
Author:
Environment:
User Mode -Win32
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#include "local.h"
BOOL
GetPortInfo2UsingPortInfo1(
LPPROVIDOR pProvidor,
LPWSTR pName,
LPBYTE pPorts,
DWORD cbBuf,
LPDWORD pcbNeeded,
LPDWORD pcReturned
)
{
BOOL bRet;
LPPORT_INFO_1 pPortInfo1;
LPPORT_INFO_2 pPortInfo2;
DWORD cReturned;
bRet = (*pProvidor->PrintProvidor.fpEnumPorts) (pName, 1, pPorts, cbBuf,
pcbNeeded, pcReturned);
if ( !bRet ) {
//
// This is the upperbound
//
if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
*pcbNeeded += (*pcbNeeded / sizeof(PORT_INFO_1)) *
(sizeof(PORT_INFO_2) - sizeof(PORT_INFO_1));
} else {
*pcbNeeded += *pcReturned * (sizeof(PORT_INFO_2) - sizeof(PORT_INFO_1));
if ( *pcbNeeded <= cbBuf ) {
cReturned = *pcReturned;
while ( cReturned-- ) {
pPortInfo1 = (LPPORT_INFO_1) (pPorts + cReturned * sizeof(PORT_INFO_1));
pPortInfo2 = (LPPORT_INFO_2) (pPorts + cReturned * sizeof(PORT_INFO_2));
pPortInfo2->pPortName = pPortInfo1->pName;
pPortInfo2->pMonitorName = NULL;
pPortInfo2->pDescription = NULL;
pPortInfo2->fPortType = 0;
pPortInfo2->Reserved = 0;
}
} else {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
*pcReturned = 0;
bRet = FALSE;
}
}
return bRet;
}
BOOL
EnumPortsW(
LPWSTR pName,
DWORD Level,
LPBYTE pPort,
DWORD cbBuf,
LPDWORD pcbNeeded,
LPDWORD pcReturned
)
{
DWORD cReturned, TotalcbNeeded;
DWORD Error = ERROR_SUCCESS, TempError = ERROR_SUCCESS;
PROVIDOR *pProvidor;
DWORD BufferSize=cbBuf;
BOOL bPartialSuccess = FALSE;
DWORD rc;
if ((pPort == NULL) && (cbBuf != 0)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
WaitForSpoolerInitialization();
pProvidor = pLocalProvidor;
TotalcbNeeded = cReturned = 0;
while (pProvidor) {
*pcReturned = 0;
*pcbNeeded = 0;
//
// CLS
//
rc = (*pProvidor->PrintProvidor.fpEnumPorts)(pName, Level,
pPort, BufferSize,
pcbNeeded, pcReturned);
if( !rc ){
TempError = GetLastError();
//
// Netware providor returns INVALID_NAME and not INVALID_LEVEL
// So if Level = 2 and error always try a Level 1 query
//
if ( Level == 2 &&
( TempError == ERROR_INVALID_LEVEL ||
TempError == ERROR_INVALID_NAME) ) {
TempError = ERROR_SUCCESS;
if ( !GetPortInfo2UsingPortInfo1(pProvidor,
pName,
pPort,
BufferSize,
pcbNeeded,
pcReturned) ) {
TempError = GetLastError();
} else {
bPartialSuccess = TRUE;
}
}
//
// HACK FIX:
//
// NT 3.51 returns bogus pcbNeeded/pcReturned data if the
// Level is invalid (i.e., PORT_INFO_2). So we should zero
// these vars if the level is bad, otherwise the error returned
// is ERROR_INSUFFICIENT_BUFFER.
//
if ( TempError ) {
*pcReturned = 0;
Error = TempError;
if ( Error != ERROR_INSUFFICIENT_BUFFER )
*pcbNeeded = 0;
}
} else {
bPartialSuccess = TRUE;
}
cReturned += *pcReturned;
switch (Level) {
case 1:
pPort += *pcReturned * sizeof(PORT_INFO_1);
break;
case 2:
pPort += *pcReturned * sizeof(PORT_INFO_2);
break;
default:
DBGMSG(DBG_ERROR,
("EnumPortsW: invalid level %d", Level));
SetLastError(ERROR_INVALID_LEVEL);
return FALSE;
}
if (*pcbNeeded <= BufferSize)
BufferSize -= *pcbNeeded;
else
BufferSize = 0;
TotalcbNeeded += *pcbNeeded;
//
// CLS
//
// Stop routing if the provider tells us to.
//
if( rc == ROUTER_STOP_ROUTING ){
break;
}
pProvidor = pProvidor->pNext;
}
*pcbNeeded = TotalcbNeeded;
*pcReturned = cReturned;
if (TotalcbNeeded > cbBuf) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
} else if (bPartialSuccess) {
SetLastError(ERROR_SUCCESS);
} else if (Error != ERROR_SUCCESS) {
SetLastError(Error);
return FALSE;
}
return TRUE;
}
BOOL
EnumMonitorsW(
LPWSTR pName,
DWORD Level,
LPBYTE pMonitor,
DWORD cbBuf,
LPDWORD pcbNeeded,
LPDWORD pcReturned
)
{
DWORD cReturned, cbStruct, TotalcbNeeded;
DWORD Error;
PROVIDOR *pProvidor;
DWORD BufferSize=cbBuf;
BOOL bPartialSuccess = FALSE;
DWORD rc;
if ((pMonitor == NULL) && (cbBuf != 0)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
WaitForSpoolerInitialization();
switch (Level) {
case 1:
cbStruct = sizeof(MONITOR_INFO_1);
break;
case 2:
cbStruct = sizeof(MONITOR_INFO_2);
break;
default:
DBGMSG(DBG_ERROR,
("EnumMonitorsW: invalid level %d", Level));
SetLastError(ERROR_INVALID_LEVEL);
return FALSE;
}
pProvidor = pLocalProvidor;
TotalcbNeeded = cReturned = 0;
Error = ERROR_SUCCESS;
while (pProvidor) {
*pcReturned = 0;
*pcbNeeded = 0;
rc = (*pProvidor->PrintProvidor.fpEnumMonitors) (pName,
Level,
pMonitor,
BufferSize,
pcbNeeded,
pcReturned);
cReturned += *pcReturned;
pMonitor += *pcReturned * cbStruct;
if (*pcbNeeded <= BufferSize)
BufferSize -= *pcbNeeded;
else
BufferSize = 0;
TotalcbNeeded += *pcbNeeded;
if( rc == ROUTER_UNKNOWN ){
Error = GetLastError();
} else {
bPartialSuccess = TRUE;
if( rc == ROUTER_STOP_ROUTING ){
break;
}
}
pProvidor = pProvidor->pNext;
}
*pcbNeeded = TotalcbNeeded;
*pcReturned = cReturned;
if (TotalcbNeeded > cbBuf) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
} else if (bPartialSuccess) {
SetLastError(ERROR_SUCCESS);
} else if (Error != ERROR_SUCCESS) {
SetLastError(Error);
return FALSE;
}
return TRUE;
}
BOOL
AddPortExW(
LPWSTR pName,
DWORD Level,
LPBYTE pBuffer,
LPWSTR pMonitorName
)
{
LPPROVIDOR pProvidor;
WaitForSpoolerInitialization();
pProvidor = pLocalProvidor;
while (pProvidor) {
if (pProvidor->PrintProvidor.fpAddPortEx) {
if ((*pProvidor->PrintProvidor.fpAddPortEx) (pName, Level, pBuffer, pMonitorName)) {
return TRUE;
}
}
pProvidor = pProvidor->pNext;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
BOOL
AddPortW(
LPWSTR pName,
HWND hWnd,
LPWSTR pMonitorName
)
{
LPPROVIDOR pProvidor;
DWORD Error = NO_ERROR;
WaitForSpoolerInitialization();
pProvidor = pLocalProvidor;
while (pProvidor) {
if (!pProvidor->PrintProvidor.fpAddPort)
break;
if ((*pProvidor->PrintProvidor.fpAddPort)(pName, hWnd, pMonitorName)) {
return TRUE;
} else {
DWORD LastError = GetLastError();
/* If the function is not supported, don't return yet
* in case there's a print provider that does support it.
*/
if (LastError == ERROR_NOT_SUPPORTED)
Error = ERROR_NOT_SUPPORTED;
else if (LastError != ERROR_INVALID_NAME)
return FALSE;
}
pProvidor = pProvidor->pNext;
}
SetLastError(Error == NO_ERROR ? ERROR_INVALID_PARAMETER : Error);
return FALSE;
}
BOOL
ConfigurePortW(
LPWSTR pName,
HWND hWnd,
LPWSTR pPortName
)
{
LPPROVIDOR pProvidor;
DWORD Error = NO_ERROR;
WaitForSpoolerInitialization();
pProvidor = pLocalProvidor;
while (pProvidor) {
if (!pProvidor->PrintProvidor.fpConfigurePort)
break;
if ((*pProvidor->PrintProvidor.fpConfigurePort) (pName, hWnd, pPortName)) {
return TRUE;
} else {
DWORD LastError = GetLastError();
/* If the function is not supported, don't return yet
* in case there's a print provider that does support it.
*/
if (LastError == ERROR_NOT_SUPPORTED)
Error = ERROR_NOT_SUPPORTED;
else if ((LastError != ERROR_INVALID_NAME) && (LastError != ERROR_UNKNOWN_PORT))
return FALSE;
}
pProvidor = pProvidor->pNext;
}
SetLastError(Error == NO_ERROR ? ERROR_INVALID_PARAMETER : Error);
return FALSE;
}
BOOL
DeletePortW(
LPWSTR pName,
HWND hWnd,
LPWSTR pPortName
)
{
LPPROVIDOR pProvidor;
DWORD Error = NO_ERROR;
WaitForSpoolerInitialization();
pProvidor = pLocalProvidor;
while (pProvidor) {
if (!pProvidor->PrintProvidor.fpDeletePort)
break;
if ((*pProvidor->PrintProvidor.fpDeletePort) (pName, hWnd, pPortName)) {
return TRUE;
} else {
DWORD LastError = GetLastError();
/* If the function is not supported, don't return yet
* in case there's a print provider that does support it.
*/
if (LastError == ERROR_NOT_SUPPORTED)
Error = ERROR_NOT_SUPPORTED;
else if ((LastError != ERROR_INVALID_NAME) && (LastError != ERROR_UNKNOWN_PORT))
return FALSE;
}
pProvidor = pProvidor->pNext;
}
SetLastError(Error == NO_ERROR ? ERROR_INVALID_PARAMETER : Error);
return FALSE;
}
BOOL
AddMonitorW(
LPWSTR pName,
DWORD Level,
LPBYTE pMonitorInfo
)
{
LPPROVIDOR pProvidor;
WaitForSpoolerInitialization();
pProvidor = pLocalProvidor;
while (pProvidor) {
if ((*pProvidor->PrintProvidor.fpAddMonitor) (pName, Level, pMonitorInfo)) {
return TRUE;
} else if (GetLastError() != ERROR_INVALID_NAME) {
return FALSE;
}
pProvidor = pProvidor->pNext;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
BOOL
DeleteMonitorW(
LPWSTR pName,
LPWSTR pEnvironment,
LPWSTR pMonitorName
)
{
LPPROVIDOR pProvidor;
DWORD Error;
WaitForSpoolerInitialization();
if (!pEnvironment || !*pEnvironment)
pEnvironment = szEnvironment;
pProvidor = pLocalProvidor;
while (pProvidor) {
if ((*pProvidor->PrintProvidor.fpDeleteMonitor)
(pName, pEnvironment, pMonitorName)) {
return TRUE;
} else if ((Error=GetLastError()) != ERROR_INVALID_NAME) {
return FALSE;
}
pProvidor = pProvidor->pNext;
}
return FALSE;
}
BOOL
SetPortW(
LPWSTR pszName,
LPWSTR pszPortName,
DWORD dwLevel,
LPBYTE pPortInfo
)
{
LPPROVIDOR pProvidor;
DWORD dwLastError;
WaitForSpoolerInitialization();
pProvidor = pLocalProvidor;
while (pProvidor) {
if ( (*pProvidor->PrintProvidor.fpSetPort)(pszName,
pszPortName,
dwLevel,
pPortInfo) ) {
return TRUE;
}
dwLastError = GetLastError();
if ( dwLastError != ERROR_INVALID_NAME &&
dwLastError != ERROR_UNKNOWN_PORT &&
dwLastError != ERROR_NOT_SUPPORTED ) {
return FALSE;
}
pProvidor = pProvidor->pNext;
}
return FALSE;
}