Hi!
I told you I would start writing to this list again as soon as I got the
basics down.
Well, I had to write earlier.
I wanted to add a AddDevice Routine to my filterdriver.
I chose the Toasterexample(wdm) of the WDK since the book Programming
the Microsoft Windows Driver Model wasn’t very specific regarding
FilterDrivers.
I modified my sourcecode according to the toaster-example(except the
code surrouded by #ifdef IOCTL #endif
so there is no IoCreateDeviceSecure-Functioncall either).
It compiles without a warning or error.
I try to load it into Windows XP using the OSR Loader.
I get a message stateing that the service could not be started because
it is either deactivated or not attached to an active device.
So I went through the sourcecode again, nothing.
Then I chose to compile the filterexample itself, moved it into my VM
tried to load it in the same way.
It failed again,with the same errormessage.
So my question is:
What am I supposed to do so that I can load a filterdriver using
OSRloader,without having to avoid AddDevice as a routine,for the
toasterexample itself isn’t loading either.
According to http://www.osronline.com/showThread.cfm?link=76259 , there
is no need for an .inf-file either.
According to http://www.osronline.com/showThread.cfm?link=87818 there is
no way to add a filterdriver into a running driverstack, but appending
is not excluded.
For completion I appended the code.
sincerly
Frank
Code
#include<ntddk.h>
#include<wdmsec.h>//for IoCreateDeviceSecure
#include<initguid.h>
/miracilously this 2 macros throw an error
#ifndef STATUS_CONTINUE_COMPLETION //required to build driver in Win2K
and XP build environment
//
// This value should be returned from completion routines to continue
// completing the IRP upwards. Otherwise, STATUS_MORE_PROCESSING_REQUIRED
// should be returned.
//
#define STATUS_CONTINUE_COMPLETION STATUS_SUCCESS
/
// {41966169-3FD7-4392-AFE4-E6A9D0A92C72} - generated using guidgen.exe
DEFINE_GUID (GUID_SD_FILTER_CONTROL_OBJECT,
0x41966169, 0x3fd7, 0x4392, 0xaf, 0xe4, 0xe6, 0xa9, 0xd0, 0xa9,
0x2c, 0x72);
#define arraysize(p) (sizeof((p))/sizeof((p)[0]))
#define POOL_TAG ‘ECHO’
DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD DriverUnload;
DRIVER_ADD_DEVICE deviceadd;
drv_dispatchType(IRP_MJ_PNP)
DRIVER_DISPATCH FilterDispatchPnP;
drv_dispatchType(IRP_MJ_POWER)
DRIVER_DISPATCH FilterDispatchPower;
drv_dispatchType_other
DRIVER_DISPATCH dispatchany;
IO_COMPLETION_ROUTINE FilterDeviceUsageNotificationCompletionRoutine;
IO_COMPLETION_ROUTINE FilterStartCompletionRoutine;
PCHAR PnPMinorFunctionString(UCHAR MinorFunction);
//
// These are the states Filter transition to upon
// receiving a specific PnP Irp. Refer to the PnP Device States
// diagram in DDK documentation for better understanding.
//
typedef enum DEVICE_PNP_STATE {
NotStarted = 0, // Not started yet
Started, // Device has received the START_DEVICE IRP
StopPending, // Device has received the QUERY_STOP IRP
Stopped, // Device has received the STOP_DEVICE IRP
RemovePending, // Device has received the QUERY_REMOVE IRP
SurpriseRemovePending, // Device has received the SURPRISE_REMOVE IRP
Deleted // Device has received the REMOVE_DEVICE IRP
} DEVICE_PNP_STATE;
#define INITIALIZE_PNP_STATE(Data) <br> (Data)->DevicePnPState = NotStarted;<br> (Data)->PreviousPnPState = NotStarted;
#define SET_NEW_PNP_STATE(Data, state) <br> (Data)->PreviousPnPState = (Data)->DevicePnPState;<br> (Data)->DevicePnPState = (state);
#define RESTORE_PREVIOUS_PNP_STATE(Data) <br> (Data)->DevicePnPState = (Data)->PreviousPnPState;
typedef enum DEVICE_TYPE{
DEVICE_TYPE_INVALID = 0,//invalid type
DEVICE_TYPE_FIDO,//Device is a filter device
DEVICE_TYPE_CDO//device is a control device
} DEVICE_TYPE;
typedef struct COMMON_DEVICE_DATA{
DEVICE_TYPE Type;
} COMMON_DEVICE_DATA,*PCOMMON_DEVICE_DATA;
typedef struct dev{
COMMON_DEVICE_DATA common;
PDEVICE_OBJECT precessor;
PDEVICE_OBJECT successor;
PDEVICE_OBJECT self;
DEVICE_PNP_STATE DevicePnPState;
DEVICE_PNP_STATE PreviousPnPState;
IO_REMOVE_LOCK RemoveLock;//for tracking Irps and thereafter
unloading the driver safely
} DEVICE_EXTENSION,*PDEVICE_EXTENSION;
int universalid;
UNICODE_STRING devicename;
#pragma alloc_text(INIT,DriverEntry)
#pragma alloc_text(PAGE,DriverUnload)
#pragma alloc_text(PAGE,deviceadd)
#pragma alloc_text(PAGE,dispatchany)
#pragma alloc_text(PAGE,FilterDispatchPnP)
NTSTATUS DriverEntry(in PDRIVER_OBJECT driverobject,
in PUNICODE_STRING registrystring){
int i;
KdPrint((“Hello”));
universalid = 0;
RtlInitUnicodeString(&devicename,L"firstdevice");
KdPrint((“MJ_Functioncodes are handeled”));
for(i = 0;i< IRP_MJ_MAXIMUM_FUNCTION;i++){
driverobject->MajorFunction[i] = dispatchany;
}
//IRP_MJ_POWER and IRP_MJ_PNP will be caught later on, they have to
be handeled
driverobject->MajorFunction[IRP_MJ_POWER] = FilterDispatchPower;
driverobject->MajorFunction[IRP_MJ_PNP] = FilterDispatchPnP;
driverobject->DriverUnload = DriverUnload;
driverobject->DriverExtension->AddDevice = deviceadd;
KdPrint((“Here is Driverentrybyebye”));
return STATUS_SUCCESS;
}
VOID DriverUnload(in PDRIVER_OBJECT driver){
PAGED_CODE();
KdPrint((“Byebye”));
}
NTSTATUS deviceadd( in PDRIVER_OBJECT driver,
in PDEVICE_OBJECT device){
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT ourdev = NULL;
PDEVICE_EXTENSION extension;
ULONG devicetype = FILE_DEVICE_UNKNOWN;
PAGED_CODE();
KdPrint((“Here is deviceadd”));
ourdev = IoGetAttachedDeviceReference(device);
devicetype = device->DeviceType;
ObReferenceObject(ourdev);
status = IoCreateDevice(driver,sizeof(DEVICE_EXTENSION),NULL,
devicetype,FILE_DEVICE_SECURE_OPEN,
FALSE,&ourdev);
if(!NT_SUCCESS(status)){
KdPrint((“IoCreateDevice failed”));
return status;
}
KdPrint((“IoCreateDevice Succeeded”));
extension = (PDEVICE_EXTENSION) ourdev->DeviceExtension;
extension->common.Type = DEVICE_TYPE_FIDO;
extension->successor = IoAttachDeviceToDeviceStack(ourdev,device);
if(extension->successor==NULL){
IoDeleteDevice(ourdev);
return STATUS_UNSUCCESSFUL;
}
KdPrint((“IoAttachDeviceToDeviceStack succeeded”));
ourdev->Flags |= extension->successor->Flags &(DO_BUFFERED_IO |
DO_DIRECT_IO |DO_POWER_PAGABLE);
ourdev->DeviceType = extension->successor->DeviceType;
ourdev->Characteristics = extension->successor->Characteristics;
extension->self = ourdev;
IoInitializeRemoveLock(&extension->RemoveLock,POOL_TAG,1,100);
INITIALIZE_PNP_STATE(extension);
ourdev->Flags &= ~DO_DEVICE_INITIALIZING;
KdPrint((“AddDevice successfull”));
return STATUS_SUCCESS;
}
NTSTATUS dispatchany( in PDEVICE_OBJECT device,
in PIRP irp){
PDEVICE_EXTENSION extension;
NTSTATUS status;
KdPrint((“This is Dispatch Any”));
PAGED_CODE();
extension = (PDEVICE_EXTENSION) device->DeviceExtension;
status = IoAcquireRemoveLock(&extension->RemoveLock,irp);
if(!NT_SUCCESS(status)){
irp->IoStatus.Status = status;
IoCompleteRequest(irp,IO_NO_INCREMENT);
}
IoSkipCurrentIrpStackLocation(irp);
status = IoCallDriver(extension->successor,irp);
IoReleaseRemoveLock(&extension->RemoveLock,irp);
return status;
}
NTSTATUS FilterDispatchPnP(PDEVICE_OBJECT DeviceObject,PIRP irp){
PDEVICE_EXTENSION extension;
PIO_STACK_LOCATION irpstack;
NTSTATUS status;
KEVENT event;
PAGED_CODE();
KdPrint((“Here is a PNP-Request”));
extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
irpstack = IoGetCurrentIrpStackLocation(irp);
status = IoAcquireRemoveLock(&extension->RemoveLock,irp);
if(!NT_SUCCESS(status)){
irp->IoStatus.Status = status;
IoCompleteRequest(irp,IO_NO_INCREMENT);
return status;
}
switch(irpstack->MinorFunction){
case IRP_MN_START_DEVICE:
KeInitializeEvent(&event,NotificationEvent,FALSE);
IoCopyCurrentIrpStackLocationToNext(irp);
IoSetCompletionRoutine(irp,
FilterStartCompletionRoutine,
&event,
TRUE,
TRUE,
TRUE);
status = IoCallDriver(extension->successor,irp);
if(status ==STATUS_PENDING){
KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL);
status = irp->IoStatus.Status;
}
if(NT_SUCCESS(status)){
SET_NEW_PNP_STATE(extension,Started);
if(extension->successor->Characteristics &
FILE_REMOVABLE_MEDIA){
DeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
}
}
irp->IoStatus.Status = status;
IoCompleteRequest(irp,IO_NO_INCREMENT);
IoReleaseRemoveLock(&extension->RemoveLock,irp);
return status;
case IRP_MN_REMOVE_DEVICE:
IoReleaseRemoveLockAndWait(&extension->RemoveLock,irp);
IoSkipCurrentIrpStackLocation(irp);
status = IoCallDriver(extension->successor,irp);
SET_NEW_PNP_STATE(extension,Deleted);
IoDetachDevice(extension->successor);
IoDeleteDevice(DeviceObject);
return status;
case IRP_MN_QUERY_STOP_DEVICE:
SET_NEW_PNP_STATE(extension,StopPending);
status = STATUS_SUCCESS;
break;
case IRP_MN_CANCEL_STOP_DEVICE:
if(StopPending == extension->DevicePnPState){
RESTORE_PREVIOUS_PNP_STATE(extension);
}
status = STATUS_SUCCESS;
break;
case IRP_MN_STOP_DEVICE:
SET_NEW_PNP_STATE(extension,Stopped);
status = STATUS_SUCCESS;
break;
case IRP_MN_QUERY_REMOVE_DEVICE:
SET_NEW_PNP_STATE(extension,RemovePending);
status = STATUS_SUCCESS;
break;
case IRP_MN_CANCEL_REMOVE_DEVICE:
if(RemovePending == extension->DevicePnPState){
RESTORE_PREVIOUS_PNP_STATE(extension);
}
status = STATUS_SUCCESS;
break;
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
#pragma prefast(suppress:WARNING_INACCESSIBLE_MEMBER)
if((DeviceObject->AttachedDevice == NULL)||
(DeviceObject->AttachedDevice->Flags & DO_POWER_PAGABLE)){
DeviceObject->Flags |= DO_POWER_PAGABLE;
}
IoCopyCurrentIrpStackLocationToNext(irp);
IoSetCompletionRoutine(irp,
FilterDeviceUsageNotificationCompletionRoutine,
NULL,
TRUE,
TRUE,
TRUE);
return IoCallDriver(extension->successor,irp);
default:
status = irp->IoStatus.Status;
break;
}
irp->IoStatus.Status = status;
IoSkipCurrentIrpStackLocation(irp);
status = IoCallDriver(extension->successor,irp);
IoReleaseRemoveLock(&extension->RemoveLock,irp);
return status;
}
NTSTATUS FilterStartCompletionRoutine(PDEVICE_OBJECT device,PIRP
irp,PVOID context){
PKEVENT event = (PKEVENT) context;
if(irp->PendingReturned == TRUE){
KeSetEvent(event,IO_NO_INCREMENT,FALSE);
}
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS FilterDeviceUsageNotificationCompletionRoutine(PDEVICE_OBJECT
device,PIRP irp,PVOID context){
PDEVICE_EXTENSION extension;
extension = (PDEVICE_EXTENSION) device->DeviceExtension;
if(irp->PendingReturned){
IoMarkIrpPending(irp);
}
if(!(extension->successor->Flags & DO_POWER_PAGABLE)){
device->Flags &=~DO_POWER_PAGABLE;
}
IoReleaseRemoveLock(&extension->RemoveLock,irp);
return STATUS_CONTINUE_COMPLETION;
}
NTSTATUS FilterDispatchPower(PDEVICE_OBJECT device,PIRP irp){
PDEVICE_EXTENSION extension;
NTSTATUS status;
extension = (PDEVICE_EXTENSION) device->DeviceExtension;
status = IoAcquireRemoveLock(&extension->RemoveLock,irp);
if(!NT_SUCCESS(status)){
irp->IoStatus.Status = status;
PoStartNextPowerIrp(irp);
IoCompleteRequest(irp,IO_NO_INCREMENT);
return status;
}
PoStartNextPowerIrp(irp);
IoSkipCurrentIrpStackLocation(irp);
status = PoCallDriver(extension->successor,irp);
IoReleaseRemoveLock(&extension->RemoveLock,irp);
return status;
}
#if DBG
PCHAR
PnPMinorFunctionString (
UCHAR MinorFunction
)
{
switch (MinorFunction)
{
case IRP_MN_START_DEVICE:
return “IRP_MN_START_DEVICE”;
case IRP_MN_QUERY_REMOVE_DEVICE:
return “IRP_MN_QUERY_REMOVE_DEVICE”;
case IRP_MN_REMOVE_DEVICE:
return “IRP_MN_REMOVE_DEVICE”;
case IRP_MN_CANCEL_REMOVE_DEVICE:
return “IRP_MN_CANCEL_REMOVE_DEVICE”;
case IRP_MN_STOP_DEVICE:
return “IRP_MN_STOP_DEVICE”;
case IRP_MN_QUERY_STOP_DEVICE:
return “IRP_MN_QUERY_STOP_DEVICE”;
case IRP_MN_CANCEL_STOP_DEVICE:
return “IRP_MN_CANCEL_STOP_DEVICE”;
case IRP_MN_QUERY_DEVICE_RELATIONS:
return “IRP_MN_QUERY_DEVICE_RELATIONS”;
case IRP_MN_QUERY_INTERFACE:
return “IRP_MN_QUERY_INTERFACE”;
case IRP_MN_QUERY_CAPABILITIES:
return “IRP_MN_QUERY_CAPABILITIES”;
case IRP_MN_QUERY_RESOURCES:
return “IRP_MN_QUERY_RESOURCES”;
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
return “IRP_MN_QUERY_RESOURCE_REQUIREMENTS”;
case IRP_MN_QUERY_DEVICE_TEXT:
return “IRP_MN_QUERY_DEVICE_TEXT”;
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
return “IRP_MN_FILTER_RESOURCE_REQUIREMENTS”;
case IRP_MN_READ_CONFIG:
return “IRP_MN_READ_CONFIG”;
case IRP_MN_WRITE_CONFIG:
return “IRP_MN_WRITE_CONFIG”;
case IRP_MN_EJECT:
return “IRP_MN_EJECT”;
case IRP_MN_SET_LOCK:
return “IRP_MN_SET_LOCK”;
case IRP_MN_QUERY_ID:
return “IRP_MN_QUERY_ID”;
case IRP_MN_QUERY_PNP_DEVICE_STATE:
return “IRP_MN_QUERY_PNP_DEVICE_STATE”;
case IRP_MN_QUERY_BUS_INFORMATION:
return “IRP_MN_QUERY_BUS_INFORMATION”;
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
return “IRP_MN_DEVICE_USAGE_NOTIFICATION”;
case IRP_MN_SURPRISE_REMOVAL:
return “IRP_MN_SURPRISE_REMOVAL”;
default:
return “unknown_pnp_irp”;
}
}
#endif
---------------------------------------------
Code End
----------------------------------------------
__________________________________________
Telefonate ohne weitere Kosten vom PC zum PC: http://messenger.yahoo.de</initguid.h></wdmsec.h></ntddk.h>