On 16 February 2014 23:37, Torsten Bergmann <asta...@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.