Tech Support > Microsoft Windows > Drivers > Erreur 0x422 (returned by OpenService
Erreur 0x422 (returned by OpenService
Posted by Sivaller on January 2nd, 2004


I install the driver which I wrote using the AddDevice
routine,
And OpenService returns me the 0x422 error,
and apparament AddDevice is not to call whole.
DriverEntry is called but not the AddDevice routine.

here my code, I have also some to recopy example GenPort
(ddk from Microsoft)
"
#include "ntddk.h"
#include "stdarg.h"
#include "stdio.h"


#define DRIVER_NAME "DriverName"
#define LDRIVER_NAME "DriverName"
// contenu des messages
// en entrée (msgin) et en sortie (msgout)
// types de messages communs




// type du driver
// valeurs entre 0-32767 reservé pour microsoft
// valeurs entre 32768-65535 reservé pour l'utilisateur
// en principe ce numéro doit être unique

#define FILE_DEVICE_MONDRIVERNT 0x00008300

// code de controle pour DEVICEIO
// valeurs entre 0-2047 reservé pour microsoft
// valeurs entre 2048-4095 pour les clients

#define IOCTL_DELAY CTL_CODE( FILE_DEVICE_MONDRIVERNT,
0x900, METHOD_BUFFERED, FILE_WRITE_ACCESS )






// interfaces externes/interne

#define DRIVER_NAME "DriverName"
#define LDRIVER_NAME L"DriverName"

#define FILE_DEVICE_MONDRIVER 0x00008300

// code de controle pour DEVICEIO
// valeurs entre 0-2047 reservé pour microsoft
// valeurs entre 2048-4095 pour les clients

#define MONDRIVER_IOCTL_INDEX 0x830

#define MD_DEVICE_NAME L"\\Device\\delay"
#define DOS_DEVICE_NAME L"\\DosDevices\\delay"


NTSTATUS MonDriverDispatch(IN PDEVICE_OBJECT
DeviceObject,IN PIRP Irp);
NTSTATUS MonDriverAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
);

NTSTATUS MonDriverAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
);

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

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

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

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN
PUNICODE_STRING RegistryPath);

VOID MonDriverUnload( IN PDRIVER_OBJECT DriverObject );

#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, MonDriverAddDevice)
#pragma alloc_text (PAGE, DispatchPnp)
#pragma alloc_text (PAGE, DispatchSystemControl)
#pragma alloc_text (PAGE, MonDriverUnload)
#pragma alloc_text (PAGE, MonDriverDispatch)

#endif





// driver local data structure specific to each device
object
typedef struct _LOCAL_DEVICE_INFO {

PDEVICE_OBJECT DeviceObject; // The Gpd device
object.
PDEVICE_OBJECT NextLowerDriver; // The top of
the stack
BOOLEAN Started;
BOOLEAN Removed;
IO_REMOVE_LOCK RemoveLock;


} LOCAL_DEVICE_INFO, *PLOCAL_DEVICE_INFO;




// fonction de déchargement du driver
VOID MonDriverUnload( IN PDRIVER_OBJECT DriverObject )
{
UNICODE_STRING deviceLinkUnicodeString;


//IoDeleteDevice (DriverObject->DeviceObject)

RtlInitUnicodeString(&deviceLinkUnicodeString,
DOS_DEVICE_NAME);
IoDeleteSymbolicLink (&deviceLinkUnicodeString);

}



NTSTATUS MonDriverDispatch(IN PDEVICE_OBJECT
DeviceObject,IN PIRP Irp)
{

NTSTATUS status;
PIO_STACK_LOCATION pIrpStack;
int IoControlCode;


pIrpStack = IoGetCurrentIrpStackLocation( Irp );
status = !NT_SUCCESS(STATUS_SUCCESS);


switch (pIrpStack->MajorFunction)
{

case IRP_MJ_CREATE: // lors de la fonction
Create file
case IRP_MJ_CLOSE: // lors de la fermeture
du fichier CloseHandle
status= STATUS_SUCCESS;
break;
case IRP_MJ_DEVICE_CONTROL:
IoControlCode = pIrpStack-
switch (IoControlCode)
{
case IOCTL_DELAY:
status = STATUS_SUCCESS;
break;
}
break;

}


Irp->IoStatus.Status = status;

Irp->IoStatus.Information = 0;
pIrpStack-
IoCompleteRequest(Irp, IO_NO_INCREMENT );
return status;



}



NTSTATUS MonDriverAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)

{

NTSTATUS status;
UNICODE_STRING ntDeviceName,winDeviceName;


PDEVICE_OBJECT LeObject;
PLOCAL_DEVICE_INFO deviceInfo;

//int bb;

PAGED_CODE();
//bb=0;
//while(bb==0);

RtlInitUnicodeString(&ntDeviceName,
MD_DEVICE_NAME);

status = IoCreateDevice (DriverObject,
sizeof (LOCAL_DEVICE_INFO),
&ntDeviceName,
FILE_DEVICE_MONDRIVERNT,
0,//FILE_REMOVABLE_MEDIA,
FALSE,
&LeObject);
LeObject->Flags |= DO_BUFFERED_IO;
RtlInitUnicodeString(&winDeviceName,
DOS_DEVICE_NAME);
status = IoCreateSymbolicLink( &winDeviceName,
&ntDeviceName );


LeObject->Flags |= DO_POWER_PAGABLE;



LeObject->Flags &= ~DO_DEVICE_INITIALIZING;

deviceInfo = (PLOCAL_DEVICE_INFO) LeObject-
deviceInfo->NextLowerDriver =
IoAttachDeviceToDeviceStack (
LeObject,

PhysicalDeviceObject);
if(NULL == deviceInfo->NextLowerDriver) {
IoDeleteSymbolicLink(&winDeviceName);
IoDeleteDevice(LeObject);
return STATUS_NO_SUCH_DEVICE;
}



return status;
}



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

Routine Description:

This routine is the dispatch routine for power irps.
Does nothing except forwarding the IRP to the next
device
in the stack.

Arguments:

DeviceObject - Pointer to the device object.

Irp - Pointer to the request packet.

Return Value:

NT Status code
--*/
{
PLOCAL_DEVICE_INFO deviceInfo;

deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject-
//
// If the device has been removed, the driver should
not pass
// the IRP down to the next lower driver.
//

if (deviceInfo->Removed) {

PoStartNextPowerIrp(Irp);
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
IoCompleteRequest(Irp, IO_NO_INCREMENT );
return STATUS_DELETE_PENDING;
}

PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(deviceInfo->NextLowerDriver, Irp);
}


NTSTATUS CompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++

Routine Description:

The completion routine for plug & play irps that needs
to be
processed first by the lower drivers.

Arguments:

DeviceObject - pointer to a device object.

Irp - pointer to an I/O Request Packet.

Context - pointer to an event object.

Return Value:

NT status code

--*/
{
PKEVENT event;

event = (PKEVENT) Context;

UNREFERENCED_PARAMETER(DeviceObject);

if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}

//
// We could switch on the major and minor functions of
the IRP to perform
// different functions, but we know that Context is an
event that needs
// to be set.
//
KeSetEvent(event, 0, FALSE);

//
// Allows the caller to reuse the IRP
//
return STATUS_MORE_PROCESSING_REQUIRED;
}



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

Routine Description:

This routine is the dispatch routine for WMI irps.
Does nothing except forwarding the IRP to the next
device
in the stack.

Arguments:

DeviceObject - Pointer to the device object.

Irp - Pointer to the request packet.

Return Value:

NT Status code
--*/
{
PLOCAL_DEVICE_INFO deviceInfo;

PAGED_CODE();

deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject-
return IoCallDriver(deviceInfo->NextLowerDriver, Irp);
}



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

Routine Description:

The plug and play dispatch routines.

Most of these the driver will completely ignore.
In all cases it must pass the IRP to the next lower
driver.

Arguments:

DeviceObject - pointer to a device object.

Irp - pointer to an I/O Request Packet.

Return Value:

NT status code

--*/
{
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_SUCCESS;
KEVENT event;
UNICODE_STRING win32DeviceName;
PLOCAL_DEVICE_INFO deviceInfo;

PAGED_CODE();

deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject-

status = IoAcquireRemoveLock (&deviceInfo->RemoveLock,
Irp);
if (!NT_SUCCESS (status)) {
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}

// DebugPrint(("%s\n",PnPMinorFunctionString(irpStack -
switch (irpStack->MinorFunction) {
case IRP_MN_START_DEVICE:

//
// The device is starting.
//
// We cannot touch the device (send it any non pnp
irps) until a
// start device has been passed down to the lower
drivers.
//
IoCopyCurrentIrpStackLocationToNext(Irp);
KeInitializeEvent(&event,
NotificationEvent,
FALSE
);

IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE)
CompletionRoutine,
&event,
TRUE,
TRUE,
TRUE);

status = IoCallDriver(deviceInfo->NextLowerDriver,
Irp);

if (STATUS_PENDING == status) {
KeWaitForSingleObject(
&event,
Executive, // Waiting for reason of a driver
KernelMode, // Must be kernelmode if event
memory is in stack
FALSE, // No allert
NULL); // No timeout
}

if (NT_SUCCESS(status) && NT_SUCCESS(Irp-
status = STATUS_SUCCESS;
}

//
// We must now complete the IRP, since we stopped
it in the
// completion routine with
STATUS_MORE_PROCESSING_REQUIRED.
//
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;

case IRP_MN_QUERY_STOP_DEVICE:

//
// Fail the query stop to prevent the system from
taking away hardware
// resources. If you do support this you must have
a queue to hold
// incoming requests between stop and subsequent
start with new set of
// resources.
//

Irp->IoStatus.Status = status =
STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;

case IRP_MN_QUERY_REMOVE_DEVICE:
//
// The device can be removed without disrupting
the machine.
//
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver,
Irp);
break;

case IRP_MN_SURPRISE_REMOVAL:

//
// The device has been unexpectedly removed from
the machine
// and is no longer available for I/O. Stop all
access to the device.
// Release any resources associated with the
device, but leave the
// device object attached to the device stack
until the PnP Manager
// sends a subsequent IRP_MN_REMOVE_DEVICE
request.
// You should fail any outstanding I/O to the
device. You will
// not get a remove until all the handles open to
the device
// have been closed.
//

deviceInfo->Removed = TRUE;
deviceInfo->Started = FALSE;


RtlInitUnicodeString(&win32DeviceName,
DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&win32DeviceName);

IoSkipCurrentIrpStackLocation(Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
status = IoCallDriver(deviceInfo->NextLowerDriver,
Irp);
break;

case IRP_MN_REMOVE_DEVICE:

//
// Relinquish all resources here.
// Detach and delete the device object so that
// your driver can be unloaded. You get remove
// either after query_remove or surprise_remove.
//

if(!deviceInfo->Removed)
{
deviceInfo->Removed = TRUE;
deviceInfo->Started = FALSE;


RtlInitUnicodeString(&win32DeviceName,
DOS_DEVICE_NAME);
IoDeleteSymbolicLink
(&win32DeviceName);
}

//
// Wait for all outstanding requests to complete
//
//DebugPrint(("Waiting for outstanding
requests\n"));
IoReleaseRemoveLockAndWait(&deviceInfo-
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver,
Irp);

IoDetachDevice(deviceInfo->NextLowerDriver);
IoDeleteDevice(DeviceObject);

return status;

case IRP_MN_STOP_DEVICE:
// Since you failed query stop, you will not get
this request.
case IRP_MN_CANCEL_REMOVE_DEVICE:
// No action required in this case. Just pass it
down.
case IRP_MN_CANCEL_STOP_DEVICE:
//No action required in this case.
Irp->IoStatus.Status = STATUS_SUCCESS;
default:
//
// Please see PnP documentation for use of these
IRPs.
//
IoSkipCurrentIrpStackLocation (Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver,
Irp);
break;
}
IoReleaseRemoveLock(&deviceInfo->RemoveLock,
Irp);
return status;
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN
PUNICODE_STRING RegistryPath)
{
//int bb;
//bb=0;
//while(bb==0);
// installe le dispatching
DriverObject->MajorFunction[IRP_MJ_CREATE] =
MonDriverDispatch; // fonction à appeller sur le OpenDevice
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
MonDriverDispatch; // fonction à appeller sur le
CloseHandle
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
MonDriverDispatch;

DriverObject->MajorFunction[IRP_MJ_PNP] =
DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] =
DispatchPower;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
DispatchSystemControl;


DriverObject->DriverExtension->AddDevice =
MonDriverAddDevice;
DriverObject->DriverUnload = MonDriverUnload;
//DriverObject->DeviceExtension = PhysicalDeviceObject;

return STATUS_SUCCESS;
}


"



Posted by Alexander Grigoriev on January 2nd, 2004


AddDevice is only called if a driver is loaded by PNP manager, for a PNP
device, or for a root enumerated device.

"Sivaller" <sivaller.bewod@laposte.net> wrote in message
news:045801c3d145$8247d480$a001280a@phx.gbl...
I install the driver which I wrote using the AddDevice
routine,
And OpenService returns me the 0x422 error,
and apparament AddDevice is not to call whole.
DriverEntry is called but not the AddDevice routine.

here my code, I have also some to recopy example GenPort
(ddk from Microsoft)
"
#include "ntddk.h"
#include "stdarg.h"
#include "stdio.h"


#define DRIVER_NAME "DriverName"
#define LDRIVER_NAME "DriverName"
// contenu des messages
// en entrée (msgin) et en sortie (msgout)
// types de messages communs




// type du driver
// valeurs entre 0-32767 reservé pour microsoft
// valeurs entre 32768-65535 reservé pour l'utilisateur
// en principe ce numéro doit être unique

#define FILE_DEVICE_MONDRIVERNT 0x00008300

// code de controle pour DEVICEIO
// valeurs entre 0-2047 reservé pour microsoft
// valeurs entre 2048-4095 pour les clients

#define IOCTL_DELAY CTL_CODE( FILE_DEVICE_MONDRIVERNT,
0x900, METHOD_BUFFERED, FILE_WRITE_ACCESS )






// interfaces externes/interne

#define DRIVER_NAME "DriverName"
#define LDRIVER_NAME L"DriverName"

#define FILE_DEVICE_MONDRIVER 0x00008300

// code de controle pour DEVICEIO
// valeurs entre 0-2047 reservé pour microsoft
// valeurs entre 2048-4095 pour les clients

#define MONDRIVER_IOCTL_INDEX 0x830

#define MD_DEVICE_NAME L"\\Device\\delay"
#define DOS_DEVICE_NAME L"\\DosDevices\\delay"


NTSTATUS MonDriverDispatch(IN PDEVICE_OBJECT
DeviceObject,IN PIRP Irp);
NTSTATUS MonDriverAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
);

NTSTATUS MonDriverAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
);

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

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

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

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN
PUNICODE_STRING RegistryPath);

VOID MonDriverUnload( IN PDRIVER_OBJECT DriverObject );

#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, MonDriverAddDevice)
#pragma alloc_text (PAGE, DispatchPnp)
#pragma alloc_text (PAGE, DispatchSystemControl)
#pragma alloc_text (PAGE, MonDriverUnload)
#pragma alloc_text (PAGE, MonDriverDispatch)

#endif





// driver local data structure specific to each device
object
typedef struct _LOCAL_DEVICE_INFO {

PDEVICE_OBJECT DeviceObject; // The Gpd device
object.
PDEVICE_OBJECT NextLowerDriver; // The top of
the stack
BOOLEAN Started;
BOOLEAN Removed;
IO_REMOVE_LOCK RemoveLock;


} LOCAL_DEVICE_INFO, *PLOCAL_DEVICE_INFO;




// fonction de déchargement du driver
VOID MonDriverUnload( IN PDRIVER_OBJECT DriverObject )
{
UNICODE_STRING deviceLinkUnicodeString;


//IoDeleteDevice (DriverObject->DeviceObject)

RtlInitUnicodeString(&deviceLinkUnicodeString,
DOS_DEVICE_NAME);
IoDeleteSymbolicLink (&deviceLinkUnicodeString);

}



NTSTATUS MonDriverDispatch(IN PDEVICE_OBJECT
DeviceObject,IN PIRP Irp)
{

NTSTATUS status;
PIO_STACK_LOCATION pIrpStack;
int IoControlCode;


pIrpStack = IoGetCurrentIrpStackLocation( Irp );
status = !NT_SUCCESS(STATUS_SUCCESS);


switch (pIrpStack->MajorFunction)
{

case IRP_MJ_CREATE: // lors de la fonction
Create file
case IRP_MJ_CLOSE: // lors de la fermeture
du fichier CloseHandle
status= STATUS_SUCCESS;
break;
case IRP_MJ_DEVICE_CONTROL:
IoControlCode = pIrpStack-
switch (IoControlCode)
{
case IOCTL_DELAY:
status = STATUS_SUCCESS;
break;
}
break;

}


Irp->IoStatus.Status = status;

Irp->IoStatus.Information = 0;
pIrpStack-
IoCompleteRequest(Irp, IO_NO_INCREMENT );
return status;



}



NTSTATUS MonDriverAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)

{

NTSTATUS status;
UNICODE_STRING ntDeviceName,winDeviceName;


PDEVICE_OBJECT LeObject;
PLOCAL_DEVICE_INFO deviceInfo;

//int bb;

PAGED_CODE();
//bb=0;
//while(bb==0);

RtlInitUnicodeString(&ntDeviceName,
MD_DEVICE_NAME);

status = IoCreateDevice (DriverObject,
sizeof (LOCAL_DEVICE_INFO),
&ntDeviceName,
FILE_DEVICE_MONDRIVERNT,
0,//FILE_REMOVABLE_MEDIA,
FALSE,
&LeObject);
LeObject->Flags |= DO_BUFFERED_IO;
RtlInitUnicodeString(&winDeviceName,
DOS_DEVICE_NAME);
status = IoCreateSymbolicLink( &winDeviceName,
&ntDeviceName );


LeObject->Flags |= DO_POWER_PAGABLE;



LeObject->Flags &= ~DO_DEVICE_INITIALIZING;

deviceInfo = (PLOCAL_DEVICE_INFO) LeObject-
deviceInfo->NextLowerDriver =
IoAttachDeviceToDeviceStack (
LeObject,

PhysicalDeviceObject);
if(NULL == deviceInfo->NextLowerDriver) {
IoDeleteSymbolicLink(&winDeviceName);
IoDeleteDevice(LeObject);
return STATUS_NO_SUCH_DEVICE;
}



return status;
}



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

Routine Description:

This routine is the dispatch routine for power irps.
Does nothing except forwarding the IRP to the next
device
in the stack.

Arguments:

DeviceObject - Pointer to the device object.

Irp - Pointer to the request packet.

Return Value:

NT Status code
--*/
{
PLOCAL_DEVICE_INFO deviceInfo;

deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject-
//
// If the device has been removed, the driver should
not pass
// the IRP down to the next lower driver.
//

if (deviceInfo->Removed) {

PoStartNextPowerIrp(Irp);
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
IoCompleteRequest(Irp, IO_NO_INCREMENT );
return STATUS_DELETE_PENDING;
}

PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(deviceInfo->NextLowerDriver, Irp);
}


NTSTATUS CompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++

Routine Description:

The completion routine for plug & play irps that needs
to be
processed first by the lower drivers.

Arguments:

DeviceObject - pointer to a device object.

Irp - pointer to an I/O Request Packet.

Context - pointer to an event object.

Return Value:

NT status code

--*/
{
PKEVENT event;

event = (PKEVENT) Context;

UNREFERENCED_PARAMETER(DeviceObject);

if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}

//
// We could switch on the major and minor functions of
the IRP to perform
// different functions, but we know that Context is an
event that needs
// to be set.
//
KeSetEvent(event, 0, FALSE);

//
// Allows the caller to reuse the IRP
//
return STATUS_MORE_PROCESSING_REQUIRED;
}



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

Routine Description:

This routine is the dispatch routine for WMI irps.
Does nothing except forwarding the IRP to the next
device
in the stack.

Arguments:

DeviceObject - Pointer to the device object.

Irp - Pointer to the request packet.

Return Value:

NT Status code
--*/
{
PLOCAL_DEVICE_INFO deviceInfo;

PAGED_CODE();

deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject-
return IoCallDriver(deviceInfo->NextLowerDriver, Irp);
}



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

Routine Description:

The plug and play dispatch routines.

Most of these the driver will completely ignore.
In all cases it must pass the IRP to the next lower
driver.

Arguments:

DeviceObject - pointer to a device object.

Irp - pointer to an I/O Request Packet.

Return Value:

NT status code

--*/
{
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_SUCCESS;
KEVENT event;
UNICODE_STRING win32DeviceName;
PLOCAL_DEVICE_INFO deviceInfo;

PAGED_CODE();

deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject-

status = IoAcquireRemoveLock (&deviceInfo->RemoveLock,
Irp);
if (!NT_SUCCESS (status)) {
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}

// DebugPrint(("%s\n",PnPMinorFunctionString(irpStack -
switch (irpStack->MinorFunction) {
case IRP_MN_START_DEVICE:

//
// The device is starting.
//
// We cannot touch the device (send it any non pnp
irps) until a
// start device has been passed down to the lower
drivers.
//
IoCopyCurrentIrpStackLocationToNext(Irp);
KeInitializeEvent(&event,
NotificationEvent,
FALSE
);

IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE)
CompletionRoutine,
&event,
TRUE,
TRUE,
TRUE);

status = IoCallDriver(deviceInfo->NextLowerDriver,
Irp);

if (STATUS_PENDING == status) {
KeWaitForSingleObject(
&event,
Executive, // Waiting for reason of a driver
KernelMode, // Must be kernelmode if event
memory is in stack
FALSE, // No allert
NULL); // No timeout
}

if (NT_SUCCESS(status) && NT_SUCCESS(Irp-
status = STATUS_SUCCESS;
}

//
// We must now complete the IRP, since we stopped
it in the
// completion routine with
STATUS_MORE_PROCESSING_REQUIRED.
//
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;

case IRP_MN_QUERY_STOP_DEVICE:

//
// Fail the query stop to prevent the system from
taking away hardware
// resources. If you do support this you must have
a queue to hold
// incoming requests between stop and subsequent
start with new set of
// resources.
//

Irp->IoStatus.Status = status =
STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;

case IRP_MN_QUERY_REMOVE_DEVICE:
//
// The device can be removed without disrupting
the machine.
//
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver,
Irp);
break;

case IRP_MN_SURPRISE_REMOVAL:

//
// The device has been unexpectedly removed from
the machine
// and is no longer available for I/O. Stop all
access to the device.
// Release any resources associated with the
device, but leave the
// device object attached to the device stack
until the PnP Manager
// sends a subsequent IRP_MN_REMOVE_DEVICE
request.
// You should fail any outstanding I/O to the
device. You will
// not get a remove until all the handles open to
the device
// have been closed.
//

deviceInfo->Removed = TRUE;
deviceInfo->Started = FALSE;


RtlInitUnicodeString(&win32DeviceName,
DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&win32DeviceName);

IoSkipCurrentIrpStackLocation(Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
status = IoCallDriver(deviceInfo->NextLowerDriver,
Irp);
break;

case IRP_MN_REMOVE_DEVICE:

//
// Relinquish all resources here.
// Detach and delete the device object so that
// your driver can be unloaded. You get remove
// either after query_remove or surprise_remove.
//

if(!deviceInfo->Removed)
{
deviceInfo->Removed = TRUE;
deviceInfo->Started = FALSE;


RtlInitUnicodeString(&win32DeviceName,
DOS_DEVICE_NAME);
IoDeleteSymbolicLink
(&win32DeviceName);
}

//
// Wait for all outstanding requests to complete
//
//DebugPrint(("Waiting for outstanding
requests\n"));
IoReleaseRemoveLockAndWait(&deviceInfo-
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver,
Irp);

IoDetachDevice(deviceInfo->NextLowerDriver);
IoDeleteDevice(DeviceObject);

return status;

case IRP_MN_STOP_DEVICE:
// Since you failed query stop, you will not get
this request.
case IRP_MN_CANCEL_REMOVE_DEVICE:
// No action required in this case. Just pass it
down.
case IRP_MN_CANCEL_STOP_DEVICE:
//No action required in this case.
Irp->IoStatus.Status = STATUS_SUCCESS;
default:
//
// Please see PnP documentation for use of these
IRPs.
//
IoSkipCurrentIrpStackLocation (Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver,
Irp);
break;
}
IoReleaseRemoveLock(&deviceInfo->RemoveLock,
Irp);
return status;
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN
PUNICODE_STRING RegistryPath)
{
//int bb;
//bb=0;
//while(bb==0);
// installe le dispatching
DriverObject->MajorFunction[IRP_MJ_CREATE] =
MonDriverDispatch; // fonction à appeller sur le OpenDevice
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
MonDriverDispatch; // fonction à appeller sur le
CloseHandle
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
MonDriverDispatch;

DriverObject->MajorFunction[IRP_MJ_PNP] =
DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] =
DispatchPower;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
DispatchSystemControl;


DriverObject->DriverExtension->AddDevice =
MonDriverAddDevice;
DriverObject->DriverUnload = MonDriverUnload;
//DriverObject->DeviceExtension = PhysicalDeviceObject;

return STATUS_SUCCESS;
}


"





Similar Posts