Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
6.0 KiB

  1. #
  2. # EventLog.pm
  3. #
  4. # Creates an object oriented interface to the Windows NT Evenlog
  5. # Written by Jesse Dougherty
  6. #
  7. package Win32::EventLog;
  8. $VERSION = $VERSION = '0.05';
  9. require Exporter;
  10. require DynaLoader;
  11. #use Win32;
  12. die "The Win32::Eventlog module works only on Windows NT"
  13. unless Win32::IsWinNT();
  14. @ISA= qw( Exporter DynaLoader );
  15. @EXPORT = qw(
  16. EVENTLOG_AUDIT_FAILURE
  17. EVENTLOG_AUDIT_SUCCESS
  18. EVENTLOG_BACKWARDS_READ
  19. EVENTLOG_END_ALL_PAIRED_EVENTS
  20. EVENTLOG_END_PAIRED_EVENT
  21. EVENTLOG_ERROR_TYPE
  22. EVENTLOG_FORWARDS_READ
  23. EVENTLOG_INFORMATION_TYPE
  24. EVENTLOG_PAIRED_EVENT_ACTIVE
  25. EVENTLOG_PAIRED_EVENT_INACTIVE
  26. EVENTLOG_SEEK_READ
  27. EVENTLOG_SEQUENTIAL_READ
  28. EVENTLOG_START_PAIRED_EVENT
  29. EVENTLOG_SUCCESS
  30. EVENTLOG_WARNING_TYPE
  31. );
  32. sub AUTOLOAD {
  33. my($constname);
  34. ($constname = $AUTOLOAD) =~ s/.*:://;
  35. # reset $! to zero to reset any current errors.
  36. $!=0;
  37. my $val = constant($constname, @_ ? $_[0] : 0);
  38. if ($! != 0) {
  39. if ($! =~ /Invalid/) {
  40. $AutoLoader::AUTOLOAD = $AUTOLOAD;
  41. goto &AutoLoader::AUTOLOAD;
  42. }
  43. else {
  44. my ($pack,$file,$line) = caller;
  45. die "Unknown Win32::EventLog macro $constname, at $file line $line.\n";
  46. }
  47. }
  48. eval "sub $AUTOLOAD { $val }";
  49. goto &$AUTOLOAD;
  50. }
  51. #
  52. # new()
  53. #
  54. # Win32::EventLog->new("source name", "ServerName");
  55. #
  56. sub new
  57. {
  58. my $c = shift;
  59. die "usage: PACKAGE->new(SOURCENAME[, SERVERNAME])\n" unless @_;
  60. my $source = shift;
  61. my $server = shift;
  62. my $handle;
  63. # Create new handle
  64. OpenEventLog($handle, $server, $source);
  65. return bless {'handle' => $handle,
  66. 'Source' => $source,
  67. 'Computer' => $server }, $c;
  68. }
  69. #
  70. # Open (the rather braindead old way)
  71. # A variable initialized to empty must be supplied as the first
  72. # arg, followed by whatever new() takes
  73. #
  74. sub Open {
  75. $_[0] = Win32::EventLog->new($_[1],$_[2]);
  76. }
  77. sub Backup
  78. {
  79. $self = shift;
  80. die " usage: OBJECT->Backup(FILENAME)\n" unless @_ == 1;
  81. my $filename = shift;
  82. my $result;
  83. $result = BackupEventLog($self->{'handle'},$filename);
  84. unless ($result) { $! = Win32::GetLastError() }
  85. return $result;
  86. }
  87. # Read
  88. # Note: the EventInfo arguement requires a hash reference.
  89. sub Read
  90. {
  91. $self = shift;
  92. die "usage: OBJECT->Read(FLAGS, RECORDOFFSET, HASHREF)\n" unless @_ == 3;
  93. my ($readflags,$recordoffset) = @_;
  94. my ($result, $datalength, $dataoffset, $sid, $length);
  95. my ($reserved, $recordnumber, $timegenerated, $timewritten, $eventid);
  96. my ($eventtype, $numstrings, $eventcategory, $reservedflags);
  97. my ($closingrecordnumber, $stringoffset, $usersidlength, $usersidoffset);
  98. # The following is stolen shamelessly from Wyt's tests for the registry.
  99. $result = ReadEventLog($self->{'handle'},
  100. $readflags,
  101. $recordoffset,
  102. $header,
  103. $source,
  104. $computer,
  105. $sid,
  106. $data,
  107. $strings);
  108. ($length,
  109. $reserved,
  110. $recordnumber,
  111. $timegenerated,
  112. $timewritten,
  113. $eventid,
  114. $eventtype,
  115. $numstrings,
  116. $eventcategory,
  117. $reservedflags,
  118. $closingrecordnumber,
  119. $stringoffset,
  120. $usersidlength,
  121. $usersidoffset,
  122. $datalength,
  123. $dataoffset) = unpack('l6s4l6', $header);
  124. # get the text message here
  125. my $message='';
  126. GetEventLogText($source, $eventid, $strings, $numstrings, $message) if ($result);
  127. # make a hash out of the values returned from ReadEventLog.
  128. my %h = ( 'Source' => $source,
  129. 'Computer' => $computer,
  130. 'Length' => $datalength,
  131. 'Category' => $eventcategory,
  132. 'RecordNumber' => $recordnumber,
  133. 'TimeGenerated' => $timegenerated,
  134. 'Timewritten' => $timewritten,
  135. 'EventID' => $eventid,
  136. 'EventType' => $eventtype,
  137. 'ClosingRecordNumber' => $closingrecordnumber,
  138. 'User' => $sid,
  139. 'Strings' => $strings,
  140. 'Data' => $data,
  141. 'Message' => $message,
  142. );
  143. if (ref($_[2]) eq 'HASH') {
  144. %{$_[2]} = %h; # this needed for Read(...,\%foo) case
  145. }
  146. else {
  147. $_[2] = \%h;
  148. }
  149. unless ($result) { $! = Win32::GetLastError() }
  150. return $result;
  151. }
  152. sub Report
  153. {
  154. my $self = shift;
  155. die "usage: OBJECT->Report( HASHREF )\n" unless @_ == 1;
  156. my $EventInfo = shift;
  157. my $result;
  158. if ( ref( $EventInfo) eq "HASH" ) {
  159. my ($length, $reserved, $recordnumber, $timegenerated, $timewritten);
  160. my ($eventid, $eventtype, $numstrings, $eventcategory, $reservedflags);
  161. my ($closingrecordnumber, $stringoffset, $usersidlength);
  162. my ($usersidoffset, $source, $data, $strings);
  163. $eventcategory = $EventInfo->{'Category'};
  164. $source = $self->{'Source'};
  165. $computer = $self->{'Computer'};
  166. $length = $EventInfo->{'Length'};
  167. $recordnumber = $EventInfo->{'RecordNumber'};
  168. $timegenerated = $EventInfo->{'TimeGenerated'};
  169. $timewritten = $EventInfo->{'Timewritten'};
  170. $eventid = $EventInfo->{'EventID'};
  171. $eventtype = $EventInfo->{'EventType'};
  172. $closingrecordnumber = $EventInfo->{'ClosingRecordNumber'};
  173. $strings = $EventInfo->{'Strings'};
  174. $data = $EventInfo->{'Data'};
  175. $result = WriteEventLog($computer,
  176. $source,
  177. $eventtype,
  178. $eventcategory,
  179. $eventid,
  180. $reserved,
  181. $data,
  182. $strings);
  183. }
  184. else {
  185. die "Win32::EventLog::Report requires a hash reference as arg 3\n";
  186. }
  187. unless ($result) { $! = Win32::GetLastError() }
  188. return $result;
  189. }
  190. sub GetOldest
  191. {
  192. my $self=shift;
  193. die "usage: OBJECT->GetOldest( SCALAREF )\n" unless @_ == 1;
  194. my $result = GetOldestEventLogRecord( $self->{'handle'},$_[0]);
  195. unless ($result) { $! = Win32::GetLastError() }
  196. return $result;
  197. }
  198. sub GetNumber
  199. {
  200. my $self=shift;
  201. die "usage: OBJECT->GetNumber( SCALARREF )\n" unless @_ == 1;
  202. my $result = GetNumberOfEventLogRecords($self->{'handle'}, $_[0]);
  203. unless ($result) { $! = Win32::GetLastError() }
  204. return $result;
  205. }
  206. sub Clear
  207. {
  208. my $self=shift;
  209. die "usage: OBJECT->Clear( FILENAME )\n" unless @_ == 1;
  210. my $filename = shift;
  211. my $result = ClearEventLog($self->{'handle'}, $filename);
  212. unless ($result) { $! = Win32::GetLastError() }
  213. return $result;
  214. }
  215. bootstrap Win32::EventLog;
  216. 1;
  217. __END__