1. Joao Ribeiro
  2. PowerBuilder
  3. Friday, 25 January 2019

Hi everybody,

 

We use some functions from Kernel32.dll to get a DLL version number. This have been always working until PB 12.5.2. But PB2017 R3 crashes when we call HeapFree fuction.

EXTERNAL FUNCTIONS CALLED:

Function long GetFileVersionInfoSize(string sFile, REF ulong uDummy) library "VERSION.DLL" alias for "GetFileVersionInfoSizeW"
Function long GetFileVersionInfo(REF string sFile, ulong uDummy, ulong uLen, ulong uPoint) LIBRARY "version.dll" alias for "GetFileVersionInfoW"
Function ulong VerQueryValue(ulong uPoint, string sValue, REF ulong uPoint, REF ulong uLen) library "VERSION.DLL" alias for "VerQueryValueW"
Subroutine CopyMemory(REF string sbytes, ulong lpbytes, ulong uLen) library "KERNEL32.DLL" ALIAS FOR "RtlMoveMemory" 
Function ulong GetProcessHeap() Library "KERNEL32.DLL"
Function ulong HeapAlloc (ulong hMem, uint uFlags, ulong uBytes) Library "KERNEL32.DLL"
Function long HeapFree (ulong hMem, uint uFlags, ulong uMemPoint) Library "KERNEL32.DLL"
Function ulong strcpy (REF string lpString1, ulong lpString2) Library "KERNEL32.DLL" alias for "lstrcpyW"

 

OUR FUNCTION:

public function integer of_product_version (string p_product_name, ref string p_version_number);

string vlsQuery, vlsLangcodepage, vlsBytes = space(62556) 
ulong vllDummy, vllSize, vllHMem, vllLpInfo, vllLpPoint, vllLen 
long vllRet 

vllSize = GetFileVersionInfoSize(p_product_name, vllDummy)
IF vllSize <= 0 THEN 
return //file not found
END IF 

// get process id
vllHMem = GetProcessHeap()

vllLpInfo = HeapAlloc(vllHMem, 0, vllSize)

//get pointer to product info
vllRet = GetFileVersionInfo(p_product_name, vllDummy, vllSize, vllLpInfo)
IF vllRet = 0 THEN 
return //some error
END IF 

vlsQuery = "\VarFileInfo\Translation" 
vllLen = VerQueryValue(vllLpInfo, vlsQuery, vllLpPoint, vllLen)

CopyMemory(vlsBytes, vllLpPoint, vllLen)

vlsQuery = "\StringFileInfo\040904E4\FileVersion"

vllRet = VerQueryValue(vllLpInfo, vlsQuery, vllLpPoint, vllLen)
if vllRet <= 0 then
p_version_number = ""
return //some error
end if

p_version_number = space(vllLen)
strcpy(p_version_number, vllLpPoint)

HeapFree(vllHMem, 0, vllLpPoint) // PB CRASHES HERE!!!!!!!

return 1

Any ideas?

 

Accepted Answer
Roland Smith Accepted Answer Pending Moderation
1
Votes
Undo
Comment
There are no comments made yet.
  1. Friday, 25 January 2019
  2. PowerBuilder
  3. # Permalink
Chris Pollach Accepted Answer Pending Moderation
0
Votes
Undo

Hi Roland;

  Would you recommend that wherever a uLong or Long variable is used in your PB Apps for external communication that we replace these with the LongPtr data type - to be both 32 & 64 bit complaint?

Regards ... Chris

Comment


LongPtr would be for any variable listed as a handle or pointer in the documentation.



I go by this:

https://docs.microsoft.com/en-us/windows/desktop/WinProg/windows-data-types



DWORD = A 32-bit unsigned integer. The range is 0 through 4294967295 decimal. This would be a ulong in PB.

INT = A 32-bit signed integer. The range is -2147483648 through 2147483647 decimal. This would be a long in PB.

UINT = An unsigned INT. The range is 0 through 4294967295 decimal. This would be a ulong in PB.
  1. Roland Smith
  2. Thursday, 7 February 2019
Yes, I was referring to the using the LongPtr data type in PB where any reference to a Handle is being used.

Thanks Roland (aka Mr C Plus Plus)! ;-)
  1. Chris Pollach
  2. Thursday, 7 February 2019
There are no comments made yet.
  1. Thursday, 7 February 2019
  2. PowerBuilder
  3. # 1
Joao Ribeiro Accepted Answer Pending Moderation
0
Votes
Undo

Hi, Roland, I used this solution with success!!

Thank you very much.

(but I'm gonna try your other tip)

Comment
There are no comments made yet.
  1. Thursday, 7 February 2019
  2. PowerBuilder
  3. # 2
Joao Ribeiro Accepted Answer Pending Moderation
0
Votes
Undo

Roland, I'm gonna try this. TIA

Comment
There are no comments made yet.
  1. Thursday, 7 February 2019
  2. PowerBuilder
  3. # 3
Joao Ribeiro Accepted Answer Pending Moderation
0
Votes
Undo

Tks, Chris, but doing that I got a problem with VerQueryValue parameters' types. So, I just used Roland's solution.

Tks again!

Comment
Glad that worked for you & thanks for that feedback Joao!
  1. Chris Pollach
  2. Thursday, 7 February 2019
There are no comments made yet.
  1. Thursday, 7 February 2019
  2. PowerBuilder
  3. # 4
Roland Smith Accepted Answer Pending Moderation
1
Votes
Undo

The definitions should be:

Function longptr GetProcessHeap() Library "kernel32.dll"

Function longptr HeapAlloc (longptr hHeap, ulong dwFlags, longptr dwBytes) Library "kernel32.dll"

Function boolean HeapFree (longptr hHeap, ulong dwFlags, longptr lpMem) Library "kernel32.dll"

 

HANDLE and SIZE_T in 32bit are long, not ulong. DWORD is ulong.

Using longptr now will allow you to compile to 64bit later.

Comment
Hi Roland;

Both uLong and Long are DWord. The only difference is that in the uLong, the high order bit is not used as a sign ( +ve / -ve), just number data. Since handle's are never negative uLong is technically the standard to use - but, long won't hurt as long as the value you pass is +ve. ;-)

Your point about using the new LongPtr data type introduced in PB 12.6 though is a great tip!

Regards ... Chris
  1. Chris Pollach
  2. Monday, 28 January 2019
The PowerBuilder function Handle returns a long so I've always tried to code handles as long. In 32bit it doesn't matter since you aren't doing any math on them, just passing them in and out of API functions. To make 32bit to 64bit seamless the longptr type works great.
  1. Roland Smith
  2. Monday, 28 January 2019
You are 100% correct ... it does not matter in the 32bit world but for 64bit Apps & O/S the LongPtr is the better choice from now on. Thanks again for the LongPtr tip Roland! :-)
  1. Chris Pollach
  2. Monday, 28 January 2019
There are no comments made yet.
  1. Friday, 25 January 2019
  2. PowerBuilder
  3. # 5
Chris Pollach Accepted Answer Pending Moderation
0
Votes
Undo

Hi Joao;

   Here is what I am using ....

FUNCTION Long   HeapAlloc (long hMem, uint uFlags, long uBytes) Library "KERNEL32.DLL"

FUNCTION Long   HeapFree (long hMem, uint uFlags, long uMemPoint) Library "KERNEL32.DLL"

HTH

Regards ... Chris

Comment
There are no comments made yet.
  1. Friday, 25 January 2019
  2. PowerBuilder
  3. # 6
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.