Extended Example: Defining a "64Bit" Field
The following example shows how to modify a 32-bit driver for 64-bit by adding a "64Bit" field to the IOCTL control code. Note that this example shows only the portions of the driver code that need to be modified.
Original Driver Code
The following is the 32-bit version of the driver:
Header File
#define REGISTER_FUNCTION 0 // Define the IOCTL function code
#define IOCTL_REGISTER CTL_CODE(FILE_DEVICE_UNKNOWN, \
REGISTER_FUNCTION, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct _IOCTL_PARAMETERS {
PVOID Addr;
SIZE_T Length;
HANDLE Handle;
} IOCTL_PARAMETERS, *PIOCTL_PARAMETERS;
DeviceControl Dispatch Routine
NTSTATUS
TestdrvDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION irpSp;
NTSTATUS status;
PIOCTL_PARAMETERS params;
IOCTL_PARAMETERS LocalParam;
PIOCTL_PARAMETERS_32 params32;
//
// Get a pointer to the current parameters for this request. The
// information is contained in the current stack location.
//
irpSp = IoGetCurrentIrpStackLocation(Irp);
//
// Case on the device control code
//
switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_REGISTER:
params = (PIOCTL_PARAMETERS)
(Irp->AssociatedIrp.SystemBuffer);
if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
sizeof(IOCTL_PARAMETERS)) {
status = STATUS_INVALID_PARAMETER;
} else {
RtlCopyMemory(&LocalParam, params,
sizeof(IOCTL_PARAMETERS));
/* Handle the ioctl here */
status = STATUS_SUCCESS;
}
Irp->IoStatus.Information = 0;
break;
//
// Unrecognized device control request
//
default:
Irp->IoStatus.Information = 0;
status = STATUS_INVALID_PARAMETER;
break;
}
//
// If status is pending, mark the IRP pending and start the
// request in a cancelable state. Otherwise, complete the IRP.
//
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(status);
}
Driver Code With Thunking Support
The following is the 64-bit version of the driver:
Header File
#define REGISTER_FUNCTION 0 // Define the IOCTL function code
#ifdef _WIN64
#define CLIENT_64BIT 0x800
#define REGISTER_FUNCTION 0
#define IOCTL_REGISTER CTL_CODE(FILE_DEVICE_UNKNOWN, \
CLIENT_64BIT|REGISTER_FUNCTION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#else
#define IOCTL_REGISTER CTL_CODE(FILE_DEVICE_UNKNOWN, \
REGISTER_FUNCTION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#endif
typedef struct _IOCTL_PARAMETERS {
PVOID Addr;
SIZE_T Length;
HANDLE Handle;
} IOCTL_PARAMETERS, *PIOCTL_PARAMETERS;
DeviceControl Dispatch Routine
#ifdef _WIN64
#define IOCTL_REGISTER_32 CTL_CODE(FILE_DEVICE_UNKNOWN, \
REGISTER_FUNCTION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#endif
...
#ifdef _WIN64
typedef struct _IOCTL_PARAMETERS_32 {
VOID*POINTER_32 Addr;
INT32 Length;
VOID*POINTER_32 Handle;
} IOCTL_PARAMETERS_32, *PIOCTL_PARAMETERS_32;
#endif
...
NTSTATUS
TestdrvDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION irpSp;
NTSTATUS status;
PIOCTL_PARAMETERS params;
IOCTL_PARAMETERS LocalParam;
PIOCTL_PARAMETERS_32 params32;
//
// Get a pointer to the current parameters for this request. The
// information is contained in the current stack location.
//
irpSp = IoGetCurrentIrpStackLocation(Irp);
//
// Case on the device control code
//
switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
#ifdef _WIN64
case IOCTL_REGISTER_32:
params32 = (PIOCTL_PARAMETERS_32)
(Irp->AssociatedIrp.SystemBuffer);
if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
sizeof(IOCTL_PARAMETERS_32)) {
status = STATUS_INVALID_PARAMETER;
} else {
LocalParam.Addr = params32->Addr;
LocalParam.Handle = params32->Handle;
LocalParam.Length = params32->Length;
/* Handle the ioctl here */
status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
}
break;
#endif
case IOCTL_REGISTER:
params = (PIOCTL_PARAMETERS)
(Irp->AssociatedIrp.SystemBuffer);
if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
sizeof(IOCTL_PARAMETERS)) {
status = STATUS_INVALID_PARAMETER;
} else {
RtlCopyMemory(&LocalParam, params,
sizeof(IOCTL_PARAMETERS));
/* Handle the ioctl here */
status = STATUS_SUCCESS;
}
Irp->IoStatus.Information = 0;
break;
//
// Unrecognized device control request
//
default:
Irp->IoStatus.Information = 0;
status = STATUS_INVALID_PARAMETER;
break;
}
//
// If status is pending, mark the IRP pending and start the
// request in a cancelable state. Otherwise, complete the IRP.
//
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(status);
}
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for