On 16 February 2014 23:37, Torsten Bergmann <astares@gmx.de> wrote:
Hi,

I'm trying to mimic the following C/C++ example in NativeBoots to allow random number
generation on windows:

�� https://gist.github.com/kbjorklu/6317361

When I combine the flags in Pharo using "|" in the same way like in the first function call
of the example:

acquireContextExample1
�� NBFFICallout stdcall: #(BOOL CryptAcquireContextA(HCRYPTPROV self, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) module: #advapi32

I get an error 'comma expected'. Looks like the NBFnSpecParser does not allow
expression evaluation like CRYPT_VERIFYCONTEXT | CRYPT_SILENT. Will this be possible
in future versions?

Nonetheless I tried to continue and since I defined:
�� ��CRYPT_VERIFYCONTEXT := 16rF0000000.
�� ��CRYPT_SILENT := 16r00000040.

I evaluated manually and tried to use the harcoded value directly:

acquireContextExample2

�� �� �� �� "Retrieves information about the current console font."
�� �� �� �� ��<primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'>

�� �� �� �� ^ NBFFICallout stdcall: #(BOOL CryptAcquireContextA(HCRYPTPROV self, 0, 0, PROV_RSA_FULL, 16rF0000040)) module: #advapi32


but this returns another error when converting using #asDWord:

�� (16rF0000040 i4) exceeds doubleword (32bit) range

in an AJImmediate but 16rF0000040. Looks like it is treated as unsiged since

�� �� 16rF0000040 asUImm32 asDWord

works. How to specifiy the number directly but as unsigned?

To reproduce:
��- take a fresh Pharo3.0 Latest update: #30759
��- load "OSWindows" from config browser to get the core and other packages
��- load "OS-Windows-Cryptography" package/mcz from smalltalkhub.com/#!/~OS/OS-Windows
��- evaluate WinCryptoProvider new acquireContextExample2 or WinCryptoProvider new acquireContextExample1

Any helping hand in converting the example would be appreciated.

Thx
T.

Yes, i am aware of this problem.

(16rF0000040 i4) exceeds doubleword (32bit) range

i4�� means signed integer 4 bytes..
the mantissa 16rF0000040 , simply don't fits, because it is > 2^31-1, which is max for 32-bit integer.

The class responsible for passing constants is NBFFIConst:

Integer>>asNBExternalType: gen
������ "integer value in callout argument description array are pushed directly on stack
������
������ #( 100 )�� - an integer value argument = 100
������ "
������ ^ NBFFIConst value: (self )

the code generator, uses:

emitPush: gen

������ gen asm push: ((gen asm imm: value) size: 4)


and #imm: sends #asImm to the value, which by default turns integer into a signed immediate:

Integer>>asImm

������ "Convert integer value into a signed immediate operand"
������ ^ AJImmediate new ivalue: self

unfortunately, there is no easy way to work around this: if you change it to unsigned (uvalue:),
then you have another problem, but now with all negative integer constants (like -1).

But you can work that around: use a 32-bit complement
of unsigned 16rF0000040
to signed one, which ends up with identical 32-bit value:

16rF0000040 - 16r100000000�� =>�� -268435392
test:
(16r100000000 - 268435392) hex '16rF0000040'��

--
Best regards,
Igor Stasenko.