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

📄 readwrit.c

📁 modem driver for windows. Tools: winddk
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * UNIMODEM "Fakemodem" controllerless driver illustrative example
 *
 * (C) 2000 Microsoft Corporation
 * All Rights Reserved
 *
 * The code in this module simply supports the very basic AT command parser.
 * This code should be completely replaced with the actual code to support
 * your controllerless modem.
 */


#include "fakemodem.h"

NTSTATUS
FakeModemRead(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

{
    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
    NTSTATUS          status=STATUS_UNSUCCESSFUL;
    KIRQL             OldIrql;
    KIRQL             CancelIrql;

    Irp->IoStatus.Information = 0;

    //
    //  make sure the device is ready for irp's
    //
    status=CheckStateAndAddReference( DeviceObject, Irp);

    if (STATUS_SUCCESS != status) {
        //
        //  not accepting irp's. The irp has already been completed
        //
        return status;

    }

    Irp->IoStatus.Status=STATUS_PENDING;
    IoMarkIrpPending(Irp);

    KeAcquireSpinLock(&deviceExtension->SpinLock, &OldIrql);

    //
    //  make irp cancelable
    //
    IoAcquireCancelSpinLock(&CancelIrql);

    IoSetCancelRoutine(Irp, ReadCancelRoutine);

    IoReleaseCancelSpinLock(CancelIrql);

    //
    //  put it on queue
    //
    InsertTailList(&deviceExtension->ReadQueue, &Irp->Tail.Overlay.ListEntry);

    KeReleaseSpinLock(&deviceExtension->SpinLock, OldIrql);


    //
    //  call the real work function to process the irps
    //
    ReadIrpWorker( DeviceObject);

    RemoveReferenceForDispatch(DeviceObject);

    return STATUS_PENDING;

}


NTSTATUS
FakeModemWrite(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

{
    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
    NTSTATUS          status=STATUS_UNSUCCESSFUL;
    KIRQL             OldIrql;
    KIRQL             CancelIrql;


    Irp->IoStatus.Information = 0;

    //  make sure the device is ready for irp's

    status=CheckStateAndAddReference( DeviceObject, Irp);

    if (STATUS_SUCCESS != status) {
    
        //  not accepting irp's. The irp has already been complted
   
        return status;

    }

    Irp->IoStatus.Status=STATUS_PENDING;
    IoMarkIrpPending(Irp);

    KeAcquireSpinLock( &deviceExtension->SpinLock, &OldIrql);

    //  make irp cancelable
    IoAcquireCancelSpinLock(&CancelIrql);

    IoSetCancelRoutine(Irp, WriteCancelRoutine);

    IoReleaseCancelSpinLock(CancelIrql);

    //  put it on queue
    InsertTailList( &deviceExtension->WriteQueue, &Irp->Tail.Overlay.ListEntry);

    KeReleaseSpinLock(&deviceExtension->SpinLock, OldIrql);


    //  call the real work function to process the irps
    if (deviceExtension->Started)
    {
        WriteIrpWorker(DeviceObject);
    }

    RemoveReferenceForDispatch(DeviceObject);

    return STATUS_PENDING;


}



VOID
WriteIrpWorker(
    IN PDEVICE_OBJECT  DeviceObject
    )

{

    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
    NTSTATUS          status=STATUS_UNSUCCESSFUL;
    KIRQL             OldIrql;


    KeAcquireSpinLock( &deviceExtension->SpinLock, &OldIrql);

    if (deviceExtension->CurrentWriteIrp != NULL) {
        //  already in use
        goto Exit;
    }

    while (!IsListEmpty(&deviceExtension->WriteQueue)) {

        PLIST_ENTRY         ListElement;
        PIRP                Irp;
        PIO_STACK_LOCATION  IrpSp;
        KIRQL               CancelIrql;

        ListElement=RemoveHeadList( &deviceExtension->WriteQueue);

        Irp=CONTAINING_RECORD(ListElement,IRP,Tail.Overlay.ListEntry);

        IoAcquireCancelSpinLock(&CancelIrql);

        if (Irp->Cancel) {
            //  this one has been canceled
            Irp->IoStatus.Information=STATUS_CANCELLED;

            IoReleaseCancelSpinLock(CancelIrql);

            continue;
        }

        IoSetCancelRoutine(
            Irp,
            NULL
            );

        IoReleaseCancelSpinLock(CancelIrql);

        deviceExtension->CurrentWriteIrp=Irp;

        IrpSp=IoGetCurrentIrpStackLocation(Irp);

        ProcessWriteBytes( deviceExtension, Irp->AssociatedIrp.SystemBuffer,
            IrpSp->Parameters.Write.Length);

        KeReleaseSpinLock( &deviceExtension->SpinLock, OldIrql);

        Irp->IoStatus.Information = IrpSp->Parameters.Write.Length;

        RemoveReferenceAndCompleteRequest( DeviceObject, Irp, STATUS_SUCCESS);

        KeAcquireSpinLock( &deviceExtension->SpinLock, &OldIrql);

        deviceExtension->CurrentWriteIrp=NULL;

    }

Exit:

    KeReleaseSpinLock( &deviceExtension->SpinLock, OldIrql);

    TryToSatisfyRead( deviceExtension);

    ReadIrpWorker( DeviceObject);

    ProcessConnectionStateChange( DeviceObject);

    return;
}

VOID
ProcessWriteBytes(
    PDEVICE_EXTENSION   DeviceExtension,
    PUCHAR              Characters,
    ULONG               Length
    )

{

    UCHAR               CurrentCharacter;

    while (Length != 0) {

        CurrentCharacter=*Characters++;

        Length--;

        PutCharInReadBuffer( DeviceExtension, CurrentCharacter);


        switch (DeviceExtension->CommandMatchState) {

            case COMMAND_MATCH_STATE_IDLE:

                if ((CurrentCharacter == 'a') || (CurrentCharacter == 'A')) {
                    //  got an A
                    DeviceExtension->CommandMatchState=COMMAND_MATCH_STATE_GOT_A;

                    DeviceExtension->ConnectCommand=FALSE;

                    DeviceExtension->IgnoreNextChar=FALSE;

                }

            break;

            case COMMAND_MATCH_STATE_GOT_A:

                if ((CurrentCharacter == 't') || (CurrentCharacter == 'T')) {
                    //  got an T
                    DeviceExtension->CommandMatchState=COMMAND_MATCH_STATE_GOT_T;

                } else {

                    if (CurrentCharacter == '\r') {

                        DeviceExtension->CommandMatchState=COMMAND_MATCH_STATE_IDLE;
                    }
                }

            break;

            case COMMAND_MATCH_STATE_GOT_T:

                if (!DeviceExtension->IgnoreNextChar) {
                    //  the last char was not a special char
                    //  check for CONNECT command
                    if ((CurrentCharacter == 'A') || (CurrentCharacter == 'a')) {

                        DeviceExtension->ConnectCommand=TRUE;
                    }

                    if ((CurrentCharacter == 'D') || (CurrentCharacter == 'd')) {

                        DeviceExtension->ConnectCommand=TRUE;
                    }
                }

                DeviceExtension->IgnoreNextChar=FALSE;


                if ((CurrentCharacter == '&')
                    ||
                    (CurrentCharacter == '/')
                    ||
                    (CurrentCharacter == '\\')
                    ||
                    (CurrentCharacter == '+')
                    ||
                    (CurrentCharacter == '%')) {

                    //  these characters are part of are used in init
                    //  strings and may be proceeding an A or D
                    //  which we don't want to misinterpret as a dial or answer
                    DeviceExtension->IgnoreNextChar=TRUE;
                }



                if (CurrentCharacter == '\r') {
                    //
                    //  got a CR, send a response to the command
                    //
                    DeviceExtension->CommandMatchState=COMMAND_MATCH_STATE_IDLE;

                    if (DeviceExtension->ConnectCommand) {
                        //
                        //  place <cr><lf>CONNECT<cr><lf>  in the buffer
                        //
                        PutCharInReadBuffer(DeviceExtension,'\r');
                        PutCharInReadBuffer(DeviceExtension,'\n');

                        PutCharInReadBuffer(DeviceExtension,'C');
                        PutCharInReadBuffer(DeviceExtension,'O');
                        PutCharInReadBuffer(DeviceExtension,'N');
                        PutCharInReadBuffer(DeviceExtension,'N');
                        PutCharInReadBuffer(DeviceExtension,'E');
                        PutCharInReadBuffer(DeviceExtension,'C');
                        PutCharInReadBuffer(DeviceExtension,'T');

                        PutCharInReadBuffer(DeviceExtension,'\r');
                        PutCharInReadBuffer(DeviceExtension,'\n');

                        //
                        //  connected now raise CD
                        //
                        DeviceExtension->CurrentlyConnected=TRUE;

                        DeviceExtension->ConnectionStateChanged=TRUE;

                    } else {
                        

⌨️ 快捷键说明

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