Shared memory between 64bit Driver / 32bit App

It is supported, I have tried this with success in the past. It creates a
valid 32 bit user address, the higher 32 bits just remain 0 and can be
safely ignored.

//Daniel

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev…
> I’m guessing that there’s probably some simple unrelated bug.

This can be a Windows bug in MmMapLockedPagesSpecifyCache(UserMode),
probably the 64bit OS does not do the check for 32bit process.

Is the issue here on several x64 Windows versions? or only in one of them?


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

thank You for inputs. I will have to try several those things you inquired.

Daniel, have You tried exactly same scenario as I have? Can You post snipped of your code how you solved it?

I don’t have the code anymore but it was nothing fancy. I probably took most
from the OSR article Peter just pointed you to with the addition of a
try/except block. I used a 64 bit wide pointer value for all possible
scenarios and did not need any special case handling for 32 bit apps (no
Is32BitProcess).

Before you wrote "if i reuse the pointer in driver … driver BSODs. ". You
can of course not use the user address in your driver. Why don’t you write
us what values you are receiving in io32->ptr (are you sure the pointer
value is the same when you use it in your app) so we can check if those may
sense.

//Daniel

wrote in message news:xxxxx@ntdev…
> thank You for inputs. I will have to try several those things you
> inquired.
>
> Daniel, have You tried exactly same scenario as I have? Can You post
> snipped of your code how you solved it?
>

> thank You for inputs. I will have to try several those things you inquired.

My bet is replacing MmCreateMdl with IoAllocateMdl can solve the issue :slight_smile:


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

AKA an Inverted call back … which normally the recommendation to replace
kernel/user shared memory.


The personal opinion of
Gary G. Little

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev…
> Peter, you dont need to spare me anything. I welcome all comments. However
> performance wise-
>there is afaik no better solution.

Allocate in the app then pass this to the driver.

I.e. - VirtualAlloc in the app, DeviceIoControl to the overlapped handle in
the app.

In the driver, just pend this IRP for the whole lifetime till the driver
needs the buffer. I.e. IoMarkIrpPending, save the IRP pointer somewhere,
then return STATUS_PENDING.

The MDL you need is in Irp->MdlAddress, do MmGetSystemAddressForMdlSafe on
it.

When the driver will want to free this buffer, it should just complete the
IRP in question.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Max… you don’t NEED to pass the MDL into MmCreateMdl. The PMdl parameter is optional. If you don’t pass it in, it’ll allocate one from NonPagedPool.

IoAllocateMdl *is* the better function to use… it has more diagnostic checks, etc. And MmCreateMdl *is* deprecated. But I don’t think that’s the problem.

Tanja, you can always try it… it’s a trivial one-line change.

Daniel… you and I are just on opposite sides of the fence today. OF COURSE you can use the user-mode pointer in the driver. It’s mapped into the low 2GB of user virtual address space, and you’re in the context of the appropriate process user process. So the pointer should work equally well in kernel mode and user mode.

Peter
OSR

i did tried to allocate it in app and use in driver. it worked. but i would prefer to keep existing layout. I like when driver cares for fundamental things and app is simplest possible. Also i tend to use driver as “trusted piece of software chain” and depending on client app is not something i would like.

will try all suggestions here, thanks everybody.

If you do find out the answer please post it back here. While I to have
advocated against the use of this approach, I know of uses, and have a new
driver comming up that will require it.


Don Burn (MVP, Windows DDK)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

wrote in message news:xxxxx@ntdev…
>i did tried to allocate it in app and use in driver. it worked. but i would
>prefer to keep existing layout. I like when driver cares for fundamental
>things and app is simplest possible. Also i tend to use driver as “trusted
>piece of software chain” and depending on client app is not something i
>would like.
>
> will try all suggestions here, thanks everybody.
>

xxxxx@osr.com wrote:

…It’s mapped into the low 2GB of user virtual address space, and you’re in the context of the appropriate process user process. So the pointer should work equally well in kernel mode and user mode.

Just on the off chance… you are the highest level driver in the device
stack, right? Because otherwise you can’t assume you’re in the process
context of the IOCTL caller. Someone higher in the stack could have
pended the IRP and passed it down to you in a different process context.

Ray
(If you want to reply to me off list, please remove “spamblock.” from my
email address)

just wanted to inform only that none of those suggested things worked. I tried to replace also
IoAllocateMdl for MMCreateMdl and that didnt helped too, as well as using MmMapLockedPagesSpecifyCache.

However i verified that pointer passed to devstr->queue_user_mem (by MmMapLockedPages) is above 32bit zeroed so PtrToUlong-ing doesnt change its value.

any input or code examples would help, thank You.

Is this by chance a kmdf driver? If so and you are processing this request in a power managed queue there is no guarantee you will in the app’s context. If this is not a kmdf driver, please disregard…

d

Sent from my phone with no t9, all spilling mistakes are not intentional.

-----Original Message-----
From: xxxxx@xpwn.net
Sent: Sunday, February 22, 2009 9:31 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Shared memory between 64bit Driver / 32bit App

just wanted to inform only that none of those suggested things worked. I tried to replace also
IoAllocateMdl for MMCreateMdl and that didnt helped too, as well as using MmMapLockedPagesSpecifyCache.

However i verified that pointer passed to devstr->queue_user_mem (by MmMapLockedPages) is above 32bit zeroed so PtrToUlong-ing doesnt change its value.

any input or code examples would help, thank You.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

it is WDM driver

all is done in DeviceIO Control routine. All powermanagement things, as well as other IOs work fine but are unrelated.

If there anybody, shared his 64bit driver memory for use with 64bit and 32bit application, just please post a example, that might be good help for me to start with.

I found it.

it was really one of those “stupid” bugs we have every now and then. I built driver with different layout on saturday which magically worked, than i found that in the shared memory block from old definition was one typo (in memory size) and one pointer behind it. That caused many content shifted for 8 bytes and was causing all those crashes.

Sadly for backward compatibility it have to be a bit “not nice” but works finally.

So closeup: my original source code really works. Thanks to everybody who tried to help.

YAY!

I’m VERY glad to hear you got it working.

Thanks, Tanya, for taking the time to “close out” this thread. I hate it when mysteries remain unsolved :slight_smile:

Peter
OSR

Hi,

not yet closed fully.

I am now in second stage where i have to reuse the pointer second time.

So now i am in stage, that i take the pointer, convert it to 32bit, this removes upper 32bits, goes up to application. Application can use it as pointer and it works.

Now i pass this 32bit pointer again to 64bit driver and want to convert it to 64bit pointer. From what i understood in MSDN, that should be done automatically when i do something like this:

VOID*POINTER_32 ptr32;
VOID *ptr64;

ptr64 = ptr32;

but the problem is, that when i look at value of ptr64, it is still 0x00000000xxxxxxxx; which causes BSOD in driver. Original 64bit pointer (before truncating to 32bit) looked like this 0xfffffa80xxxxxxxx.

so i tried this hard hack:

queue = (VOID*)((unsigned __int64)io32->ptr | 0xfffffa8000000000);

and it works.

So can anybody please tell me how can i without hard hacking convert pointer variable inside IOCTL structure (that is important because they are not converted as whole structure is simply memcopied) to 64bit pointer?

Thanks again!!

Please post your MmMapLockedPagesSpecifyCache call source and the returned
pointer value (from the debugger). It doesn’t make sense to me why you’d get
an address that you had to cast bits off of.

Also, the !analyze output is necessary to make any sense out of what’s
happening. If the pointer is valid in the application it should be valid in
the driver (assuming you’re in the correct context of course).

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

Looking forward to seeing you at the next OSR Kernel Debugging Class April
6, 2009 in Portland, OR!

wrote in message news:xxxxx@ntdev…
> Hi,
>
> not yet closed fully.
>
> I am now in second stage where i have to reuse the pointer second time.
>
> So now i am in stage, that i take the pointer, convert it to 32bit, this
> removes upper 32bits, goes up to application. Application can use it as
> pointer and it works.
>
> Now i pass this 32bit pointer again to 64bit driver and want to convert it
> to 64bit pointer. From what i understood in MSDN, that should be done
> automatically when i do something like this:
>
> VOID*POINTER_32 ptr32;
> VOID ptr64;
>
> ptr64 = ptr32;
>
> but the problem is, that when i look at value of ptr64, it is still
> 0x00000000xxxxxxxx; which causes BSOD in driver. Original 64bit pointer
> (before truncating to 32bit) looked like this 0xfffffa80xxxxxxxx.
>
> so i tried this hard hack:
>
> queue = (VOID
)((unsigned __int64)io32->ptr |
> 0xfffffa8000000000);
>
> and it works.
>
> So can anybody please tell me how can i without hard hacking convert
> pointer variable inside IOCTL structure (that is important because they
> are not converted as whole structure is simply memcopied) to 64bit
> pointer?
>
> Thanks again!!
>
>

This statement, and your others regarding 32 versus 64 bit addresses, concern me. I think you might not fully understand some of the details that are going on with regard to driver access to user-mode memory.

(a) When you call MmMapLockedPages[SpecifyCache] and indicate UserMode, the address you’ll get back will be an address in user virtual address space. If the calling application is a 32-bit application, the address returned will be in the low 2GB of virtual address space, meaning the address you’re returned will be all zeros in the top 32-bits. So the “conversion” is just really a truncation.

(b) This returned user virtual address will, in fact, also be a valid kernel virtual address and can be used (only) IN THE CONTEXT OF THE PROCESS into which you’ve mapped the buffer.

(c) If you want to access the buffer in an arbitrary process context, you need to be sure you have the buffer mapped into the “system” part (high half) of the kernel virtual address space. Given an arbitrary buffer described by an MDL, you’d do this using MmGetSystemAddressForMdl[Safe]. If you’re still using a block of non-paged pool (security bug) then you already HAVE a kernel virtual address that’s usable in an arbitrary process context.

Does that help any?

Peter
OSR

Yes, because you truncated the pointer to 32 bits. Any pointer given to you by a 32-bit process will only have 32 significant bits.

You’re not letting the app pass you a *kernel mode* pointer that you have an intention to trust, right?

Because that would be a broken design if so.

  • S

-----Original Message-----
From: xxxxx@xpwn.net
Sent: Thursday, February 26, 2009 01:56
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Shared memory between 64bit Driver / 32bit App

Hi,

not yet closed fully.

I am now in second stage where i have to reuse the pointer second time.

So now i am in stage, that i take the pointer, convert it to 32bit, this removes upper 32bits, goes up to application. Application can use it as pointer and it works.

Now i pass this 32bit pointer again to 64bit driver and want to convert it to 64bit pointer. From what i understood in MSDN, that should be done automatically when i do something like this:

VOID*POINTER_32 ptr32;
VOID ptr64;

ptr64 = ptr32;

but the problem is, that when i look at value of ptr64, it is still 0x00000000xxxxxxxx; which causes BSOD in driver. Original 64bit pointer (before truncating to 32bit) looked like this 0xfffffa80xxxxxxxx.

so i tried this hard hack:

queue = (VOID
)((unsigned __int64)io32->ptr | 0xfffffa8000000000);

and it works.

So can anybody please tell me how can i without hard hacking convert pointer variable inside IOCTL structure (that is important because they are not converted as whole structure is simply memcopied) to 64bit pointer?

Thanks again!!


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer