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.