MikePol
Постоялец
Offline
|
|
« Ответ #3 : 14-07-2004 11:54 » |
|
Вот исходники : переделанный pci42 из Oney // Main program for pci42 driver // Copyright (C) 1999 by Walter Oney // All rights reserved
#include "stddcls.h" #include "driver.h"
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo); VOID DriverUnload(IN PDRIVER_OBJECT fdo);
BOOLEAN win98 = FALSE;
UNICODE_STRING servkey; KSPIN_LOCK MySpinLock;
///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { // DriverEntry KdPrint((DRIVERNAME " - Entering DriverEntry: DriverObject %8.8lX\n", DriverObject));
// Insist that OS support at least the WDM level of the DDK we use
if (!IoIsWdmVersionAvailable(1, 0)) { KdPrint((DRIVERNAME " - Expected version of WDM (%d.%2.2d) not available\n", 1, 0)); return STATUS_UNSUCCESSFUL; }
// See if we're running under Win98 or NT:
win98 = FALSE;
#if DBG if (win98) KdPrint((DRIVERNAME " - Running under Windows 98\n")); else KdPrint((DRIVERNAME " - Running under NT\n")); #endif
// Save the name of the service key
servkey.Buffer = (PWSTR) ExAllocatePool(PagedPool, RegistryPath->Length + sizeof(WCHAR)); if (!servkey.Buffer) { KdPrint((DRIVERNAME " - Unable to allocate %d bytes for copy of service key name\n", RegistryPath->Length + sizeof(WCHAR))); return STATUS_INSUFFICIENT_RESOURCES; } servkey.MaximumLength = RegistryPath->Length + sizeof(WCHAR); RtlCopyUnicodeString(&servkey, RegistryPath); servkey.Buffer[RegistryPath->Length / 2] = 0;
// Initialize function pointers
DriverObject->DriverUnload = DriverUnload; DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; //DriverObject->MajorFunction[IRP_MJ_READ] = DispatchReadWrite; // DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup; //DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower; DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp; //DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DispatchWmi; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DispatchControl; KdPrint(("Mike : Entry Completed "));
return STATUS_SUCCESS; } // DriverEntry
///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) { // DriverUnload PAGED_CODE(); KdPrint((DRIVERNAME " - Entering DriverUnload: DriverObject %8.8lX\n", DriverObject)); RtlFreeUnicodeString(&servkey); } // DriverUnload
///////////////////////////////////////////////////////////////////////////////
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo) { // AddDevice PAGED_CODE(); KdPrint((DRIVERNAME " - Entering AddDevice: DriverObject %8.8lX, pdo %8.8lX\n", DriverObject, pdo)); NTSTATUS status;
// Create a function device object to represent the hardware we're managing.
PDEVICE_OBJECT fdo;
/*ULONG dxsize = (sizeof(DEVICE_EXTENSION) + 7) & ~7; ULONG xsize = dxsize ; */ UNICODE_STRING devname; RtlInitUnicodeString(&devname, L"\\DosDevices\\PCI42");
status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &devname, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &fdo); if (!NT_SUCCESS(status)) { // can't create device object KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status)); return status; } // can't create device object PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
// From this point forward, any error will have side effects that need to // be cleaned up.
do { // finish initialization pdx->DeviceObject = fdo; pdx->Pdo = pdo;
// Make a copy of the device name
pdx->devname.Buffer = (PWCHAR) ExAllocatePool(NonPagedPool, devname.MaximumLength); if (!pdx->devname.Buffer) { // can't allocate buffer status = STATUS_INSUFFICIENT_RESOURCES; KdPrint((DRIVERNAME " - Unable to allocate %d bytes for copy of name\n", devname.MaximumLength)); break;; } // can't allocate buffer pdx->devname.MaximumLength = devname.MaximumLength; RtlCopyUnicodeString(&pdx->devname, &devname);
// Declare the buffering method we'll use for read/write requests
fdo->Flags |= DO_BUFFERED_IO;
// Initialize DPC object
// Link our device object into the stack leading to the PDO pdx->LowerDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo); if (!pdx->LowerDeviceObject) { // can't attach KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n")); status = STATUS_DEVICE_REMOVED; break; } // can't attach
// Clear the "initializing" flag so that we can get IRPs
fdo->Flags &= ~DO_DEVICE_INITIALIZING; } // finish initialization while (FALSE);
if (!NT_SUCCESS(status)) { // need to cleanup
KdPrint(("Mike ^ Error on Init ")); if (pdx->devname.Buffer) RtlFreeUnicodeString(&pdx->devname); if (pdx->LowerDeviceObject) IoDetachDevice(pdx->LowerDeviceObject); IoDeleteDevice(fdo); } // need to cleanup //if (NT_SUCCESS(status)) KdPrint(("MIke : AddDevice is OK "));
return status; } // AddDevice
///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info) { // CompleteRequest Irp->IoStatus.Status = status; Irp->IoStatus.Information = info; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } // CompleteRequest
///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
NTSTATUS DispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp) { // DispatchPnp PAGED_CODE(); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); ULONG fcn = stack->MinorFunction; switch (fcn) { case IRP_MN_START_DEVICE: { PCM_PARTIAL_RESOURCE_LIST raw, translated; raw = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList; translated = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList; return StartDevice(fdo,raw,translated); break; } case IRP_MN_REMOVE_DEVICE: { KdPrint((" MIke : IRP_MN_STOP_DEVICE")); StopDevice(fdo,FALSE); RemoveDevice(fdo); return STATUS_SUCCESS; break; } default: { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(pdx->LowerDeviceObject, Irp); } } }
// DispatchPnp
/*NTSTATUS DispatchPower(PDEVICE_OBJECT fdo, PIRP Irp) { // DispatchPower PAGED_CODE(); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; return GenericDispatchPower(pdx->pgx, Irp); } // DispatchPower
NTSTATUS DispatchWmi(PDEVICE_OBJECT fdo, PIRP Irp) { // DispatchWmi PAGED_CODE(); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(pdx->LowerDeviceObject, Irp); } // DispatchWmi */
///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
VOID RemoveDevice(IN PDEVICE_OBJECT fdo) { // RemoveDevice PAGED_CODE(); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; NTSTATUS status; RtlFreeUnicodeString(&pdx->devname);
if (pdx->LowerDeviceObject) IoDetachDevice(pdx->LowerDeviceObject);
IoDeleteDevice(fdo); } // RemoveDevice
#pragma PAGEDCODE // force inline functions into locked code
NTSTATUS DispatchControl(PDEVICE_OBJECT fdo, PIRP Irp) {
PAGED_CODE(); KIRQL irql=KeGetCurrentIrql(); KdPrint(("Mikee D IO CTL ")); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; NTSTATUS status = STATUS_SUCCESS; ULONG info = 0;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength; ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; ULONG *buff= (PULONG) Irp->AssociatedIrp.SystemBuffer; ULONG inbuff=*buff;
KdPrint(("MIke : Input Buffer Length = %d OutPut buffer Length = %d COde = %d " ,cbin,cbout,code)); status = STATUS_SUCCESS; switch (code) { case IOCTL_MYCTL: { KdPrint(("Mike : Device get IOCTL_MYCTL !!!!!"));
if (buff!=NULL) { *buff=READ_PORT_ULONG((PULONG) (pdx->portaddr+(inbuff-1)*4)); KdPrint(("Mike : Device on addrr %0x has %0x ",(pdx->portaddr+(inbuff-1)*4), *buff)); info=4; } else status=STATUS_INVALID_PARAMETER; break; } case IOCTL_WRITE_DWORD: { UCHAR number=(UCHAR) (inbuff>>8); UCHAR bit= (UCHAR) (inbuff); UCHAR tempstate= (UCHAR) (READ_PORT_ULONG((PULONG) (pdx->portaddr+(number-1)*4))>>24) ; KdPrint(("Last State %d",tempstate)); KdPrint(( "READ_PORT_ULONG((PULONG) %0x",READ_PORT_ULONG((PULONG) 0xdc00))) ; UCHAR mask=1; mask=mask<<bit; KdPrint(("Mask after << = %d",mask)); mask=255-mask; KdPrint(("Mask after != %d ",mask)); tempstate=tempstate&mask; ULONG outstate=tempstate; KdPrint((" Mask = %d Outstate = tempstate = %d ",mask, outstate)); outstate=outstate<<24; WRITE_PORT_ULONG((PULONG) (pdx->portaddr+(number-1)*4),outstate); KdPrint(("Mike : INB = %d low %d hi %d number %d bit %d ", inbuff, inbuff>>8 ,inbuff & 0x000000FF,number, bit )); KdPrint(("MIke: tempstate is %d on address %d ",outstate,pdx->portaddr+(number-1)*4)); break; } default: KdPrint(("Mike:Device get Anything, but not My control")); }
//if (pdx->portbase!=NULL) DbgPrint("Port base = %0x ", *((PULONG) pdx->portbase));
/* KeAcquireSpinLock(&MySpinLock,&irql); KeReleaseSpinLock(&MySpinLock,irql); */ return CompleteRequest(Irp, status, info); }
//////////////////////////////////////////////////////////////////////////////////////////
// Read/Write request processors for pci42 driver // Copyright (C) 1999 by Walter Oney // All rights reserved
#include "stddcls.h" #include "driver.h"
//VOID OnCancelReadWrite(PDEVICE_OBJECT fdo, PIRP Irp);
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp) { // DispatchCreate PAGED_CODE(); KdPrint((DRIVERNAME " - IRP_MJ_CREATE\n")); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS; InterlockedIncrement(&pdx->handles); return CompleteRequest(Irp, status, 0); } // DispatchCreate
///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp) { // DispatchClose PAGED_CODE(); KdPrint((DRIVERNAME " - IRP_MJ_CLOSE\n")); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); InterlockedDecrement(&pdx->handles); return CompleteRequest(Irp, STATUS_SUCCESS, 0); } // DispatchClose
///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
NTSTATUS StartDevice(PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated) { // StartDevice NTSTATUS status=STATUS_SUCCESS; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
// Identify the I/O resources we're supposed to use. KdPrint(("Mike : Entry Start Device "));
PHYSICAL_ADDRESS portbase; BOOLEAN gotport = FALSE; if (!translated) return STATUS_DEVICE_CONFIGURATION_ERROR; // no resources assigned??
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = translated->PartialDescriptors; ULONG nres = translated->Count; KdPrint((" N resourse %d \n", nres)); for (ULONG i = 0; i < nres; ++i, ++resource) { // for each resource switch (resource->Type) { // switch on resource type
case CmResourceTypePort: portbase = resource->u.Port.Start; pdx->nports = resource->u.Port.Length; KdPrint((DRIVERNAME " - I/O resource PORT %d\n", portbase)); pdx->mappedport = (resource->Flags & CM_RESOURCE_PORT_IO) == 0; gotport = TRUE;
break; default: KdPrint((DRIVERNAME " - Unexpected I/O resource type %d\n", resource->Type)); break; } // switch on resource type } // for each resource
if (!(TRUE && gotport )) { KdPrint((DRIVERNAME " - Didn't get expected I/O resources\n")); return STATUS_DEVICE_CONFIGURATION_ERROR; }
pdx->portbase = (PUCHAR) portbase.QuadPart; pdx->portaddr = portbase.LowPart; KdPrint((DRIVERNAME " MIke - PortADDR %0x My ", pdx->portaddr ));
// ResetDevice(pdx); // reset the device
if (!NT_SUCCESS(status)) { KdPrint((DRIVERNAME " - IoConnectInterrupt failed - %X\n", status)); if (pdx->portbase && pdx->mappedport) MmUnmapIoSpace(pdx->portbase, pdx->nports); pdx->portbase = NULL; return status; }
// Initialize the device
// KeSynchronizeExecution(pdx->InterruptObject, (PKSYNCHRONIZE_ROUTINE) SetupDevice, pdx);
return status; } // StartDevice
///////////////////////////////////////////////////////////////////////////////
/*#pragma LOCKEDCODE
VOID StartIo(IN PDEVICE_OBJECT fdo, IN PIRP Irp) { // StartIo PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) { CompleteRequest(Irp, status, 0); return; }
// Short-circuit a read for zero bytes
if (!stack->Parameters.Read.Length) { // nothing to do StartNextPacket(&pdx->dqReadWrite, fdo); CompleteRequest(Irp, STATUS_SUCCESS, 0); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return; } // nothing to do
// Save description of current request in the device extension
pdx->buffer = (PUCHAR) Irp->AssociatedIrp.SystemBuffer; pdx->nbytes = stack->Parameters.Read.Length; pdx->numxfer = 0;
// See if an input byte is already available. After this first byte, we wait for // an interrupt to tell us the next byte is available.
} // StartIo
/////////////////////////////////////////////////////////////////////////////// */
#pragma PAGEDCODE
VOID StopDevice(IN PDEVICE_OBJECT fdo, BOOLEAN oktouch /* = FALSE */) { // StopDevice PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; KdPrint((" MIke : In Stop Device "));
if (pdx->portbase && pdx->mappedport) MmUnmapIoSpace(pdx->portbase, pdx->nports); pdx->portbase = NULL; } // StopDevice
///////////////////////////////////////////////////////////////////////////////
|