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

📄 charsample.c

📁 一个简单的wdm驱动开发实例,可以大概看开发流程作为入门
💻 C
📖 第 1 页 / 共 2 页
字号:

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

        CharSampleDebugPrint(DBG_CREATECLOSE, DBG_WARN, __FUNCTION__"$$--. IRP %p, STATUS %x", Irp, status);

        return status;
    }

    // increment open count
    InterlockedIncrement(&deviceExtension->OpenHandleCount);

    status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    CharSampleReleaseRemoveLock(deviceExtension);

    CharSampleDebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleCloseDispatch
//      Dispatch routine for IRP_MJ_CLOSE requests.
//
//  Arguments:
//      IN  DeviceObject
//              pointer to the device object for our device
//
//      IN  Irp
//              the close IRP
//
//  Return Value:
//      NT status code.
//
NTSTATUS CharSampleCloseDispatch(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
{
    PCHARSAMPLE_DEVICE_EXTENSION    deviceExtension;
    NTSTATUS                status;

    CharSampleDebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);

    deviceExtension = (PCHARSAMPLE_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);

    InterlockedDecrement(&deviceExtension->OpenHandleCount);

    CharSampleDebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleUnload
//      Driver Unload routine.
//
//  Arguments:
//      IN  DriverObject
//              pointer to the driver object
//
//  Return Value:
//      none
//
VOID CharSampleUnload(
    IN  PDRIVER_OBJECT  DriverObject
    )
{
    CharSampleDebugPrint(DBG_UNLOAD, DBG_TRACE, __FUNCTION__"++");

    // The device object(s) should be NULL now
    // (since we unload, all the devices objects associated with this
    // driver must be deleted.
    ASSERT(DriverObject->DeviceObject == NULL);

    // We should not be unloaded until all the devices we control
    // have been removed from our queue.

    // release memory block allocated for registry path
    if (g_Data.RegistryPath.Buffer != NULL)
    {
        ExFreePool(g_Data.RegistryPath.Buffer);
        g_Data.RegistryPath.Buffer = NULL;
    }

    CharSampleDebugPrint(DBG_UNLOAD, DBG_TRACE, __FUNCTION__"--");

#ifdef CHARSAMPLE_WMI_TRACE
    WPP_CLEANUP(DriverObject);
#endif

    return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleIsStoppable
//      This routine determines whether the device can be safely stopped. 
//      In our particular case, we'll assume we can always stop the device.
//      A device might fail the request if it doesn't have a queue for the
//      requests that might come or if it was notified that it is in the 
//      paging path.
//
//  Arguments:
//      IN  DeviceExtension
//              our device extension
//
//  Return Value:
//      returns TRUE if the device is stoppable, FALSE otherwise
//
BOOLEAN CharSampleIsStoppable(
    IN  PCHARSAMPLE_DEVICE_EXTENSION    DeviceExtension
    )
{
    return TRUE;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleIsRemovable
//      This routine determines whether the device can be safely removed. 
//      A device shouldn't be removed if, for example, it has open handles or
//      removing the device could result in losing data (plus the reasons
//      mentioned in the CharSampleIsStoppable function comments). The PnP manager on 
//      Windows 2000 fails on its own any attempt to remove, if there any 
//      open handles to the device.  However on Win9x, the driver must keep 
//      count of open handles and fail QueryRemove if there are any open 
//      handles.
//
//  Arguments:
//      IN  DeviceExtension
//              our device extension
//
//  Return Value:
//      returns TRUE if the device is stoppable, FALSE otherwise
//
BOOLEAN CharSampleIsRemovable(
    IN  PCHARSAMPLE_DEVICE_EXTENSION    DeviceExtension
    )
{
    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleSubmitIrpSyncComplete
//      Completion routine for sync IRP requests.
//
//  Arguments:
//      IN  DeviceObject
//              pointer to our device object
//
//      IN  Irp
//              pointer to the PnP IRP
//
//      IN  Context
//              our event used to signal IRP completion
//
//  Return Value:
//      STATUS_MORE_PROCESSING_REQUIRED
//
NTSTATUS  CharSampleSubmitIrpSyncComplete(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp,
    IN  PVOID           Context
    )
{
    PKEVENT event = (PKEVENT)Context;

    // If the lower driver didn't return STATUS_PENDING, we don't need to 
    // set the event because we won't be waiting on it. 
    if (Irp->PendingReturned) 
    {
        KeSetEvent(event, IO_NO_INCREMENT, FALSE);
    }

    return STATUS_MORE_PROCESSING_REQUIRED;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleSubmitIrpSync
//      Sends the given IRP down the stack to the next lower driver and 
//      waits in a synchronous fashion for the IRP to complete
//
//  Arguments:
//      IN  DeviceObject
//              Pointer to device object for our device
//
//      IN  Irp
//              IRP to send down
//
//  Return Value:
//      NT status code
//
NTSTATUS CharSampleSubmitIrpSync(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
{
    KEVENT   event;
    NTSTATUS status;

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    IoCopyCurrentIrpStackLocationToNext(Irp);

    IoSetCompletionRoutine(
        Irp,
        CharSampleSubmitIrpSyncComplete,
        &event,
        TRUE,
        TRUE,
        TRUE
        );

    status = IoCallDriver(DeviceObject, Irp);

    // Wait for lower drivers to be done with the Irp.
    // Important thing to note here is when you allocate
    // memory for an event in the stack you must do a
    // KernelMode wait instead of UserMode to prevent
    // the stack from getting paged out.

    if (status == STATUS_PENDING) 
    {
       KeWaitForSingleObject(
           &event,
           Executive,
           KernelMode,
           FALSE,
           NULL
           );

       status = Irp->IoStatus.Status;
    }

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleAcquireRemoveLock
//      Acquires remove lock.
//
//  Arguments:
//      IN  DeviceExtension
//              our device extension
//
//  Return Value:
//      FALSE if remove device pending, TRUE otherwise.
//
BOOLEAN CharSampleAcquireRemoveLock(
    IN  PCHARSAMPLE_DEVICE_EXTENSION    DeviceExtension
    )
{
    LONG    count;

    count = InterlockedIncrement(&DeviceExtension->RemoveCount);

    ASSERT(count > 0);

    if (DeviceExtension->PnpState == PnpStateRemoved)
    {
        CharSampleReleaseRemoveLock(DeviceExtension);

        return FALSE;
    }

    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleReleaseRemoveLock
//      Releases remove lock.
//
//  Arguments:
//      IN  DeviceExtension
//              our device extension
//
//  Return Value:
//      None.
//
VOID CharSampleReleaseRemoveLock(
    IN  PCHARSAMPLE_DEVICE_EXTENSION    DeviceExtension
    )
{
    LONG    count;

    count = InterlockedDecrement(&DeviceExtension->RemoveCount);

    ASSERT(count >= 0);

    if (count == 0)
    {
        KeSetEvent(&DeviceExtension->RemoveEvent, IO_NO_INCREMENT, FALSE);
    }

    return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleWaitForSafeRemove
//      Waits for all remove locks to be released
//
//  Arguments:
//      IN  DeviceExtension
//              our device extension
//
//  Return Value:
//      None.
//
//  Comment:
//      This routine should be called with no remove locks held 
//      by the calling thread
//
VOID CharSampleWaitForSafeRemove(
    IN  PCHARSAMPLE_DEVICE_EXTENSION    DeviceExtension
    )
{
    DeviceExtension->PnpState = PnpStateRemoved;
    CharSampleReleaseRemoveLock(DeviceExtension);

    KeWaitForSingleObject(
        &DeviceExtension->RemoveEvent, 
        Executive, 
        KernelMode, 
        FALSE, 
        NULL
        );

    return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleStallQueues
//      Pauses all of the queues, and waits for them to get to paused state.
//
//  Arguments:
//      IN  DeviceExtension
//              our device extension
//
//  Return Value:
//      none
//
VOID CharSampleStallQueues(
    IN  PCHARSAMPLE_DEVICE_EXTENSION DeviceExtension
    )
{
    ULONG   index;

    CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++");

    // stall IRP processing
    CharSampleLockIo(&DeviceExtension->IoLock);

    CharSampleWaitForStopIo(&DeviceExtension->IoLock);

    CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--");

    return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleRestartQueues
//      Restarts all paused queues.
//
//  Arguments:
//      IN  DeviceExtension
//              our device extension
//
//  Return Value:
//      none
//
VOID CharSampleRestartQueues(
    IN  PCHARSAMPLE_DEVICE_EXTENSION   DeviceExtension
    )
{
    ULONG   index;

    CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++");

    CharSampleUnlockIo(&DeviceExtension->IoLock);

    CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--");

    return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//  CharSampleFlushQueues
//      Flush oustanding IRPs for closed file object.
//
//  Arguments:
//      IN  DeviceExtension
//              our device extension
//
//      IN  FileObject
//              about to be closed file object
//
//  Return Value:
//      none
//
VOID CharSampleFlushQueues(
    IN  PCHARSAMPLE_DEVICE_EXTENSION   DeviceExtension,
    IN  PFILE_OBJECT            FileObject
    )
{
    ULONG   index;

    CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++");

    CharSampleFlushPendingIo(&DeviceExtension->IoLock, FileObject);

    CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--");

    return;
}

⌨️ 快捷键说明

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