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

📄 comeml.c

📁 The Lite Evaluation/Demonstration Kit is intended to illustrate use of the AN3042. The AN3042 is c
💻 C
📖 第 1 页 / 共 4 页
字号:
//////////////////////////////////////////////////////////////////////
//
// File:      comeml.c
// $Archive: /ComemL/Host/Driver/WinNT/comeml.c $
//
// Purpose:
//   main module for the Windows NT comem lite device driver
//
// Environment:
//    kernel mode
//
// $Author: Markm $
//
// $History: comeml.c $           
//  
//  *****************  Version 1  *****************
//  User: Markm        Date: 1/27/99    Time: 10:47a
//  Created in $/ComemL/Host/Driver/WinNT
//  initial revision - based on Comem driver
//  
//  
// Copyright (c) 1997 Anchor Chips, Inc.  May not be reproduced without
// permission.  See the license agreement for more details.
//
//////////////////////////////////////////////////////////////////////

#include "ntddk.h"
#include "comemdrv.h"
#include "stdarg.h"

NTSTATUS
CoMemCreateDeviceObject(
   IN PDRIVER_OBJECT DriverObject,
   IN PDEVICE_OBJECT *DeviceObject,
   IN PUNICODE_STRING RegistryPath,
   LONG Instance
   );

NTSTATUS
CoMemGetVendorId(
    IN PUNICODE_STRING RegistryPath,
    OUT WORD * vendorId
    );

NTSTATUS
CoMemGetDeviceId(
    IN PUNICODE_STRING RegistryPath,
    OUT WORD * deviceId
    );

NTSTATUS
CoMemDispatch(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

VOID
CoMemUnload(
    IN PDRIVER_OBJECT DriverObject
    );


NTSTATUS
CoMemAllocContigMemory(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

void
CoMemDeAllocContigMemory(
    IN PDEVICE_OBJECT DeviceObject
    );

PVOID
CoMemGetLinearPointer(
   IN PVOID SystemAddress,
   IN ULONG Length
   );

NTSTATUS
CoMemGetPciConfig(
      IN WORD VendorId,
      IN WORD DeviceId,
      IN int  Instance,
      OUT PCI_CONFIG_HEADER_0 *PciCfgHdr
      );

NTSTATUS
CoMemSetPciConfig(
      IN WORD VendorId,
      IN WORD DeviceId,
      IN int  Instance,
      IN PCI_CONFIG_HEADER_0 *PciCfgHdr
    );

NTSTATUS
CoMemMapBars(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

void
CoMemUnmapBars(
    IN PDEVICE_OBJECT DeviceObject
    );

NTSTATUS
GetLinearBarPointer(
   IN ULONG PhysicalBarAddress,
   IN ULONG Length,
   IN OUT PVOID *LinearBarAddress
   );

#if DBG
#define CoMemKdPrint(arg) DbgPrint arg
#else
#define CoMemKdPrint(arg)
#endif

#define COMEM_NAME_MAX 64

//
// The device Extension
//

typedef struct
{
   WORD     vendorId;                     // PCI vendor ID for this comem device
   WORD     deviceId;                     // PCI device ID for this comem device
   int      instance;                     // Instance ofthis comem device

   ULONG    baseAddresses[COMEM_MAX_BARS]; // PCI base address registers for this comem device
   PVOID    linearBaseAddr[COMEM_MAX_BARS]; // user mode BAR pointers

   //
   // The whole idea of this driver is to allocate a contiguous buffer that can be
   // used for DMA transfers and can be accessed from a user mode app. To accomplish
   // this, we need to keep track of three different "pointers" to the buffer.
   //
   // A kernel mode pointer to the DMA buffer.  It
   // is above 2GB, so it can't be accessed from user mode.
   // This is the pointer that the driver will use to access the
   // buffer
   //
   PVOID    systemAddr;
   //
   // A user mode pointer to the DMA buffer.  This is the pointer that a user
   // can use to access the DMA buffer.  This pointer is only valid in the context of 
   // the user mode process that allocated the buffer.
   //
   PVOID    linearAddr;
   //
   // Actual physical address of the DMA buffer.
   //
   DWORD    physAddr;

   //
   // The size of the DMA buffer.
   //
   ULONG    bufferSize;

   ULONG    referenceCount;               // the number of open handles to this device

   // Name buffer for our named Functional device object link
   WCHAR DeviceLinkNameBuffer[COMEM_NAME_MAX];

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
// 
// Routine Description:
// 
//  Installable driver initialization entry point.
//  This entry point is called directly by the I/O system.
// 
// Arguments:
// 
//  DriverObject - pointer to the driver object
// 
//  RegistryPath - pointer to a unicode string representing the path
//                 to driver-specific key in the registry
// 
// Return Value:
// 
//  STATUS_SUCCESS if successful,
//  STATUS_UNSUCCESSFUL otherwise
// 
//////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{

   PDEVICE_OBJECT deviceObject = NULL;
   int instance = 0;

   CoMemKdPrint (("COMEM.SYS: entering DriverEntry\n"));


   //
   // Create dispatch points for device control, create, close.
   //
   DriverObject->MajorFunction[IRP_MJ_CREATE]         =
   DriverObject->MajorFunction[IRP_MJ_CLOSE]          =
   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CoMemDispatch;
   DriverObject->DriverUnload                         = CoMemUnload;


   //
   // create a device object for the comem device.  For now create
   // a single device object.  This driver will eventually be updated
   // to search for Comem devices in the system and will create
   // a device object for each one
   //

   //
   // Create a device object for each comem device in the system
   //
   while (NT_SUCCESS(CoMemCreateDeviceObject(DriverObject,&deviceObject, RegistryPath, instance++)));

   CoMemKdPrint (("COMEM.SYS: exiting DriverEntry\n"));


   return STATUS_SUCCESS;
}

//////////////////////////////////////////////////////////////////////////
// 
// Routine Description:
// 
// Arguments:
// 
// Return Value:
// 
//  STATUS_SUCCESS if successful,
//  STATUS_UNSUCCESSFUL otherwise
// 
//////////////////////////////////////////////////////////////////////////
NTSTATUS
CoMemCreateDeviceObject(
   IN PDRIVER_OBJECT DriverObject,
   IN PDEVICE_OBJECT *DeviceObject,
   IN PUNICODE_STRING RegistryPath,
   LONG Instance
   )
{
   WCHAR             deviceNameBuffer[] = L"\\Device\\COMEM-0";
   UNICODE_STRING    deviceNameUnicodeString;
   WCHAR             deviceLinkBuffer[] = L"\\DosDevices\\COMEM-0";
   UNICODE_STRING    deviceLinkUnicodeString;
   PDEVICE_EXTENSION deviceExtension;
   NTSTATUS          ntStatus = STATUS_SUCCESS;
   PCI_CONFIG_HEADER_0 pciCfg;
   int i;
   WORD              vendorId = 0;
   WORD              deviceId = 0;

   CoMemKdPrint (("COMEM.SYS: entering CoMemCreateDeviceObject\n"));

   //
   // Fix up the device name based on Instance
   //
   deviceLinkBuffer[18] = (USHORT) ('0' + Instance);
   deviceNameBuffer[14] = (USHORT) ('0' + Instance);

   RtlInitUnicodeString (&deviceNameUnicodeString,
                         deviceNameBuffer);

   ntStatus = IoCreateDevice (DriverObject,
                              sizeof(DEVICE_EXTENSION),
                              &deviceNameUnicodeString,
                              FILE_DEVICE_COMEM,
                              0,
                              FALSE,
                              DeviceObject);

   CoMemKdPrint (("COMEM.SYS: returned from IoCreateDevice\n"));

   if (NT_SUCCESS(ntStatus))
   {
      //
      // initialize the Device Extension
      //

      deviceExtension = (PDEVICE_EXTENSION) ((*DeviceObject)->DeviceExtension);

      RtlZeroMemory((PVOID)deviceExtension,sizeof(DEVICE_EXTENSION));

      deviceExtension->referenceCount = 0;
      //
      // fill in pci information about this device in the device extension.
      // First get the target vendor and device ID's from the registry
      // (CoMemGetVendorId(), CoMemGetDeviceId()), then try to find them
      // them on the PCI bus (CoMemGetPciConfig()).
      //
      
      CoMemGetVendorId(RegistryPath, &vendorId);
      CoMemGetDeviceId(RegistryPath, &deviceId);

      ntStatus = CoMemGetPciConfig(vendorId, deviceId, Instance, &pciCfg);

      if (!NT_SUCCESS(ntStatus))
      {
         CoMemKdPrint (("COMEM.SYS: Unable to locate comem device\n"));

         IoDeleteDevice (*DeviceObject);
         return ntStatus;
      }
      else
      {
         deviceExtension->vendorId = pciCfg.VendorID;
         deviceExtension->deviceId = pciCfg.DeviceID;
         deviceExtension->instance = Instance;

         for (i = 0; i < COMEM_MAX_BARS; i++)
         {
            deviceExtension->baseAddresses[i] = pciCfg.BaseAddresses[i];
         }
      }

      //
      // Create a symbolic link, e.g. a name that a Win32 app can specify
      // to open the device
      //

      RtlInitUnicodeString(&deviceLinkUnicodeString,
                           deviceLinkBuffer);

      ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
                                       &deviceNameUnicodeString);

      RtlCopyMemory(deviceExtension->DeviceLinkNameBuffer,
                    deviceLinkBuffer,
                    sizeof(deviceLinkBuffer));

      if (!NT_SUCCESS(ntStatus))
      {
         //
         // Symbolic link creation failed- note this & then delete the
         // device object (it's useless if a Win32 app can't get at it).
         //

         CoMemKdPrint (("COMEM.SYS: IoCreateSymbolicLink failed\n"));
         
         IoDeleteDevice (*DeviceObject);
         return ntStatus;
      }


   }
   else
   {
      CoMemKdPrint (("COMEM.SYS: IoCreateDevice failed\n"));
   }

   CoMemKdPrint (("COMEM.SYS: exiting CoMemCreateDeviceObject\n"));

   return ntStatus;   
}

NTSTATUS
CoMemGetVendorId(
    IN PUNICODE_STRING RegistryPath,
    OUT WORD * vendorId
)
{
   UNICODE_STRING  paramPath;
   static  WCHAR   SubKeyString[] = L"\\Parameters";
   RTL_QUERY_REGISTRY_TABLE    paramTable[2];
   ULONG                       zero = 0;

   CoMemKdPrint (("COMEM.SYS: Enter CoMemGetVendorId\n"));

   //
   // The registry path parameter points to our key, we will append
   // the Parameters key and look for any additional configuration items
   // there.  We add room for a trailing NUL for those routines which
   // require it.

   paramPath.MaximumLength = RegistryPath->Length + sizeof(SubKeyString);
   paramPath.Buffer = ExAllocatePool(PagedPool, paramPath.MaximumLength);

   if (paramPath.Buffer != NULL)
   {
      RtlCopyMemory(paramPath.Buffer, RegistryPath->Buffer, RegistryPath->Length);

      RtlCopyMemory(&paramPath.Buffer[RegistryPath->Length / 2], SubKeyString,

⌨️ 快捷键说明

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