⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdopnp.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
        
    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 );
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -