Recent

Author Topic: [Solved] 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)  (Read 1415 times)

Peter H

  • Full Member
  • ***
  • Posts: 197
This compiles in 32 Bit, but not in 64 Bit.
Must I declare "MessageRes" as Windows.DWORD_PTR or must I pass "MessageRes" as "@MessageRes"? Both compiles in 64 Bit.
I use FPC331 (Trunk) on Windows 64 Bit.
How must I test "CompilerVersion" to get this reliably going in FPC 3.3.1 64 Bit and 32 Bit?
The code snippet is taken from a Sourceforge project "path manager" that was last updated in 2013.
https://sourceforge.net/projects/pathtool/
There is a 32 bit binary exe included that works without problems, but I want to add functionality (automatic Backup of environment variables before and after)

The $IF, $IFDEF conditions marked with "// -> No" are not active, I indented them for clarity, for these the $ELSE branch is active.

Code: Pascal  [Select][+][-]
  1. procedure EnvInformation.RefreshEnvironment(const Timeout: Cardinal = 5000);
  2. var
  3.   {$IFDEF CONDITIONALEXPRESSIONS}   //->No
  4.           {$IF CompilerVersion >= 23.0} // Delphi XE2
  5.           MessageRes: Windows.DWORD_PTR;
  6.           {$ELSE}
  7.           MessageRes: Windows.DWORD;
  8.           {$IFEND}
  9.   {$ELSE}
  10.   MessageRes: Windows.DWORD;
  11.   {$ENDIF}
  12. begin
  13.   Windows.SendMessageTimeout(
  14.     Windows.HWND_BROADCAST,
  15.     Messages.WM_SETTINGCHANGE,
  16.     0,
  17.     LPARAM(PChar('Environment')),
  18.     Windows.SMTO_ABORTIFHUNG, Timeout,
  19.     {$IFDEF CONDITIONALEXPRESSIONS}  //->No
  20.             {$IF CompilerVersion >= 23.0} // Delphi XE2    //-No
  21.             @MessageRes
  22.             {$ELSE}
  23.             MessageRes
  24.             {$IFEND}
  25.     {$ELSE}
  26.     MessageRes    // -> Compiles in 32 Bit, but not in 64 Bit
  27.     {$ENDIF}
  28.   );
  29. end;
  30.  
« Last Edit: January 21, 2021, 08:08:34 pm by Peter H »

MarkMLl

  • Hero Member
  • *****
  • Posts: 2428
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #1 on: January 21, 2021, 01:46:26 pm »
I don't like opining on a Windows topic, but what exactly is your error message and have you tried either PtrInt or PtrUint as the type?

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Peter H

  • Full Member
  • ***
  • Posts: 197
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #2 on: January 21, 2021, 01:54:27 pm »
I tried this:
 MessageRes: Windows.DWORD_PTR;
and - alternatively -  this
 @MessageRes

Both compiles in 64 Bit

Then I destroyed my environment variables  :-[
I am unsure about the reason: Is this a typical 32/64 Bit problem or shouldnt I write to environment variables while in debugger?  ;D
The error Messages in 64 Bit compilation:
Code: Pascal  [Select][+][-]
  1. Compile Project, Target: PathManager.exe: Exit code 1, Errors: 1, Warnings: 1, Hints: 4
  2. regunit.pas(254,62) Warning: Function result variable of a managed type does not seem to be initialized
  3. regunit.pas(299,21) Hint: Function result variable of a managed type does not seem to be initialized
  4. regunit.pas(342,5) Hint: Conversion between ordinals and pointers is not portable
  5. regunit.pas(353,3) Error: Call by var for arg no. 7 has to match exactly: Got "LongWord" expected "QWord"
  6. redef.inc(832,10) Hint: Found declaration: SendMessageTimeout(QWord;LongWord;Int64;Int64;LongWord;LongWord;var QWord):Int64;
  7. ascdef.inc(184,10) Hint: Found declaration: SendMessageTimeout(QWord;LongWord;Int64;Int64;LongWord;LongWord;PDWORD_PTR):Int64;
  8.  
« Last Edit: January 21, 2021, 02:03:02 pm by Peter H »

MarkMLl

  • Hero Member
  • *****
  • Posts: 2428
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #3 on: January 21, 2021, 02:01:31 pm »
You said you had something that didn't compile in 64 bit. Post the code that didn't compile and the error message, then find the declaration of the function that's failing.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Peter H

  • Full Member
  • ***
  • Posts: 197
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #4 on: January 21, 2021, 02:06:12 pm »
The error is where I marked it in the source above at line 26.

This is argument no. 7 as indicated in the error message.
There is no other error, apart from this the unmodified project compiles in 64 bit.

I attached the unmodified Sourceforge project.
If you or somebody tries it, build or compile in 64 bit, but dont run it and save the environment variables unless you are in a throw away virtual machine!
If you want a working Pathmanager, the 32 bit exe from sourceforge is save and comfortable to use so far I found much more features than the windows pathmanager.
« Last Edit: January 21, 2021, 02:34:12 pm by Peter H »

PascalDragon

  • Hero Member
  • *****
  • Posts: 2918
  • Compiler Developer
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #5 on: January 21, 2021, 02:22:24 pm »
SendMessageTimeout is declared by FPC as follows which matches the declaration in MSDN:

Code: Pascal  [Select][+][-]
  1. function SendMessageTimeout(hWnd:HWND; Msg:UINT; wParam:WPARAM; lParam:LPARAM; fuFlags:UINT;uTimeout:UINT; lpdwResult:PDWORD_PTR):LRESULT; external 'user32' name 'SendMessageTimeoutA';

Thus you need to pass a pointer to MessageRes which should be declared as DWORD_PTR.

For simplicity you can rework the code like this:

Code: Pascal  [Select][+][-]
  1. procedure EnvInformation.RefreshEnvironment(const Timeout: Cardinal = 5000);
  2. {$IFDEF FPC}
  3.   {$DEFINE USE_DWORD_PTR}
  4. {$ELSE}
  5.   {$IFDEF CONDITIONALEXPRESSIONS}   //->No
  6.     {$IF CompilerVersion >= 23.0} // Delphi XE2
  7.        {$DEFINE USE_DWORD_PTR}
  8.     {$IFEND}
  9.   {$ENDIF}
  10. {$ENDIF}
  11. var
  12.   {$IF USE_DWORD_PTR}
  13.   MessageRes: Windows.DWORD_PTR;
  14.   {$ELSE}
  15.   MessageRes: Windows.DWORD;
  16.   {$ENDIF}
  17. begin
  18.   Windows.SendMessageTimeout(
  19.     Windows.HWND_BROADCAST,
  20.     Messages.WM_SETTINGCHANGE,
  21.     0,
  22.     LPARAM(PChar('Environment')),
  23.     Windows.SMTO_ABORTIFHUNG, Timeout,
  24.     {$IFDEF USE_DWORD_PTR}
  25.     @MessageRes
  26.     {$ELSE}
  27.     MessageRes
  28.     {$ENDIF}
  29.   );
  30. {$IFDEF USE_DWORD_PTR}
  31. {$UNDEFINE USE_DWORD_PTR}
  32. {$ENDIF}
  33. end;

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 9235
  • FPC developer.
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #6 on: January 21, 2021, 02:38:06 pm »
Without the pointer will also work, because there is an overload in redef. But in general we recommend using the pointer values.

COMPILER_VERSION is a Delphi define, it has no meaning in Free Pascal. Testing for Free Pascal is done with

Code: Pascal  [Select][+][-]
  1. {$ifdef FPC}
  2. // this is FPC
  3. {$else}
  4.   // legacy Object Pascal compilers (Delphi)
  5. {$endif}

In general, there are not as much FPC versions in circulation so the number of version tests will be much less.

Peter H

  • Full Member
  • ***
  • Posts: 197
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #7 on: January 21, 2021, 02:43:51 pm »
Thus you need to pass a pointer to MessageRes which should be declared as DWORD_PTR.

Thank you!
Is this supposed to work in a 32 bit compilation too?

I will try it, however first I must find a secure way to test it, currently I have no virtual machine, I must set up one.
Last time I destroyed my path variables then I tried to go to a recovery point, but windows said "There is none".  :'(
« Last Edit: January 21, 2021, 02:45:47 pm by Peter H »

MarkMLl

  • Hero Member
  • *****
  • Posts: 2428
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #8 on: January 21, 2021, 02:48:29 pm »
I agree that  Got "LongWord" expected "QWord"  isn't exactly helpful, but happily defer to the others for the correct fix.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Peter H

  • Full Member
  • ***
  • Posts: 197
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #9 on: January 21, 2021, 02:54:50 pm »
I agree that  Got "LongWord" expected "QWord"  isn't exactly helpful, but happily defer to the others for the correct fix.

I can find and fix the problem by trial and eror and studying the sources and docs on my own. The problem in this case is, simply trying is risky without parachute, so I preferred to ask more experienced people.
Thank you all so far.

BTW. I have studyed this project a little bit and the purpose of this routine is to notify other windows or processes about the changed environment, so probably this is not the reason why I destroyed my User and System path variables.
« Last Edit: January 21, 2021, 03:10:34 pm by Peter H »

ASerge

  • Hero Member
  • *****
  • Posts: 1772
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #10 on: January 21, 2021, 05:52:35 pm »
This compiles in 32 Bit, but not in 64 Bit.
Must I declare "MessageRes" as Windows.DWORD_PTR or must I pass "MessageRes" as "@MessageRes"? Both compiles in 64 Bit.
...
You're making this too complicated for nothing. Throw out all IFDEFS altogether.
Such code compiles correctly in both FPC and Delphi in both 32-bit and 64-bit mode:
Code: Pascal  [Select][+][-]
  1. procedure RefreshEnvironment(const Timeout: Cardinal = 5000);
  2. var
  3.   MessageRes: DWORD_PTR;
  4. begin
  5.   SendMessageTimeout(
  6.     HWND_BROADCAST,
  7.     WM_SETTINGCHANGE,
  8.     0,
  9.     LPARAM(PChar('Environment')),
  10.     SMTO_ABORTIFHUNG,
  11.     Timeout,
  12.     @MessageRes
  13.   );
  14. end;

Peter H

  • Full Member
  • ***
  • Posts: 197
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #11 on: January 21, 2021, 06:07:30 pm »
This makes me think.

If c is of type char then "@c" will compile as well as "@MessageRes", because "@" generates an equivalent to a void * .

I already had versions that compiled.
The question is, if it will work.
However the content of "MessageRes" is not used, so if the size of the variable is correct or larger than required it should work.

« Last Edit: January 21, 2021, 06:46:02 pm by Peter H »

ASerge

  • Hero Member
  • *****
  • Posts: 1772
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #12 on: January 21, 2021, 06:19:06 pm »
However the content of "MessageRes" is not used, so if the size of the variable is correct or larger than required it should work.
No "or large" ones. The size of the variable which address is passed to the function is what the function expects. In 32-bit mode, it is 32-bit, in 64-bit - 64-bit.

Peter H

  • Full Member
  • ***
  • Posts: 197
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #13 on: January 21, 2021, 06:29:05 pm »
No. the result of the call will be stored at the location where Arg7 aka MessageRes points to.
The size of the result is determined by windows, probably it is Quadword in Win64,
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessagetimeouta

lpdwResult
Type: PDWORD_PTR
The result of the message processing. The value of this parameter depends on the message that is specified.


Therefore Arg7 must be a valid pointer that points to large enough memory
« Last Edit: January 21, 2021, 06:38:52 pm by Peter H »

ASerge

  • Hero Member
  • *****
  • Posts: 1772
Re: 32 Bit vs 64 Bit Question (Compiling "Path Manager" project)
« Reply #14 on: January 21, 2021, 06:38:00 pm »
No...
I don't understand you. You said the same thing I did, why "no"?

 

TinyPortal © 2005-2018