Solved SalDlgOpenFileStd

Discussion forum about all things Team Developer 7.x
huemerjo
Austria
Posts: 9
Joined: 28 Aug 2017, 10:26
Location: Linz / Austria

SalDlgOpenFileStd

Post by huemerjo » 01 Jun 2018, 06:35

hello,

has anyone already a working X64 version for the Salextension 'SalDlgOpenFileStd' or GetOpenFileNameW of COMDLG32.dll ?
Last edited by huemerjo on 02 Jun 2018, 04:42, edited 1 time in total.

Dave Rabelink
Founder/Site Admin
Founder/Site Admin
Netherlands
Posts: 691
Joined: 24 Feb 2017, 09:12
Location: Gouda, The Netherlands

SalDlgOpenFileStd

Post by Dave Rabelink » 01 Jun 2018, 09:04

No, not yet. But I quickly tried...

I tried changing the function for x64, which is mainly a different struct size due to 4 vs 8 bytes for pointers/handles.

But it fails on every structsize I tried.

Using CommDlgExtendedError you can get the error code. IN all cases I get

Code: Select all

CDERR_STRUCTSIZE
0x0001 
The lStructSize member of the initialization structure for the corresponding common dialog box is invalid.
 
So, if someone has this working, would be great.

The structsize I calculated to be is 140 bytes.

Based on the total bytes calculated from the list of parameter types for the struct:

Code: Select all

DWORD         4
HWND          8
HINSTANCE     8
LPCTSTR       8
LPTSTR        8
DWORD         4
DWORD         4
LPTSTR        8
DWORD         4
LPTSTR        8
DWORD         4
LPCTSTR       8
LPCTSTR       8
DWORD         4
WORD          2
WORD          2
LPCTSTR       8
LPARAM        8
LPOFNHOOKPROC 8
LPCTSTR       8
void          8
DWORD         4
DWORD         4
Regards,
Dave Rabelink

Image
Articles and information on Team Developer Tips & Tricks Wiki
Download samples, documents and resources from TD Sample Vault
Videos on TDWiki YouTube Channel

huemerjo
Austria
Posts: 9
Joined: 28 Aug 2017, 10:26
Location: Linz / Austria

SalDlgOpenFileStd

Post by huemerjo » 04 Jun 2018, 12:37

i found some info on the web
lStructSize should be 152 for x64

Dave Rabelink
Founder/Site Admin
Founder/Site Admin
Netherlands
Posts: 691
Joined: 24 Feb 2017, 09:12
Location: Gouda, The Netherlands

SalDlgOpenFileStd

Post by Dave Rabelink » 05 Jun 2018, 10:10

huemerjo wrote:
04 Jun 2018, 12:37
i found some info on the web
lStructSize should be 152 for x64
Yes. The size on x64 should be 152.

But I'm very confused now.

have a look at this webpage which actually gives the structure offsets:

https://knowledgebase.progress.com/arti ... /000055761

Have a look at the MSDN description for the structure:

https://msdn.microsoft.com/en-us/librar ... s.85).aspx

Focus on the first element, the size of the structure. This is defined as:

Code: Select all

DWORD         lStructSize;
So, it is a DWORD.

Have a look at the structure offsets described on the website:

Code: Select all

&IF PROCESS-ARCHITECTURE EQ 32 &THEN
/* size */              PUT-LONG (lpOfn, 1) = GET-SIZE(lpOfn).
/* hwndOwner */         PUT-LONG (lpOfn, 5) = QCurrentHWND.
...

&ELSEIF PROCESS-ARCHITECTURE EQ 64 &THEN
/* lStructSize */       PUT-LONG (lpOfn, 1) = GET-SIZE(lpOfn).
/* hwndOwner */         PUT-LONG (lpOfn, 9) = QCurrentHWND.
...
The offsets are one based in the description above, in TD we use 0 based offsets. So just subtract one from the offset to have the TD offset.

What makes me confused is that on 32 bit, the first element (DWORD) is 4 bytes (=32bit). It has a rage of 0..3
But on 64 bit, a DWORD seems to have a size of 8 bytes (=64bit). It has a range of 0..7.

To my knowledge, in WinAPI on x64 systems a DWORD is 32 bit and not 64bit.

Am I wrong here?
Regards,
Dave Rabelink

Image
Articles and information on Team Developer Tips & Tricks Wiki
Download samples, documents and resources from TD Sample Vault
Videos on TDWiki YouTube Channel

Dave Rabelink
Founder/Site Admin
Founder/Site Admin
Netherlands
Posts: 691
Joined: 24 Feb 2017, 09:12
Location: Gouda, The Netherlands

SalDlgOpenFileStd

Post by Dave Rabelink » 05 Jun 2018, 13:43

Yes. Found it.

WinAPI x64 structures require that pointers and handles need to be aligned at 8 byte boundaries.
This means that within a structure, a pointer/handle member must be at offsets 0, 8, 16, 24...

Looking at the beginning of OPENFILENAME structure

https://msdn.microsoft.com/en-us/librar ... s.85).aspx

Code: Select all

DWORD		lStructSize;
HWND		hwndOwner;
HINSTANCE	hInstance;
LPCTSTR		lpstrFilter;

etc etc
A DWORD is indeed 32 bits wide (4 bytes).

This makes this list of sizes and offsets:

Code: Select all

TYPE		NAME		BYTES	OFFSET
DWORD		lStructSize;	4	0
HWND		hwndOwner;	8	4
HINSTANCE	hInstance;	8	12
LPCTSTR		lpstrFilter;	8	20
The second member, hwndOwner, is a handle. This means it must be on a 8 byte boundary.
But in this case, the offset will be at position 4, which is not a 8 byte boundary.

In such situations you need to have a FILLER value (internal padding). Between the first and second member to force the second member to be at offset 8.

In TD, when defining structures in external functions, the members are sequentially aligned, from top to bottom.
So, to force a FILLER, you have to define an extra member at the correct location having the correct filler size.
In this particular case, we need to add a 4 byte member between the first and second member, like this:

Code: Select all

TYPE		NAME		BYTES	OFFSET
DWORD		lStructSize;	4	0
DWORD		FILLER		4	4
HWND		hwndOwner;	8	8
HINSTANCE	hInstance;	8	16
LPCTSTR		lpstrFilter;	8	24
When calling the external function, you need to pass in the extra parameter. Value is not important, but it is best to use zero's (0).


The OPENFILENAME structure has other members which need to be aligned to 8 byte boundaries.

The complete structure having all the needed FILLERS is displayed below:

StructureAlignment.png


So, having the correct structure I changed the SalDlgOpenFileStd function.
During testing I found that this function from SalExtension is not working at all on UNICODE TD versions. I had to change more code to get it completely working.

So, in the end I created two versions of the function. A x86 UNICODE version (TD51 and up) and a x64 UNICODE version (TD70 and up).

I quickly tested it so maybe there could be some other issues.

You can download the archive here:

SalDlgOpenFileStd_UNICODE_x86_x64.zip


For more detailed info on data structure padding see:

https://en.wikipedia.org/wiki/Data_structure_alignment
You do not have the required permissions to view the files attached to this post.
Regards,
Dave Rabelink

Image
Articles and information on Team Developer Tips & Tricks Wiki
Download samples, documents and resources from TD Sample Vault
Videos on TDWiki YouTube Channel

Return to “General Discussion”

Who is online

Users browsing this forum: No registered users and 1 guest