From: Moulefrite on
Hello Maxim and thanks a lot for your help.

I have understood the difference between both Structure.
But could you give me an example of use.

If I understand you, for ALL variable that use HANDLE type or Pointers type,
it's necessary to create both Struct for 32 and 64bit.
This MSDN link
http://msdn.microsoft.com/en-us/library/ff545635%28v=VS.85%29.aspx
present this :

typedef struct _TESTDRV_EVENT_BUFFER {
HANDLE Handle;
ULONG Key;
} TESTDRV_EVENT_BUFFER, *PTESTDRV_EVENT_BUFFER;

//
// Define a 32-bit thunking structure
//

#if defined(_WIN64)
typedef struct _TESTDRV_EVENT_BUFFER32 {
UINT32 Handle;
ULONG Key;
} TESTDRV_EVENT_BUFFER32, *PTESTDRV_EVENT_BUFFER32;
#endif

//
// Intercept the input buffer as a 32-bit structure and thunk it to
// 64-bit
NTSTATUS
TestdrvFsControl (
IN PTESTDRV_DEVICE_OBJECT TestdrvDeviceObject,
IN PIRP Irp
)
{
TESTDRV_EVENT_BUFFER LocalBuffer;

...

InputBufferLength =
IrpSp->Parameters.FileSystemControl.InputBufferLength;

#if defined(_WIN64)
if (IoIs32bitProcess(Irp)) {
PTESTDRV_EVENT_BUFFER32 Buffer32;

if (InputBufferLength < sizeof(TESTDRV_EVENT_BUFFER32)) {
DebugTrace(0, Dbg, "Irp32 : System buffer size is too
small\n", 0);

FsRtlCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
return STATUS_INVALID_PARAMETER;
}
Buffer = &LocalBuffer;
Buffer32 = Irp->AssociatedIrp.SystemBuffer;
Buffer->Handle = (HANDLE)Buffer32->Handle;
Buffer->Key = Buffer32->Key;
}
else {
#endif
if (InputBufferLength < sizeof(TESTDRV_EVENT_BUFFER)) {

DebugTrace(0, Dbg, "System buffer size is too small\n", 0);

FsRtlCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
return STATUS_INVALID_PARAMETER;
}

Buffer = Irp->AssociatedIrp.SystemBuffer;
#if defined(_WIN64)
}
#endif

// start using the Event Buffer

...

}


If I compare your response with this example, only bufferLength is concerned
or all parameters struct present in the IRP.
I have a difficult for understand the mecanism of adaptation 32 to 64 bit
and where adapt the code.
only where there are IRP and IOCTL exchange, in dispatch Routine ?
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
BulkUsb_DispatchDevCtrl;
DriverObject->MajorFunction[IRP_MJ_POWER] =
BulkUsb_DispatchPower;
DriverObject->MajorFunction[IRP_MJ_PNP] = BulkUsb_DispatchPnP;
DriverObject->MajorFunction[IRP_MJ_CREATE] =
BulkUsb_DispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
BulkUsb_DispatchClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
BulkUsb_DispatchClean;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
Standard_DispatchSysCtrl;

DriverObject->DriverUnload = BulkUsb_DriverUnload;
DriverObject->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE)
BulkUsb_AddDevice;

Have you got a complete example of this adaptation to 64bit ( I have
searched in DDK sample but nothing ).

Thanks a lot for your futur help

"Maxim S. Shatskih" wrote:

> > I noticed that with an OS 64 Bit (XP/Vista/Seven) I have a problem with
> > deviceIoControl routine ( MAJOR : IRP_MJ_DEVICE_CONTROL).
> > It appears that IOCTL process are different from 32 bit OS.
>
> If you use pointers or handles in IOCTL buffers - then yes.
>
> In this case, you must declare 2 structures in your 64bit driver code - one is IOCTL buffer for 32bit clients, another - for 64bit. Like:
>
> typedef struct _IOCTL_BUFFER
> {
> ...
> } IOCTL_BUFFER, *PIOCTL_BUFFER;
>
> #ifdef _WIN64
>
> typedef struct _IOCTL_BUFFER32
> {
> // This is for 32bit clients of 64bit driver
> // Here, use VOID *POINTER_32 instead of PVOID and HANDLE
> ...
> } IOCTL_BUFFER32, *PIOCTL_BUFFER32;
>
> #endif
>
> Then the 64bit driver must call IoIs32BitProcess and use one of these structures.
>
> The apps always use IOCTL_BUFFER, both 32 and 64 bit builds.
>
> --
> Maxim S. Shatskih
>
> Windows DDK MVP
>
> maxim(a)storagecraft.com
>
> http://www.storagecraft.com
>
> .
>
From: Satya on
Yes the "adaptation"s would be in dispatch routines (such as
BulkUsb_DispatchDevCtrl)

Satya
http://www.winprogger.com


"Moulefrite" wrote:

> Hello Maxim and thanks a lot for your help.
>
> I have understood the difference between both Structure.
> But could you give me an example of use.
>
> If I understand you, for ALL variable that use HANDLE type or Pointers type,
> it's necessary to create both Struct for 32 and 64bit.
> This MSDN link
> http://msdn.microsoft.com/en-us/library/ff545635%28v=VS.85%29.aspx
> present this :
>
> typedef struct _TESTDRV_EVENT_BUFFER {
> HANDLE Handle;
> ULONG Key;
> } TESTDRV_EVENT_BUFFER, *PTESTDRV_EVENT_BUFFER;
>
> //
> // Define a 32-bit thunking structure
> //
>
> #if defined(_WIN64)
> typedef struct _TESTDRV_EVENT_BUFFER32 {
> UINT32 Handle;
> ULONG Key;
> } TESTDRV_EVENT_BUFFER32, *PTESTDRV_EVENT_BUFFER32;
> #endif
>
> //
> // Intercept the input buffer as a 32-bit structure and thunk it to
> // 64-bit
> NTSTATUS
> TestdrvFsControl (
> IN PTESTDRV_DEVICE_OBJECT TestdrvDeviceObject,
> IN PIRP Irp
> )
> {
> TESTDRV_EVENT_BUFFER LocalBuffer;
>
> ...
>
> InputBufferLength =
> IrpSp->Parameters.FileSystemControl.InputBufferLength;
>
> #if defined(_WIN64)
> if (IoIs32bitProcess(Irp)) {
> PTESTDRV_EVENT_BUFFER32 Buffer32;
>
> if (InputBufferLength < sizeof(TESTDRV_EVENT_BUFFER32)) {
> DebugTrace(0, Dbg, "Irp32 : System buffer size is too
> small\n", 0);
>
> FsRtlCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
> return STATUS_INVALID_PARAMETER;
> }
> Buffer = &LocalBuffer;
> Buffer32 = Irp->AssociatedIrp.SystemBuffer;
> Buffer->Handle = (HANDLE)Buffer32->Handle;
> Buffer->Key = Buffer32->Key;
> }
> else {
> #endif
> if (InputBufferLength < sizeof(TESTDRV_EVENT_BUFFER)) {
>
> DebugTrace(0, Dbg, "System buffer size is too small\n", 0);
>
> FsRtlCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
> return STATUS_INVALID_PARAMETER;
> }
>
> Buffer = Irp->AssociatedIrp.SystemBuffer;
> #if defined(_WIN64)
> }
> #endif
>
> // start using the Event Buffer
>
> ...
>
> }
>
>
> If I compare your response with this example, only bufferLength is concerned
> or all parameters struct present in the IRP.
> I have a difficult for understand the mecanism of adaptation 32 to 64 bit
> and where adapt the code.
> only where there are IRP and IOCTL exchange, in dispatch Routine ?
> DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
> BulkUsb_DispatchDevCtrl;
> DriverObject->MajorFunction[IRP_MJ_POWER] =
> BulkUsb_DispatchPower;
> DriverObject->MajorFunction[IRP_MJ_PNP] = BulkUsb_DispatchPnP;
> DriverObject->MajorFunction[IRP_MJ_CREATE] =
> BulkUsb_DispatchCreate;
> DriverObject->MajorFunction[IRP_MJ_CLOSE] =
> BulkUsb_DispatchClose;
> DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
> BulkUsb_DispatchClean;
> DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
> Standard_DispatchSysCtrl;
>
> DriverObject->DriverUnload = BulkUsb_DriverUnload;
> DriverObject->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE)
> BulkUsb_AddDevice;
>
> Have you got a complete example of this adaptation to 64bit ( I have
> searched in DDK sample but nothing ).
>
> Thanks a lot for your futur help
>
> "Maxim S. Shatskih" wrote:
>
> > > I noticed that with an OS 64 Bit (XP/Vista/Seven) I have a problem with
> > > deviceIoControl routine ( MAJOR : IRP_MJ_DEVICE_CONTROL).
> > > It appears that IOCTL process are different from 32 bit OS.
> >
> > If you use pointers or handles in IOCTL buffers - then yes.
> >
> > In this case, you must declare 2 structures in your 64bit driver code - one is IOCTL buffer for 32bit clients, another - for 64bit. Like:
> >
> > typedef struct _IOCTL_BUFFER
> > {
> > ...
> > } IOCTL_BUFFER, *PIOCTL_BUFFER;
> >
> > #ifdef _WIN64
> >
> > typedef struct _IOCTL_BUFFER32
> > {
> > // This is for 32bit clients of 64bit driver
> > // Here, use VOID *POINTER_32 instead of PVOID and HANDLE
> > ...
> > } IOCTL_BUFFER32, *PIOCTL_BUFFER32;
> >
> > #endif
> >
> > Then the 64bit driver must call IoIs32BitProcess and use one of these structures.
> >
> > The apps always use IOCTL_BUFFER, both 32 and 64 bit builds.
> >
> > --
> > Maxim S. Shatskih
> >
> > Windows DDK MVP
> >
> > maxim(a)storagecraft.com
> >
> > http://www.storagecraft.com
> >
> > .
> >
From: Moulefrite on
Thanks Satya for your help.

My problem, is I don't have "handle" or "ulong" value like presented in the
sample to "Think".
For example, I don't have an instance of "Irp->AssociatedIrp.SystemBuffer"
to "thunk".

I have a big problem for understand clearly, what's necessary to rewrite for
work fine to 64 bit environement.

Have you got any sample ?

Thanks by advance,

Regards,

"Satya" wrote:

> Yes the "adaptation"s would be in dispatch routines (such as
> BulkUsb_DispatchDevCtrl)
>
> Satya
> http://www.winprogger.com
>
>
> "Moulefrite" wrote:
>
> > Hello Maxim and thanks a lot for your help.
> >
> > I have understood the difference between both Structure.
> > But could you give me an example of use.
> >
> > If I understand you, for ALL variable that use HANDLE type or Pointers type,
> > it's necessary to create both Struct for 32 and 64bit.
> > This MSDN link
> > http://msdn.microsoft.com/en-us/library/ff545635%28v=VS.85%29.aspx
> > present this :
> >
> > typedef struct _TESTDRV_EVENT_BUFFER {
> > HANDLE Handle;
> > ULONG Key;
> > } TESTDRV_EVENT_BUFFER, *PTESTDRV_EVENT_BUFFER;
> >
> > //
> > // Define a 32-bit thunking structure
> > //
> >
> > #if defined(_WIN64)
> > typedef struct _TESTDRV_EVENT_BUFFER32 {
> > UINT32 Handle;
> > ULONG Key;
> > } TESTDRV_EVENT_BUFFER32, *PTESTDRV_EVENT_BUFFER32;
> > #endif
> >
> > //
> > // Intercept the input buffer as a 32-bit structure and thunk it to
> > // 64-bit
> > NTSTATUS
> > TestdrvFsControl (
> > IN PTESTDRV_DEVICE_OBJECT TestdrvDeviceObject,
> > IN PIRP Irp
> > )
> > {
> > TESTDRV_EVENT_BUFFER LocalBuffer;
> >
> > ...
> >
> > InputBufferLength =
> > IrpSp->Parameters.FileSystemControl.InputBufferLength;
> >
> > #if defined(_WIN64)
> > if (IoIs32bitProcess(Irp)) {
> > PTESTDRV_EVENT_BUFFER32 Buffer32;
> >
> > if (InputBufferLength < sizeof(TESTDRV_EVENT_BUFFER32)) {
> > DebugTrace(0, Dbg, "Irp32 : System buffer size is too
> > small\n", 0);
> >
> > FsRtlCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
> > return STATUS_INVALID_PARAMETER;
> > }
> > Buffer = &LocalBuffer;
> > Buffer32 = Irp->AssociatedIrp.SystemBuffer;
> > Buffer->Handle = (HANDLE)Buffer32->Handle;
> > Buffer->Key = Buffer32->Key;
> > }
> > else {
> > #endif
> > if (InputBufferLength < sizeof(TESTDRV_EVENT_BUFFER)) {
> >
> > DebugTrace(0, Dbg, "System buffer size is too small\n", 0);
> >
> > FsRtlCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
> > return STATUS_INVALID_PARAMETER;
> > }
> >
> > Buffer = Irp->AssociatedIrp.SystemBuffer;
> > #if defined(_WIN64)
> > }
> > #endif
> >
> > // start using the Event Buffer
> >
> > ...
> >
> > }
> >
> >
> > If I compare your response with this example, only bufferLength is concerned
> > or all parameters struct present in the IRP.
> > I have a difficult for understand the mecanism of adaptation 32 to 64 bit
> > and where adapt the code.
> > only where there are IRP and IOCTL exchange, in dispatch Routine ?
> > DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
> > BulkUsb_DispatchDevCtrl;
> > DriverObject->MajorFunction[IRP_MJ_POWER] =
> > BulkUsb_DispatchPower;
> > DriverObject->MajorFunction[IRP_MJ_PNP] = BulkUsb_DispatchPnP;
> > DriverObject->MajorFunction[IRP_MJ_CREATE] =
> > BulkUsb_DispatchCreate;
> > DriverObject->MajorFunction[IRP_MJ_CLOSE] =
> > BulkUsb_DispatchClose;
> > DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
> > BulkUsb_DispatchClean;
> > DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
> > Standard_DispatchSysCtrl;
> >
> > DriverObject->DriverUnload = BulkUsb_DriverUnload;
> > DriverObject->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE)
> > BulkUsb_AddDevice;
> >
> > Have you got a complete example of this adaptation to 64bit ( I have
> > searched in DDK sample but nothing ).
> >
> > Thanks a lot for your futur help
> >
> > "Maxim S. Shatskih" wrote:
> >
> > > > I noticed that with an OS 64 Bit (XP/Vista/Seven) I have a problem with
> > > > deviceIoControl routine ( MAJOR : IRP_MJ_DEVICE_CONTROL).
> > > > It appears that IOCTL process are different from 32 bit OS.
> > >
> > > If you use pointers or handles in IOCTL buffers - then yes.
> > >
> > > In this case, you must declare 2 structures in your 64bit driver code - one is IOCTL buffer for 32bit clients, another - for 64bit. Like:
> > >
> > > typedef struct _IOCTL_BUFFER
> > > {
> > > ...
> > > } IOCTL_BUFFER, *PIOCTL_BUFFER;
> > >
> > > #ifdef _WIN64
> > >
> > > typedef struct _IOCTL_BUFFER32
> > > {
> > > // This is for 32bit clients of 64bit driver
> > > // Here, use VOID *POINTER_32 instead of PVOID and HANDLE
> > > ...
> > > } IOCTL_BUFFER32, *PIOCTL_BUFFER32;
> > >
> > > #endif
> > >
> > > Then the 64bit driver must call IoIs32BitProcess and use one of these structures.
> > >
> > > The apps always use IOCTL_BUFFER, both 32 and 64 bit builds.
> > >
> > > --
> > > Maxim S. Shatskih
> > >
> > > Windows DDK MVP
> > >
> > > maxim(a)storagecraft.com
> > >
> > > http://www.storagecraft.com
> > >
> > > .
> > >