Professional Web Applications Themes

help with Win32API - Ruby

I'm trying to do the equivalent of this C code: long getrand() { HCRYPTPROV hProv = 0; CryptAcquireContext(&hProv, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); long rnd; CryptGenRandom(hProv, sizeof(rnd), (BYTE*)&rnd); CryptReleaseContext(hProv, 0); return rnd; } Eexcept that I want to generate 16 bytes of random numbers. Here's my stab so far: require 'Win32API' cac = Win32API.new("advapi32", "CryptAcquireContext", ['P','L','L','I','I'], 'N') cgr = Win32API.new("advapi32", "CryptGenRandom", ['P','I','P'], 'N') hProv = " " * 16 cac.call(hProv, 0, 0, 1, 251658240) guid = " " * 16 cgr.call(hProv, 16, guid) p guid From wincrypt.h: #define PROV_RSA_FULL 1 #define CRYPT_VERIFYCONTEXT 0xF0000000 BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE ...

  1. #1

    Default help with Win32API

    I'm trying to do the equivalent of this C code:

    long getrand()
    {
    HCRYPTPROV hProv = 0;
    CryptAcquireContext(&hProv,
    0, 0, PROV_RSA_FULL,
    CRYPT_VERIFYCONTEXT);
    long rnd;
    CryptGenRandom(hProv,
    sizeof(rnd), (BYTE*)&rnd);
    CryptReleaseContext(hProv, 0);
    return rnd;
    }

    Eexcept that I want to generate 16 bytes of random numbers. Here's my
    stab so far:

    require 'Win32API'
    cac = Win32API.new("advapi32", "CryptAcquireContext",
    ['P','L','L','I','I'], 'N')
    cgr = Win32API.new("advapi32", "CryptGenRandom", ['P','I','P'], 'N')
    hProv = " " * 16
    cac.call(hProv, 0, 0, 1, 251658240)
    guid = " " * 16
    cgr.call(hProv, 16, guid)
    p guid

    From wincrypt.h:

    #define PROV_RSA_FULL 1
    #define CRYPT_VERIFYCONTEXT 0xF0000000

    BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer);

    BOOL WINAPI CryptAcquireContext(HCRYPTPROV *phProv, LPCSTR pszContainer,
    LPCSTR pszProvider, DWORD dwProvType,
    DWORD dwFlags);


    No segfaults, but the output comes up still empty. Any pointer where I
    did wrong? Sigh, I'm so terrible when it comes to C.

    --
    dave



    David Guest

  2. #2

    Default Re: help with Win32API

    Without checking in detail, it seems you are on the right track.
    You just need to use unpack() on your guid to turn the string into fixnums or
    whatever you want, like:

    x = guid.unpack('c*')
    # assuming all is one byte data

    GGarramuno Guest

  3. #3

    Default Re: help with Win32API

    David Garamond <6.isreserved.com> wrote in message news:<6.isreserved.com>... 


    Unfortunately you have two mistakes. The first simple one is that the
    decimal equivalent for 0xF0000000 (CRYPT_VERIFYCONTEXT) is 4026531840
    not 251658240.

    The second is a little more subtle. CryptAcquireContext takes a
    pointer to a HCRYPTPROV which is a 4 byte long. After this call
    returns, the HCRYPTPROV value needs to be unpacked as a L:

    hProvI, = hProv.unpack('L')

    CryptGenRandom takes a HCRYPTPROV value (a long). So the first
    parameter should be specified as a 'L':

    cgr = Win32API.new("advapi32", "CryptGenRandom", ['L','I','P'], 'N')

    Here is you code snippet rewritten with as few changes as possible:

    #================================================= =========================
    require 'Win32API'
    cac = Win32API.new("advapi32", "CryptAcquireContext",
    ['P','L','L','I','I'], 'N')
    cgr = Win32API.new("advapi32", "CryptGenRandom", ['L','I','P'], 'N')
    hProv = " " * 16
    cac.call(hProv, 0, 0, 1, 4026531840)
    guid = " " * 16
    hProvI, = hProv.unpack('L')
    cgr.call(hProvI, 16, guid)
    p guid
    #================================================= =========================


    Really you should check for errors and display them. Here is a
    somewhat more refined implementation:

    #================================================= =========================
    require 'Win32API'

    PROV_RSA_FULL = 1
    CRYPT_VERIFYCONTEXT = 0xF0000000

    FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200
    FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000

    CryptAcquireContext = Win32API.new("advapi32", "CryptAcquireContext",
    'PPPII', 'L')
    CryptGenRandom = Win32API.new("advapi32", "CryptGenRandom",
    'LIP', 'L')
    GetLastError = Win32API.new("Kernel32", "GetLastError", '', 'L')
    FormatMessageA = Win32API.new("Kernel32", "FormatMessageA",
    'LPLLPLPPPPPPPP', 'L')

    def lastErrorMessage
    code = GetLastError.call
    msg = "\0" * 1024
    len = FormatMessageA.call(FORMAT_MESSAGE_IGNORE_INSERTS +
    FORMAT_MESSAGE_FROM_SYSTEM, 0,
    code, 0, msg, 1024, nil, nil,
    nil, nil, nil, nil, nil, nil)
    msg[0, len].tr("\r", '').chomp
    end

    def getRandGUID
    hProvStr = " " * 4
    if CryptAcquireContext.call(hProvStr, nil, nil, PROV_RSA_FULL,
    CRYPT_VERIFYCONTEXT) == 0
    raise "CryptAcquireContext failed: #{lastErrorMessage}"
    end
    hProv, = hProvStr.unpack('L')
    guid = " " * 16
    if CryptGenRandom.call(hProv, 16, guid) == 0
    raise "CryptAcquireContext failed: #{lastErrorMessage}"
    end
    guid
    end

    p getRandGUID
    #================================================= =========================
    Stephen Guest

  4. #4

    Default Re: help with Win32API

    Stephen Veit wrote: 

    Ah, missed another zero there (251658240 = 0xF000000).

    [snip] 

    Thanks so much! I'm learning a bit more about C and Win32... I'm now
    using your code; all that's left to do is adding the CryptReleaseContext
    call.

    --
    dave


    David Guest

Similar Threads

  1. Win32API::Registry hell... help??
    By davido@codethought.nospamforme.com in forum PERL Modules
    Replies: 0
    Last Post: February 13th, 05:27 PM
  2. NULL pointer given, Win32API
    By Berger, in forum Ruby
    Replies: 4
    Last Post: January 18th, 06:18 PM
  3. Win32API question/suggestion
    By Daniel in forum Ruby
    Replies: 4
    Last Post: January 3rd, 12:58 AM
  4. Anyone using RegisterClass from Win32API?
    By Michael Davis in forum Ruby
    Replies: 1
    Last Post: July 29th, 03:42 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139