Professional Web Applications Themes

dereferencing pointers in Win32 API - Ruby

Ruby/Win Gurus, I haven't figured out how to dereference pointers passed in as arguments to Win32 API. For example, in the following call (in C) to NetStatisticsGet API (which may be broken on NT, but that is not the point here). LPBYTE lpBuffer; int ret; ret = NetStatisticsGet ( NULL, (char *)is_workstation ? L"LanmanWorkstation" : L"LanmanServer"), 0, 0, &lpBuffer); The last parameter lpBuffer is a pointer to a pointer. The API call internally allocates memory and sets the value of the pointer to the variable whose pointer you have passed in. It is your responsibility to free the memory using ...

  1. #1

    Default dereferencing pointers in Win32 API

    Ruby/Win Gurus,

    I haven't figured out how to dereference pointers passed in as arguments
    to Win32 API. For example, in the following call (in C) to NetStatisticsGet
    API (which may be broken on NT, but that is not the point here).

    LPBYTE lpBuffer;
    int ret;
    ret = NetStatisticsGet (
    NULL,
    (char *)is_workstation ? L"LanmanWorkstation" : L"LanmanServer"),
    0,
    0,
    &lpBuffer);

    The last parameter lpBuffer is a pointer to a pointer.
    The API call internally allocates memory and sets the value of the pointer
    to the
    variable whose pointer you have passed in. It is your responsibility to free
    the
    memory using NetApiBufferFree function.

    When I call this in Ruby, I do the following:
    #----------------

    netStatisticsGet = Win32API.new('netapi32','NetStatisticsGet','PPNNP' ,'I')

    lpBuffer = ' ' * 4 # area to store the pointer value

    # assume that the variable 'service' contains "LanmanWorkstation" in Unicode
    ret = netStatisticsGet.call(0,service,0,0,lpBuffer)

    #-----------------

    This call succeeds (because I get ret == 0) which means lpBuffer now points
    to the
    buffer in memory. My questions is how do I de-reference this variable in
    Ruby?

    TIA,
    -- shanko



    Shashank Guest

  2. #2

    Default Re: dereferencing pointers in Win32 API

    On Sat, 10 Jan 2004 11:26:59 -0600, Shashank Date <net>
    wrote:
     

    If I'm not completely wrong, you should be able to dereference it using
    lpBuffer.unpack('P<size>') where <size> is the size of the buffer in
    bytes. Just remember that unpack returns an array, the first element of
    which will be the dereferenced buffer as a string.

    --
    Dennis Ranke
    Dennis Guest

  3. #3

    Default Re: dereferencing pointers in Win32 API

    Thanks for looking.

    "Dennis Ranke" <de> wrote in message 

    I tried that and i get:

    C:/atest/tst_netapi32.rb:28:in `unpack': no associated pointer
    (ArgumentError)
    from C:/atest/tst_netapi32.rb:28

    Here is the program, and I am on Win XP (Home)
    ruby 1.8.0 (2003-08-04) [i386-mswin32]:

    #---------------------------------------------------------------------------
    require "Win32API"

    SERVICE_WORKSTATION = [
    76,0,97,0,110,0,109,0,97,0,110,0,87,0,111,0,114,0,
    107,0,115,0,116,0,97,0,116,0,105,0,111,0,110,0,0,0]

    SERVICE_WORKSTATION.each{|e| print "%c" % e if e > 0}
    puts

    service = SERVICE_WORKSTATION.pack("U*") # Unicode

    NetStatisticsGet = Win32API.new('netapi32','NetStatisticsGet','PPNNP' ,'I')

    bufptr = " " * 4
    ret = NetStatisticsGet.call(0,service,0,0,bufptr)

    if 0 != ret
    puts "Failed:#{ret}"
    exit
    end

    # Here's where I'm confused...
    #packstring = "I" * 13
    #packstring += "L" * 27
    #struct = bufptr.unpack(packstring)

    STAT_WORKSTATION_SIZE = (13*8) + (28*4)
    p STAT_WORKSTATION_SIZE

    struct = bufptr.unpack("P#{STAT_WORKSTATION_SIZE}")
    p struct

    __END__


    Shashank Guest

  4. #4

    Default Re: dereferencing pointers in Win32 API

    Hi, 
    >
    > I tried that and i get:
    >
    > C:/atest/tst_netapi32.rb:28:in `unpack': no associated pointer
    > (ArgumentError)
    > from C:/atest/tst_netapi32.rb:28
    >[/ref]
    Just use memcpy.
    Try this code.

    require "Win32API"

    SERVICE_WORKSTATION = [
    76,0,97,0,110,0,109,0,97,0,110,0,87,0,111,0,114,0,
    107,0,115,0,116,0,97,0,116,0,105,0,111,0,110,0,0,0]


    SERVICE_WORKSTATION.each{|e| print "%c" % e if e > 0}
    puts

    service = SERVICE_WORKSTATION.pack("U*") # Unicode

    NetStatisticsGet = Win32API.new('netapi32','NetStatisticsGet','PPNNP' ,'I')

    bufptr = "\0" * 4
    ret = NetStatisticsGet.call(0,service,0,0,bufptr)

    if 0 != ret
    puts "Failed:#{ret}"
    exit
    end

    STAT_WORKSTATION_SIZE = (13*8) + (28*4)

    rbuf = "\0" * STAT_WORKSTATION_SIZE
    memcpy = Win32API.new('msvcrt','memcpy','PPL','P')
    memcpy.Call(rbuf,bufptr,STAT_WORKSTATION_SIZE)

    struct = rbuf.unpack("L*")
    p struct

    __END__

    Regards,

    Park Heesob





    Park Guest

  5. #5

    Default Re: dereferencing pointers in Win32 API

    On Sat, 10 Jan 2004 14:43:19 -0600, Shashank Date <net>
    wrote:
     
    >
    > I tried that and i get:
    >
    > C:/atest/tst_netapi32.rb:28:in `unpack': no associated pointer
    > (ArgumentError)
    > from C:/atest/tst_netapi32.rb:28[/ref]

    You are right, after reading the relevant ruby source, it seems that you
    can only dereference pointers that you have written into the string
    yourself using Array#pack('P'). So the suggestion of Park to use memcpy
    might be your best bet.

    As a sidenote to matz:

    Is it intentional that String#unpack('P') can raise both
    "no associated pointer" (when the string doesn't have any associates)
    and
    "non associated pointer" (then the string does have associates, but this
    pointer isn't among them)?

    --
    Dennis Ranke
    Dennis Guest

  6. #6

    Default Re: dereferencing pointers in Win32 API

    This worked :
     

    Thanks, Park.
    -- shanko


    Shashank Guest

Similar Threads

  1. Problem with Win32::API and pointers
    By jrgoody@googlemail.com in forum PERL Modules
    Replies: 6
    Last Post: May 16th, 03:02 PM
  2. Problem with dereferencing of $_
    By Duan Toh in forum PERL Beginners
    Replies: 2
    Last Post: January 14th, 02:47 PM
  3. Dereferencing variable name
    By Owen Funkhouser in forum PHP Development
    Replies: 8
    Last Post: September 24th, 11:36 PM
  4. Probably a dereferencing problem - maybe???
    By Mike Flannigan in forum PERL Miscellaneous
    Replies: 5
    Last Post: August 25th, 01:50 AM
  5. Array dereferencing
    By Jan Fure in forum PERL Miscellaneous
    Replies: 5
    Last Post: June 26th, 09:09 PM

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