1. Joao Ribeiro
  2. PowerBuilder
  3. Friday, 25 January 2019 16:03 PM UTC

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. Friday, 25 January 2019 19:33 PM UTC
  2. PowerBuilder
  3. # Permalink
Comment
  1. Kari Paukku
  2. Saturday, 22 January 2022 08:04 AM UTC
Roland,

thanks for the code - it worked fine and is a neat solution.

But as always, there is a but - is there a way how to get the dates (e.g. created date) from the GetFileVersionInfo?



Thanks,

Kari
  1. Helpful
  1. Roland Smith
  2. Saturday, 22 January 2022 16:24 PM UTC
My Filesys example has of_GetCreationTime and of_GetLastWriteTime functions among others.



https://www.topwizprogramming.com/freecode_filesys.html
  1. Helpful 1
  1. Kari Paukku
  2. Monday, 24 January 2022 15:35 PM UTC
thanks, that did the trick.
  1. Helpful
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Friday, 25 January 2019 19:27 PM UTC
  2. PowerBuilder
  3. # 1

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.
Roland Smith Accepted Answer Pending Moderation
  1. Friday, 25 January 2019 19:41 PM UTC
  2. PowerBuilder
  3. # 2

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
  1. Roland Smith
  2. Monday, 24 January 2022 17:17 PM UTC
No, handles and pointers are signed.
  1. Helpful 1
  1. Miguel Leeuwe
  2. Monday, 24 January 2022 17:27 PM UTC
Thanks Roland!
  1. Helpful
  1. Miguel Leeuwe
  2. Monday, 24 January 2022 18:18 PM UTC
Roland, I understand what you say as far as external function calls go, but I was thinking of a more generic use of the variable type, thinking of 32 vs. 64 bit execution. This guy also had the same question and has managed to record it as an enhancement request. https://www.appeon.com/standardsupport/search/view?id=3377

regards
  1. Helpful
There are no comments made yet.
Joao Ribeiro Accepted Answer Pending Moderation
  1. Thursday, 7 February 2019 19:42 PM UTC
  2. PowerBuilder
  3. # 3

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

Tks again!

Comment
  1. Chris Pollach @Appeon
  2. Thursday, 7 February 2019 20:33 PM UTC
Glad that worked for you & thanks for that feedback Joao!
  1. Helpful
There are no comments made yet.
Joao Ribeiro Accepted Answer Pending Moderation
  1. Thursday, 7 February 2019 19:44 PM UTC
  2. PowerBuilder
  3. # 4

Roland, I'm gonna try this. TIA

Comment
There are no comments made yet.
Joao Ribeiro Accepted Answer Pending Moderation
  1. Thursday, 7 February 2019 19:47 PM UTC
  2. PowerBuilder
  3. # 5

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.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Thursday, 7 February 2019 20:48 PM UTC
  2. PowerBuilder
  3. # 6

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
  1. Roland Smith
  2. Thursday, 7 February 2019 21:39 PM UTC


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. Helpful
  1. Chris Pollach @Appeon
  2. Thursday, 7 February 2019 22:02 PM UTC
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. Helpful
There are no comments made yet.
  • Page :
  • 1


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