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

📄 functions.c

📁 Introduction to the Transport Device Interface-f
💻 C
📖 第 1 页 / 共 3 页
字号:
 *    This is where we perform our Network Writes
 *
 **********************************************************************/
VOID TdiExample_NetworkWriteThread(PVOID StartContext)
{
    PTDI_EXAMPLE_CONTEXT pTdiExampleContext = (PVOID)StartContext;
    PVOID pEvents[2];
    NTSTATUS NtStatus;

    DbgPrint("TdiExample_NetworkWriteThread Called \r\n");

    /*
     * This thread will continue until the instance handle is closed.
     *
     */
    while(pTdiExampleContext->bWriteThreadAlive)
    {
         pEvents[0] = (PVOID)&pTdiExampleContext->kWriteIrpReady;
         pEvents[1] = (PVOID)&pTdiExampleContext->kWakeWriteIrpThread;

         NtStatus = KeWaitForMultipleObjects(2, (PVOID)pEvents, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);

         /*
          * The first wait object will return "STATUS_WAIT_0".  Other objects will
          * increment from there.  We only send data on a wait of 0.  The other
          * return values from this function are simply used to wake up not send data.
          */
         if(NtStatus == STATUS_WAIT_0)
         {
             BOOLEAN bMoreIrps = FALSE;
             PIRP Irp;
             /*
              * We will need to remove an IRP from the Queue and then send the data.  We will
              * continue to do this until there are no more IRP's to send or the thread
              * has been terminated.
              */
             do {
                 bMoreIrps = FALSE;

                 Irp = HandleIrp_RemoveNextIrp(pTdiExampleContext->pWriteIrpListHead);

                 if(Irp)
                 {  
                    NTSTATUS NtStatus;
                    UINT uiDataSent;
                    PIO_STACK_LOCATION pIoStackLocation = IoGetCurrentIrpStackLocation(Irp);

                    Irp->Tail.Overlay.DriverContext[0] = NULL;

                    bMoreIrps = TRUE;
                    
                    NtStatus = TdiFuncs_Send(pTdiExampleContext->TdiHandle.pfoConnection, Irp->AssociatedIrp.SystemBuffer, pIoStackLocation->Parameters.Write.Length, &uiDataSent);

                    Irp->IoStatus.Status      = NtStatus;
                    Irp->IoStatus.Information = uiDataSent;

                    DbgPrint("TdiExample_NetworkWriteThread Complete IRP = 0x%0x \r\n", Irp);
                    IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);

                 }


             } while(pTdiExampleContext->bWriteThreadAlive && bMoreIrps);
         }
    }
    DbgPrint("TdiExample_NetworkWriteThread Exit \r\n");
}



/**********************************************************************
 * 
 *  TdiExample_CleanUp
 *
 *    This is called when an instance of this driver is closed (CloseHandle)
 *
 *    This is actually IRP_MJ_CLEANUP so we can release the IRP's.
 *
 **********************************************************************/
NTSTATUS TdiExample_CleanUp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_SUCCESS;
    PIO_STACK_LOCATION pIoStackIrp = NULL;
    PTDI_EXAMPLE_CONTEXT pTdiExampleContext = NULL;

    DbgPrint("TdiExample_CleanUp Called \r\n");

    pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);

    pTdiExampleContext = (PTDI_EXAMPLE_CONTEXT)pIoStackIrp->FileObject->FsContext;

    if(pTdiExampleContext)
    {
        /*
         * The first thing we want to do is close the write thread.  We will do this
         * by signaling the thread and then waiting for it to be destroyed.
         *
         * 1. Set Boolean to False
         * 2. Signal Thread to Wake Up
         * 3. Wait for Thread Object to become signaled
         * 4. Remove Reference to Thread Object
         *
         */
        pTdiExampleContext->bWriteThreadAlive = FALSE;

        KeSetEvent(&pTdiExampleContext->kWakeWriteIrpThread, IO_NO_INCREMENT, FALSE);

        NtStatus = KeWaitForSingleObject(pTdiExampleContext->pWriteThread, Executive, KernelMode, FALSE, NULL);

        DbgPrint("Write Thread Close - 0x%0x\n", NtStatus);

        NtStatus = STATUS_SUCCESS;

        ObDereferenceObject(pTdiExampleContext->pWriteThread);

        pTdiExampleContext->pWriteThread = NULL;
                
        /*
         * If the handle is connected disconnect.  We no longer
         * require the connection lock since we are currently closing this handle.
         */
        if(pTdiExampleContext->csConnectionState == CS_CONNECTED)
        {
           TdiFuncs_Disconnect(pTdiExampleContext->TdiHandle.pfoConnection);
           pTdiExampleContext->csConnectionState = CS_NOT_CONNECTED;
        }

        /*
         * Free Handles, IRPs, etc.
         */
        TdiFuncs_FreeHandles(&pTdiExampleContext->TdiHandle);
        
        HandleIrp_FreeIrpListWithCleanUp(pTdiExampleContext->pReadIrpListHead);
        HandleIrp_FreeIrpListWithCleanUp(pTdiExampleContext->pWriteIrpListHead);

        DbgPrint("TdiExample_CleanUp Free = 0x%0x \r\n", pTdiExampleContext);
        KMem_FreeNonPagedMemory(pTdiExampleContext);

        pIoStackIrp->FileObject->FsContext = NULL;
    }

    Irp->IoStatus.Status      = NtStatus;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    DbgPrint("TdiExample_CleanUp Exit 0x%0x \r\n", NtStatus);

    
    return NtStatus;
}


/**********************************************************************
 * 
 *  TdiExample_IoControlInternal
 *
 *    These are IOCTL's which can only be sent by other drivers.
 *
 **********************************************************************/
NTSTATUS TdiExample_IoControlInternal(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_NOT_SUPPORTED;
    PIO_STACK_LOCATION pIoStackIrp = NULL;

    DbgPrint("TdiExample_IoControlInternal Called \r\n");

    Irp->IoStatus.Status      = NtStatus;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    DbgPrint("TdiExample_IoControlInternal Exit 0x%0x \r\n", NtStatus);

    return NtStatus;
}



/**********************************************************************
 * 
 *  TdiExample_IoControl
 *
 *    This is called when an IOCTL is issued on the device handle (DeviceIoControl)
 *
 **********************************************************************/
NTSTATUS TdiExample_IoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_NOT_SUPPORTED;
    PIO_STACK_LOCATION pIoStackIrp = NULL;
    PTDI_EXAMPLE_CONTEXT pTdiExampleContext = NULL;
    
    DbgPrint("TdiExample_IoControl Called \r\n");

    /*
     * Each time the IRP is passed down the driver stack a new stack location is added
     * specifying certain parameters for the IRP to the driver.
     */
    pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);    

    if(pIoStackIrp) /* Should Never Be NULL! */
    {
        DbgPrint("Example_IoControl Called IOCTL = 0x%0x\r\n", pIoStackIrp->Parameters.DeviceIoControl.IoControlCode);
        
        pTdiExampleContext = (PTDI_EXAMPLE_CONTEXT)pIoStackIrp->FileObject->FsContext;

        switch(pIoStackIrp->Parameters.DeviceIoControl.IoControlCode)
        {
            case IOCTL_TDIEXAMPLE_CONNECT:
                 NtStatus = TdiExample_Connect(pTdiExampleContext, Irp->AssociatedIrp.SystemBuffer, pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength);
                 break;
            
            case IOCTL_TDIEXAMPLE_DISCONNECT:
                 NtStatus = TdiExample_Disconnect(pTdiExampleContext);
                 break;

        }
    }


    Irp->IoStatus.Status      = NtStatus;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    DbgPrint("TdiExample_IoControl Exit 0x%0x \r\n", NtStatus);

    return NtStatus;
}






/**********************************************************************
 * 
 *  TdiExample_Write
 *
 *    This is called when a write is issued on the device handle (WriteFile/WriteFileEx)
 *
 *
 **********************************************************************/
NTSTATUS TdiExample_Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
    PIO_STACK_LOCATION pIoStackIrp = NULL;
    PTDI_EXAMPLE_CONTEXT pTdiExampleContext = NULL;


    DbgPrint("TdiExample_Write Called 0x%0x\r\n", Irp);
    
    /*
     * Each time the IRP is passed down the driver stack a new stack location is added
     * specifying certain parameters for the IRP to the driver.
     */
    pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);    
    
    pTdiExampleContext = (PTDI_EXAMPLE_CONTEXT)pIoStackIrp->FileObject->FsContext;

    if(pTdiExampleContext->csConnectionState == CS_CONNECTED)
    {
        /*
         * We can use the "Overlay.DriverContext" data on the IRP to use driver specific contexts
         * onto an IRP but only WHILE WE OWN THE IRP.  Since we will be owning this IRP
         * we can use this as the context we can find in our cancel routine.  The problem
         * is that we cannot use teh IO_STACK_LOCATION in the cancel routine since we 
         * can't be guarentteed what the current stack location is when the cancel
         * routine is called.
         *
         * We then add our IRP to the list.
         */
        Irp->Tail.Overlay.DriverContext[0] = (PVOID)pTdiExampleContext->pWriteIrpListHead;
        NtStatus = HandleIrp_AddIrp(pTdiExampleContext->pWriteIrpListHead, Irp, TdiExample_CancelRoutine, TdiExample_IrpCleanUp, NULL);

        if(NT_SUCCESS(NtStatus))
        {
            KeSetEvent(&pTdiExampleContext->kWriteIrpReady, IO_NO_INCREMENT, FALSE);
            NtStatus = STATUS_PENDING;
        }

    }
    else
    {
    
        Irp->IoStatus.Status      = NtStatus;
        Irp->IoStatus.Information = 0;
    
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }

    DbgPrint("TdiExample_Write Exit 0x%0x \r\n", NtStatus);

    
    return NtStatus;
}


/**********************************************************************
 * 
 *  TdiExample_Read
 *
 *    This is called when a read is issued on the device handle (ReadFile/ReadFileEx)
 *
 *
 **********************************************************************/
NTSTATUS TdiExample_Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS NtStatus = STATUS_BUFFER_TOO_SMALL;
    PIO_STACK_LOCATION pIoStackIrp = NULL;
    PTDI_EXAMPLE_CONTEXT pTdiExampleContext = NULL;

    DbgPrint("TdiExample_Read Called 0x%0x \r\n", Irp);

    /*

⌨️ 快捷键说明

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