access violation on DeviceIoControl

Hello, everyone
I have a simple driver for virtual device, and it handles some ioctl, and each does very simple job. after I call DeviceIoControl from app, the driver pops up an access violation. even i make the ioctl handler do almost nothing. my code is below.

#define FILE_DEVICE_VS8 0x00008260

#define VS8_IOCTL_INDEX 0x860

#define IOCTL_VS8_INIT CTL_CODE(FILE_DEVICE_VS8, \
VS8_IOCTL_INDEX + 1, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING DeviceNameUnicodeString;
UNICODE_STRING DeviceLinkUnicodeString;
NTSTATUS ntStatus;
PDEVICE_OBJECT DeviceObject = NULL;

KdPrint((“Vs8 Entering DriverEntry\n”));

RtlInitUnicodeString (&DeviceNameUnicodeString, L"\Device\Vs8");

ntStatus = IoCreateDevice (DriverObject,
0,
&DeviceNameUnicodeString,
FILE_DEVICE_VS8,
0,
TRUE,
&DeviceObject);

if (NT_SUCCESS(ntStatus))
{
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Vs8Dispatch;
DriverObject->DriverUnload = Vs8Unload;

RtlInitUnicodeString (&DeviceLinkUnicodeString, L"\DosDevices\Vs8");

ntStatus = IoCreateSymbolicLink (&DeviceLinkUnicodeString,
&DeviceNameUnicodeString);

if (!NT_SUCCESS(ntStatus))
{
KdPrint((“Vs8 ERROR: IoCreateSymbolicLink failed”));

IoDeleteDevice (DeviceObject);

return ntStatus;
}
}
else
{
KdPrint((“Vs8 ERROR: IoCreateDevice failed\n”));
}

KdPrint((“Vs8 Leaving DriverEntry\n”));

return ntStatus;
}

NTSTATUS Vs8Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
ULONG dwInputBufferLength;
ULONG dwOutputBufferLength;
ULONG dwIoControlCode;
NTSTATUS ntStatus;
UCHAR *pbValue;
LARGE_INTEGER largeint;
int i;

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;

IrpStack = IoGetCurrentIrpStackLocation(Irp);

switch (IrpStack->MajorFunction)
{
case IRP_MJ_CREATE:

KdPrint((“IRP_MJ_CREATE\n”));

break;

case IRP_MJ_CLOSE:

KdPrint((“IRP_MJ_CLOSE\n”));

break;

case IRP_MJ_DEVICE_CONTROL:
{
pbValue = (PUCHAR)(Irp->AssociatedIrp.SystemBuffer);
dwInputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
dwOutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

KdPrint((“IRP_MJ_DEVICE_CONTROL:%d\n”,dwIoControlCode));

switch (dwIoControlCode)
{
case IOCTL_VS8_INIT:
{ // i make here do almost nothing, but i call deviceiocontrol in app still gets access violation
char al;
al = 0;
break;
}

case …:
{
break;
}

default:

KdPrint((“ERROR: Unknown IRP_MJ_DEVICE_CONTROL\n”));

Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

break;
}

break;
}
}

ntStatus = Irp->IoStatus.Status;

IoCompleteRequest (Irp, IO_NO_INCREMENT);

KdPrint((“Leaving Vs8Dispatch\n”));

return ntStatus;
}

in my app :
hDriver = CreateFile(“\\.\VS8”,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if(!DeviceIoControl(hDriver,IOCTL_VS8_INIT,NULL,0,NULL,0,NULL,NULL))
{

}

i traced with softice, my ioctl handler goes no error, but access violation occurs after it and in kernel’s deviceiocontrol.

thank in advance

metawest

The application call
DeviceIoControl(hDriver,IOCTL_VS8_INIT,NULL,0,NULL,0,NULL,NULL)) is not
correct. You need put the input param/length and output param/length
accordingly.

Peter’s Windows NT device driver development has a very good and thorough
explain on how to use DeviceIoControl.

William
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of netease
Sent: Tuesday, December 09, 2003 6:51 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] access violation on DeviceIoControl

Hello, everyone
I have a simple driver for virtual device, and it handles some ioctl,
and each does very simple job. after I call DeviceIoControl from app, the
driver pops up an access violation. even i make the ioctl handler do almost
nothing. my code is below.

#define FILE_DEVICE_VS8 0x00008260

#define VS8_IOCTL_INDEX 0x860

#define IOCTL_VS8_INIT CTL_CODE(FILE_DEVICE_VS8, \
VS8_IOCTL_INDEX + 1, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING DeviceNameUnicodeString;
UNICODE_STRING DeviceLinkUnicodeString;
NTSTATUS ntStatus;
PDEVICE_OBJECT DeviceObject = NULL;

KdPrint((“Vs8 Entering DriverEntry\n”));

RtlInitUnicodeString (&DeviceNameUnicodeString, L"\Device\Vs8");

ntStatus = IoCreateDevice (DriverObject,
0,
&DeviceNameUnicodeString,
FILE_DEVICE_VS8,
0,
TRUE,
&DeviceObject);

if (NT_SUCCESS(ntStatus))
{
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Vs8Dispatch;
DriverObject->DriverUnload = Vs8Unload;

RtlInitUnicodeString (&DeviceLinkUnicodeString, L"\DosDevices\Vs8");

ntStatus = IoCreateSymbolicLink (&DeviceLinkUnicodeString,
&DeviceNameUnicodeString);

if (!NT_SUCCESS(ntStatus))
{
KdPrint((“Vs8 ERROR: IoCreateSymbolicLink failed”));

IoDeleteDevice (DeviceObject);

return ntStatus;
}
}
else
{
KdPrint((“Vs8 ERROR: IoCreateDevice failed\n”));
}

KdPrint((“Vs8 Leaving DriverEntry\n”));

return ntStatus;
}

NTSTATUS Vs8Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
ULONG dwInputBufferLength;
ULONG dwOutputBufferLength;
ULONG dwIoControlCode;
NTSTATUS ntStatus;
UCHAR *pbValue;
LARGE_INTEGER largeint;
int i;

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;

IrpStack = IoGetCurrentIrpStackLocation(Irp);

switch (IrpStack->MajorFunction)
{
case IRP_MJ_CREATE:

KdPrint((“IRP_MJ_CREATE\n”));

break;

case IRP_MJ_CLOSE:

KdPrint((“IRP_MJ_CLOSE\n”));

break;

case IRP_MJ_DEVICE_CONTROL:
{
pbValue = (PUCHAR)(Irp->AssociatedIrp.SystemBuffer);
dwInputBufferLength =
IrpStack->Parameters.DeviceIoControl.InputBufferLength;
dwOutputBufferLength =
IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

KdPrint((“IRP_MJ_DEVICE_CONTROL:%d\n”,dwIoControlCode));

switch (dwIoControlCode)
{
case IOCTL_VS8_INIT:
{ // i make here do almost nothing, but i call deviceiocontrol in app
still gets access violation
char al;
al = 0;
break;
}

case …:
{
break;
}

default:

KdPrint((“ERROR: Unknown IRP_MJ_DEVICE_CONTROL\n”));

Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

break;
}

break;
}
}

ntStatus = Irp->IoStatus.Status;

IoCompleteRequest (Irp, IO_NO_INCREMENT);

KdPrint((“Leaving Vs8Dispatch\n”));

return ntStatus;
}

in my app :
hDriver = CreateFile(“\\.\VS8”,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if(!DeviceIoControl(hDriver,IOCTL_VS8_INIT,NULL,0,NULL,0,NULL,NULL))
{

}

i traced with softice, my ioctl handler goes no error, but access
violation occurs after it and in kernel’s deviceiocontrol.

thank in advance

metawest
B¶°²y…®zA?¢žyý‰q?.žË›±Êâm?Ö›•©äzf¢–?y«Þž×^¿]»çÒåŠËl¢Ê

i tried, it can do.
but if i left the input param/length and output param/length null, lpBytesReturned not null, this deviceiocontrol also work.

----- Original Message -----
From: William Zhang
Sent: Wednesday, December 10, 2003 11:09 AM
Subject: RE: access violation on DeviceIoControl

The application call DeviceIoControl(hDriver,IOCTL_VS8_INIT,NULL,0,NULL,0,NULL,NULL)) is not correct. You need put the input param/length and output param/length accordingly.

Peter’s Windows NT device driver development has a very good and thorough explain on how to use DeviceIoControl.

William
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com]On Behalf Of netease
Sent: Tuesday, December 09, 2003 6:51 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] access violation on DeviceIoControl

Hello, everyone
I have a simple driver for virtual device, and it handles some ioctl, and each does very simple job. after I call DeviceIoControl from app, the driver pops up an access violation. even i make the ioctl handler do almost nothing. my code is below.

#define FILE_DEVICE_VS8 0x00008260

#define VS8_IOCTL_INDEX 0x860

#define IOCTL_VS8_INIT CTL_CODE(FILE_DEVICE_VS8, \
VS8_IOCTL_INDEX + 1, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING DeviceNameUnicodeString;
UNICODE_STRING DeviceLinkUnicodeString;
NTSTATUS ntStatus;
PDEVICE_OBJECT DeviceObject = NULL;

KdPrint((“Vs8 Entering DriverEntry\n”));

RtlInitUnicodeString (&DeviceNameUnicodeString, L"\Device\Vs8");

ntStatus = IoCreateDevice (DriverObject,
0,
&DeviceNameUnicodeString,
FILE_DEVICE_VS8,
0,
TRUE,
&DeviceObject);

if (NT_SUCCESS(ntStatus))
{
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Vs8Dispatch;
DriverObject->DriverUnload = Vs8Unload;

RtlInitUnicodeString (&DeviceLinkUnicodeString, L"\DosDevices\Vs8");

ntStatus = IoCreateSymbolicLink (&DeviceLinkUnicodeString,
&DeviceNameUnicodeString);

if (!NT_SUCCESS(ntStatus))
{
KdPrint((“Vs8 ERROR: IoCreateSymbolicLink failed”));

IoDeleteDevice (DeviceObject);

return ntStatus;
}
}
else
{
KdPrint((“Vs8 ERROR: IoCreateDevice failed\n”));
}

KdPrint((“Vs8 Leaving DriverEntry\n”));

return ntStatus;
}

NTSTATUS Vs8Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
ULONG dwInputBufferLength;
ULONG dwOutputBufferLength;
ULONG dwIoControlCode;
NTSTATUS ntStatus;
UCHAR *pbValue;
LARGE_INTEGER largeint;
int i;

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;

IrpStack = IoGetCurrentIrpStackLocation(Irp);

switch (IrpStack->MajorFunction)
{
case IRP_MJ_CREATE:

KdPrint((“IRP_MJ_CREATE\n”));

break;

case IRP_MJ_CLOSE:

KdPrint((“IRP_MJ_CLOSE\n”));

break;

case IRP_MJ_DEVICE_CONTROL:
{
pbValue = (PUCHAR)(Irp->AssociatedIrp.SystemBuffer);
dwInputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
dwOutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

KdPrint((“IRP_MJ_DEVICE_CONTROL:%d\n”,dwIoControlCode));

switch (dwIoControlCode)
{
case IOCTL_VS8_INIT:
{ // i make here do almost nothing, but i call deviceiocontrol in app still gets access violation
char al;
al = 0;
break;
}

case …:
{
break;
}

default:

KdPrint((“ERROR: Unknown IRP_MJ_DEVICE_CONTROL\n”));

Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

break;
}

break;
}
}

ntStatus = Irp->IoStatus.Status;

IoCompleteRequest (Irp, IO_NO_INCREMENT);

KdPrint((“Leaving Vs8Dispatch\n”));

return ntStatus;
}

in my app :
hDriver = CreateFile(“\\.\VS8”,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if(!DeviceIoControl(hDriver,IOCTL_VS8_INIT,NULL,0,NULL,0,NULL,NULL))
{

}

i traced with softice, my ioctl handler goes no error, but access violation occurs after it and in kernel’s deviceiocontrol.

thank in advance

metawest
B???y??zA???y??q?.?˛???m??֛???zf???y?ޞ?^?]???l??

Hello, netease.

lpBytesReturned and lpOverlapped cannot be NULL at the same time.
Did you read MSDN documentation about DeviceIoControl?

MSDN:
If lpOverlapped is NULL, lpBytesReturned cannot be NULL. Even
when an operation returns no output data and lpOutBuffer is NULL,
DeviceIoControl makes use of lpBytesReturned. After such an operation,
the value of lpBytesReturned is meaningless.

If lpOverlapped is not NULL, lpBytesReturned can be NULL. If this
parameter is not NULL and the operation returns data, lpBytesReturned
is meaningless until the overlapped operation has completed. To
retrieve the number of bytes returned, call GetOverlappedResult. If
hDevice is associated with an I/O completion port, you can retrieve
the number of bytes returned by calling GetQueuedCompletionStatus.

n> if(!DeviceIoControl(hDriver,IOCTL_VS8_INIT,NULL,0,NULL,0,NULL,NULL))
n> {
n> …
n> }

– Alexey

According to the MSDN docs on DeviceIoControl
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/
base/deviceiocontrol.asp), the second-to-last parameter
(lpBytesReturned) is not listed as optional, but you are providing its
value as NULL:

if(!DeviceIoControl(hDriver,IOCTL_VS8_INIT,NULL,0,NULL,0,NULL,NULL))

What is happening is that your IOCTL is working, and then when the
number of bytes transferred is being copied back into your application
(Irp->IoStatus.Information gets copied here on success), a NULL
dereference is occurring because you didn’t provide a location to store
this value.

Hth,
.

TIP: Always enable driver verifier when developing a driver. Won’t
catch the below problem (user-mode), but it’ll save the average
developer countless hours.

-----Original Message-----
From: netease [mailto:metawest@163.com]
Sent: Tuesday, December 09, 2003 6:51 PM
Subject: access violation on DeviceIoControl

Hello, everyone
I have a simple driver for virtual device, and it handles some
ioctl, and each does very simple job. after I call DeviceIoControl from
app, the driver pops up an access violation. even i make the ioctl
handler do almost nothing. my code is below.

#define FILE_DEVICE_VS8 0x00008260

#define VS8_IOCTL_INDEX 0x860

#define IOCTL_VS8_INIT CTL_CODE(FILE_DEVICE_VS8, \
VS8_IOCTL_INDEX + 1, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING DeviceNameUnicodeString;
UNICODE_STRING DeviceLinkUnicodeString;
NTSTATUS ntStatus;
PDEVICE_OBJECT DeviceObject = NULL;

KdPrint((“Vs8 Entering DriverEntry\n”));

RtlInitUnicodeString (&DeviceNameUnicodeString, L"\Device\Vs8");

ntStatus = IoCreateDevice (DriverObject,
0,
&DeviceNameUnicodeString,
FILE_DEVICE_VS8,
0,
TRUE,
&DeviceObject);

if (NT_SUCCESS(ntStatus))
{
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Vs8Dispatch;
DriverObject->DriverUnload = Vs8Unload;

RtlInitUnicodeString (&DeviceLinkUnicodeString, L"\DosDevices\Vs8");

ntStatus = IoCreateSymbolicLink (&DeviceLinkUnicodeString,
&DeviceNameUnicodeString);

if (!NT_SUCCESS(ntStatus))
{
KdPrint((“Vs8 ERROR: IoCreateSymbolicLink failed”));

IoDeleteDevice (DeviceObject);

return ntStatus;
}
}
else
{
KdPrint((“Vs8 ERROR: IoCreateDevice failed\n”));
}

KdPrint((“Vs8 Leaving DriverEntry\n”));

return ntStatus;
}

NTSTATUS Vs8Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
ULONG dwInputBufferLength;
ULONG dwOutputBufferLength;
ULONG dwIoControlCode;
NTSTATUS ntStatus;
UCHAR *pbValue;
LARGE_INTEGER largeint;
int i;

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;

IrpStack = IoGetCurrentIrpStackLocation(Irp);

switch (IrpStack->MajorFunction)
{
case IRP_MJ_CREATE:

KdPrint((“IRP_MJ_CREATE\n”));

break;

case IRP_MJ_CLOSE:

KdPrint((“IRP_MJ_CLOSE\n”));

break;

case IRP_MJ_DEVICE_CONTROL:
{
pbValue = (PUCHAR)(Irp->AssociatedIrp.SystemBuffer);
dwInputBufferLength =
IrpStack->Parameters.DeviceIoControl.InputBufferLength;
dwOutputBufferLength =
IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

KdPrint((“IRP_MJ_DEVICE_CONTROL:%d\n”,dwIoControlCode));

switch (dwIoControlCode)
{
case IOCTL_VS8_INIT:
{ // i make here do almost nothing, but i call deviceiocontrol in app
still gets access violation
char al;
al = 0;
break;
}

case …:
{
break;
}

default:

KdPrint((“ERROR: Unknown IRP_MJ_DEVICE_CONTROL\n”));

Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

break;
}

break;
}
}

ntStatus = Irp->IoStatus.Status;

IoCompleteRequest (Irp, IO_NO_INCREMENT);

KdPrint((“Leaving Vs8Dispatch\n”));

return ntStatus;
}

in my app :
hDriver = CreateFile(“\\.\VS8”,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if(!DeviceIoControl(hDriver,IOCTL_VS8_INIT,NULL,0,NULL,0,NULL,NULL))
{

}

i traced with softice, my ioctl handler goes no error, but access
violation occurs after it and in kernel’s deviceiocontrol.

thank in advance

metawest

I call DeviceIoControl with wrong parameters, but these code can run under win98,
how does this occur?

----- Original Message -----
From: “Henry Gabryjelski”
Sent: Thursday, December 11, 2003 1:19 AM
Subject: RE: access violation on DeviceIoControl

According to the MSDN docs on DeviceIoControl
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/
base/deviceiocontrol.asp), the second-to-last parameter
(lpBytesReturned) is not listed as optional, but you are providing its
value as NULL:

if(!DeviceIoControl(hDriver,IOCTL_VS8_INIT,NULL,0,NULL,0,NULL,NULL))

What is happening is that your IOCTL is working, and then when the
number of bytes transferred is being copied back into your application
(Irp->IoStatus.Information gets copied here on success), a NULL
dereference is occurring because you didn’t provide a location to store
this value.

Hth,
.

TIP: Always enable driver verifier when developing a driver. Won’t
catch the below problem (user-mode), but it’ll save the average
developer countless hours.

-----Original Message-----
From: netease [mailto:metawest@163.com]
Sent: Tuesday, December 09, 2003 6:51 PM
Subject: access violation on DeviceIoControl

Hello, everyone
I have a simple driver for virtual device, and it handles some
ioctl, and each does very simple job. after I call DeviceIoControl from
app, the driver pops up an access violation. even i make the ioctl
handler do almost nothing. my code is below.

#define FILE_DEVICE_VS8 0x00008260

#define VS8_IOCTL_INDEX 0x860

#define IOCTL_VS8_INIT CTL_CODE(FILE_DEVICE_VS8, <br> VS8_IOCTL_INDEX + 1, <br> METHOD_BUFFERED, <br> FILE_ANY_ACCESS)

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING DeviceNameUnicodeString;
UNICODE_STRING DeviceLinkUnicodeString;
NTSTATUS ntStatus;
PDEVICE_OBJECT DeviceObject = NULL;

KdPrint((“Vs8 Entering DriverEntry\n”));

RtlInitUnicodeString (&DeviceNameUnicodeString, L"\Device\Vs8");

ntStatus = IoCreateDevice (DriverObject,
0,
&DeviceNameUnicodeString,
FILE_DEVICE_VS8,
0,
TRUE,
&DeviceObject);

if (NT_SUCCESS(ntStatus))
{
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Vs8Dispatch;
DriverObject->DriverUnload = Vs8Unload;

RtlInitUnicodeString (&DeviceLinkUnicodeString, L"\DosDevices\Vs8");

ntStatus = IoCreateSymbolicLink (&DeviceLinkUnicodeString,
&DeviceNameUnicodeString);

if (!NT_SUCCESS(ntStatus))
{
KdPrint((“Vs8 ERROR: IoCreateSymbolicLink failed”));

IoDeleteDevice (DeviceObject);

return ntStatus;
}
}
else
{
KdPrint((“Vs8 ERROR: IoCreateDevice failed\n”));
}

KdPrint((“Vs8 Leaving DriverEntry\n”));

return ntStatus;
}

NTSTATUS Vs8Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
ULONG dwInputBufferLength;
ULONG dwOutputBufferLength;
ULONG dwIoControlCode;
NTSTATUS ntStatus;
UCHAR *pbValue;
LARGE_INTEGER largeint;
int i;

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;

IrpStack = IoGetCurrentIrpStackLocation(Irp);

switch (IrpStack->MajorFunction)
{
case IRP_MJ_CREATE:

KdPrint((“IRP_MJ_CREATE\n”));

break;

case IRP_MJ_CLOSE:

KdPrint((“IRP_MJ_CLOSE\n”));

break;

case IRP_MJ_DEVICE_CONTROL:
{
pbValue = (PUCHAR)(Irp->AssociatedIrp.SystemBuffer);
dwInputBufferLength =
IrpStack->Parameters.DeviceIoControl.InputBufferLength;
dwOutputBufferLength =
IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

KdPrint((“IRP_MJ_DEVICE_CONTROL:%d\n”,dwIoControlCode));

switch (dwIoControlCode)
{
case IOCTL_VS8_INIT:
{ // i make here do almost nothing, but i call deviceiocontrol in app
still gets access violation
char al;
al = 0;
break;
}

case …:
{
break;
}

default:

KdPrint((“ERROR: Unknown IRP_MJ_DEVICE_CONTROL\n”));

Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

break;
}

break;
}
}

ntStatus = Irp->IoStatus.Status;

IoCompleteRequest (Irp, IO_NO_INCREMENT);

KdPrint((“Leaving Vs8Dispatch\n”));

return ntStatus;
}

in my app :
hDriver = CreateFile(“\\.\VS8”,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if(!DeviceIoControl(hDriver,IOCTL_VS8_INIT,NULL,0,NULL,0,NULL,NULL))
{

}

i traced with softice, my ioctl handler goes no error, but access
violation occurs after it and in kernel’s deviceiocontrol.

thank in advance

metawest

> I call DeviceIoControl with wrong parameters, but these code can run under
win98,

how does this occur?

Who cares? If its busted, fix it.

Win98 is probably not checking null pointers and just happily trashing
memory.

Loren

> > I call DeviceIoControl with wrong parameters, but these

code can run under
win98,
> how does this occur?

Who cares? If its busted, fix it.

Win98 is probably not checking null pointers and just happily trashing
memory.

That would probably be because of the DOS part running below Win98 having
the low region of memory mapped in as valid memory in kernel mode, so that
some DOS/BIOS accesses can be performed in 32-bit mode before switching to
real or V86 mode.

In fact, I’ve seen cases where WinNT/2K/XP does NOT crash due to NULL
pointer access, it just happily writes to that address. Other times it would
crash, so it’s obviously depending on the circumstances (for example what
apps are running, what drivers are loaded, etc).

I agree with Loren, it’s probably just writing over some (hopefully not
used) data at address 0…3, and happily continuing. Or Win98 checks for a
NULL pointer although it’s not valid, and ignores to write the data. Since
the Win32 spec says that NULL is not a valid option here, it’s probably a
good idea to NOT use this.


Mats

metawest wrote:

I call DeviceIoControl with wrong parameters, but these code can run under win98,
how does this occur?

Because the pointer is optional in Win98. But, actually, most VxD
writers don’t know that, and they uncritically store through the
cbBytesReturned pointer without checking it for NULL. As Mats Petersson
points out, address zero points to valid virtual memory in 9x, so you
don’t get an access violation.


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Check out our schedule at http://www.oneysoft.com