Solved

Writing structs for interoperability between x86 application and x64 driver

Posted on 2014-01-24
5
507 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
  • 3
  • 2
5 Comments
 
LVL 32

Expert Comment

by:sarabande
Comment Utility
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
Comment Utility
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 32

Accepted Solution

by:
sarabande earned 500 total points
Comment Utility
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
Comment Utility
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 32

Expert Comment

by:sarabande
Comment Utility
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Storage devices are generally used to save the data or sometime transfer the data from one computer system to another system. However, sometimes user accidentally erased their important data from the Storage devices. Users have to know how data reco…
Possible fixes for Windows 7 and Windows Server 2008 updating problem. Solutions mentioned are from Microsoft themselves. I started a case with them from our Microsoft Silver Partner option to open a case and get direct support from Microsoft. If s…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…

772 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now