[Win32utils-devel] Need a little help with the pureRubywin32-eventlog

Heesob Park phasis at gmail.com
Wed May 17 22:29:28 EDT 2006


Hi,

2006/5/18, Berger, Daniel <Daniel.Berger at qwest.com>:
>
>
> > -----Original Message-----
> > From: win32utils-devel-bounces at rubyforge.org
> > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of
> > Berger, Daniel
> > Sent: Wednesday, May 17, 2006 12:07 PM
> > To: Development and ideas for win32utils projects
> > Subject: Re: [Win32utils-devel] Need a little help with the
> > pureRubywin32-eventlog
> >
> >
> > > -----Original Message-----
> > > From: win32utils-devel-bounces at rubyforge.org
> > > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of
> > > Heesob Park
> > > Sent: Tuesday, May 16, 2006 9:51 PM
> > > To: Development and ideas for win32utils projects
> > > Subject: Re: [Win32utils-devel] Need a little help with the
> > > pure Rubywin32-eventlog
> > >
> > >
> > > Hi,
> > >
> > > 2006/5/17, Daniel Berger <djberg96 at gmail.com>:
> > > > Hi all,
> > > >
> > > > I'm working on the EventLog#read method for the pure Ruby
> > > version of
> > > > win32-eventlog, but I'm stuck on the get_description
> > private method.
> > > >
> > > > Here are the problems:
> > > >
> > > > * I don't think I'm advancing the EVENTLOGRECORD properly between
> > > > iterations.  Take a look at the end of the "while dwread >
> > > 0" loop.  I
> > > > get some records, but not all of them.
> > > >
> > > > * I'm not sure how to properly populate or pack/unpack
> > the va_list,
> > > > which is later passed to the FormatMessage() function.
> > > >
> > > > Please take a look.
> > > >
> > > > Thanks,
> > > >
> > > > Dan
> > >
> > > Here is the patch:
> >
> > <snip>
> >
> > Thanks.  That mostly seems to work.  However, I'm hitting a
> > segfault after a few records.  As far as I can tell this
> > happens when +buf+ is empty, but I'm not positive that's the culprit.
> >
> > I also noticed that FormatMessage's parameter list is defined
> > as 'LPLLPLP' in error.rb (from windows-pr).  Thinking that
> > might be the culprit I tried changing the second param to
> > 'L', but that didn't seem to have any effect.
> >
> > Any ideas?
> >
> > Dan
>
> Here's some more info.  Using the C version of win32-eventlog I can see
> the record in question looks like this:
>
> #<struct Struct::EventLogStruct record_number=12302, time_generated=Sat
> Mar 18 23:13:43 MST 2006, ti
> me_written=Sat Mar 18 23:13:43 MST 2006, event_id=11203,
> event_type="error", category=0, source="Sms
> Client", computer="CO3840GDJBERGEX", user=nil, description="Software
> updates evaluation failed: coul
> d not locate the scan component of the specified software update
> inventory tool.  The scan component
>  advertisement might not have run on the client
> computer.\r\n\r\nPossible cause: Incorrect package a
> nd program name in the Scan.ini file.\r\nSolution:  Verify that the
> package and program name specifi
> ed in the scan.ini file are correct.\r\n\r\nPossible cause: Scan
> component was never run on client.\
> r\nSolution: Specify that the scan component is run in a program
> dependency of the software updates
> package. This will ensure that new client computers always run the scan
> component before software up
> date installation is attempted.">
>
> The description length is 664, so we should have enough buffer space.
> Hm...looking at the records that precede it, this appears to be the
> first description that contains "\r\n" in it.
>
> In other news I don't think the user code is right.  The pure Ruby
> version returns 'djberge' for the user instead of nil as it should.
>
> HTH,
>
> Dan
>
The user,computer,cateogory code were wrong.
Here is the patch for the CVS version:

--- eventlog.rb	2006-05-17 10:40:34.000000000 +0900
+++ eventlog.rb.new	2006-05-18 10:49:45.990803200 +0900
@@ -209,13 +209,14 @@
             dwread = read.unpack('L').first

             event_type = get_event_type(buf[24,2].unpack('S').first)
-            user = get_user(buf)
+

             while dwread > 0
                struct       = EventLogStruct.new
                event_source = buf[56..-1].split(0.chr).first
-               computer     = buf[56 + source.length +
1..-1].split(0.chr).first
+               computer     = buf[56 + event_source.length +
1..-1].split(0.chr).first

+               user = get_user(buf)
                desc = get_description(buf, event_source)

                struct.source         = event_source
@@ -226,8 +227,9 @@
                struct.event_id       = buf[20,4].unpack('L').first & 0x0000FFFF
                struct.event_type     = event_type
                struct.user           = user
-               struct.category       = buf[26,2].unpack('S').first
-
+               struct.category       = buf[28,2].unpack('S').first
+               struct.description 	 = desc
+
                if block_given?
                   yield struct
                else
@@ -239,9 +241,9 @@
                end

                length = buf[0,4].unpack('L').first # Length
-
-               dwread -= buf.strip.length
-               buf += 0.chr * length
+
+               dwread -= length
+               buf = buf[length..-1]
             end

             buf = 0.chr * BUFFER_SIZE
@@ -254,19 +256,20 @@
       private

       # TODO: finish
-      def get_description(rec, event_source)
-         str     = rec[36,4].unpack('L').first # StringOffset
-         num     = rec[24,2].unpack('S').first # NumStrings
+      def get_description(rec, event_source)
+         str     = rec[ rec[36,4].unpack('L').first .. -1]
+         num     = rec[26,2].unpack('S').first # NumStrings
          hkey    = [0].pack('L')
          key     = BASE_KEY + "#{@source}\\#{event_source}"
-         va_list = []
+         buf = 0.chr * 1024

-         # TODO: Fix this loop
-         0.upto(num){
-            va_list.push(str)
-            str += str.size + 1
-         }
-
+         if num==0
+           va_list_ptr = 0.chr * 4
+         else
+	         va_list = str.split(0.chr)[0...num]
+	         va_list_ptr = va_list.map {|x|
[x+0.chr].pack('P').unpack('L').first }.pack('L*')
+         end
+         	         	
          if RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, hkey) == 0
             value = 'EventMessageFile'
             file  = 0.chr * MAX_SIZE
@@ -284,9 +287,7 @@
                   hmodule  = LoadLibraryEx(file, 0, LOAD_LIBRARY_AS_DATAFILE)
                   event_id = rec[20,4].unpack('L').first
                   if hmodule != 0
-                     buf = 0.chr * 260
                      FormatMessage(
-                        FORMAT_MESSAGE_ALLOCATE_BUFFER |
                         FORMAT_MESSAGE_FROM_HMODULE |
                         FORMAT_MESSAGE_FROM_SYSTEM |
                         FORMAT_MESSAGE_ARGUMENT_ARRAY,
@@ -295,7 +296,7 @@
                         0,
                         buf,
                         buf.size,
-                        va_list # TODO: unpack this properly
+                        va_list_ptr
                      )
                      FreeLibrary(hmodule)
                   end
@@ -304,4 +305,5 @@

             RegCloseKey(hkey)
          end
+         buf.strip
       end


Regards,

Park Heesob



More information about the win32utils-devel mailing list