|
|
#include "pch.h"
NTSTATUS PptPdoStartDevice( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoQueryRemove( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoRemoveDevice( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoCancelRemove( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoStopDevice( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoQueryStop( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoCancelStop( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoQueryDeviceRelations( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoQueryCapabilities( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoQueryDeviceText( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoQueryId( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoQueryPnpDeviceState( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoQueryBusInformation( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoSurpriseRemoval( PDEVICE_OBJECT DevObj, PIRP Irp ); NTSTATUS PptPdoDefaultPnpHandler( PDEVICE_OBJECT DevObj, PIRP Irp );
PDRIVER_DISPATCH PptPdoPnpDispatchTable[] = { PptPdoStartDevice, // IRP_MN_START_DEVICE 0x00
PptPdoQueryRemove, // IRP_MN_QUERY_REMOVE_DEVICE 0x01
PptPdoRemoveDevice, // IRP_MN_REMOVE_DEVICE 0x02
PptPdoCancelRemove, // IRP_MN_CANCEL_REMOVE_DEVICE 0x03
PptPdoStopDevice, // IRP_MN_STOP_DEVICE 0x04
PptPdoQueryStop, // IRP_MN_QUERY_STOP_DEVICE 0x05
PptPdoCancelStop, // IRP_MN_CANCEL_STOP_DEVICE 0x06
PptPdoQueryDeviceRelations, // IRP_MN_QUERY_DEVICE_RELATIONS 0x07
PptPdoDefaultPnpHandler, // IRP_MN_QUERY_INTERFACE 0x08
PptPdoQueryCapabilities, // IRP_MN_QUERY_CAPABILITIES 0x09
PptPdoDefaultPnpHandler, // IRP_MN_QUERY_RESOURCES 0x0A
PptPdoDefaultPnpHandler, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B
PptPdoQueryDeviceText, // IRP_MN_QUERY_DEVICE_TEXT 0x0C
PptPdoDefaultPnpHandler, // IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D
PptPdoDefaultPnpHandler, // no such PnP request 0x0E
PptPdoDefaultPnpHandler, // IRP_MN_READ_CONFIG 0x0F
PptPdoDefaultPnpHandler, // IRP_MN_WRITE_CONFIG 0x10
PptPdoDefaultPnpHandler, // IRP_MN_EJECT 0x11
PptPdoDefaultPnpHandler, // IRP_MN_SET_LOCK 0x12
PptPdoQueryId, // IRP_MN_QUERY_ID 0x13
PptPdoQueryPnpDeviceState, // IRP_MN_QUERY_PNP_DEVICE_STATE 0x14
PptPdoQueryBusInformation, // IRP_MN_QUERY_BUS_INFORMATION 0x15
PptPdoDefaultPnpHandler, // IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16
PptPdoSurpriseRemoval, // IRP_MN_SURPRISE_REMOVAL 0x17
PptPdoDefaultPnpHandler // IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
};
NTSTATUS PptPdoStartDevice( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension;
pdx->DeviceStateFlags = PPT_DEVICE_STARTED; KeSetEvent(&pdx->PauseEvent, 0, FALSE); // unpause any worker thread
PptRegGetDeviceParameterDword( Pdo, L"Event22Delay", &pdx->Event22Delay );
//
// Register device interface for Legacy LPTx interface PDOs and set the interface active
// - succeed start even if the device interface code fails
//
if( PdoTypeRawPort == pdx->PdoType ) {
// This is a legacy interface "raw port" PDO, don't set interface for other types of PDOs
NTSTATUS status; BOOLEAN setActive = FALSE;
if( NULL == pdx->DeviceInterface.Buffer ) { // Register device interface
status = IoRegisterDeviceInterface( Pdo, &GUID_PARCLASS_DEVICE, NULL, &pdx->DeviceInterface ); if( STATUS_SUCCESS == status ) { setActive = TRUE; } }
if( (TRUE == setActive) && (FALSE == pdx->DeviceInterfaceState) ) { // set interface active
status = IoSetDeviceInterfaceState( &pdx->DeviceInterface, TRUE ); if( STATUS_SUCCESS == status ) { pdx->DeviceInterfaceState = TRUE; } } }
return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information ); }
NTSTATUS PptPdoQueryRemove( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension;
// DDpnp2( ("PptPdoQueryRemove\n") );
// PnP won't remove us if there are open handles to us - so WE don't need to check for open handles
pdx->DeviceStateFlags |= (PPT_DEVICE_REMOVE_PENDING | PAR_DEVICE_PAUSED); KeClearEvent(&pdx->PauseEvent); // pause any worker thread
return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information ); }
NTSTATUS PptPdoRemoveDevice( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension; NTSTATUS status;
pdx->DeviceStateFlags = PAR_DEVICE_PAUSED; KeClearEvent(&pdx->PauseEvent); // pause any worker thread
// Set Device Interface inactive for PdoTypeRawPort - other PDO types don't have device interfaces
if( PdoTypeRawPort == pdx->PdoType ) { if( (pdx->DeviceInterface.Buffer != NULL) && (TRUE == pdx->DeviceInterfaceState) ) { IoSetDeviceInterfaceState( &pdx->DeviceInterface, FALSE ); pdx->DeviceInterfaceState = FALSE; } }
// If we were not reported in the last FDO BusRelations enumeration then it is safe to delete self
if( pdx->DeleteOnRemoveOk ) { DD((PCE)pdx,DDT,"PptPdoRemoveDevice - DeleteOnRemoveOk == TRUE - cleaning up self\n"); P4DestroyPdo( Pdo ); status = P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information ); return status; } else { return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information ); } }
NTSTATUS PptPdoCancelRemove( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension;
pdx->DeviceStateFlags &= ~(PPT_DEVICE_REMOVE_PENDING | PAR_DEVICE_PAUSED); KeSetEvent(&pdx->PauseEvent, 0, FALSE); // unpause any worker thread
return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information ); }
NTSTATUS PptPdoStopDevice( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension;
// DDpnp2( ("PptPdoStopDevice\n") );
pdx->DeviceStateFlags |= PAR_DEVICE_PAUSED; pdx->DeviceStateFlags &= ~PPT_DEVICE_STARTED; KeClearEvent(&pdx->PauseEvent); // pause any worker thread
return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information ); }
NTSTATUS PptPdoQueryStop( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension;
// DDpnp2( ("PptPdoQueryStop\n") );
pdx->DeviceStateFlags |= (PPT_DEVICE_STOP_PENDING | PAR_DEVICE_PAUSED); KeClearEvent(&pdx->PauseEvent); // pause any worker thread
return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information ); }
NTSTATUS PptPdoCancelStop( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension;
pdx->DeviceStateFlags &= ~PPT_DEVICE_STOP_PENDING; KeSetEvent(&pdx->PauseEvent, 0, FALSE); // unpause any worker thread
return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information ); }
NTSTATUS PptPdoQueryDeviceRelations( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp ); DEVICE_RELATION_TYPE requestType = irpSp->Parameters.QueryDeviceRelations.Type; NTSTATUS status = Irp->IoStatus.Status; ULONG_PTR info = Irp->IoStatus.Information;
if( TargetDeviceRelation == requestType ) { PDEVICE_RELATIONS devRel = ExAllocatePool( PagedPool, sizeof(DEVICE_RELATIONS) ); if( devRel ) { devRel->Count = 1; ObReferenceObject( Pdo ); devRel->Objects[0] = Pdo; status = STATUS_SUCCESS; info = (ULONG_PTR)devRel; } else { status = STATUS_NO_MEMORY; } } else { DD((PCE)pdx,DDT,"PptPdoQueryDeviceRelations - unhandled request Type = %d\n",requestType); } return P4CompleteRequest( Irp, status, info ); }
NTSTATUS PptPdoQueryCapabilities( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
irpSp->Parameters.DeviceCapabilities.Capabilities->RawDeviceOK = TRUE; if( PdoTypeRawPort == pdx->PdoType ) { // This is the legacy LPTx interface device - no driver should
// ever be installed for this so don't bother the user with a popup.
irpSp->Parameters.DeviceCapabilities.Capabilities->SilentInstall = TRUE; }
return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information ); }
NTSTATUS PptPdoQueryDeviceText( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp ); PWSTR buffer = NULL; ULONG bufLen; ULONG_PTR info; NTSTATUS status;
if( DeviceTextDescription == irpSp->Parameters.QueryDeviceText.DeviceTextType ) {
//
// DeviceTextDescription is: catenation of MFG+<SPACE>+MDL
//
if( pdx->Mfg && pdx->Mdl ) { //
// Construct UNICODE string to return from the ANSI strings
// that we have in our extension
//
// need space for <SPACE> and terminating NULL
//
bufLen = strlen( (const PCHAR)pdx->Mfg ) + strlen( (const PCHAR)pdx->Mdl ) + 2 * sizeof(CHAR); bufLen *= ( sizeof(WCHAR)/sizeof(CHAR) ); buffer = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, bufLen ); if( buffer ) { RtlZeroMemory( buffer, bufLen ); _snwprintf( buffer, bufLen/2, L"%S %S", pdx->Mfg, pdx->Mdl ); DD((PCE)pdx,DDT,"PptPdoQueryDeviceText - DeviceTextDescription - <%S>\n",buffer); status = STATUS_SUCCESS; } else { status = STATUS_NO_MEMORY; } } else { DD((PCE)pdx,DDE,"PptPdoQueryDeviceText - MFG and/or MDL NULL - FAIL DeviceTextDescription\n"); status = STATUS_UNSUCCESSFUL; } } else if( DeviceTextLocationInformation == irpSp->Parameters.QueryDeviceText.DeviceTextType ) {
//
// DeviceTextLocationInformation is LPTx or LPTx.y (note that
// this is also the symlink name minus the L"\\DosDevices\\"
// prefix)
//
if( pdx->Location ) { bufLen = strlen( (const PCHAR)pdx->Location ) + sizeof(CHAR); bufLen *= ( sizeof(WCHAR)/sizeof(CHAR) ); buffer = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, bufLen ); if( buffer ) { RtlZeroMemory( buffer, bufLen ); _snwprintf( buffer, bufLen/2, L"%S", pdx->Location ); DD((PCE)pdx,DDT,"PptPdoQueryDeviceText - DeviceTextLocationInformation - <%S>\n",buffer); status = STATUS_SUCCESS; } else { status = STATUS_NO_MEMORY; } } else { DD((PCE)pdx,DDE,"PptPdoQueryDeviceText - Location NULL - FAIL DeviceTextLocationInformation\n"); status = STATUS_UNSUCCESSFUL; } } else {
// Unknown DeviceTextType - don't change anything in IRP
buffer = NULL; status = Irp->IoStatus.Status; }
if( (STATUS_SUCCESS == status) && buffer ) { info = (ULONG_PTR)buffer; } else { if( buffer ) { ExFreePool( buffer ); } info = Irp->IoStatus.Information; }
return P4CompleteRequest( Irp, status, info ); }
NTSTATUS PptPdoQueryId( PDEVICE_OBJECT Pdo, PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp ); PWSTR buffer = NULL; ULONG bufLen; NTSTATUS status; ULONG_PTR info;
switch( irpSp->Parameters.QueryId.IdType ) { case BusQueryDeviceID : //
// DeviceID generation: catenate MFG and MDL fields from the
// IEEE 1284 device ID string (no space between fields), append
// MFG+MDL catenation to LPTENUM\ prefix
//
if( pdx->Mfg && pdx->Mdl ) { //
// Construct UNICODE string to return from the ANSI strings
// that we have in our extension
//
CHAR prefix[] = "LPTENUM\\"; // sizeof(prefix) provides space for NULL terminator
bufLen = sizeof(prefix) + strlen( (const PCHAR)pdx->Mfg ) + strlen( (const PCHAR)pdx->Mdl ); bufLen *= ( sizeof(WCHAR)/sizeof(CHAR) ); buffer = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, bufLen ); if( buffer ) { RtlZeroMemory( buffer, bufLen ); _snwprintf( buffer, bufLen/2, L"%S%S%S", prefix, pdx->Mfg, pdx->Mdl ); P4SanitizeId( buffer ); // replace any illegal characters with underscore
DD((PCE)pdx,DDT,"PptPdoQueryId - BusQueryDeviceID - <%S>\n",buffer); status = STATUS_SUCCESS; } else { status = STATUS_NO_MEMORY; }
} else {
DD((PCE)pdx,DDE,"PptPdoQueryId - MFG and/or MDL NULL - FAIL BusQueryDeviceID\n"); status = STATUS_UNSUCCESSFUL;
} break; case BusQueryInstanceID : //
// InstanceID is LPTx or LPTx.y Location of the device (note
// that this is also the symlink name minus the
// \DosDevices\ prefix)
//
if( pdx->Location ) { //
// Construct UNICODE string to return from the ANSI string
// that we have in our extension
//
bufLen = strlen( (const PCHAR)pdx->Location ) + sizeof(CHAR); bufLen *= ( sizeof(WCHAR)/sizeof(CHAR) ); buffer = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, bufLen ); if( buffer ) { RtlZeroMemory( buffer, bufLen ); _snwprintf( buffer, bufLen/2, L"%S", pdx->Location ); P4SanitizeId( buffer ); // replace any illegal characters with underscore
DD((PCE)pdx,DDT,"PptPdoQueryId - BusQueryInstanceID - <%S>\n",buffer); status = STATUS_SUCCESS; } else { status = STATUS_NO_MEMORY; } } else {
DD((PCE)pdx,DDE,"PptPdoQueryId - Location NULL - FAIL BusQueryInstanceID\n"); status = STATUS_UNSUCCESSFUL;
} break; case BusQueryHardwareIDs : //
// HardwareID generation:
//
// Generate MfgMdlCrc string as follows:
// 1) catenate MFG and MDL fields
// 2) generate checksum on MFG+MDL catenation
// 3) truncate MFG+MDL catenation
// 4) append checksum
//
// Return as HardwareID MULTI_SZ: LPTENUM\%MfgMdlCrc% followed by bare %MfgMdlCrc%
//
// example: LPTENUM\Acme_CorpFooBarPrint3FA5\0Acme_CorpFooBarPrint3FA5\0\0
//
if( pdx->Mfg && pdx->Mdl ) { ULONG lengthOfMfgMdlBuffer = strlen( (const PCHAR)pdx->Mfg ) + strlen( (const PCHAR)pdx->Mdl ) + sizeof(CHAR); PCHAR mfgMdlBuffer = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, lengthOfMfgMdlBuffer );
if( mfgMdlBuffer ) { const CHAR prefix[] = "LPTENUM\\"; const ULONG mfgMdlTruncationLimit = 20; const ULONG checksumLength = 4; USHORT checksum;
// 1) catenate MFG and MDL fields and 2) generate checksum on catenation
RtlZeroMemory( mfgMdlBuffer, lengthOfMfgMdlBuffer ); _snprintf( mfgMdlBuffer, lengthOfMfgMdlBuffer, "%s%s", pdx->Mfg, pdx->Mdl ); GetCheckSum( mfgMdlBuffer, (USHORT)strlen(mfgMdlBuffer), &checksum );
//
// alloc buffer large enough for result returned to PnP,
// include space for 4 checksum chars (twice) + 1 NULL between strings + 2 termination chars (MULTI_SZ)
//
bufLen = strlen( prefix ) + 2 * mfgMdlTruncationLimit + 2 * checksumLength + 3 * sizeof(CHAR); bufLen *= (sizeof(WCHAR)/sizeof(CHAR)); // convert to size needed for WCHARs
buffer = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, bufLen ); if( buffer ) { ULONG wcharsWritten; RtlZeroMemory( buffer, bufLen );
// Construct the HardwareID MULTI_SZ:
//
// Write the first Hardware ID: LPTENUM\xxx
wcharsWritten = _snwprintf( buffer, bufLen/2, L"%S%.20S%04X", prefix, mfgMdlBuffer, checksum );
// Skip forward a UNICODE_NULL past the end of the first Hardware ID and write the second
// Hardware ID: bare xxx
_snwprintf( buffer+wcharsWritten+1, bufLen/2-wcharsWritten-1, L"%.20S%04X", mfgMdlBuffer, checksum );
ExFreePool( mfgMdlBuffer );
DD((PCE)pdx,DDT,"PptPdoQueryId - BusQueryHardwareIDs 1st ID - <%S>\n",buffer); DD((PCE)pdx,DDT,"PptPdoQueryId - BusQueryHardwareIDs 2nd ID - <%S>\n",buffer+wcslen(buffer)+1); // replace any illegal characters with underscore, preserve UNICODE_NULLs
P4SanitizeMultiSzId( buffer, bufLen/2 );
status = STATUS_SUCCESS;
// printing looks for PortName in the devnode - Pdo's Location is the PortName
P4WritePortNameToDevNode( Pdo, pdx->Location );
} else { ExFreePool( mfgMdlBuffer ); DD((PCE)pdx,DDT,"PptPdoQueryId - no pool for buffer - FAIL BusQueryHardwareIDs\n"); status = STATUS_INSUFFICIENT_RESOURCES; }
} else { DD((PCE)pdx,DDT,"PptPdoQueryId - no pool for mfgMdlBuffer - FAIL BusQueryHardwareIDs\n"); status = STATUS_INSUFFICIENT_RESOURCES; } } else { DD((PCE)pdx,DDT,"PptPdoQueryId - MFG and/or MDL NULL - FAIL BusQueryHardwareIDs\n"); status = STATUS_UNSUCCESSFUL; }
//
// Save the MFG and MDL fields from the IEEE 1284 Device ID string under the
// "<DevNode>\Device Parameters" key so that user mode code (e.g., printing)
// can retrieve the fields.
//
PptWriteMfgMdlToDevNode( Pdo, pdx->Mfg, pdx->Mdl );
break; case BusQueryCompatibleIDs :
//
// Printing group specified that we not report compatible IDs - 2000-04-24
//
#define PPT_REPORT_COMPATIBLE_IDS 0
#if (0 == PPT_REPORT_COMPATIBLE_IDS)
DD((PCE)pdx,DDT,"PptPdoQueryId - BusQueryCompatibleIDs - query not supported\n"); status = Irp->IoStatus.Status;
#else
//
// Return the compatible ID string reported by device, if any
//
if( pdx->Cid ) { //
// Construct UNICODE string to return from the ANSI string
// that we have in our extension
//
bufLen = strlen( pdx->Cid ) + 2 * sizeof(CHAR); bufLen *= ( sizeof(WCHAR)/sizeof(CHAR) ); buffer = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, bufLen ); if( buffer ) { RtlZeroMemory( buffer, bufLen ); _snwprintf( buffer, bufLen/2, L"%S", pdx->Cid ); DD((PCE)pdx,DDT,"PptPdoQueryId - BusQueryCompatibleIDs - <%S>\n",buffer);
//
// convert the 1284 ID representation of a Compatible ID seperator (',') into
// a MULTI_SZ - (i.e., scan the WSTR and replace any L',' with L'\0')
//
{ PWCHAR p = buffer; while( *p ) { if( L',' == *p ) { *p = L'\0'; } ++p; } }
// replace any illegal characters with underscore, preserve UNICODE_NULLs
P4SanitizeMultiSzId( buffer, bufLen/2 );
status = STATUS_SUCCESS;
} else { DD((PCE)pdx,DDT,"PptPdoQueryId - no pool - FAIL BusQueryCompatibleIDs\n"); status = STATUS_INSUFFICIENT_RESOURCES; } } else { DD((PCE)pdx,DDT,"PptPdoQueryId - CID NULL - BusQueryCompatibleIDs\n"); status = Irp->IoStatus.Status; } #endif // #if (0 == PPT_REPORT_COMPATIBLE_IDS)
break; default : //
// Invalid irpSp->Parameters.QueryId.IdType
//
DD((PCE)pdx,DDT,"PptPdoQueryId - unrecognized irpSp->Parameters.QueryId.IdType\n"); status = Irp->IoStatus.Status; }
if( (STATUS_SUCCESS == status) && buffer ) { info = (ULONG_PTR)buffer; } else { if( buffer ) { ExFreePool( buffer ); } info = Irp->IoStatus.Information; }
return P4CompleteRequest( Irp, status, info ); }
NTSTATUS PptPdoQueryPnpDeviceState( PDEVICE_OBJECT Pdo, PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension; NTSTATUS status = Irp->IoStatus.Status; ULONG_PTR info = Irp->IoStatus.Information;
if( PdoTypeRawPort == pdx->PdoType ) { info |= PNP_DEVICE_DONT_DISPLAY_IN_UI; status = STATUS_SUCCESS; } return P4CompleteRequest( Irp, status, info ); }
NTSTATUS PptPdoQueryBusInformation( PDEVICE_OBJECT Pdo, PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension; NTSTATUS status; ULONG_PTR info;
if( pdx->PdoType != PdoTypeRawPort ) {
//
// we are a "real" device enumerated by parport - report BusInformation
//
PPNP_BUS_INFORMATION pBusInfo = ExAllocatePool( PagedPool, sizeof(PNP_BUS_INFORMATION) );
if( pBusInfo ) {
pBusInfo->BusTypeGuid = GUID_BUS_TYPE_LPTENUM; pBusInfo->LegacyBusType = PNPBus; pBusInfo->BusNumber = 0;
status = STATUS_SUCCESS; info = (ULONG_PTR)pBusInfo;
} else {
// no pool
status = STATUS_NO_MEMORY; info = Irp->IoStatus.Information;
}
} else {
//
// we are a pseudo device (Legacy Interface Raw Port PDO LPTx) - don't report BusInformation
//
status = Irp->IoStatus.Status; info = Irp->IoStatus.Information;
}
return P4CompleteRequest( Irp, status, info ); }
NTSTATUS PptPdoSurpriseRemoval( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension;
// Set Device Interface inactive for PdoTypeRawPort - other PDO types don't have device interfaces
if( PdoTypeRawPort == pdx->PdoType ) { if( (pdx->DeviceInterface.Buffer != NULL) && (TRUE == pdx->DeviceInterfaceState) ) { IoSetDeviceInterfaceState( &pdx->DeviceInterface, FALSE ); pdx->DeviceInterfaceState = FALSE; } }
pdx->DeviceStateFlags |= PPT_DEVICE_SURPRISE_REMOVED; KeClearEvent(&pdx->PauseEvent); // pause any worker thread
return P4CompleteRequest( Irp, STATUS_SUCCESS, Irp->IoStatus.Information ); }
NTSTATUS PptPdoDefaultPnpHandler( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { UNREFERENCED_PARAMETER( Pdo );
return P4CompleteRequest( Irp, Irp->IoStatus.Status, Irp->IoStatus.Information ); }
NTSTATUS PptPdoPnp( IN PDEVICE_OBJECT Pdo, IN PIRP Irp ) { PPDO_EXTENSION pdx = Pdo->DeviceExtension; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
// diagnostic
PptPdoDumpPnpIrpInfo( Pdo, Irp);
if( pdx->DeviceStateFlags & PPT_DEVICE_DELETE_PENDING ) { DD((PCE)pdx,DDT,"PptPdoPnp - PPT_DEVICE_DELETE_PENDING - bailing out\n"); return P4CompleteRequest( Irp, STATUS_DELETE_PENDING, Irp->IoStatus.Information ); }
if( irpSp->MinorFunction < arraysize(PptPdoPnpDispatchTable) ) { return PptPdoPnpDispatchTable[ irpSp->MinorFunction ]( Pdo, Irp ); } else { DD((PCE)pdx,DDT,"PptPdoPnp - Default Handler - IRP_MN = %x\n",irpSp->MinorFunction); return PptPdoDefaultPnpHandler( Pdo, Irp ); } }
|