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.
 
 
 
 
 
 

172 lines
4.7 KiB

// Dot4Port.cpp: implementation of the Dot4Port class.
//
//////////////////////////////////////////////////////////////////////
#include "precomp.h"
#include "initguid.h"
#include "ntddpar.h"
const TCHAR cszCFGMGR32[]=TEXT("cfgmgr32.dll");
const CHAR cszReenumFunc[]="CM_Reenumerate_DevNode_Ex";
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDot4Port::CDot4Port( BOOL bActive, LPTSTR pszPortName, LPTSTR pszDevicePath )
: CBasePort( bActive, pszPortName, pszDevicePath, cszDot4PortDesc )
{
// Basically let the default constructor do the work.
}
CDot4Port::~CDot4Port()
{
}
PORTTYPE CDot4Port::getPortType()
{
return DOT4PORT;
}
BOOL CDot4Port::checkPnP()
{
SETUPAPI_INFO SetupApiInfo;
BOOL bRet = FALSE;
DWORD dwIndex, dwLastError;
UINT uOldErrorMode;
HANDLE hToken = NULL;
HDEVINFO hDevList = INVALID_HANDLE_VALUE;
SP_DEVINFO_DATA DeviceInfoData;
HINSTANCE hCfgMgr32 = 0; // Library instance.
// Pointers to the pnp function...
pfCM_Reenumerate_DevNode_Ex pfnReenumDevNode;
if ( !LoadSetupApiDll( &SetupApiInfo ) )
return FALSE;
// For a dot4 device we need to force a pnp event on the parallel port to get the
// dot4 stack rebuilt.
// If any of these fail, fail the call just as if the port couldn't be opened.
//
// Load the pnp dll.
uOldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
hCfgMgr32 = LoadLibrary( cszCFGMGR32 );
if(!hCfgMgr32)
{
SetErrorMode(uOldErrorMode);
goto Done;
}
SetErrorMode(uOldErrorMode);
//
// Get the Addressed of pnp functions we want to call...
//
pfnReenumDevNode = (pfCM_Reenumerate_DevNode_Ex)GetProcAddress( hCfgMgr32, cszReenumFunc );
if( !pfnReenumDevNode )
goto Done;
hToken = RevertToPrinterSelf();
if ( !hToken )
{
dwLastError = GetLastError();
goto Done;
}
hDevList = SetupApiInfo.GetClassDevs( (LPGUID) &GUID_PARALLEL_DEVICE,
NULL, NULL, DIGCF_INTERFACEDEVICE);
if ( hDevList == INVALID_HANDLE_VALUE )
{
dwLastError = GetLastError();
goto Done;
}
// Now get the DevInst handles for each DevNode
dwLastError = ERROR_SUCCESS;
dwIndex = 0;
do
{
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if ( !SetupApiInfo.EnumDeviceInfo( hDevList,
dwIndex,
&DeviceInfoData) )
{
dwLastError = GetLastError();
if ( dwLastError == ERROR_NO_MORE_ITEMS )
break; // Normal exit
DBGMSG(DBG_WARNING,
("DynaMon: Dot4.CheckPnP: SetupDiEnumDeviceInfo failed with %d for index %d\n",
dwLastError, dwIndex));
goto Next;
}
// ReEnum on the current parallel port DevNode
pfnReenumDevNode( DeviceInfoData.DevInst, CM_REENUMERATE_NORMAL, NULL );
Next:
dwLastError = ERROR_SUCCESS;
++dwIndex;
} while ( dwLastError == ERROR_SUCCESS );
// Revert back to the user's context.
if ( !ImpersonatePrinterClient(hToken) )
{
// Failure - Clear token so it won't happen again and save the error
hToken = NULL;
dwLastError = GetLastError();
goto Done;
}
// Impersonate worked so clear token
hToken = NULL;
// Try and open the port again.
// If we fail, then the device must not be there any more or still switched off - fail as usual.
m_hDeviceHandle = CreateFile( m_szDevicePath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if ( m_hDeviceHandle == INVALID_HANDLE_VALUE )
goto Done;
bRet = TRUE;
Done:
if ( hDevList != INVALID_HANDLE_VALUE )
SetupApiInfo.DestroyDeviceInfoList( hDevList );
if (hToken)
{
if ( !ImpersonatePrinterClient(hToken) )
{
if (bRet)
{
dwLastError = GetLastError();
bRet = FALSE;
}
}
}
if ( hCfgMgr32 )
FreeLibrary( hCfgMgr32 );
if ( SetupApiInfo.hSetupApi )
FreeLibrary(SetupApiInfo.hSetupApi);
SetLastError( dwLastError );
return bRet;
}