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.
 
 
 
 
 
 

400 lines
9.8 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
All Rights Reserved
Module Name:
DynaMon.cpp
Abstract:
Multiple Transport core port monitor routines
Author: M. Fenelon
Revision History:
--*/
#include "precomp.h"
#include "ntddpar.h"
// Global Values for Monitor
TCHAR cszUSB[] = TEXT("USB");
TCHAR cszDOT4[] = TEXT("DOT4");
TCHAR cszTS[] = TEXT("TS");
TCHAR csz1394[] = TEXT("1394");
TCHAR cszBaseName[] = TEXT("Base Name");
TCHAR cszPortNumber[] = TEXT("Port Number");
TCHAR cszRecyclable[] = TEXT("recyclable");
TCHAR cszPortDescription[] = TEXT("Port Description");
TCHAR cszMaxBufferSize[] = TEXT("MaxBufferSize");
TCHAR cszUSBPortDesc[] = TEXT("Virtual printer port for USB");
TCHAR cszDot4PortDesc[] = TEXT("Virtual printer port for Dot4");
TCHAR csz1394PortDesc[] = TEXT("Virtual printer port for 1394");
TCHAR cszTSPortDesc[] = TEXT("Virtual printer port for TS");
DYNAMON_MONITOR_INFO gDynaMonInfo;
MODULE_DEBUG_INIT( DBG_ERROR, DBG_ERROR );
BOOL
APIENTRY
DllMain(
HANDLE hModule,
DWORD dwReason,
LPVOID lpRes
)
{
if ( dwReason == DLL_PROCESS_ATTACH )
DisableThreadLibraryCalls(hModule);
return TRUE;
}
// Construct MonitorEx structure to provide to Spooler
MONITOREX MonitorEx = {
sizeof(MONITOR),
{
DynaMon_EnumPorts,
DynaMon_OpenPort,
NULL, // OpenPortEx not supported
DynaMon_StartDocPort,
DynaMon_WritePort,
DynaMon_ReadPort,
DynaMon_EndDocPort,
DynaMon_ClosePort,
NULL, // AddPort not supported
NULL, // AddPortEx not supported
NULL, // ConfigurePort not supported
NULL, // DeletePort not supported
DynaMon_GetPrinterDataFromPort,
DynaMon_SetPortTimeOuts,
NULL, // XcvOpenPort not supported
NULL, // XcvDataPort not supported
NULL // XcvClosePort not supported
}
};
LPMONITOREX
WINAPI
InitializePrintMonitor(
LPTSTR pszRegistryRoot
)
{
BOOL bEnumPortsCS = FALSE;
BOOL bUpdateListCS = FALSE;
LPMONITOREX pMonitorEx = NULL;
DWORD dwStatus = ERROR_SUCCESS;
// Clear the Global info
ZeroMemory( &gDynaMonInfo, sizeof(gDynaMonInfo) );
if (dwStatus == ERROR_SUCCESS)
{
__try
{
InitializeCriticalSection (&gDynaMonInfo.EnumPortsCS);
bEnumPortsCS = TRUE;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
dwStatus = GetExceptionCode ();
}
}
if (dwStatus == ERROR_SUCCESS)
{
__try
{
InitializeCriticalSection (&gDynaMonInfo.UpdateListCS);
bUpdateListCS = TRUE;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
dwStatus = GetExceptionCode ();
}
}
if (dwStatus == ERROR_SUCCESS)
{
gDynaMonInfo.hUpdateEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
if (gDynaMonInfo.hUpdateEvent == NULL)
{
dwStatus = GetLastError ();
}
}
if (dwStatus == ERROR_SUCCESS)
{
//
// Get the Background Thread going
//
dwStatus = SpinUpdateThread ();
}
//
//
if (dwStatus == ERROR_SUCCESS)
{
pMonitorEx = &MonitorEx;
}
else
{
if (bEnumPortsCS)
{
DeleteCriticalSection (&gDynaMonInfo.EnumPortsCS);
}
if (bUpdateListCS)
{
DeleteCriticalSection (&gDynaMonInfo.UpdateListCS);
}
if (gDynaMonInfo.hUpdateEvent)
{
CloseHandle (&gDynaMonInfo.hUpdateEvent);
}
ZeroMemory( &gDynaMonInfo, sizeof(gDynaMonInfo) );
SetLastError (dwStatus);
}
return pMonitorEx;
}
BOOL
WINAPI
DynaMon_EnumPorts(
LPTSTR pszName,
DWORD dwLevel,
LPBYTE pPorts,
DWORD cbBuf,
LPDWORD pcbNeeded,
LPDWORD pcReturned
)
{
DWORD dwLastError = ERROR_SUCCESS, dwRequestIndex;
LPBYTE pEnd;
PDYNAMON_PORT pPortList;
PPORT_UPDATE pPortUpdateList = NULL;
*pcbNeeded = *pcReturned = 0;
if ( dwLevel != 1 && dwLevel != 2 )
{
SetLastError(ERROR_INVALID_LEVEL);
return FALSE;
}
dwRequestIndex = gDynaMonInfo.dwLastEnumIndex;
ECS( gDynaMonInfo.EnumPortsCS );
if ( dwRequestIndex >= gDynaMonInfo.dwLastEnumIndex )
{
//
// No complete enumeration has occurred since this request was made.
// Since the request may be an indication that something has changed,
// the full reenumeration must be done.
//
// Updated the index of enumeration before actually doing the
// work so it will show up as the most conservative
//
// Consequence of rollover on gdwLastEnumIndex:
// Any threads that recorded 0xFFFFFFFF as the dwRequestIndex
// will show as greater than the new value 0 and therefore reenum
// gratuitously. Not very much extra work.
//
++gDynaMonInfo.dwLastEnumIndex;
if ( dwLastError = BuildPortList( &gDynaMonInfo, &pPortUpdateList) )
goto Done;
}
for ( pPortList = gDynaMonInfo.pPortList ;
pPortList ;
pPortList = pPortList->pNext )
{
*pcbNeeded += pPortList->pBasePort->getEnumInfoSize( dwLevel );
}
if ( cbBuf < *pcbNeeded )
{
dwLastError = ERROR_INSUFFICIENT_BUFFER;
goto Done;
}
pEnd = pPorts + cbBuf;
for ( pPortList = gDynaMonInfo.pPortList ;
pPortList ;
pPortList = pPortList->pNext )
{
pEnd = pPortList->pBasePort->copyEnumInfo( dwLevel, pPorts, pEnd );
if ( dwLevel == 1 )
pPorts += sizeof(PORT_INFO_1);
else
pPorts += sizeof(PORT_INFO_2);
++(*pcReturned);
}
SPLASSERT(pEnd >= pPorts);
Done:
// If we have anything to update do it now
if ( pPortUpdateList )
PassPortUpdateListToUpdateThread( pPortUpdateList );
LCS( gDynaMonInfo.EnumPortsCS );
if ( dwLastError )
{
SetLastError(dwLastError);
return FALSE;
}
else
return TRUE;
}
BOOL
WINAPI
DynaMon_OpenPort(
LPTSTR pszPortName,
LPHANDLE pHandle
)
{
PDYNAMON_PORT pPort, pPrev;
pPort = FindPort( &gDynaMonInfo, pszPortName, &pPrev);
if ( pPort )
{
*pHandle = (LPHANDLE)pPort;
pPort->pBasePort->InitCS();
return TRUE;
}
else
{
SetLastError(ERROR_PATH_NOT_FOUND);
return FALSE;
}
}
BOOL
WINAPI
DynaMon_ClosePort(
HANDLE hPort
)
{
PDYNAMON_PORT pPort = (PDYNAMON_PORT) hPort;
IF_INVALID_PORT_FAIL( pPort )
pPort->pBasePort->ClearCS();
return TRUE;
}
BOOL
WINAPI
DynaMon_StartDocPort(
HANDLE hPort,
LPTSTR pPrinterName,
DWORD dwJobId,
DWORD dwLevel,
LPBYTE pDocInfo
)
{
PDYNAMON_PORT pPort = (PDYNAMON_PORT) hPort;
IF_INVALID_PORT_FAIL( pPort )
return pPort->pBasePort->startDoc( pPrinterName, dwJobId, dwLevel, pDocInfo );
}
BOOL
WINAPI
DynaMon_EndDocPort(
HANDLE hPort
)
{
PDYNAMON_PORT pPort = (PDYNAMON_PORT) hPort;
IF_INVALID_PORT_FAIL( pPort )
return pPort->pBasePort->endDoc();
}
BOOL
WINAPI
DynaMon_GetPrinterDataFromPort(
HANDLE hPort,
DWORD dwControlID,
LPWSTR pValueName,
LPWSTR lpInBuffer,
DWORD cbInBuffer,
LPWSTR lpOutBuffer,
DWORD cbOutBuffer,
LPDWORD lpcbReturned
)
{
PDYNAMON_PORT pPort = (PDYNAMON_PORT) hPort;
IF_INVALID_PORT_FAIL( pPort )
return pPort->pBasePort->getPrinterDataFromPort( dwControlID, pValueName, lpInBuffer, cbInBuffer,
lpOutBuffer, cbOutBuffer, lpcbReturned );
}
BOOL
WINAPI
DynaMon_ReadPort(
HANDLE hPort,
LPBYTE pBuffer,
DWORD cbBuffer,
LPDWORD pcbRead
)
{
PDYNAMON_PORT pPort = (PDYNAMON_PORT) hPort;
IF_INVALID_PORT_FAIL( pPort )
return pPort->pBasePort->read( pBuffer, cbBuffer, pcbRead );
}
BOOL
WINAPI
DynaMon_WritePort(
HANDLE hPort,
LPBYTE pBuffer,
DWORD cbBuffer,
LPDWORD pcbWritten
)
{
PDYNAMON_PORT pPort = (PDYNAMON_PORT) hPort;
IF_INVALID_PORT_FAIL( pPort )
return pPort->pBasePort->write( pBuffer, cbBuffer, pcbWritten );
}
BOOL
WINAPI
DynaMon_SetPortTimeOuts(
HANDLE hPort,
LPCOMMTIMEOUTS lpCTO,
DWORD reserved
)
{
PDYNAMON_PORT pPort = (PDYNAMON_PORT) hPort;
IF_INVALID_PORT_FAIL( pPort )
return pPort->pBasePort->setPortTimeOuts( lpCTO );
}