-
Notifications
You must be signed in to change notification settings - Fork 807
/
win32evtlog.i
2186 lines (2008 loc) · 80.7 KB
/
win32evtlog.i
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* File : win32evtlog.i */
%module win32evtlog // A module, encapsulating the Windows Win32 event log API.
// <nl>The Evt* functions are only available on Vista and later. Attempting to call
// them on XP will result in the process exiting, rather than a python exception.
%include "typemaps.i"
%include "pywin32.i"
%{
#include <structmember.h>
#undef PyHANDLE
#include "PyWinObjects.h"
#include "WinEvt.h"
// @object PyEVTLOG_HANDLE|Object representing a handle to the windows event log.
// Identical to <o PyHANDLE>, but calls CloseEventLog() on destruction
class PyEVTLOG_HANDLE: public PyHANDLE
{
public:
PyEVTLOG_HANDLE(HANDLE hInit) : PyHANDLE(hInit) {}
virtual BOOL Close(void) {
BOOL ok = m_handle ? CloseEventLog(m_handle) : TRUE;
m_handle = 0;
if (!ok)
PyWin_SetAPIError("CloseEventLog");
return ok;
}
virtual const char *GetTypeName() {
return "PyEVTLOG_HANDLE";
}
};
// @object PyEVT_HANDLE|Handle to an event log, session, query, or any other object used with
// the Evt* event log functions on Vista and later.
// When the object is destroyed, EvtClose is called.
class PyEVT_HANDLE: public PyHANDLE
{
public:
PyEVT_HANDLE(HANDLE hInit, PyObject *context) : PyHANDLE(hInit){
callback_objects = context;
Py_XINCREF(callback_objects);
}
virtual BOOL Close(void){
BOOL ret=EvtClose(m_handle);
if (!ret)
PyWin_SetAPIError("EvtClose");
m_handle = 0;
Py_XDECREF(callback_objects);
callback_objects=NULL;
return ret;
}
virtual const char *GetTypeName(){
return "PyEVT_HANDLE";
}
// Only used with push subscription handles. Will be a 2-tuple
// that keeps references to the callback function and context object
PyObject *callback_objects;
};
#define PyHANDLE HANDLE
PyObject *PyWinObject_FromEVTLOG_HANDLE(HANDLE h)
{
PyObject *ret = new PyEVTLOG_HANDLE(h);
if (!ret)
PyErr_NoMemory();
return ret;
}
PyObject *PyWinObject_FromEVT_HANDLE(HANDLE h, PyObject *context=NULL)
{
PyObject *ret=new PyEVT_HANDLE(h, context);
if (ret==NULL){
EvtClose(h);
PyErr_NoMemory();
}
return ret;
}
%}
%typemap(python,except) PyEVTLOG_HANDLE {
Py_BEGIN_ALLOW_THREADS
$function
Py_END_ALLOW_THREADS
if ($source==0 || $source==INVALID_HANDLE_VALUE) {
$cleanup
return PyWin_SetAPIError("$name");
}
}
%typemap(python,out) PyEVTLOG_HANDLE {
$target = PyWinObject_FromEVTLOG_HANDLE($source);
}
typedef HANDLE PyEVTLOG_HANDLE;
%{
#define PyEVTLOG_HANDLE HANDLE
%}
%{
// @object PyEventLogRecord|An object containing the data in an EVENTLOGRECORD.
class PyEventLogRecord : public PyObject
{
public:
PyEventLogRecord(EVENTLOGRECORD *pEvt);
~PyEventLogRecord(void);
static void deallocFunc(PyObject *ob);
static struct PyMemberDef members[];
protected:
DWORD Reserved;
DWORD RecordNumber;
PyObject *TimeGenerated;
PyObject * TimeWritten;
DWORD EventID;
WORD EventType;
PyObject *SourceName;
PyObject *StringInserts;
WORD EventCategory;
WORD ReservedFlags;
DWORD ClosingRecordNumber;
PyObject *Sids;
PyObject *Data;
PyObject *ComputerName;
};
/*
PyObject *PyWinMethod_NewEventLogRecord(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":EventLogRecord"))
return NULL;
return new PyEventLogRecord();
}
*/
PyTypeObject PyEventLogRecordType =
{
PYWIN_OBJECT_HEAD
"PyEventLogRecord",
sizeof(PyEventLogRecord),
0,
PyEventLogRecord::deallocFunc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
PyObject_GenericSetAttr, /* tp_setattro */
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
PyEventLogRecord::members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};
#define OFF(e) offsetof(PyEventLogRecord, e)
/*static*/ struct PyMemberDef PyEventLogRecord::members[] = {
{"Reserved", T_INT, OFF(Reserved)}, // @prop integer|Reserved|
{"RecordNumber", T_INT, OFF(RecordNumber)}, // @prop integer|RecordNumber|
{"TimeGenerated", T_OBJECT, OFF(TimeGenerated)}, // @prop <o PyDateTime>|TimeGenerated|
{"TimeWritten", T_OBJECT, OFF(TimeWritten)}, // @prop <o PyDateTime>|TimeWritten|
{"EventID", T_INT, OFF(EventID)}, // @prop integer|EventID|
{"EventType", T_SHORT, OFF(EventType)}, // @prop integer|EventType|
{"EventCategory", T_SHORT, OFF(EventCategory)}, // @prop integer|EventCategory|
{"ReservedFlags", T_SHORT, OFF(ReservedFlags)}, // @prop integer|ReservedFlags|
{"ClosingRecordNumber",T_INT, OFF(ClosingRecordNumber)}, // @prop integer|ClosingRecordNumber|
{"SourceName", T_OBJECT, OFF(SourceName)}, // @prop <o PyUnicode>|SourceName|
{"StringInserts", T_OBJECT, OFF(StringInserts)}, // @prop (<o PyUnicode>,...)|StringInserts|
{"Sid", T_OBJECT, OFF(Sids)}, // @prop <o PySID>|Sid|
{"Data", T_OBJECT, OFF(Data)}, // @prop string|Data|
{"ComputerName", T_OBJECT, OFF(ComputerName)}, // @prop <o PyUnicode>|ComputerName|
{NULL}
};
PyEventLogRecord::PyEventLogRecord(EVENTLOGRECORD *pEvt)
{
ob_type = &PyEventLogRecordType;
_Py_NewReference(this);
Reserved = RecordNumber = EventID = ClosingRecordNumber = 0;
TimeWritten = TimeGenerated = SourceName = ComputerName = StringInserts = Sids = Data = NULL;
EventType = EventCategory = ReservedFlags = 0;
if (pEvt==NULL) // Empty one.
return;
Reserved = pEvt->Reserved;
RecordNumber = pEvt->RecordNumber;
EventID = pEvt->EventID;
EventType = pEvt->EventType;
EventCategory = pEvt->EventCategory;
ReservedFlags = pEvt->ReservedFlags;
ClosingRecordNumber = pEvt->ClosingRecordNumber;
if (pEvt->NumStrings==0) {
StringInserts = Py_None;
Py_INCREF(Py_None);
} else {
StringInserts = PyTuple_New(pEvt->NumStrings);
if (StringInserts) {
WCHAR *stringOffset = (WCHAR *) (((BYTE *)pEvt) + pEvt->StringOffset);
for (DWORD stringNo = 0;stringNo<pEvt->NumStrings;stringNo++) {
PyTuple_SET_ITEM( StringInserts, (int)stringNo, PyWinObject_FromWCHAR(stringOffset));
stringOffset = stringOffset + (wcslen(stringOffset)) + 1;
}
}
}
TimeGenerated = PyWinTimeObject_Fromtime_t((time_t)pEvt->TimeGenerated);
TimeWritten = PyWinTimeObject_Fromtime_t((time_t)pEvt->TimeWritten);
if (pEvt->UserSidLength==0) {
Sids = Py_None; // No SID in this record.
Py_INCREF(Sids);
} else {
Sids = PyWinObject_FromSID( (PSID)(((BYTE *)pEvt) + pEvt->UserSidOffset));
}
Data = PyBytes_FromStringAndSize(((char *)pEvt)+pEvt->DataOffset, pEvt->DataLength);
WCHAR *szSourceName = (WCHAR *)(((BYTE *)pEvt) + sizeof(EVENTLOGRECORD));
SourceName = PyWinObject_FromWCHAR(szSourceName);
ComputerName = PyWinObject_FromWCHAR(szSourceName + wcslen(szSourceName) + 1);
}
PyEventLogRecord::~PyEventLogRecord(void)
{
Py_XDECREF(TimeWritten);
Py_XDECREF(TimeGenerated);
Py_XDECREF(SourceName);
Py_XDECREF(StringInserts);
Py_XDECREF(Sids);
Py_XDECREF(Data);
Py_XDECREF(ComputerName);
}
/*static*/ void PyEventLogRecord::deallocFunc(PyObject *ob)
{
delete (PyEventLogRecord *)ob;
}
PyObject *MakeEventLogObject( BYTE *buf, DWORD numBytes )
{
PyObject *ret = PyList_New(0);
if (ret==NULL) return NULL;
while (numBytes>0) {
EVENTLOGRECORD *pEvt = (EVENTLOGRECORD *)buf;
PyObject *subItem = new PyEventLogRecord(pEvt);
if (subItem==NULL) {
Py_DECREF(ret);
PyErr_SetString(PyExc_MemoryError, "Allocating EventLogRecord object");
return NULL;
}
PyList_Append(ret, subItem);
Py_DECREF(subItem);
buf = buf + pEvt->Length;
numBytes -= pEvt->Length;
}
return ret;
}
PyObject *_MyReadEventLog(HANDLE hEventLog, DWORD dwReadFlags, DWORD dwRecordOffset, DWORD nNumberOfBytesToRead)
{
DWORD needed = nNumberOfBytesToRead, read;
BYTE *buf;
BOOL ok;
while (1) {
buf = (BYTE *)malloc(needed);
if (buf==NULL) {
PyErr_SetString(PyExc_MemoryError, "Allocating initial buffer");
return NULL;
}
Py_BEGIN_ALLOW_THREADS
ok = ReadEventLogW(hEventLog, dwReadFlags, dwRecordOffset, buf, needed, &read, &needed);
Py_END_ALLOW_THREADS
if (!ok) {
DWORD err = GetLastError();
if (err==ERROR_HANDLE_EOF) {
read = 0;// pretend everything is OK...
break;
}
else if (err==ERROR_INSUFFICIENT_BUFFER) {
free(buf);
continue; // try again.
} else {
free(buf);
return PyWin_SetAPIError("ReadEventLog");
}
}
else
break;
}
// Convert the object.
PyObject *ret = MakeEventLogObject(buf, read);
free(buf);
return ret;
}
#define EVTLOG_READ_BUF_LEN_MAX 0x7ffff
#define EVTLOG_READ_BUF_LEN_DEFAULT 0x1000
// @pyswig [object,...]|ReadEventLog|Reads some event log records.
// @rdesc If there are no event log records available, then an empty list is returned.
PyObject *MyReadEventLog(PyObject *self, PyObject *args) {
HANDLE hEventLog = INVALID_HANDLE_VALUE;
DWORD dwReadFlags, dwRecordOffset, nNumberOfBytesToRead = EVTLOG_READ_BUF_LEN_DEFAULT;
if (!PyArg_ParseTuple(args, "O&kk|k:ReadEventLog",
PyWinObject_AsHANDLE, &hEventLog, // @pyparm <o Py_HANDLE>|Handle||Handle to a an opened event log (see <om win32evtlog.OpenEventLog>)
&dwReadFlags, // @pyparm int|Flags||Reading flags
&dwRecordOffset, // @pyparm int|Offset||Record offset to read (in SEEK mode).
&nNumberOfBytesToRead)) // @pyparm int|Size|4096|Output buffer size.
return NULL;
if (nNumberOfBytesToRead == 0)
nNumberOfBytesToRead = EVTLOG_READ_BUF_LEN_DEFAULT;
if (nNumberOfBytesToRead > EVTLOG_READ_BUF_LEN_MAX)
nNumberOfBytesToRead = EVTLOG_READ_BUF_LEN_MAX;
return _MyReadEventLog(hEventLog, dwReadFlags, dwRecordOffset, nNumberOfBytesToRead);
}
PyObject * MyReportEvent( HANDLE hEventLog,
WORD wType, // event type to log
WORD wCategory, // event category
DWORD dwEventID, // event identifier
PyObject *obSID, // user security identifier object (optional)
PyObject *obStrings, // insert strings
PyObject *obData) // raw data
{
PyObject *rc = NULL;
DWORD numStrings = 0;
WCHAR **pStrings = NULL;
PSID sid;
if (!PyWinObject_AsSID(obSID, &sid, TRUE))
return NULL;
PyWinBufferView pybuf(obData, false, true);
if (!pybuf.ok())
return NULL;
if (!PyWinObject_AsWCHARArray(obStrings, &pStrings, &numStrings, TRUE))
return NULL;
if (numStrings > USHRT_MAX){
PyErr_Format(PyExc_ValueError, "String inserts can contain at most %d strings", USHRT_MAX);
goto cleanup;
}
BOOL ok;
Py_BEGIN_ALLOW_THREADS
ok = ReportEventW(hEventLog, wType, wCategory, dwEventID, sid, (WORD)numStrings, pybuf.len(), (const WCHAR **)pStrings, pybuf.ptr());
Py_END_ALLOW_THREADS
if (!ok) {
PyWin_SetAPIError("ReportEvent");
goto cleanup;
}
Py_INCREF(Py_None);
rc = Py_None;
cleanup:
PyWinObject_FreeWCHARArray(pStrings, numStrings);
return rc;
}
%}
#define EVENTLOG_FORWARDS_READ EVENTLOG_FORWARDS_READ
#define EVENTLOG_BACKWARDS_READ EVENTLOG_BACKWARDS_READ
#define EVENTLOG_SEEK_READ EVENTLOG_SEEK_READ
#define EVENTLOG_SEQUENTIAL_READ EVENTLOG_SEQUENTIAL_READ
#define EVENTLOG_SUCCESS EVENTLOG_SUCCESS
#define EVENTLOG_ERROR_TYPE EVENTLOG_ERROR_TYPE
#define EVENTLOG_WARNING_TYPE EVENTLOG_WARNING_TYPE
#define EVENTLOG_INFORMATION_TYPE EVENTLOG_INFORMATION_TYPE
#define EVENTLOG_AUDIT_SUCCESS EVENTLOG_AUDIT_SUCCESS
#define EVENTLOG_AUDIT_FAILURE EVENTLOG_AUDIT_FAILURE
#define EVENTLOG_START_PAIRED_EVENT EVENTLOG_START_PAIRED_EVENT
#define EVENTLOG_END_PAIRED_EVENT EVENTLOG_END_PAIRED_EVENT
#define EVENTLOG_END_ALL_PAIRED_EVENTS EVENTLOG_END_ALL_PAIRED_EVENTS
#define EVENTLOG_PAIRED_EVENT_ACTIVE EVENTLOG_PAIRED_EVENT_ACTIVE
#define EVENTLOG_PAIRED_EVENT_INACTIVE EVENTLOG_PAIRED_EVENT_INACTIVE
// @pyswig |ClearEventLog|Clears the event log
%name (ClearEventLog) BOOLAPI
ClearEventLogW (
HANDLE hEventLog, // @pyparm int|handle||Handle to the event log to clear.
WCHAR *INPUT_NULLOK // @pyparm <o PyUnicode>|eventLogName||The name of the event log to save to, or None
);
// @pyswig |BackupEventLog|Backs up the event log
%name (BackupEventLog) BOOLAPI
BackupEventLogW (
HANDLE hEventLog, // @pyparm int|handle||Handle to the event log to backup.
WCHAR *lpBackupFileName // @pyparm <o PyUnicode>|eventLogName||The name of the event log to save to
);
// @pyswig |CloseEventLog|Closes the eventlog
BOOLAPI
CloseEventLog (
HANDLE hEventLog // @pyparm int|handle||Handle to the event log to close
);
// @pyswig |DeregisterEventSource|Deregisters an Event Source
BOOLAPI
DeregisterEventSource (
HANDLE hEventLog // @pyparm int|handle||Identifies the event log whose handle was returned by <om win32evtlog.RegisterEventSource.>
);
// @pyswig |NotifyChangeEventLog|Lets an application receive notification when an event is written to the event log file specified by the hEventLog parameter. When the event is written to the event log file, the function causes the event object specified by the hEvent parameter to become signaled.
BOOLAPI
NotifyChangeEventLog(
HANDLE hEventLog, // @pyparm int|handle||Handle to an event log file, obtained by calling <om win32evtlog.OpenEventLog> function. When an event is written to this log file, the event specified by hEvent becomes signaled.
PyHANDLE hEvent // @pyparm int|handle||A handle to a Win32 event. This is the event that becomes signaled when an event is written to the event log file specified by the hEventLog parameter.
);
// @pyswig int|GetNumberOfEventLogRecords|Returns the number of event log records.
BOOLAPI
GetNumberOfEventLogRecords (
HANDLE hEventLog, // @pyparm int|handle||Handle to the event log to query.
unsigned long *OUTPUT
);
// @pyswig int|GetOldestEventLogRecord|Returns the number of event log records.
// @rdesc The result is the absolute record number of the oldest record in the given event log.
BOOLAPI
GetOldestEventLogRecord (
HANDLE hEventLog,
unsigned long *OUTPUT
);
// @pyswig <o PyEVTLOG_HANDLE>|OpenEventLog|Opens an event log.
%name (OpenEventLog) PyEVTLOG_HANDLE OpenEventLogW (
WCHAR *INPUT_NULLOK, // @pyparm <o PyUnicode>|serverName||The server name, or None
WCHAR *sourceName // @pyparm <o PyUnicode>|sourceName||specifies the name of the source that the returned handle will reference. The source name must be a subkey of a logfile entry under the EventLog key in the registry.
);
// @pyswig int|RegisterEventSource|Registers an Event Source
%name (RegisterEventSource) HANDLE
RegisterEventSourceW (
WCHAR *INPUT_NULLOK, // @pyparm <o PyUnicode>|serverName||The server name, or None
WCHAR *sourceName // @pyparm <o PyUnicode>|sourceName||The source name
);
// @pyswig <o PyEVTLOG_HANDLE>|OpenBackupEventLog|Opens a previously saved event log.
%name (OpenBackupEventLog) HANDLE OpenBackupEventLogW (
WCHAR *INPUT_NULLOK, // @pyparm <o PyUnicode>|serverName||The server name, or None
WCHAR *fileName // @pyparm <o PyUnicode>|fileName||The filename to open
);
%native (ReadEventLog) MyReadEventLog;
// @pyswig |ReportEvent|Reports an event
%name (ReportEvent) PyObject *MyReportEvent (
HANDLE hEventLog, // @pyparm <o PyHANDLE>|EventLog||Handle to an event log
WORD wType, // @pyparm int|Type||win32con.EVENTLOG_* value
WORD wCategory, // @pyparm int|Category||Source-specific event category
DWORD dwEventID, // @pyparm int|EventID||Source-specific event identifier
PyObject *obUserSid, // @pyparm <o PySID>|UserSid||Sid of current user, can be None
PyObject *obStrings, // @pyparm sequence|Strings||Sequence of unicode strings to be inserted in message
PyObject *obRawData // @pyparm str|RawData||Binary data for event, can be None
);
%{
PyObject *PyWinObject_FromEVT_VARIANT(PEVT_VARIANT val);
// New event log functions available on Vista and later
// @pyswig <o PyEVT_HANDLE>|EvtOpenChannelEnum|Begins an enumeration of event channels
// @comm Accepts keyword args
static PyObject *PyEvtOpenChannelEnum(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[]={"Session", "Flags", NULL};
EVT_HANDLE session=NULL, enum_handle;
DWORD flags=0;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&k:EvtOpenChannelEnum", keywords,
PyWinObject_AsHANDLE, &session, // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine.
&flags)) // @pyparm int|Flags|0|Reserved, use only 0
return NULL;
Py_BEGIN_ALLOW_THREADS
enum_handle=EvtOpenChannelEnum(session, flags);
Py_END_ALLOW_THREADS
if (enum_handle==NULL)
return PyWin_SetAPIError("EvtOpenChannelEnum");
return PyWinObject_FromEVT_HANDLE(enum_handle);
}
PyCFunction pfnPyEvtOpenChannelEnum = (PyCFunction) PyEvtOpenChannelEnum;
// Helper function to convert a list of strings double zero terminated
// into a Python list of strings.
// e.g. hello\0world\0\0 -> [ "hello", "world" ]
static PyObject* PyList_FromDoubleTerminatedWSTR(LPWSTR strings)
{
PyObject* ret = PyList_New(0);
if (ret == NULL) {
return NULL;
}
WCHAR* cur = strings;
while (*cur) {
PyObject* keyword = PyWinObject_FromWCHAR(cur);
PyList_Append(ret, keyword);
Py_XDECREF(keyword);
cur += wcslen(cur) + 1;
}
return ret;
}
// Used internally to format event messages
static PyObject *FormatMessageInternal(EVT_HANDLE metadata, EVT_HANDLE event, DWORD flags, DWORD resourceId)
{
LPWSTR buf = NULL;
PyObject *ret = NULL;
DWORD allocated_size = 0;
DWORD returned_size = 0;
DWORD status = 0;
DWORD err = 0;
BOOL bsuccess = 0;
Py_BEGIN_ALLOW_THREADS
// Get the size of the buffer
bsuccess = EvtFormatMessage(metadata, event, resourceId, 0, NULL, flags, allocated_size, buf, &returned_size);
Py_END_ALLOW_THREADS
err = GetLastError();
// The above call should always return ERROR_INSUFFICIENT_BUFFER
if (!bsuccess && err != ERROR_INSUFFICIENT_BUFFER) {
return PyWin_SetAPIError("EvtFormatMessage");
}
allocated_size = returned_size;
if (flags == EvtFormatMessageKeyword) {
allocated_size += 1; // +1 to double terminate the keyword list
}
allocated_size *= sizeof(WCHAR);
buf = (WCHAR *)malloc(allocated_size);
if (buf == NULL) {
PyErr_NoMemory();
return NULL;
}
Py_BEGIN_ALLOW_THREADS
bsuccess = EvtFormatMessage(metadata, event, resourceId, 0, NULL, flags, allocated_size, buf, &returned_size);
Py_END_ALLOW_THREADS
if (!bsuccess) {
free(buf);
return PyWin_SetAPIError("EvtFormatMessage");
}
if (flags == EvtFormatMessageKeyword) {
buf[returned_size] = L'\0';
}
if (flags == EvtFormatMessageKeyword) {
ret = PyList_FromDoubleTerminatedWSTR(buf);
} else {
ret = PyWinObject_FromWCHAR(buf);
}
free(buf);
return ret;
}
// @pyswig str,list|EvtFormatMessage|Formats a message string.
// @rdesc Returns a formatted message string, or a list of strings if Flags=EvtFormatMessageKeyword
// @comm Accepts keyword args
static PyObject *PyEvtFormatMessage(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[] = {"Metadata", "Event", "Flags", "ResourceId", NULL};
EVT_HANDLE metadata_handle = NULL;
EVT_HANDLE event_handle = NULL;
DWORD flags = 0;
DWORD resourceId = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&k|k:EvtFormatMessage", keywords,
PyWinObject_AsHANDLE, &metadata_handle, // @pyparm <o PyEVT_HANDLE>|Metadata||Handle to provider metadata returned by <om win32evtlog.EvtOpenPublisherMetadata>
PyWinObject_AsHANDLE, &event_handle, // @pyparm <o PyEVT_HANDLE>|Event||Handle to an event
&flags, // @pyparm int|Flags||Type of message to format. EvtFormatMessageEvent or EvtFormatMessageLevel or EvtFormatMessageTask or EvtFormatMessageOpcode or EvtFormatMessageKeyword or EvtFormatMessageChannel or EvtFormatMessageProvider or EvtFormatMessageId or EvtFormatMessageXml. If set to EvtFormatMessageId, callers should also set the 'ResourceId' parameter
&resourceId)) // @pyparm int|ResourceId|0|The resource identifier of a message string returned by <om win32evtlog.EvtGetPublisherMetadataProperty>. Only set this if flags = EvtFormatMessageId.
return NULL;
return FormatMessageInternal(metadata_handle, event_handle, flags, resourceId);
}
PyCFunction pfnPyEvtFormatMessage = (PyCFunction) PyEvtFormatMessage;
// @pyswig str|EvtNextChannelPath|Retrieves a channel path from an enumeration
// @rdesc Returns None at end of enumeration
// @comm Accepts keyword args
static PyObject *PyEvtNextChannelPath(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[]={"ChannelEnum", NULL};
EVT_HANDLE enum_handle;
DWORD allocated_size=256, returned_size, err;
WCHAR *buf=NULL;
PyObject *ret=NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:EvtNextChannelPath", keywords,
PyWinObject_AsHANDLE, &enum_handle)) // @pyparm <o PyEVT_HANDLE>|ChannelEnum||Handle to an enumeration as returned by <om win32evtlog.EvtOpenChannelEnum>
return NULL;
BOOL bsuccess;
while (true){
if (buf)
free(buf);
// MSDN docs say sizes are in bytes, but it doesn't seem to be so ???
WCHAR *buf=(WCHAR *)malloc(allocated_size * sizeof(WCHAR));
if (!buf)
return NULL;
Py_BEGIN_ALLOW_THREADS
bsuccess = EvtNextChannelPath(enum_handle, allocated_size, buf, &returned_size);
Py_END_ALLOW_THREADS
if (bsuccess){
ret=PyWinObject_FromWCHAR(buf);
break;
}
err=GetLastError();
if (err==ERROR_INSUFFICIENT_BUFFER){
allocated_size=returned_size;
continue;
}
if (err==ERROR_NO_MORE_ITEMS){
Py_INCREF(Py_None);
ret=Py_None;
break;
}
PyWin_SetAPIError("EvtNextChannelPath", err);
break;
}
if (buf)
free(buf);
return ret;
}
PyCFunction pfnPyEvtNextChannelPath = (PyCFunction) PyEvtNextChannelPath;
// @pyswig <o PyEVT_HANDLE>|EvtOpenLog|Opens an event log or exported log archive
// @comm Accepts keyword args
static PyObject *PyEvtOpenLog(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[]={"Path", "Flags", "Session", NULL};
EVT_HANDLE session=NULL, log_handle;
DWORD flags=0;
WCHAR *path;
PyObject *obpath;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ok|O&:EvtOpenLog", keywords,
&obpath, // @pyparm str|Path||Event log name or Path of an export file
&flags, // @pyparm int|Flags||EvtOpenChannelPath (1) or EvtOpenFilePath (2)
PyWinObject_AsHANDLE, &session)) // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine.
return NULL;
if (!PyWinObject_AsWCHAR(obpath, &path, FALSE))
return NULL;
Py_BEGIN_ALLOW_THREADS
log_handle=EvtOpenLog(session, path, flags);
Py_END_ALLOW_THREADS
PyWinObject_FreeWCHAR(path);
if (log_handle==NULL)
return PyWin_SetAPIError("EvtOpenLog");
return PyWinObject_FromEVT_HANDLE(log_handle);
}
PyCFunction pfnPyEvtOpenLog = (PyCFunction) PyEvtOpenLog;
// @pyswig |EvtClearLog|Clears an event log and optionally exports events to an archive
// @comm Accepts keyword args
static PyObject *PyEvtClearLog(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[]={"ChannelPath", "TargetFilePath", "Session", "Flags", NULL};
EVT_HANDLE session=NULL;
DWORD flags=0;
TmpWCHAR path, export_path;
PyObject *obpath, *obexport_path=Py_None;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO&k:EvtClearLog", keywords,
&obpath, // @pyparm str|ChannelPath||Name of event log to be cleared
&obexport_path, // @pyparm str|TargetFilePath|None|Name of file in which cleared events will be archived, or None
PyWinObject_AsHANDLE, &session, // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine.
&flags)) // @pyparm int|Flags|0|Reserved, use only 0
return NULL;
if (!PyWinObject_AsWCHAR(obpath, &path, FALSE))
return NULL;
if (!PyWinObject_AsWCHAR(obexport_path, &export_path, TRUE))
return NULL;
BOOL bsuccess;
Py_BEGIN_ALLOW_THREADS
bsuccess = EvtClearLog(session, path, export_path, flags);
Py_END_ALLOW_THREADS
if (bsuccess){
Py_INCREF(Py_None);
return Py_None;
}
return PyWin_SetAPIError("EvtClearLog");
}
PyCFunction pfnPyEvtClearLog = (PyCFunction) PyEvtClearLog;
// @pyswig |EvtExportLog|Exports events from a channel or log file
// @comm Accepts keyword args
static PyObject *PyEvtExportLog(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[]={"Path", "TargetFilePath", "Flags", "Query", "Session", NULL};
EVT_HANDLE session=NULL;
DWORD flags=0;
TmpWCHAR path, query, export_path;
PyObject *obpath, *obexport_path, *obquery=Py_None;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOk|OO&:EvtExportLog", keywords,
&obpath, // @pyparm str|Path||Path of a live event log channel or exported log file
&obexport_path, // @pyparm str|TargetFilePath||File to create, cannot already exist
&flags, // @pyparm int|Flags||Combination of EvtExportLog* flags specifying the type of path
&obquery, // @pyparm str|Query|None|Selects specific events to export
PyWinObject_AsHANDLE, &session)) // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine.
return NULL;
if (!PyWinObject_AsWCHAR(obpath, &path, FALSE))
return NULL;
if (!PyWinObject_AsWCHAR(obexport_path, &export_path, FALSE))
return NULL;
if (!PyWinObject_AsWCHAR(obquery, &query, TRUE))
return NULL;
BOOL bsuccess;
Py_BEGIN_ALLOW_THREADS
bsuccess = EvtExportLog(session, path, query, export_path, flags);
Py_END_ALLOW_THREADS
if (bsuccess){
Py_INCREF(Py_None);
return Py_None;
}
return PyWin_SetAPIError("EvtExportLog");
}
PyCFunction pfnPyEvtExportLog = (PyCFunction) PyEvtExportLog;
// @pyswig |EvtArchiveExportedLog|Localizes an exported event log file
// @comm Accepts keyword args
static PyObject *PyEvtArchiveExportedLog(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[]={"LogFilePath", "Locale", "Session", "Flags", NULL};
EVT_HANDLE session=NULL;
DWORD flags=0;
TmpWCHAR path;
LCID lcid;
PyObject *obpath;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ol|O&k:EvtArchiveExportedLog", keywords,
&obpath, // @pyparm str|LogFilePath||Filename of an exported log file
&lcid, // @pyparm int|Locale||Locale id
PyWinObject_AsHANDLE, &session, // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine.
&flags)) // @pyparm int|Flags|0|Reserved
return NULL;
if (!PyWinObject_AsWCHAR(obpath, &path, FALSE))
return NULL;
BOOL bsuccess;
Py_BEGIN_ALLOW_THREADS
bsuccess = EvtArchiveExportedLog(session, path, lcid, flags);
Py_END_ALLOW_THREADS
if (bsuccess){
Py_INCREF(Py_None);
return Py_None;
}
return PyWin_SetAPIError("EvtArchiveExportedLog");
}
PyCFunction pfnPyEvtArchiveExportedLog = (PyCFunction) PyEvtArchiveExportedLog;
// @pyswig str|EvtGetExtendedStatus|Returns additional error info from last Evt* call
static PyObject *PyEvtGetExtendedStatus(PyObject *self, PyObject *args)
{
DWORD buflen=0, bufneeded=1024;
WCHAR *msg=NULL;
PyObject *ret=NULL;
if (!PyArg_ParseTuple(args, ":EvtGetExtendedStatus"))
return NULL;
BOOL bsuccess;
while (1){
if (msg)
free(msg);
buflen=bufneeded;
msg=(WCHAR *)malloc(buflen * sizeof(WCHAR));
if (msg==NULL){
PyErr_NoMemory();
return NULL;
}
Py_BEGIN_ALLOW_THREADS
bsuccess = EvtGetExtendedStatus(buflen, msg, &bufneeded);
Py_END_ALLOW_THREADS
if (bsuccess){
ret=PyWinObject_FromWCHAR(msg, bufneeded);
break;
}
if (bufneeded <= buflen){
PyWin_SetAPIError("EvtGetExtendedStatus");
break;
}
}
if (msg)
free(msg);
return ret;
}
// @pyswig <o PyEVT_HANDLE>|EvtQuery|Opens a query over a log channel or exported log file
// @comm Accepts keyword args
static PyObject *PyEvtQuery(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[]={"Path", "Flags", "Query", "Session", NULL};
EVT_HANDLE ret, session=NULL;
DWORD flags;
TmpWCHAR path, query;
PyObject *obpath, *obquery=Py_None;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ol|OO&:EvtQuery", keywords,
&obpath, // @pyparm str|Path||Log channel or exported log file, depending on Flags
&flags, // @pyparm int|Flags||Combination of EVT_QUERY_FLAGS (EvtQuery*)
&obquery, // @pyparm str|Query|None|Selects events to return, None or '*' for all events
PyWinObject_AsHANDLE, &session)) // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine.
return NULL;
if (!PyWinObject_AsWCHAR(obpath, &path, FALSE))
return NULL;
if (!PyWinObject_AsWCHAR(obquery, &query, TRUE))
return NULL;
Py_BEGIN_ALLOW_THREADS
ret = EvtQuery(session, path, query, flags);
Py_END_ALLOW_THREADS
if (ret == NULL)
return PyWin_SetAPIError("EvtQuery");
return PyWinObject_FromEVT_HANDLE(ret);
}
PyCFunction pfnPyEvtQuery = (PyCFunction) PyEvtQuery;
// @pyswig (<o PyEVT_HANDLE>,...)|EvtNext|Returns events from a query
// @rdesc Returns a tuple of handles to events. If no items are available, returns
// an empty tuple instead of raising an exception.
// @comm Accepts keyword args
static PyObject *PyEvtNext(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[]={"ResultSet", "Count", "Timeout", "Flags", NULL};
EVT_HANDLE query;
EVT_HANDLE *events =NULL;
DWORD nbr_requested, nbr_returned, flags=0, timeout=(DWORD)-1;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|kk:EvtNext", keywords,
PyWinObject_AsHANDLE, &query, // @pyparm <o PyEVT_HANDLE>|ResultSet||Handle to event query or subscription
&nbr_requested, // @pyparm int|Count||Number of events to return
&timeout, // @pyparm int|Timeout|-1|Time to wait in milliseconds, use -1 for infinite
&flags)) // @pyparm int|Flags|0|Reserved, use only 0
return NULL;
events = (EVT_HANDLE *)malloc(nbr_requested * sizeof(EVT_HANDLE *));
if (events==NULL){
PyErr_NoMemory();
return NULL;
}
BOOL bsuccess;
Py_BEGIN_ALLOW_THREADS
bsuccess = EvtNext(query, nbr_requested, events, timeout, flags, &nbr_returned);
Py_END_ALLOW_THREADS
if (!bsuccess){
free(events);
DWORD err=GetLastError();
if (err == ERROR_NO_MORE_ITEMS || (err == ERROR_INVALID_OPERATION && nbr_returned == 0))
return PyTuple_New(0);
return PyWin_SetAPIError("EvtNext", err);
}
// If tuple construction fails, any handle not yet wrapped in a PyEVT_HANDLE
// will be orphaned and remain open. Should be a rare occurence, though.
PyObject *ret=PyTuple_New(nbr_returned);
if (ret){
for (DWORD i=0;i<nbr_returned;i++){
PyObject *obevt=PyWinObject_FromEVT_HANDLE(events[i]);
if (obevt==NULL){
Py_DECREF(ret);
ret=NULL;
break;
}
PyTuple_SET_ITEM(ret, i, obevt);
}
}
free(events);
return ret;
}
PyCFunction pfnPyEvtNext = (PyCFunction) PyEvtNext;
// @pyswig |EvtSeek|Changes the current position in a result set
// @comm Accepts keyword args
static PyObject *PyEvtSeek(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[]={"ResultSet", "Position", "Flags", "Bookmark", "Timeout", NULL};
EVT_HANDLE query, bookmark=NULL;
DWORD flags, timeout=0;
LONGLONG position;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&Lk|O&k:EvtSeek", keywords,
PyWinObject_AsHANDLE, &query, // @pyparm <o PyEVT_HANDLE>|ResultSet||Handle to event query or subscription
&position, // @pyparm int|Position||Offset (base from which to seek is specified by Flags)
&flags, // @pyparm int|Flags||EvtSeekRelative* flag indicating seek origin
PyWinObject_AsHANDLE, &bookmark, // @pyparm <o PyEVT_HANDLE>|Bookmark|None|Used as seek origin only if Flags contains EvtSeekRelativeToBookmark
&timeout)) // @pyparm int|Timeout|0|Reserved, use only 0
return NULL;
BOOL bsuccess;
Py_BEGIN_ALLOW_THREADS
bsuccess = EvtSeek(query, position, bookmark, timeout, flags);
Py_END_ALLOW_THREADS
if (!bsuccess)
return PyWin_SetAPIError("EvtSeek");
Py_INCREF(Py_None);
return Py_None;;
}
PyCFunction pfnPyEvtSeek = (PyCFunction) PyEvtSeek;
// @pyswig <o PyEVT_HANDLE>|EvtCreateRenderContext|Creates a render context
// @comm Accepts keyword args
static PyObject* PyEvtCreateRenderContext(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[] = {"Flags", NULL};
DWORD flags = EvtRenderContextSystem;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "k:EvtCreateRenderContext", keywords,
&flags)) // @pyparm int|Flags||EvtRenderContextSystem or EvtRenderContextUser. EvtRenderContextValues not currently supported
return NULL;
EVT_HANDLE ret = NULL;
Py_BEGIN_ALLOW_THREADS
ret = EvtCreateRenderContext(0, NULL, flags);
Py_END_ALLOW_THREADS
if (ret == NULL) {
return PyWin_SetAPIError("EvtCreateRenderContext", GetLastError());
}
return PyWinObject_FromEVT_HANDLE(ret);
}
PyCFunction pfnPyEvtCreateRenderContext = (PyCFunction) PyEvtCreateRenderContext;
// Returns a list of Event Values in the same order as returned by the EvtRender function
static PyObject *RenderEventValues(EVT_HANDLE render_context, EVT_HANDLE event)
{
PyObject* ret = NULL;
if (render_context == NULL) {
PyWin_SetAPIError("EvtRender - Invalid render context for EvtRenderEventValues");
return NULL;
}
DWORD allocated_size = 0;
DWORD returned_size = 0;
DWORD prop_count = 0;
PEVT_VARIANT variants = NULL;
BOOL bsuccess = 0;
DWORD err = ERROR_SUCCESS;
Py_BEGIN_ALLOW_THREADS
bsuccess = EvtRender(render_context, event, EvtRenderEventValues, allocated_size, variants, &returned_size, &prop_count);
Py_END_ALLOW_THREADS
// bsuccess should always be false here, because we call it initially to get
// the size of the buffer
if (!bsuccess) {
err = GetLastError();
if (err != ERROR_INSUFFICIENT_BUFFER) {
PyWin_SetAPIError("EvtRender", err);
goto cleanup;
}
// allocate buffer size
allocated_size = returned_size;
variants = (PEVT_VARIANT)malloc(allocated_size);
if (variants == NULL) {
PyErr_NoMemory();
goto cleanup;
}
Py_BEGIN_ALLOW_THREADS
bsuccess = EvtRender(render_context, event, EvtRenderEventValues, allocated_size, variants, &returned_size, &prop_count);
Py_END_ALLOW_THREADS
}
if (!bsuccess) {
PyWin_SetAPIError("EvtRender");
goto cleanup;
}