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

📄 util.c

📁 win2k kernel 的并口驱动程序模板
💻 C
📖 第 1 页 / 共 3 页
字号:
//+-------------------------------------------------------------------------
//
//  Microsoft Windows
//
//  Copyright (C) Microsoft Corporation, 1998 - 1999
//
//  File:       util.c
//
//--------------------------------------------------------------------------

#include "pch.h"

// PptSucceedRequestNullInfo(Irp)                  - IoStatus.Status=STATUS_SUCCESS, IoStatus.Information=NULL
// PptSucceedRequest(Irp)                          - IoStatus.Status=STATUS_SUCCESS, IoStatus.Information unmodified
// PptSucceedRequestBoostPriority(Irp, Increment)  - IoStatus.Status=STATUS_SUCCESS, IoStatus.Information=NULL
// PptFailRequest(Irp, status)                     - IoStatus.Status=STATUS_SUCCESS, IoStatus.Information=NULL

NTSTATUS
PptFailRequest(PIRP Irp, NTSTATUS Status) {
    Irp->IoStatus.Status      = Status;
    Irp->IoStatus.Information = 0;
    PptCompleteRequest(Irp, IO_NO_INCREMENT);
    return Status;
}

NTSTATUS
PptAcquireRemoveLockOrFailIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    PDEVICE_EXTENSION extension  = DeviceObject->DeviceExtension;
    PIO_REMOVE_LOCK   removeLock = &extension->RemoveLock;

    NTSTATUS          status     = IoAcquireRemoveLock(removeLock, Irp);

    if( !NT_SUCCESS(status) ) {
        PptFailRequest(Irp, status);
    }

    return status;
}


NTSTATUS
PptDispatchPreProcessIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++

    - Acquire removelock
    - If(!Special Handling IRP) {
          check if we are running, stalled
         

--*/
{
    PDEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;
    NTSTATUS status = PptAcquireRemoveLock(&Extension->RemoveLock, Irp);
    UNREFERENCED_PARAMETER(DeviceObject);
    UNREFERENCED_PARAMETER(Irp);


        if ( !NT_SUCCESS( status ) ) {
            //
            // Someone gave us a pnp irp after a remove.  Unthinkable!
            //
            ASSERT(FALSE);
            Irp->IoStatus.Information = 0;
            Irp->IoStatus.Status = status;
            PptCompleteRequest(Irp, IO_NO_INCREMENT);
        }

    return status;
}

NTSTATUS
PptDispatchPostProcessIrp() { return STATUS_SUCCESS; }

NTSTATUS
PptSynchCompletionRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PKEVENT Event
    )
/*++
      
Routine Description:
      
    This routine is for use with synchronous IRP processing.
    All it does is signal an event, so the driver knows it
    can continue.
      
Arguments:
      
    DriverObject - Pointer to driver object created by system.
      
    Irp          - Irp that just completed
      
    Event        - Event we'll signal to say Irp is done
      
Return Value:
      
    None.
      
--*/
{
    UNREFERENCED_PARAMETER( Irp );
    UNREFERENCED_PARAMETER( DeviceObject );

    KeSetEvent((PKEVENT) Event, 0, FALSE);
    return (STATUS_MORE_PROCESSING_REQUIRED);
}

PWSTR
PptGetPortNameFromPhysicalDeviceObject(
  PDEVICE_OBJECT PhysicalDeviceObject
)

/*++

Routine Description:

    Retrieve the PortName for the ParPort from the registry. This PortName
      will be used as the symbolic link name for the end of chain device 
      object created by ParClass for this ParPort.

    *** This function allocates pool. ExFreePool must be called when
          result is no longer needed.

Arguments:

    PortDeviceObject - The ParPort Device Object

Return Value:

    PortName - if successful
    NULL     - otherwise

--*/

{
    NTSTATUS                    status;
    HANDLE                      hKey;
    PKEY_VALUE_FULL_INFORMATION buffer;
    ULONG                       bufferLength;
    ULONG                       resultLength;
    PWSTR                       valueNameWstr;
    UNICODE_STRING              valueName;
    PWSTR                       portName;

    PAGED_CODE ();

    //
    // try to open the registry key
    //

    PptDumpV( ("PptGetPortNameFromPhysicalDeviceObject()\n") );

    status = IoOpenDeviceRegistryKey(PhysicalDeviceObject,
                                     PLUGPLAY_REGKEY_DEVICE,
                                     STANDARD_RIGHTS_ALL,
                                     &hKey);

    if( !NT_SUCCESS(status) ) {
        // unable to open key, bail out
        PptDumpV( ("PptGetPortNameFromPhysicalDeviceObject(): "
                   "registry key open failed, status = %x\n", status) );
        return NULL;    
    }

    //
    // we have a handle to the registry key
    //
    // loop trying to read registry value until either we succeed or
    //   we get a hard failure, grow the result buffer as needed
    //

    bufferLength  = 0;          // we will ask how large a buffer we need
    buffer        = NULL;
    valueNameWstr = (PWSTR)L"PortName";
    RtlInitUnicodeString(&valueName, valueNameWstr);
    status        = STATUS_BUFFER_TOO_SMALL;

    while(status == STATUS_BUFFER_TOO_SMALL) {

      status = ZwQueryValueKey(hKey,
                               &valueName,
                               KeyValueFullInformation,
                               buffer,
                               bufferLength,
                               &resultLength);

      if(status == STATUS_BUFFER_TOO_SMALL) {
        // 
        // buffer too small, free it and allocate a larger buffer
        //
        if(buffer) ExFreePool(buffer);
        buffer       = ExAllocatePool(PagedPool, resultLength);
        bufferLength = resultLength;
        if(!buffer) {
          // unable to allocate pool, clean up and exit
            PptDumpV( (" - unable to allocate pool to for PortName query\n") );
          ZwClose(hKey);
          return NULL;
        }
      }

    } // end while BUFFER_TOO_SMALL

    
    //
    // query is complete
    //

    // no longer need the handle so close it
    ZwClose(hKey);

    // check the status of our query
    if( !NT_SUCCESS(status) ) {
        if(buffer) ExFreePool(buffer);
        PptDumpV( (" - query for PortName FAILED - status = %x\n",
                  status) );
        return NULL;
    }

    // sanity check our result
    if( (buffer->Type != REG_SZ) || (!buffer->DataLength) ) {
        PptDumpV( (" - either bogus PortName data type or zero length\n",
                  status) );
        ExFreePool(buffer);       // query succeeded, so we know we have a buffer
        return NULL;
    }
    

    // 
    // result looks ok, copy PortName to its own allocation of the proper size
    //   and return a pointer to it
    //

    portName = ExAllocatePool(PagedPool, buffer->DataLength);
    if(!portName) {
      // unable to allocate pool, clean up and exit
        PptDumpV( (" - unable to allocate pool to hold PortName(SymbolicLinkName)\n") );
        ExFreePool(buffer);
        return NULL;
    }

    RtlCopyMemory(portName, 
                  (PUCHAR)buffer + buffer->DataOffset, 
                  buffer->DataLength);

    ExFreePool(buffer);

    return portName;
}

NTSTATUS
PptConnectInterrupt(
    IN  PDEVICE_EXTENSION   Extension
    )

/*++
      
Routine Description:
      
    This routine connects the port interrupt service routine
      to the interrupt.
      
Arguments:
      
    Extension   - Supplies the device extension.
      
Return Value:
      
    NTSTATUS code.
      
--*/
    
{
    NTSTATUS Status = STATUS_SUCCESS;
    
    if (!Extension->FoundInterrupt) {
        
        return STATUS_NOT_SUPPORTED;
        
    }
    
    //
    // Connect the interrupt.
    //
    
    Status = IoConnectInterrupt(&Extension->InterruptObject,
                                PptInterruptService,
                                Extension,
                                NULL,
                                Extension->InterruptVector,
                                Extension->InterruptLevel,
                                Extension->InterruptLevel,
                                Extension->InterruptMode,
                                TRUE,
                                Extension->InterruptAffinity,
                                FALSE);
    
    if (!NT_SUCCESS(Status)) {
        
        PptLogError(Extension->DeviceObject->DriverObject,
                    Extension->DeviceObject,
                    Extension->PortInfo.OriginalController,
                    PhysicalZero, 0, 0, 0, 14,
                    Status, PAR_INTERRUPT_CONFLICT);
        
        PptDump2(PARERRORS, ("Could not connect to interrupt for %x\n",
                             Extension->PortInfo.OriginalController.LowPart) );
    }
    
    return Status;
}

VOID
PptDisconnectInterrupt(
    IN  PDEVICE_EXTENSION   Extension
    )

/*++
      
Routine Description:
      
    This routine disconnects the port interrupt service routine
      from the interrupt.
      
Arguments:
      
    Extension   - Supplies the device extension.
      
Return Value:
      
    None.
      
--*/
    
{
    IoDisconnectInterrupt(Extension->InterruptObject);
}

BOOLEAN
PptSynchronizedIncrement(
    IN OUT  PVOID   SyncContext
    )

/*++
      
Routine Description:
      
    This routine increments the 'Count' variable in the context and returns
      its new value in the 'NewCount' variable.
      
Arguments:
      
    SyncContext - Supplies the synchronize count context.
      
Return Value:
      
    TRUE
      
--*/
    
{
    ((PSYNCHRONIZED_COUNT_CONTEXT) SyncContext)->NewCount =
        ++(*(((PSYNCHRONIZED_COUNT_CONTEXT) SyncContext)->Count));
    return(TRUE);
}

BOOLEAN
PptSynchronizedDecrement(
    IN OUT  PVOID   SyncContext
    )

/*++
      
Routine Description:
      
    This routine decrements the 'Count' variable in the context and returns
      its new value in the 'NewCount' variable.
      
Arguments:
      
    SyncContext - Supplies the synchronize count context.
      
Return Value:
      
    TRUE
      
--*/
    
{
    ((PSYNCHRONIZED_COUNT_CONTEXT) SyncContext)->NewCount =
        --(*(((PSYNCHRONIZED_COUNT_CONTEXT) SyncContext)->Count));
    return(TRUE);
}

BOOLEAN
PptSynchronizedRead(
    IN OUT  PVOID   SyncContext
    )

/*++
      
Routine Description:
      
    This routine reads the 'Count' variable in the context and returns
      its value in the 'NewCount' variable.
      
Arguments:
      
    SyncContext - Supplies the synchronize count context.
      
Return Value:
      
    None.
      
--*/
    
{
    ((PSYNCHRONIZED_COUNT_CONTEXT) SyncContext)->NewCount =
        *(((PSYNCHRONIZED_COUNT_CONTEXT) SyncContext)->Count);
    return(TRUE);
}

BOOLEAN
PptSynchronizedQueue(
    IN  PVOID   Context
    )

/*++
      
Routine Description:
      
    This routine adds the given list entry to the given list.
      
Arguments:
      
    Context - Supplies the synchronized list context.
      
Return Value:
      
    TRUE
      
--*/
    
{
    PSYNCHRONIZED_LIST_CONTEXT  ListContext;
    
    ListContext = Context;
    InsertTailList(ListContext->List, ListContext->NewEntry);
    return(TRUE);
}

BOOLEAN
PptSynchronizedDisconnect(
    IN  PVOID   Context
    )

/*++
      
Routine Description:
    
    This routine removes the given list entry from the ISR
      list.
      
Arguments:
      
    Context - Supplies the synchronized disconnect context.
      
Return Value:
      
    FALSE   - The given list entry was not removed from the list.
    TRUE    - The given list entry was removed from the list.
      
--*/
    
{
    PSYNCHRONIZED_DISCONNECT_CONTEXT    DisconnectContext;
    PKSERVICE_ROUTINE                   ServiceRoutine;
    PVOID                               ServiceContext;
    PLIST_ENTRY                         Current;
    PISR_LIST_ENTRY                     ListEntry;
    
    DisconnectContext = Context;
    ServiceRoutine = DisconnectContext->IsrInfo->InterruptServiceRoutine;
    ServiceContext = DisconnectContext->IsrInfo->InterruptServiceContext;
    
    for (Current = DisconnectContext->Extension->IsrList.Flink;
         Current != &(DisconnectContext->Extension->IsrList);
         Current = Current->Flink) {
        
        ListEntry = CONTAINING_RECORD(Current, ISR_LIST_ENTRY, ListEntry);
        if (ListEntry->ServiceRoutine == ServiceRoutine &&
            ListEntry->ServiceContext == ServiceContext) {
            
            RemoveEntryList(Current);
            return TRUE;
        }
    }
    
    return FALSE;
}

VOID
PptCancelRoutine(
    IN OUT  PDEVICE_OBJECT  DeviceObject,
    IN OUT  PIRP            Irp
    )

⌨️ 快捷键说明

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