First, embedded pointers are generally a bad idea and very few cases
actually require this type of design. I would strongly suggest
re-designing this IOCTL to accept a variable buffer, unless you are
expecting to parse rather large buffers (think disk IO or gigabit+
network IO here) using this IOCTL. Even then it might not be necessary.
Presuming you absolutely *must* do this, then look at how the
IOCTL_SCSI_PASS_THROUGH_DIRECT structures are defined. Basically,
define a special 32-bit version of your structure, but only for 64-bit
builds:
#if defined(_WIN64)
typedef struct _SCSI_PASS_THROUGH_DIRECT32 {
USHORT Length;
UCHAR ScsiStatus;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR CdbLength;
UCHAR SenseInfoLength;
UCHAR DataIn;
ULONG DataTransferLength;
ULONG TimeOutValue;
VOID * POINTER_32 DataBuffer;
ULONG SenseInfoOffset;
UCHAR Cdb[16];
}SCSI_PASS_THROUGH_DIRECT32, *PSCSI_PASS_THROUGH_DIRECT32;
#endif
In particular, note the “POINTER_32” markup on the embedded pointer.
Then, anyplace you process the IOCTL with an embedded pointer, you need
to determine if the application using the driver is 32-bit or 64-bit.
This can be done using the IoIs32bitProcess() API, with a trivial
example as follows:
#if defined (_WIN64)
if (IoIs32bitProcess(Irp)) {
DoTrace((TRACE_LEVEL_VERBOSE,
"32-bit IOCTL with embedded pointers "
“in 64-bit build”.));
}
#endif //defined (_WIN64)
As ‘cd’ mentioned, you cannot directly use this buffer address without
additional work. Generating the MDL is sufficient for hardware access
(but be careful about memory alignment requirements of the device), and
you still need to be sure that you’re in the original caller’s context
(which is only guaranteed by rules orthogonal to WDM – the storage
stack ensures this for storage IOCTLs, for example).
Good luck, as embedded pointers in IOCTLs is a very rocky road to
travel.
.
-----Original Message-----
From: cd [mailto:xxxxx@hotmail.com]
Sent: Monday, June 21, 2004 11:11 AM
Subject: Re: 32bit pointers for 64bit driver
You cannot use user buffer pointers in kernel space (32 bit or 64 bit).
I would assume that when you get a user buffer pointer, you could use
IoAllocateMdl to create an MDL using the 32bit pointer, lock the pages
using
MmProbeAndLockPages, and then use MmGetSystemAddressForMdlSafe to get a
kernel mode pointer. Make sure you probe & lock pages inside a
try/except
block .
“Al Shatilo” wrote in message news:xxxxx@ntdev…
> Hello All!
>
> We have a 32-bit application and 64-bit driver working together.
> In some IOCTLs we have embedded pointers to user mode buffers.
> How can we turn those 32bit pointers into 64bit pointers that our
driver
can use?
>
> Can we just do it this way:
> PTR32 p32 = ioctlStruct.pointer_to_buffer;
> PTR64 p64 = (PTR64)p32;
>
> or are other steps required?
>
>
>
> __________________________________
> Do you Yahoo!?
> Yahoo! Mail is new and improved - Check it out!
> http://promotions.yahoo.com/new_mail
>