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

📄 pnputils.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++dvdf

Routine Description:

    This routine releases the specified parallel port back to the the parallel 
      port arbiter ParPort via an IOCTL_INTERNAL_PARALLEL_PORT_FREE.

Arguments:

    PortDeviceObject - points to the ParPort device to be released

Return Value:

    STATUS_SUCCESS  - if the port was successfully released
    !STATUS_SUCCESS - otherwise

--*/
{
    return ParBuildSendInternalIoctl(IOCTL_INTERNAL_PARALLEL_PORT_FREE, 
                                     PortDeviceObject, NULL, 0, NULL, 0, NULL);
}


VOID
PptWriteMfgMdlToDevNode(
    IN  PDEVICE_OBJECT  Pdo,
    IN  PCHAR           Mfg,
    IN  PCHAR           Mdl
    )
{
    PPDO_EXTENSION  pdx = Pdo->DeviceExtension;

    if( Mfg && Mdl ) {
    
        NTSTATUS  status;
        HANDLE    handle;
        LONG      mfgLen = strlen( Mfg );
        LONG      mdlLen = strlen( Mdl );
        LONG      maxLen = mfgLen > mdlLen ? mfgLen : mdlLen;
        LONG      bufLen = ( maxLen + sizeof(CHAR) ) * sizeof(WCHAR);
        PWSTR     buffer = ExAllocatePool( PagedPool | POOL_COLD_ALLOCATION, bufLen );

        if( buffer ) {

            status = IoOpenDeviceRegistryKey( Pdo, PLUGPLAY_REGKEY_DEVICE, KEY_ALL_ACCESS, &handle );
            
            if( STATUS_SUCCESS == status ) {
                UNICODE_STRING  uniValueName;
                LONG            wcharCount;
                
                //
                // Write MFG to DevNode
                //
                RtlInitUnicodeString( &uniValueName, L"IEEE_1284_Manufacturer" );
                wcharCount = _snwprintf( buffer, bufLen/sizeof(WCHAR), L"%S", Mfg );
                if( (wcharCount > 0) && (wcharCount < (LONG)(bufLen/sizeof(WCHAR))) ){
                    // no buffer overflow - continue
                    status = ZwSetValueKey( handle, &uniValueName, 0, REG_SZ, buffer, (wcharCount+1)*sizeof(WCHAR) );
                    PptAssert( STATUS_SUCCESS == status );
                } else {
                    // buffer overflow - skip writing this value to devnode
                    PptAssert(!"PptWriteMfgMdlToDevNode - buffer overflow on Mfg");
                    DD((PCE)pdx,DDW,"PptWriteMfgMdlToDevNode - buffer overflow on Mfg\n");
                }
                
                //
                // Write MDL to DevNode
                //
                RtlInitUnicodeString( &uniValueName, L"IEEE_1284_Model" );
                wcharCount = _snwprintf( buffer, bufLen/sizeof(WCHAR), L"%S", Mdl );
                if( (wcharCount > 0) && (wcharCount < (LONG)(bufLen/sizeof(WCHAR))) ){
                    // no buffer overflow - continue
                    status = ZwSetValueKey( handle, &uniValueName, 0, REG_SZ, buffer, (wcharCount+1)*sizeof(WCHAR) );
                    PptAssert( STATUS_SUCCESS == status );
                } else {
                    // buffer overflow - skip writing this value to devnode
                    PptAssert(!"PptWriteMfgMdlToDevNode - buffer overflow on Mdl");
                    DD((PCE)pdx,DDW,"PptWriteMfgMdlToDevNode - buffer overflow on Mdl\n");
                }
                
                ZwClose( handle );

            } else {
                DD((PCE)pdx,DDW,"PptWriteMfgMdlToDevNode - IoOpenDeviceRegistryKey FAILED - status = %x\n",status);
            }

            ExFreePool( buffer );

        } // end if( buffer )            

    } else {
        PptAssert(!"PptWriteMfgMdlToDevNode - Mfg or Mdl is NULL - calling function should catch this!");
        DD((PCE)pdx,DDW,"PptWriteMfgMdlToDevNode - Mfg or Mdl is NULL - calling function should catch this!");
    }
}


NTSTATUS
PptFdoHandleBusRelations(
    IN PDEVICE_OBJECT Fdo,
    IN PIRP           Irp
    )
{
    PFDO_EXTENSION     fdx         = Fdo->DeviceExtension;
    ULONG              deviceCount = 0;
    ULONG              daisyChainDevCount;
    PDEVICE_RELATIONS  devRel;
    ULONG              devRelSize;
    NTSTATUS           status;
    LARGE_INTEGER      acquirePortTimeout;
    BOOLEAN            acquiredPort;
    PUCHAR             controller  = fdx->PortInfo.Controller;
    BOOLEAN            changeDetected;

    DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - enter\n");

    //
    // acquire exclusive access to bus
    //

    // timeout is in 100 ns units
    acquirePortTimeout.QuadPart = -(10 * 1000 * 1000 * 2); // 2 seconds
    
    // RMT - is it valid to send this IOCTL to FDO from here?
    status = PptAcquirePortViaIoctl( Fdo, &acquirePortTimeout );

    if( STATUS_SUCCESS == status ) {
        // we have the port
        acquiredPort = TRUE;
    } else {
        // failed to aquire port
        acquiredPort = FALSE;
        // skip rescanning port - just report same thing we reported during previous scan
        DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - failed to acquire port for rescan\n");
        goto target_failed_to_acquire_port;
    }

    DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - Port Acquired\n");

    //
    // Rescan the bus, note changes, create new PDOs or mark existing
    //   PDOs for removal as required
    //


    //
    // Handle Raw Port Legacy Interface LPTx device
    //
    if( !fdx->RawPortPdo ) {
        // first time through this - create our LPTx legacy interface PDO
        DD((PCE)fdx,DDT,"PptFdoHandleBusRelations - attempting to create RawPortPdo\n");
        fdx->RawPortPdo = P4CreatePdo( Fdo, PdoTypeRawPort, 0, NULL );
    }


    //
    // Handle End of Chain Device
    //

    // make sure all 1284.3 daisy chain devices are deselected
    P5DeselectAllDaisyChainDevices( controller );

    {
        // A small delay here seems to improve reliablility of 1284 device ID queries below.
        LARGE_INTEGER delay;
        delay.QuadPart = -1;
        KeDelayExecutionThread( KernelMode, FALSE, &delay );
    }

    if( fdx->EndOfChainPdo ) {

        if( fdx->DisableEndOfChainBusRescan ) {

            //
            // Pretend that the LPTx.4 device from previous rescan is still present.
            // 
            // This is needed to work around firmware state machines that can't handle a 
            // 1284 Device ID query while a print job is active.
            //

            ; // do nothing

        } else {

            //
            // we had an end of chain device - verify that it's still there
            //
            if( !P5IsDeviceStillThere( Fdo, fdx->EndOfChainPdo ) ) {
                // End of chain device is gone - do some cleanup and mark the PDO for removal/deletion
                DD((PCE)fdx,DDE,"PptFdoHandleBusRelations - EndOfChain device gone\n");
                // note - P5MarkPdoAsHardwareGone sets fdx->EndOfChainPdo to NULL
                P5MarkPdoAsHardwareGone( Fdo, PdoTypeEndOfChain, 0 );
            }
        }
    }

    if( NULL == fdx->EndOfChainPdo ) {
        //
        // we don't have an EndOfChain device - check for EndOfChain device arrival
        //
        PCHAR devId = P4ReadRawIeee1284DeviceId( controller );
        if( devId ) {
            // RawIeee1284 string includes 2 bytes of length data at beginning, omit these 2 bytes in call to P4CreatePdo
            PDEVICE_OBJECT EndOfChainPdo = P4CreatePdo( Fdo, PdoTypeEndOfChain, 0, (devId+2) );
            DD((PCE)fdx,DDE,"PptFdoHandleBusRelations - EndOfChain device detected <%s>\n",(devId+2));
            if( EndOfChainPdo ) {
                fdx->EndOfChainPdo = EndOfChainPdo;
                DD((PCE)fdx,DDE,"PptFdoHandleBusRelations - created EndOfChainPdo\n");
            } else {
                DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - FAILED to create EndOfChainPdo\n");
            }
            ExFreePool( devId );
        }
    }


#ifdef _X86_ // Zip drives not supported on 64bit systems

    //
    // Handle Legacy Zip device
    //

    if( fdx->LegacyZipPdo ) {
        //
        // we had a Legacy Zip device - verify that it's still there
        //
        if( !P5IsDeviceStillThere( Fdo, fdx->LegacyZipPdo ) ) {
            // Legacy Zip device is gone - do some cleanup and mark the PDO for removal/deletion
            DD((PCE)fdx,DDE,"PptFdoHandleBusRelations - LegacyZip device gone\n");
            // note - P5MarkPdoAsHardwareGone sets fdx->LegacyZipPdo to NULL
            P5MarkPdoAsHardwareGone( Fdo, PdoTypeLegacyZip, 0 );
        }
    }

    if( NULL == fdx->LegacyZipPdo ) {
        // 
        // We don't have a LegacyZip - check for arrival
        //
        if( !ParEnableLegacyZip ) {
            
            //
            // Enumeration of LegacyZip drives was disabled, check the
            //   registry to see if user has enabled LegacyZip detection
            // 
            
            // Check under \HKLM\SYSTEM\CCS\Services\Parport\Parameters
            PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"ParEnableLegacyZip", &ParEnableLegacyZip );
            
            if( !ParEnableLegacyZip ) {
                // Check under \HKLM\SYSTEM\CCS\Services\Parallel\Parameters (upgrade case - under Win2k flag was here)
                PptRegGetDword( RTL_REGISTRY_SERVICES, L"Parallel\\Parameters", L"ParEnableLegacyZip", &ParEnableLegacyZip );
                
                if( ParEnableLegacyZip ) {
                    // we found the setting in the old location, save
                    //   setting in new Parport location so that we find the
                    //   flag on the first check in the future
                    PptRegSetDword( RTL_REGISTRY_SERVICES, L"Parport\\Parameters", L"ParEnableLegacyZip", &ParEnableLegacyZip );
                }
            }
        } 
        
        if( ParEnableLegacyZip ) {
            
            //
            // Enumeration of LegacyZip drives is enabled - check for a LegacyZip arrival
            //
            
            if( P5LegacyZipDetected( controller ) ) {
                // detected drive - create LegacyZip PDO
                PDEVICE_OBJECT legacyZipPdo = P4CreatePdo( Fdo, PdoTypeLegacyZip, 0, NULL );
                DD((PCE)fdx,DDE,"legacy Zip arrival detected\n");
                if( legacyZipPdo ) {
                    fdx->LegacyZipPdo = legacyZipPdo;
                    DD((PCE)fdx,DDE,"PptFdoHandleBusRelations - created LegacyZipPdo\n");
                } else {
                    DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - FAILED to create LegacyZipPdo\n");
                }
            } else {
                // no legacy Zip detected - nothing more to do here
                DD((PCE)fdx,DDE,"no legacy Zip detected\n");
            }

        } // if( ParEnableLegacyZip ) -- Detection of LegacyZips is enabled

    } // if( fdx->LegacyZipPdo )


    //
    // Handle enumeration of IEEE 1284.3 Daisy Chain Devices
    //

    // did the 1284.3 daisy chain change since the last rescan?
    daisyChainDevCount = PptInitiate1284_3( fdx );
    DD((PCE)fdx,DDW,"daisyChainDevCount = %d\n",daisyChainDevCount);

    changeDetected = FALSE;

    {
        ULONG id;
        const ULONG maxId = 1;
        ULONG count = 0;
        for( id = 0 ; id <= maxId ; ++id ) {
            if( fdx->DaisyChainPdo[id] ) {
                ++count;
            }
        }
        if( count != daisyChainDevCount ) {
            // number of devices changed from previous scan
            DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - number of DC devices changed - count=%d, daisyChainDevCount=%d\n",
               count, daisyChainDevCount);
            changeDetected = TRUE;
        }
    }
    
    if( !changeDetected ) {
        // number of devices stayed the same - are any of the devices different?
        //
        // number of daisy chain devices didn't change
        // check if any of the devices changed
        ULONG id;
        const ULONG maxId = 1;
        DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - number of DC devices stayed same - check the devices\n");
        for( id = 0 ; id <= maxId ; ++id ) {
            if( fdx->DaisyChainPdo[id] && !P5IsDeviceStillThere( Fdo, fdx->DaisyChainPdo[id] ) ) {
                DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - a DC device changed\n");
                changeDetected = TRUE;
                break;
            }
        }
    }


    if( changeDetected ) {
        // we detected a change in the 1284.3 daisy chain devices - nuke all existing devices
        ULONG id;
        const ULONG maxId = 1;
        DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - changeDetected - nuking existing daisy chain PDOs\n");
        for( id = 0 ; id <= maxId ; ++id ) {
            if( fdx->DaisyChainPdo[id] ) {
                DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - nuking daisy chain %d\n",id);
                P5MarkPdoAsHardwareGone( Fdo, PdoTypeDaisyChain, id );
                PptAssert( NULL == fdx->DaisyChainPdo[id] );
            }
        }
        fdx->PnpInfo.Ieee1284_3DeviceCount = 0;
    } else {
        DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - !changeDetected in daisy chain PDOs\n");
    }

    // reinit daisy chain and assign addresses
    daisyChainDevCount = PptInitiate1284_3( fdx );
    DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - daisyChainDevCount = %d\n",daisyChainDevCount);
    if( daisyChainDevCount > 2 ) {
        // we only support 2 devices per port even though the spec supports up to 4 devices per port
        DD((PCE)fdx,DDW,"PptFdoHandleBusRelations - DaisyChainDevCount > 2, set to 2\n");
        daisyChainDevCount = 2;
    }

    if( changeDetected ) {
        // we detected a change in the 1284.3 daisy chain devices - we
        // previously nuked all old devices - now create a new PDO for
        // each device detected
        UCHAR id;
        PptAssert( 0 == fdx->PnpInfo.Ieee1284_3DeviceCount );

⌨️ 快捷键说明

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