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

📄 serenum.c

📁 enumerates Plug-n-Play RS-232 devices that are compliant with the current revision of Plug and Play
💻 C
📖 第 1 页 / 共 2 页
字号:
        // This IOCTL is used by the modem cpl.
        //

        status = IoOpenDeviceRegistryKey(fdoData->UnderlyingPDO,
                                         PLUGPLAY_REGKEY_DEVICE,
                                         STANDARD_RIGHTS_READ,
                                         &keyHandle);

        if (!NT_SUCCESS(status)) {
           //
           // This is a fatal error.  If we can't get to our registry key,
           // we are sunk.
           //
           Serenum_KdPrint_Def (SER_DBG_PNP_ERROR,
                ("IoOpenDeviceRegistryKey failed - %x \n", status));
        } else {
            status = Serenum_GetRegistryKeyValue(
                keyHandle,
                L"PortName",
                sizeof(L"PortName"),
                Irp->AssociatedIrp.SystemBuffer,
                irpStack->Parameters.DeviceIoControl.OutputBufferLength,
                &actualLength);
            if ( STATUS_OBJECT_NAME_NOT_FOUND == status ||
                 STATUS_INVALID_PARAMETER  == status ) {
                status = Serenum_GetRegistryKeyValue(
                    keyHandle,
                    L"Identifier",
                    sizeof(L"Identifier"),
                    Irp->AssociatedIrp.SystemBuffer,
                    irpStack->Parameters.DeviceIoControl.OutputBufferLength,
                    &actualLength);
            }
            Irp->IoStatus.Information = actualLength;
            ZwClose (keyHandle);
        }
        break;
    default:
        //
        // This is not intended for us - fire and forget!
        //

       Serenum_DecIoCount (fdoData);
        return Serenum_DispatchPassThrough(
            DeviceObject,
            Irp);
    }

    Serenum_DecIoCount (fdoData);

    Irp->IoStatus.Status = status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);
    return status;
}

NTSTATUS
Serenum_InternIoCtl (
    PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
/*++
Routine Description:

--*/
{
    PIO_STACK_LOCATION      irpStack;
    NTSTATUS                status;
    PCOMMON_DEVICE_DATA     commonData;
    PPDO_DEVICE_DATA        pdoData;
    PVOID                   buffer;

//    PAGED_CODE();

    status = STATUS_SUCCESS;
    irpStack = IoGetCurrentIrpStackLocation (Irp);
    ASSERT (IRP_MJ_INTERNAL_DEVICE_CONTROL == irpStack->MajorFunction);

    commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
    pdoData = (PPDO_DEVICE_DATA) DeviceObject->DeviceExtension;

    //
    // We only take Internal Device Control requests for the PDO.
    // That is the objects on the bus (representing the serial ports)
    //
    // We do pass on the irp if this comes into the fdo, but not if it comes
    // into the pdo.
    //

    if (commonData->IsFDO) {
        return Serenum_DispatchPassThrough(
            DeviceObject,
            Irp);
    } else if (pdoData->Removed) {
    //
    // This bus has received the PlugPlay remove IRP.  It will no longer
    // respond to external requests.
    //
    status = STATUS_DELETE_PENDING;

    } else {
        buffer = Irp->UserBuffer;

        switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
        case IOCTL_INTERNAL_SERENUM_REMOVE_SELF:
            Serenum_KdPrint(pdoData, SER_DBG_SS_TRACE, ("Remove self\n"));

            ((PFDO_DEVICE_DATA) pdoData->ParentFdo->DeviceExtension)->
                PDOForcedRemove = TRUE;
            IoInvalidateDeviceRelations(
                ((PFDO_DEVICE_DATA) pdoData->ParentFdo->DeviceExtension)->
                UnderlyingPDO,
                BusRelations );
            status = STATUS_SUCCESS;
            break;

        default:
            //
            // Pass it through
            //
            return Serenum_DispatchPassThrough(DeviceObject, Irp);
        }
    }

    Irp->IoStatus.Status = status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);
    return status;
}


VOID
Serenum_DriverUnload (
    IN PDRIVER_OBJECT Driver
    )
/*++
Routine Description:
    Clean up everything we did in driver entry.

--*/
{
    UNREFERENCED_PARAMETER (Driver);
    PAGED_CODE();

    //
    // All the device objects should be gone.
    //

    ASSERT (NULL == Driver->DeviceObject);

    //
    // Here we free any resources allocated in DriverEntry
    //

    return;
}

NTSTATUS
Serenum_IncIoCount (
    PFDO_DEVICE_DATA Data
    )
{
    InterlockedIncrement (&Data->OutstandingIO);
    if (Data->Removed) {

        if (0 == InterlockedDecrement (&Data->OutstandingIO)) {
            KeSetEvent (&Data->RemoveEvent, 0, FALSE);
        }
        return STATUS_DELETE_PENDING;
    }
    return STATUS_SUCCESS;
}

VOID
Serenum_DecIoCount (
    PFDO_DEVICE_DATA Data
    )
{
    if (0 == InterlockedDecrement (&Data->OutstandingIO)) {
        KeSetEvent (&Data->RemoveEvent, 0, FALSE);
    }
}

NTSTATUS
Serenum_DispatchPassThrough(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++
Routine Description:

    Passes a request on to the lower driver.

--*/
{
    PIO_STACK_LOCATION IrpStack =
            IoGetCurrentIrpStackLocation( Irp );

#if 0
        Serenum_KdPrint_Def (SER_DBG_SS_TRACE, (
            "[Serenum_DispatchPassThrough] "
            "IRP: %8x; "
            "MajorFunction: %d\n",
            Irp,
            IrpStack->MajorFunction ));
#endif

    //
    // Pass the IRP to the target
    //
   IoSkipCurrentIrpStackLocation (Irp);
    // CIMEXCIMEX:  VERIFY THIS FUNCTIONS CORRECTLY!!!

    if (((PPDO_DEVICE_DATA) DeviceObject->DeviceExtension)->IsFDO) {
        return IoCallDriver(
            ((PFDO_DEVICE_DATA) DeviceObject->DeviceExtension)->TopOfStack,
            Irp );
    } else {
        return IoCallDriver(
            ((PFDO_DEVICE_DATA) ((PPDO_DEVICE_DATA) DeviceObject->
                DeviceExtension)->ParentFdo->DeviceExtension)->TopOfStack,
                Irp );
    }
}

void
Serenum_InitPDO (
    PDEVICE_OBJECT      Pdo,
    PFDO_DEVICE_DATA    FdoData
    )
/*
Description:
    Common code to initialize a newly created serenum pdo.
    Called either when the control panel exposes a device or when Serenum senses
    a new device was attached.

Parameters:
    Pdo - The pdo
    FdoData - The fdo's device extension
*/
{
    ULONG FdoFlags = FdoData->Self->Flags;
    PPDO_DEVICE_DATA pdoData = Pdo->DeviceExtension;

    //
    // Check the IO style
    //
    if (FdoFlags & DO_BUFFERED_IO) {
        Pdo->Flags |= DO_BUFFERED_IO;
    } else if (FdoFlags & DO_DIRECT_IO) {
        Pdo->Flags |= DO_DIRECT_IO;
    }

    //
    // Increment the pdo's stacksize so that it can pass irps through
    //
    Pdo->StackSize += FdoData->Self->StackSize;

    //
    // Initialize the rest of the device extension
    //
    pdoData->IsFDO = FALSE;
    pdoData->Self = Pdo;

    pdoData->ParentFdo = FdoData->Self;

    pdoData->Started = FALSE; // irp_mn_start has yet to be received
    pdoData->Attached = TRUE; // attached to the bus
    pdoData->Removed = FALSE; // no irp_mn_remove as of yet
    pdoData->DebugLevel = FdoData->DebugLevel;  // Copy the debug level

    pdoData->DeviceState = PowerDeviceD0;
    pdoData->SystemState = PowerSystemWorking;

    //
    // Add the pdo to serenum's list
    //

    ASSERT(FdoData->AttachedPDO == NULL);
    ASSERT(FdoData->PdoData == NULL);
    ASSERT(FdoData->NumPDOs == 0);

    FdoData->AttachedPDO = Pdo;
    FdoData->PdoData = pdoData;
    FdoData->NumPDOs = 1;

    Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
    Pdo->Flags |= DO_POWER_PAGABLE;
}

⌨️ 快捷键说明

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