Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Writing structs for interoperability between x86 application and x64 driver

Posted on 2014-01-24
5
Medium Priority
?
565 Views
Last Modified: 2014-01-27
I am having trouble finding documentation that is clear about the proper method of organizing/defining structures that are used in a x86 application and passed to a x64 kernel driver.

I am thinking if the struct has members of various byte sizes we need to account for unused bytes in the application with place holders when in the x86 application?  The kernel would then have a different define of the struct without the place holders.  My main concern is pointers.  I do not think I can redefine them to work in x86 app and the x64 kernel.

How about an example and anyone can tell me if I am on the right track or if I need a redirect.

For the User side code in x86 compile
typedef struct EXAMPLE_STRUCT_32B
{
     DWORD dwPlaceholder;  //4 bytes in x86 and x64
     PVOID phwHandle;          //4 bytes in x86, 8 bytes in x64
     DWORD dwAddress;        //4 bytes in x86 and x64
     WORD wFlag;                   //2 bytes in x86 and x64
     WORD wLock;                  //2 bytes in x86 and x64
     UINT64 unData;               //8 bytes in x86 and x64
}

Open in new window


For kernel side in x64 compile
typedef struct EXAMPLE_STRUCT
{
     PVOID phwHandle;          //8 bytes in x64
     DWORD dwAddress;        //4 bytes in x64
     WORD wFlag;                   //2 bytes in x64
     WORD wLock;                  //2 bytes in x64
     UINT64 unData;               //8 bytes in x64
}

Open in new window


Another question: what is the proper way to order members?  Is it large to small grouped in 8 byte boundaries if possible?  Thanks for your help.
0
Comment
Question by:efryevt
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 35

Expert Comment

by:sarabande
ID: 39812324
some remarks to your question:

an x86 compile or x64 compile is determined by the compiler and not by the platform you were developing on. so you may develop 64-bit programs on a 32-bit platform and vice versa if you were using the appropriate compiler.

the integer types also can be used arbitrary. it is right, that a 64-bit compiler needs a 64-bit for pointers but many 32-bit compiler also were doing so. if you want to go sure that members have the same size in source and target platform simply use the fixed-size types like INT32 or UINT64 (which may have different names depending on  the platform but easily can be typedef'd to same name). if you need to pass structures between platforms, you rarely can pass pointers because pointers were only valid where they were created. if you want to pass pointers as handles for the callback, you should use a UINT64 buffer or INTPTR or similar helper type of sufficient size for both.

for structure size and alignment you could sort the members by size, first 64-bit, then 32-bit, then 16-bit and finally bytes. for arrays only have array sizes such that the total size of the array is  dividable by 8. that would solve the most alignment issues, but to make it sure you should use the option "packed" or 1-byte-alignment at both sides.

Sara
0
 

Author Comment

by:efryevt
ID: 39812402
I do realize the compiler determines if an application is x86 or x64.  I am compiling on a x64 platform, but I have an x64 kernel driver and an x86 application that needs to communicate through this driver to hardware.  All of this will be on the x64 platform.  

When I first open the driver I have to pass a structure that does contain pointers.  This is where all my issues are arising.  I am trying to create a same size structure in the x64 kernel to copy the x86 passed struct to.  I have not found much documentation on how to go about this.  Unfortunately I am not able to compile the application as an x64 for reasons that are beyond my control at this time.  

I keep thinking if I can adjust the application side struct to match byte for byte, I could do a memcpy in the kernel driver.  But without any documentation, I am not sure this is the best method.
0
 
LVL 35

Accepted Solution

by:
sarabande earned 2000 total points
ID: 39812764
an x86 application that needs to communicate through this driver to hardware.
the WOW64 (windows on windows) allows to call from 32-bit to 64-bit driver via DeviceIoControl.

see: http://msdn.microsoft.com/en-us/library/windows/hardware/ff563897(v=vs.85).aspx

you also can pass a pointer to a structure which was converted to a 64-bit pointer. however, the pointer members of your structure are not converted.

When I first open the driver I have to pass a structure that does contain pointers
you may use pointer-precision types like UINT_PTR.

see http://msdn.microsoft.com/en-us/library/windows/desktop/aa384264(v=vs.85).aspx

for detail.

I keep thinking if I can adjust the application side struct to match byte for byte, I could do a memcpy in the kernel driver.
if you only use the fixed size types, the structure has the same size for both 32-bit and 64-bit.

Sara
0
 

Author Comment

by:efryevt
ID: 39813286
I think my situation if further complicated by the fact that the structure I pass to kernel has pointers which point to structs with pointers and so on for a few levels.  Unfortunately, I inherited the code and I am trying to avoid a complete rewrite.

I had seen some of the documents you link, but your explanations did help me understand better.  Thank you very much for your help.
0
 
LVL 35

Expert Comment

by:sarabande
ID: 39814252
the structure I pass to kernel has pointers which point to structs with pointers and so on for a few levels.
you should consider to create a new structure which replaces pointers by the value type the pointer is pointing to or by fixed sized arrays of sub structures if the pointer was pointing to an array. you can avoid rewriting your current code if you do the conversion from current structure to new fixed-sized structure just before the final call to the driver.

Sara
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article helps those who get the 0xc004d307 error when trying to rearm (reset the license) Office 2013 in a Virtual Desktop Infrastructure (VDI) and/or those trying to prep the master image for Microsoft Key Management (KMS) activation. (i.e.- C…
When asking a question in a forum or creating documentation, screenshots are vital tools that can convey a lot more information and save you and your reader a lot of time
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question