📄 dt2851.c
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=gb2312" http-equiv=Content-Type></HEAD>
<BODY scroll=yes><XMP>//
// DataTranslations DT2851 frame grabber driver version 1.0
//
// Adapted from NT DDK GENPORT driver
//
//
#include "DT2851.h"
#include "stdlib.h"
#define DT2851KdPrint(x)
///////////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT driverObject,
IN PUNICODE_STRING registryPath )
/*
Routine Description:
This routine is the entry point for the driver. It is responsible
for setting the dispatch entry points in the driver object and creating
the device object. Any resources such as ports, interrupts and DMA
channels used must be reported. A symbolic link must be created between
the device name and an entry in \DosDevices in order to allow Win32
applications to open the device.
Arguments:
driverObject - Pointer to driver object created by the system.
Return Value:
STATUS_SUCCESS if the driver initialized correctly, otherwise an error
indicating the reason for failure.
*/
{
PDEVICE_OBJECT deviceObject = NULL;
// NT Device Name
WCHAR deviceNameBuffer[] = DT2851_DEVICE_NAME;
UNICODE_STRING deviceNameUnicodeString;
// DOS-Win32 Device Link
WCHAR deviceLinkBuffer[] = DOS_DT2851_DEVICE_NAME;
UNICODE_STRING deviceLinkUnicodeString;
DT2851_EXTENSION *extension; // Device extension
ULONG physicalPortAddress32; // 32 bit physical address of port
PHYSICAL_ADDRESS physicalPortAddress64; // 64 bit physical address of port
ULONG portCount = 16; // Count of contiguous I/O ports
ULONG physicalMemoryAddress32; // 32 bit physical address of memory
PHYSICAL_ADDRESS physicalMemoryAddress64; // 64 bit physical address of memory
ULONG addressSpace = MEMORY_SIZE;
CM_RESOURCE_LIST resourceList; // Resource usage list to report to system
BOOLEAN resourceConflict; // This is set true if our I/O ports
// conflict with another driver
BOOLEAN result;
NTSTATUS status;
// Try to retrieve base I/O port, number of ports and base memory address
// from the Registry.
// If there isn't anything specified then use the values compiled into
// this driver.
{
static WCHAR subKeyString[] = L"\\Parameters";
UNICODE_STRING paramPath;
RTL_QUERY_REGISTRY_TABLE paramTable[3];
ULONG defaultportBase = BASE_PORT;
ULONG defaultphysicalMemoryAddress32 = BASE_ADDRESS;
//
// Since the registry path parameter is a "counted" UNICODE string, it
// might not be zero terminated. For a very short time allocate memory
// to hold the registry path as well as the Parameters key name zero
// terminated so that we can use it to delve into the registry.
//
paramPath.MaximumLength = registryPath->Length + sizeof(subKeyString);
paramPath.Buffer = ExAllocatePool(PagedPool, paramPath.MaximumLength);
if (paramPath.Buffer != NULL)
{
RtlMoveMemory(
paramPath.Buffer, registryPath->Buffer, registryPath->Length);
RtlMoveMemory(
¶mPath.Buffer[registryPath->Length / 2], subKeyString,
sizeof(subKeyString));
paramPath.Length = paramPath.MaximumLength - 2;
RtlZeroMemory(¶mTable[0], sizeof(paramTable));
paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[0].Name = L"IoPortAddress";
paramTable[0].EntryContext = &physicalPortAddress32;
paramTable[0].DefaultType = REG_DWORD;
paramTable[0].DefaultData = &defaultportBase;
paramTable[0].DefaultLength = sizeof(ULONG);
paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[1].Name = L"BaseMemoryAddress";
paramTable[1].EntryContext = &physicalMemoryAddress32;
paramTable[1].DefaultType = REG_DWORD;
paramTable[1].DefaultData = &defaultphysicalMemoryAddress32;
paramTable[1].DefaultLength = sizeof(ULONG);
if (!NT_SUCCESS(RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
paramPath.Buffer, ¶mTable[0], NULL, NULL)))
{
physicalPortAddress32 = defaultportBase;
physicalMemoryAddress32 = defaultphysicalMemoryAddress32;
}
ExFreePool(paramPath.Buffer);
}
}
// put physical port address in 64 bit word
physicalPortAddress64.LowPart = physicalPortAddress32;
physicalPortAddress64.HighPart = 0;
// put physical memory address in 64 bit word
physicalMemoryAddress64.LowPart = physicalMemoryAddress32;
physicalMemoryAddress64.HighPart = 0;
#if 0
// Register resource usage (ports)
//
// This ensures that there isn't a conflict between this driver and
// a previously loaded one or a future loaded one.
RtlZeroMemory((PVOID)&resourceList, sizeof(resourceList));
resourceList.Count = 1;
resourceList.List[0].InterfaceType = Isa;
resourceList.List[0].BusNumber = 0;
resourceList.List[0].PartialResourceList.Count = 2;
// Port I/O resource list
resourceList.List[0].PartialResourceList.PartialDescriptors[0].Type =
CmResourceTypePort;
resourceList.List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition =
CmResourceShareDriverExclusive;
resourceList.List[0].PartialResourceList.PartialDescriptors[0].Flags =
CM_RESOURCE_PORT_IO;
resourceList.List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start =
physicalPortAddress64;
resourceList.List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length =
portCount;
// Mapped memory resource list
resourceList.List[0].PartialResourceList.PartialDescriptors[1].Type =
CmResourceTypeMemory;
resourceList.List[0].PartialResourceList.PartialDescriptors[1].ShareDisposition =
CmResourceShareDriverExclusive;
resourceList.List[0].PartialResourceList.PartialDescriptors[1].Flags =
CM_RESOURCE_MEMORY_READ_WRITE;
resourceList.List[0].PartialResourceList.PartialDescriptors[1].u.Memory.Start =
physicalMemoryAddress64;
resourceList.List[0].PartialResourceList.PartialDescriptors[1].u.Memory.Length =
addressSpace;
// Report our resource usage and detect conflicts
status = IoReportResourceUsage(
NULL,
driverObject,
&resourceList,
sizeof(resourceList),
NULL,
NULL,
0,
FALSE,
&resourceConflict);
if (resourceConflict)
{
DT2851KdPrint (("DT2851.SYS: Resource conflict\n"));
status = STATUS_DEVICE_CONFIGURATION_ERROR;
return status;
}
if (!NT_SUCCESS(status))
{
DT2851KdPrint (("DT2851.SYS: Resource reporting problem %8X", status));
return status;
}
#endif
// Initialize the driver object dispatch table.
// NT sends requests to these routines.
driverObject->MajorFunction[IRP_MJ_CREATE] = DT2851Dispatch;
driverObject->MajorFunction[IRP_MJ_CLOSE] = DT2851Dispatch;
driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DT2851Dispatch;
driverObject->DriverUnload = DT2851Unload;
DT2851KdPrint (("DT2851.SYS: entering DriverEntry\n"));
// Create an EXCLUSIVE device object (only 1 thread at a time
// can make requests to this device)
RtlInitUnicodeString (&deviceNameUnicodeString,
deviceNameBuffer);
status = IoCreateDevice (driverObject,
sizeof(DT2851_EXTENSION),
&deviceNameUnicodeString,
DT2851_TYPE,
0,
TRUE,
&deviceObject);
if (NT_SUCCESS(status))
{
// Create a symbolic link, e.g. a name that a Win32 app can specify
// to open the device
RtlInitUnicodeString(&deviceLinkUnicodeString,
deviceLinkBuffer);
status = IoCreateSymbolicLink (&deviceLinkUnicodeString,
&deviceNameUnicodeString);
if (!NT_SUCCESS(status)) // failed to create symbolic link
{
// Symbolic link creation failed- note this & then delete the
// device object (it's useless if a Win32 app can't get at it).
DT2851KdPrint (("DT2851.SYS: IoCreateSymbolicLink failed\n"));
IoDeleteDevice (deviceObject);
}
else // else create symbolic link successful
{
PHYSICAL_ADDRESS mappedMemoryAddress64;
ULONG memType;
memType = 0; // mapped memory space
// Clear local device extension memory
RtlZeroMemory(deviceObject->DeviceExtension,
sizeof(DT2851_EXTENSION));
extension = deviceObject->DeviceExtension;
extension->deviceObject = deviceObject;
// Map physical address of frame grabber to bus address
// Then turn this translated address into a virtual address
if(HalTranslateBusAddress (
Isa, // device on ISA bus
0, // bus number 0
physicalMemoryAddress64, // physical address
&memType, // address space
&mappedMemoryAddress64)) // translated address
{
extension->baseAddress = MmMapIoSpace (
mappedMemoryAddress64,
addressSpace,
FALSE); // don't cache these addresses
if(extension->baseAddress == NULL)
{
DT2851KdPrint (("DT2851.SYS: MmMapIoSpace failed\n"));
status = STATUS_UNSUCCESSFUL;
IoDeleteDevice(deviceObject);
}
else
{
// Everyting good so far
// Now set up for maping the I/O ports
PHYSICAL_ADDRESS mappedPortAddress64;
// Convert the IO port address into a form NT likes.
memType = 1; // I/O space
if(HalTranslateBusAddress( Isa,
0,
physicalPortAddress64,
&memType,
&mappedPortAddress64 ))
{
if (memType == 0)
{
// Port is accessed through memory space - so get a virtual address
extension->portWasMapped = TRUE;
// MmMapIoSpace can fail if we run out of PTEs, we should be
// checking the return value here
extension->portBase = MmMapIoSpace(mappedPortAddress64,
portCount,
FALSE);
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -