Daniel Berger
2006-Jun-21 05:06 UTC
[Win32utils-devel] Yet another data structure + pack/unpack question (win32-service)
Hi all, If you take a look at the service.rb file in the win32-service repository (the new one in the toplevel repository path), I''ve got this bit of code, which succeeds, but I can''t seem to unpack the data structure properly. Did I pack it wrong to begin with? I should know this but I''m spacing out. proc_status = [0,0,0,0,0,0,0,0,0,0].pack(''LLLLLLLLLL'') enum_service = [0.chr, 0.chr].pack(''pp'') + proc_status service_buf = enum_service * 1000 bytes_needed = [0].pack(''L'') services_returned = [0].pack(''L'') resume_handle = [0].pack(''L'') bool = EnumServicesStatusEx( handle_scm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32 | SERVICE_DRIVER, SERVICE_STATE_ALL, service_buf, service_buf.size, bytes_needed, services_returned, resume_handle, group ) if bool num_services = services_returned.unpack(''L'').first index = 0 1.upto(num_services){ |num| info = service_buf[index, enum_service.size-1] service_name = info[0,4].pack(''p'') # boom! index += enum_service.size } end Regards, Dan
Heesob Park
2006-Jun-21 05:59 UTC
[Win32utils-devel] Yet another data structure + pack/unpack question (win32-service)
Hi, 2006/6/21, Daniel Berger <djberg96 at gmail.com>:> Hi all, > > If you take a look at the service.rb file in the win32-service > repository (the new one in the toplevel repository path), I''ve got this > bit of code, which succeeds, but I can''t seem to unpack the data > structure properly. Did I pack it wrong to begin with? I should know > this but I''m spacing out. > > proc_status = [0,0,0,0,0,0,0,0,0,0].pack(''LLLLLLLLLL'') > enum_service = [0.chr, 0.chr].pack(''pp'') + proc_status > service_buf = enum_service * 1000 > bytes_needed = [0].pack(''L'') > services_returned = [0].pack(''L'') > resume_handle = [0].pack(''L'') > > bool = EnumServicesStatusEx( > handle_scm, > SC_ENUM_PROCESS_INFO, > SERVICE_WIN32 | SERVICE_DRIVER, > SERVICE_STATE_ALL, > service_buf, > service_buf.size, > bytes_needed, > services_returned, > resume_handle, > group > ) > > if bool > num_services = services_returned.unpack(''L'').first > index = 0 > > 1.upto(num_services){ |num| > info = service_buf[index, enum_service.size-1] > service_name = info[0,4].pack(''p'') # boom! > index += enum_service.size > } > end >I guess you still don''t understand the difference of C pointer and ruby buffer :) Try this: Strcpy = Win32API.new(''msvcrt'', ''strcpy'', ''PL'', ''L'') 1.upto(num_services){ |num| info = service_buf[index, enum_service.size-1] service_name = 0.chr * 256 Strcpy.call(service_name,info[0,4].unpack(''L'').first) service_name = service_name.strip index += enum_service.size } But, the code still segfault for another bug. Regards, Park Heesob
Heesob Park
2006-Jun-21 06:12 UTC
[Win32utils-devel] Yet another data structure + pack/unpack question (win32-service)
2006/6/21, Heesob Park <phasis at gmail.com>:> Hi, > > 2006/6/21, Daniel Berger <djberg96 at gmail.com>: > > Hi all, > > > > If you take a look at the service.rb file in the win32-service > > repository (the new one in the toplevel repository path), I''ve got this > > bit of code, which succeeds, but I can''t seem to unpack the data > > structure properly. Did I pack it wrong to begin with? I should know > > this but I''m spacing out. > > > > proc_status = [0,0,0,0,0,0,0,0,0,0].pack(''LLLLLLLLLL'') > > enum_service = [0.chr, 0.chr].pack(''pp'') + proc_status > > service_buf = enum_service * 1000 > > bytes_needed = [0].pack(''L'') > > services_returned = [0].pack(''L'') > > resume_handle = [0].pack(''L'') > > > > bool = EnumServicesStatusEx( > > handle_scm, > > SC_ENUM_PROCESS_INFO, > > SERVICE_WIN32 | SERVICE_DRIVER, > > SERVICE_STATE_ALL, > > service_buf, > > service_buf.size, > > bytes_needed, > > services_returned, > > resume_handle, > > group > > ) > > > > if bool > > num_services = services_returned.unpack(''L'').first > > index = 0 > > > > 1.upto(num_services){ |num| > > info = service_buf[index, enum_service.size-1] > > service_name = info[0,4].pack(''p'') # boom! > > index += enum_service.size > > } > > end > > > I guess you still don''t understand the difference of C pointer and > ruby buffer :) > > Try this: > > Strcpy = Win32API.new(''msvcrt'', ''strcpy'', ''PL'', ''L'') > > 1.upto(num_services){ |num| > info = service_buf[index, enum_service.size-1] > service_name = 0.chr * 256 > Strcpy.call(service_name,info[0,4].unpack(''L'').first) > service_name = service_name.strip > index += enum_service.size > } > > But, the code still segfault for another bug. >And I found the bug. proc_status = [0,0,0,0,0,0,0,0,0,0].pack(''LLLLLLLLLL'') should be proc_status = [0,0,0,0,0,0,0,0,0].pack(''LLLLLLLLL'') Regards, Park Heesob
Daniel Berger
2006-Jun-21 12:48 UTC
[Win32utils-devel] Yet another data structure + pack/unpack question (win32-service)
Heesob Park wrote:> Hi, > > 2006/6/21, Daniel Berger <djberg96 at gmail.com>: > >> Hi all, >> >> If you take a look at the service.rb file in the win32-service >> repository (the new one in the toplevel repository path), I''ve got this >> bit of code, which succeeds, but I can''t seem to unpack the data >> structure properly. Did I pack it wrong to begin with? I should know >> this but I''m spacing out. >> >> proc_status = [0,0,0,0,0,0,0,0,0,0].pack(''LLLLLLLLLL'') >> enum_service = [0.chr, 0.chr].pack(''pp'') + proc_status >> service_buf = enum_service * 1000 >> bytes_needed = [0].pack(''L'') >> services_returned = [0].pack(''L'') >> resume_handle = [0].pack(''L'') >> >> bool = EnumServicesStatusEx( >> handle_scm, >> SC_ENUM_PROCESS_INFO, >> SERVICE_WIN32 | SERVICE_DRIVER, >> SERVICE_STATE_ALL, >> service_buf, >> service_buf.size, >> bytes_needed, >> services_returned, >> resume_handle, >> group >> ) >> >> if bool >> num_services = services_returned.unpack(''L'').first >> index = 0 >> >> 1.upto(num_services){ |num| >> info = service_buf[index, enum_service.size-1] >> service_name = info[0,4].pack(''p'') # boom! >> index += enum_service.size >> } >> end >> >> > I guess you still don''t understand the difference of C pointer and > ruby buffer :) > > Try this: > > Strcpy = Win32API.new(''msvcrt'', ''strcpy'', ''PL'', ''L'') > > 1.upto(num_services){ |num| > info = service_buf[index, enum_service.size-1] > service_name = 0.chr * 256 > Strcpy.call(service_name,info[0,4].unpack(''L'').first) > service_name = service_name.strip > index += enum_service.size > } > > But, the code still segfault for another bug. > > Regards, > > Park Heesob > _______________________________________________ > win32utils-devel mailing list > win32utils-devel at rubyforge.org > http://rubyforge.org/mailman/listinfo/win32utils-devel > >Ok, thanks. I guess part of the reason I got confused as to why you can''t do this: irb(main):016:0> bar = ''hello'' => "hello" irb(main):017:0> bar.unpack("l").pack("l").unpack("p") ArgumentError: no associated pointer Is Ruby attaching some metadata to the string that can only be gotten to if it''s packed with ''p''? I mean, why can''t you go from address to object? Thanks, Dan
Heesob Park
2006-Jun-21 13:21 UTC
[Win32utils-devel] Yet another data structure + pack/unpack question (win32-service)
Hi, 2006/6/21, Daniel Berger <djberg96 at gmail.com>:> Heesob Park wrote: > > Hi, > > > > 2006/6/21, Daniel Berger <djberg96 at gmail.com>: > > > >> Hi all, > >> > >> If you take a look at the service.rb file in the win32-service > >> repository (the new one in the toplevel repository path), I''ve got this > >> bit of code, which succeeds, but I can''t seem to unpack the data > >> structure properly. Did I pack it wrong to begin with? I should know > >> this but I''m spacing out. > >> > >> proc_status = [0,0,0,0,0,0,0,0,0,0].pack(''LLLLLLLLLL'') > >> enum_service = [0.chr, 0.chr].pack(''pp'') + proc_status > >> service_buf = enum_service * 1000 > >> bytes_needed = [0].pack(''L'') > >> services_returned = [0].pack(''L'') > >> resume_handle = [0].pack(''L'') > >> > >> bool = EnumServicesStatusEx( > >> handle_scm, > >> SC_ENUM_PROCESS_INFO, > >> SERVICE_WIN32 | SERVICE_DRIVER, > >> SERVICE_STATE_ALL, > >> service_buf, > >> service_buf.size, > >> bytes_needed, > >> services_returned, > >> resume_handle, > >> group > >> ) > >> > >> if bool > >> num_services = services_returned.unpack(''L'').first > >> index = 0 > >> > >> 1.upto(num_services){ |num| > >> info = service_buf[index, enum_service.size-1] > >> service_name = info[0,4].pack(''p'') # boom! > >> index += enum_service.size > >> } > >> end > >> > >> > > I guess you still don''t understand the difference of C pointer and > > ruby buffer :) > > > > Try this: > > > > Strcpy = Win32API.new(''msvcrt'', ''strcpy'', ''PL'', ''L'') > > > > 1.upto(num_services){ |num| > > info = service_buf[index, enum_service.size-1] > > service_name = 0.chr * 256 > > Strcpy.call(service_name,info[0,4].unpack(''L'').first) > > service_name = service_name.strip > > index += enum_service.size > > } > > > > But, the code still segfault for another bug. > > > > Regards, > > > > Park Heesob > > _______________________________________________ > > win32utils-devel mailing list > > win32utils-devel at rubyforge.org > > http://rubyforge.org/mailman/listinfo/win32utils-devel > > > > > Ok, thanks. I guess part of the reason I got confused as to why you > can''t do this: > > irb(main):016:0> bar = ''hello'' > => "hello" > irb(main):017:0> bar.unpack("l").pack("l").unpack("p") > ArgumentError: no associated pointer > > Is Ruby attaching some metadata to the string that can only be gotten to > if it''s packed with ''p''? I mean, why can''t you go from address to object? >Yes, you''re right. According to Ruby source pack.c and string.c, Ruby make the string associated with "rb_str_associate". And when unpacking ''p'', ruby check the string with "rb_str_associated" I mean it is almost impossible you go from address to object. Regards, Park Heesob