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.
828 lines
22 KiB
828 lines
22 KiB
/*++
|
|
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
tracedp.c
|
|
|
|
Abstract:
|
|
|
|
Sample trace provider program.
|
|
|
|
// end_sdk
|
|
Author:
|
|
|
|
Jee Fung Pang (jeepang) 03-Dec-1997
|
|
|
|
Revision History:
|
|
|
|
Insung Park (insungp) 18-Jan-2001
|
|
|
|
Modified tracedp so that when tracedp generates User Mof Events
|
|
with some sample strings, integers, floats, and arrays.
|
|
|
|
|
|
// begin_sdk
|
|
--*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <windows.h>
|
|
#include <shellapi.h>
|
|
|
|
#include <tchar.h>
|
|
#include <wmistr.h>
|
|
|
|
#include <guiddef.h>
|
|
#include <evntrace.h>
|
|
|
|
#define MAXEVENTS 5000
|
|
#define MAXSTR 1024
|
|
#define MAXTHREADS 128
|
|
|
|
// sample string data
|
|
#define WIDE_DATA_STRING L"Sample Wide String"
|
|
#define COUNTED_DATA_STRING L"Sample Counted String"
|
|
|
|
TRACEHANDLE LoggerHandle;
|
|
#define ResourceName _T("MofResource")
|
|
TCHAR ImagePath[MAXSTR];
|
|
|
|
GUID TransactionGuid =
|
|
{0xce5b1020, 0x8ea9, 0x11d0, 0xa4, 0xec, 0x00, 0xa0, 0xc9, 0x06, 0x29, 0x10};
|
|
GUID ControlGuid[2] =
|
|
{
|
|
{0xd58c126f, 0xb309, 0x11d1, 0x96, 0x9e, 0x00, 0x00, 0xf8, 0x75, 0xa5, 0xbc},
|
|
{0x7c6a708a, 0xba1e, 0x11d2, 0x8b, 0xbf, 0x00, 0x00, 0xf8, 0x06, 0xef, 0xe0}
|
|
};
|
|
|
|
TRACE_GUID_REGISTRATION TraceGuidReg[] =
|
|
{
|
|
{ (LPGUID)&TransactionGuid,
|
|
NULL
|
|
}
|
|
};
|
|
|
|
typedef enum {
|
|
TYPE_USER_EVENT,
|
|
TYPE_INSTANCE_EVENT,
|
|
TYPE_MOF_EVENT,
|
|
TYPEPTR_GUID
|
|
} TypeEventType;
|
|
|
|
typedef struct _USER_EVENT {
|
|
EVENT_TRACE_HEADER Header;
|
|
ULONG EventInfo;
|
|
} USER_EVENT, *PUSER_EVENT;
|
|
|
|
typedef struct _USER_INSTANCE_EVENT {
|
|
EVENT_INSTANCE_HEADER Header;
|
|
ULONG mofData;
|
|
} USER_INSTANCE_EVENT, *PUSER_INSTANCE_EVENT;
|
|
|
|
// customized event to use sample data that follow
|
|
typedef struct _USER_MOF_EVENT {
|
|
EVENT_TRACE_HEADER Header;
|
|
MOF_FIELD mofData;
|
|
} USER_MOF_EVENT, *PUSER_MOF_EVENT;
|
|
|
|
// sample data structure
|
|
typedef struct _INTEGER_SAMPLE_EVENT {
|
|
CHAR sc;
|
|
UCHAR uc;
|
|
SHORT sh;
|
|
ULONG ul;
|
|
} INTEGER_SAMPLE_EVENT, *PINTEGER_SAMPLE_EVENT;
|
|
|
|
typedef struct _FLOAT_SAMPLE_EVENT {
|
|
float fl;
|
|
double db;
|
|
} FLOAT_SAMPLE_EVENT, *PFLOAT_SAMPLE_EVENT;
|
|
|
|
typedef struct _ARRAY_SAMPLE_EVENT {
|
|
CHAR ca[9];
|
|
} ARRAY_SAMPLE_EVENT, *PARRAY_SAMPLE_EVENT;
|
|
|
|
TypeEventType EventType = TYPE_USER_EVENT;
|
|
TRACEHANDLE RegistrationHandle[2];
|
|
BOOLEAN TraceOnFlag;
|
|
ULONG EnableLevel = 0;
|
|
ULONG EnableFlags = 0;
|
|
BOOLEAN bPersistData = FALSE;
|
|
ULONG nSleepTime = 0;
|
|
ULONG EventCount = 0;
|
|
|
|
BOOLEAN bInstanceTrace=0, bUseGuidPtr=0, bUseMofPtr=0;
|
|
BOOLEAN bIncorrect = FALSE;
|
|
BOOLEAN bUseNullPtr = FALSE;
|
|
BOOLEAN bFirstTime = TRUE;
|
|
|
|
ULONG InitializeTrace(
|
|
void
|
|
);
|
|
|
|
ULONG
|
|
ControlCallback(
|
|
IN WMIDPREQUESTCODE RequestCode,
|
|
IN PVOID Context,
|
|
IN OUT ULONG *InOutBufferSize,
|
|
IN OUT PVOID Buffer
|
|
);
|
|
|
|
LPTSTR
|
|
DecodeStatus(
|
|
IN ULONG Status,
|
|
TCHAR *ErrorMsg,
|
|
IN ULONG StringSize
|
|
);
|
|
|
|
|
|
void
|
|
LogProc();
|
|
|
|
ULONG
|
|
ahextoi(
|
|
IN TCHAR *s
|
|
);
|
|
|
|
void
|
|
StringToGuid(
|
|
TCHAR *str,
|
|
LPGUID guid
|
|
);
|
|
|
|
ULONG MaxEvents = MAXEVENTS;
|
|
ULONG gnMultiReg = 1;
|
|
|
|
ULONG
|
|
ahextoi(
|
|
IN TCHAR *s
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Converts a hex string into a number.
|
|
|
|
Arguments:
|
|
|
|
s - A hex string in TCHAR.
|
|
|
|
Return Value:
|
|
|
|
ULONG - The number in the string.
|
|
|
|
|
|
--*/
|
|
{
|
|
int len;
|
|
ULONG num, base, hex;
|
|
|
|
len = _tcslen(s);
|
|
hex = 0; base = 1; num = 0;
|
|
while (--len >= 0) {
|
|
if ( (s[len] == 'x' || s[len] == 'X') &&
|
|
(s[len-1] == '0') )
|
|
break;
|
|
if (s[len] >= '0' && s[len] <= '9')
|
|
num = s[len] - '0';
|
|
else if (s[len] >= 'a' && s[len] <= 'f')
|
|
num = (s[len] - 'a') + 10;
|
|
else if (s[len] >= 'A' && s[len] <= 'F')
|
|
num = (s[len] - 'A') + 10;
|
|
else
|
|
continue;
|
|
|
|
hex += num * base;
|
|
base = base * 16;
|
|
}
|
|
return hex;
|
|
}
|
|
|
|
void StringToGuid(
|
|
TCHAR *str,
|
|
LPGUID guid
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Converts a String into a GUID.
|
|
|
|
Arguments:
|
|
|
|
str - String representing a GUID.
|
|
guid - Pointer to a GUID for ourput
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
TCHAR temp[10];
|
|
int i, n;
|
|
|
|
_tcsncpy(temp, str, 8);
|
|
temp[8] = 0;
|
|
guid->Data1 = ahextoi(temp);
|
|
_tcsncpy(temp, &str[9], 4);
|
|
temp[4] = 0;
|
|
guid->Data2 = (USHORT) ahextoi(temp);
|
|
_tcsncpy(temp, &str[14], 4);
|
|
temp[4] = 0;
|
|
guid->Data3 = (USHORT) ahextoi(temp);
|
|
|
|
for (i=0; i<2; i++) {
|
|
_tcsncpy(temp, &str[19 + (i*2)], 2);
|
|
temp[2] = 0;
|
|
guid->Data4[i] = (UCHAR) ahextoi(temp);
|
|
}
|
|
for (i=2; i<8; i++) {
|
|
_tcsncpy(temp, &str[20 + (i*2)], 2);
|
|
temp[2] = 0;
|
|
guid->Data4[i] = (UCHAR) ahextoi(temp);
|
|
}
|
|
}
|
|
|
|
__cdecl main(argc, argv)
|
|
int argc;
|
|
char **argv;
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
main() routine.
|
|
|
|
Arguments:
|
|
|
|
Usage: TraceDp [options] [number of events]
|
|
-UseEventTraceHeader this is default.
|
|
-UseEventInstanceHeader
|
|
-UseMofPtrFlag
|
|
-Thread [n] Sets the number of event-generating threads.
|
|
-GuidPtr Use GUID pointer instead of GUID itself.
|
|
-MofPtr Use MOF pointer for additional data.
|
|
-GuidPtrMofPtr User GUID pointer and MOF pointer.
|
|
-InCorrectMofPtr Use incorrect MOF pointer (Creates an error case).
|
|
-NullMofPtr Use NULL MOF pointer (Creates an error case).
|
|
-MultiReg Register multiple event GUIDS.
|
|
-Sleep [n] Sets the sleep time before unregistering.
|
|
[number of events] default is 5000
|
|
|
|
Return Value:
|
|
|
|
Error Code defined in winerror.h : If the function succeeds,
|
|
it returns ERROR_SUCCESS (== 0).
|
|
|
|
--*/
|
|
{
|
|
ULONG Status;
|
|
LPGUID Guid = NULL;
|
|
DWORD ThreadId;
|
|
HANDLE hThreadVector[MAXTHREADS];
|
|
ULONG i;
|
|
ULONG nThreads = 1;
|
|
LPTSTR *targv, *utargv = NULL;
|
|
|
|
MaxEvents = MAXEVENTS;
|
|
TraceOnFlag = FALSE;
|
|
|
|
#ifdef UNICODE
|
|
if ((targv = CommandLineToArgvW(
|
|
GetCommandLineW(), // pointer to a command-line string
|
|
&argc // receives the argument count
|
|
)) == NULL)
|
|
{
|
|
return(GetLastError());
|
|
};
|
|
utargv = targv;
|
|
#else
|
|
targv = argv;
|
|
#endif
|
|
|
|
// process command line arguments to override defaults
|
|
//
|
|
while (--argc > 0)
|
|
{
|
|
targv ++;
|
|
if (**targv == '-' || **targv == '/')
|
|
{
|
|
if(targv[0][0] == '/' ) targv[0][0] = '-';
|
|
if (!_tcsicmp(targv[0],_T("-UseEventTraceHeader")))
|
|
{
|
|
EventType = TYPE_USER_EVENT;
|
|
}
|
|
else if (!_tcsicmp(targv[0],_T("-UseEventInstanceHeader")))
|
|
{
|
|
EventType = TYPE_INSTANCE_EVENT;
|
|
}
|
|
else if (!_tcsicmp(targv[0],_T("-UseMofPtrFlag")))
|
|
{
|
|
EventType = TYPE_MOF_EVENT;
|
|
}
|
|
// end_sdk
|
|
else if (!_tcsicmp(targv[0],_T("-Persist")))
|
|
{
|
|
bPersistData = TRUE;
|
|
}
|
|
// begin_sdk
|
|
else if (!_tcsicmp(targv[0],_T("-Thread")))
|
|
{
|
|
if (argc > 1) {
|
|
targv++; --argc;
|
|
nThreads = _ttoi(targv[0]);
|
|
if (nThreads > MAXTHREADS)
|
|
nThreads = MAXTHREADS;
|
|
}
|
|
}
|
|
else if (!_tcsicmp(targv[0],_T("-GuidPtr")))
|
|
{
|
|
bUseGuidPtr = TRUE;
|
|
}
|
|
else if (!_tcsicmp(targv[0],_T("-MofPtr")))
|
|
{
|
|
bUseMofPtr = TRUE;
|
|
}
|
|
else if (!_tcsicmp(targv[0],_T("-GuidPtrMofPtr")))
|
|
{
|
|
bUseGuidPtr = TRUE;
|
|
bUseMofPtr = TRUE;
|
|
}
|
|
else if (!_tcsicmp(targv[0],_T("-InCorrectMofPtr")))
|
|
{
|
|
bUseMofPtr = TRUE;
|
|
bIncorrect = TRUE;
|
|
}
|
|
else if (!_tcsicmp(targv[0],_T("-NullMofPtr")))
|
|
{
|
|
bUseMofPtr = TRUE;
|
|
bUseNullPtr = TRUE;
|
|
bIncorrect = TRUE;;
|
|
}
|
|
else if (!_tcsicmp(targv[0],_T("-MultiReg")))
|
|
{
|
|
gnMultiReg = 2;
|
|
}
|
|
else if (!_tcsicmp(targv[0], _T("-Guid"))) {
|
|
if (argc > 1) {
|
|
if (targv[1][0] == _T('#')) {
|
|
StringToGuid(&targv[1][1], &ControlGuid[0]);
|
|
++targv; --argc;
|
|
}
|
|
}
|
|
}
|
|
else if (!_tcsicmp(targv[0],_T("-Sleep")))
|
|
{
|
|
if (argc > 1) {
|
|
targv++; --argc;
|
|
nSleepTime = _ttoi(targv[0]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("Usage: TraceDp [options] [number of events]\n");
|
|
printf("\t-UseEventTraceHeader this is default.\n");
|
|
printf("\t-UseEventInstanceHeader\n");
|
|
printf("\t-UseMofPtrFlag\n");
|
|
printf("\t-Thread [n]\n");
|
|
printf("\t-GuidPtr\n");
|
|
printf("\t-MofPtr\n");
|
|
printf("\t-GuidPtrMofPtr\n");
|
|
printf("\t-InCorrectMofPtr\n");
|
|
printf("\t-NullMofPtr\n");
|
|
printf("\t-MultiReg\n");
|
|
printf("\t-Guid #[guid] alternative control GUID\n");
|
|
printf("\t-Sleep [n]\n");
|
|
printf("\t[number of events] default is 5000\n");
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
else if (** targv >= '0' && ** targv <= '9')
|
|
{
|
|
MaxEvents = _ttoi(targv[0]);
|
|
}
|
|
}
|
|
|
|
if (utargv != NULL) {
|
|
GlobalFree(utargv);
|
|
}
|
|
|
|
Status = InitializeTrace();
|
|
if (Status != ERROR_SUCCESS) {
|
|
return Status;
|
|
}
|
|
|
|
_tprintf(_T("Testing Logger with %d events (%d,%d)\n"),
|
|
MaxEvents, EventType, bPersistData);
|
|
|
|
while (! TraceOnFlag)
|
|
_sleep(1000);
|
|
|
|
for (i=0; i < nThreads; i++) {
|
|
hThreadVector[i] = CreateThread(NULL,
|
|
0,
|
|
(LPTHREAD_START_ROUTINE) LogProc,
|
|
NULL,
|
|
0,
|
|
(LPDWORD)&ThreadId);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, hThreadVector, TRUE, INFINITE);
|
|
|
|
if (nSleepTime > 0) {
|
|
_sleep(nSleepTime * 1000);
|
|
}
|
|
|
|
for (i=0; i<gnMultiReg; i++) {
|
|
UnregisterTraceGuids(RegistrationHandle[i]);
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
LPTSTR
|
|
DecodeStatus(
|
|
IN ULONG Status,
|
|
IN OUT TCHAR *ErrorMsg,
|
|
IN ULONG StringSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Decodes error status.
|
|
|
|
Arguments:
|
|
|
|
Status - Return status of function calls to be decoded.
|
|
|
|
Return Value:
|
|
|
|
Pointer to a decoded error message.
|
|
|
|
--*/
|
|
{
|
|
RtlZeroMemory(ErrorMsg, (StringSize * sizeof(TCHAR)));
|
|
FormatMessage(
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
Status,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
(LPTSTR) ErrorMsg,
|
|
StringSize,
|
|
NULL );
|
|
return ErrorMsg;
|
|
}
|
|
|
|
ULONG InitializeTrace(
|
|
void
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Register traces.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Error Status. ERROR_SUCCESS if successful.
|
|
|
|
--*/
|
|
{
|
|
ULONG Status;
|
|
ULONG i, j;
|
|
|
|
if (!GetModuleFileName(NULL, ImagePath, MAXSTR)) {
|
|
return (ERROR_FILE_NOT_FOUND);
|
|
}
|
|
|
|
for (i=0; i<gnMultiReg; i++) {
|
|
|
|
Status = RegisterTraceGuids(
|
|
(WMIDPREQUEST)ControlCallback, //use same callback function
|
|
(PVOID)(INT_PTR)(0x12345678+i), // RequestContext
|
|
(LPCGUID)&ControlGuid[i],
|
|
1,
|
|
&TraceGuidReg[i],
|
|
(LPCTSTR)&ImagePath[0],
|
|
(LPCTSTR)ResourceName,
|
|
&RegistrationHandle[i]
|
|
);
|
|
|
|
if (Status != ERROR_SUCCESS) {
|
|
TCHAR ErrorMsg[MAXSTR];
|
|
|
|
_tprintf(_T("Trace registration failed\n"));
|
|
if( i > 0) {
|
|
for (j=0; j<i; j++) {
|
|
UnregisterTraceGuids(RegistrationHandle[j]);
|
|
}
|
|
}
|
|
_tprintf(_T("InitializeTrace failed. i=%d, status=%d, %s\n"), i, Status, DecodeStatus(Status, ErrorMsg, MAXSTR));
|
|
return(Status);
|
|
}
|
|
else {
|
|
_tprintf(_T("Trace registered successfully\n"));
|
|
}
|
|
}
|
|
|
|
return(Status);
|
|
}
|
|
|
|
ULONG
|
|
ControlCallback(
|
|
IN WMIDPREQUESTCODE RequestCode,
|
|
IN PVOID Context,
|
|
IN OUT ULONG *InOutBufferSize,
|
|
IN OUT PVOID Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Callback function when enabled.
|
|
|
|
Arguments:
|
|
|
|
RequestCode - Flag for either enable or disable.
|
|
Context - User-defined context.
|
|
InOutBufferSize - not used.
|
|
Buffer - WNODE_HEADER for the logger session.
|
|
|
|
Return Value:
|
|
|
|
Error Status. ERROR_SUCCESS if successful.
|
|
|
|
--*/
|
|
{
|
|
ULONG Status;
|
|
ULONG RetSize;
|
|
|
|
Status = ERROR_SUCCESS;
|
|
|
|
switch (RequestCode)
|
|
{
|
|
case WMI_ENABLE_EVENTS:
|
|
{
|
|
RetSize = 0;
|
|
LoggerHandle = GetTraceLoggerHandle( Buffer );
|
|
EnableLevel = GetTraceEnableLevel(LoggerHandle);
|
|
EnableFlags = GetTraceEnableFlags(LoggerHandle);
|
|
_tprintf(_T("Logging enabled to 0x%016I64x(%d,%d,%d)\n"),
|
|
LoggerHandle, RequestCode, EnableLevel, EnableFlags);
|
|
TraceOnFlag = TRUE;
|
|
break;
|
|
}
|
|
case WMI_DISABLE_EVENTS:
|
|
{
|
|
TraceOnFlag = FALSE;
|
|
RetSize = 0;
|
|
LoggerHandle = 0;
|
|
_tprintf(_T("\nLogging Disabled\n"));
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
RetSize = 0;
|
|
Status = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
*InOutBufferSize = RetSize;
|
|
return(Status);
|
|
}
|
|
|
|
void
|
|
LogProc()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Generates events. It is spawned as separate threads.
|
|
Based on the options given by users, it generates different events.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
USER_EVENT UserEvent;
|
|
USER_INSTANCE_EVENT UserInstanceEvent;
|
|
USER_MOF_EVENT UserMofEvent;
|
|
EVENT_INSTANCE_INFO InstInfo;
|
|
PMOF_FIELD mofField;
|
|
ULONG i;
|
|
PWNODE_HEADER Wnode;
|
|
ULONG status;
|
|
ULONG InstanceId;
|
|
LPGUID Guid = NULL;
|
|
ULONG nTemp;
|
|
USHORT nSize, nStrEventSize;
|
|
WCHAR wstrTemp[MAXSTR];
|
|
|
|
INTEGER_SAMPLE_EVENT ise;
|
|
FLOAT_SAMPLE_EVENT fse;
|
|
ARRAY_SAMPLE_EVENT ase;
|
|
CHAR *sse, *ptr;
|
|
|
|
// some arbitrary data for MOF structs
|
|
ise.sc = 'x';
|
|
ise.uc = 'y';
|
|
ise.sh = (SHORT)rand();
|
|
ise.ul = (ULONG)rand();
|
|
|
|
nTemp = 0;
|
|
while (nTemp == 0) {
|
|
nTemp = rand();
|
|
}
|
|
|
|
fse.fl = ((float)rand() / (float)nTemp);
|
|
fse.db = ((double)rand() / (double)nTemp);
|
|
|
|
ase.ca[0] = 'M';
|
|
ase.ca[1] = 'i';
|
|
ase.ca[2] = 'c';
|
|
ase.ca[3] = 'r';
|
|
ase.ca[4] = 'o';
|
|
ase.ca[5] = 's';
|
|
ase.ca[6] = 'o';
|
|
ase.ca[7] = 'f';
|
|
ase.ca[8] = 't';
|
|
|
|
nStrEventSize = ((wcslen(WIDE_DATA_STRING) + 1) * sizeof(WCHAR)) + sizeof(SHORT) + (wcslen(COUNTED_DATA_STRING) * sizeof(WCHAR));
|
|
sse = (PCHAR) malloc(nStrEventSize);
|
|
|
|
if (NULL != sse) {
|
|
ptr = sse;
|
|
wcscpy(wstrTemp, WIDE_DATA_STRING);
|
|
wstrTemp[wcslen(WIDE_DATA_STRING)] = L'\0';
|
|
memcpy(ptr, wstrTemp, (wcslen(WIDE_DATA_STRING) + 1) * sizeof(WCHAR));
|
|
ptr += (wcslen(WIDE_DATA_STRING) + 1) * sizeof(WCHAR);
|
|
nSize = (USHORT)(wcslen(COUNTED_DATA_STRING) * sizeof(WCHAR));
|
|
memcpy(ptr, &nSize, sizeof(USHORT));
|
|
ptr += sizeof(USHORT);
|
|
wcscpy(wstrTemp, COUNTED_DATA_STRING);
|
|
memcpy(ptr, wstrTemp, wcslen(COUNTED_DATA_STRING) * sizeof(WCHAR));
|
|
}
|
|
|
|
RtlZeroMemory(&UserEvent, sizeof(UserEvent));
|
|
Wnode = (PWNODE_HEADER) &UserEvent;
|
|
UserEvent.Header.Size = sizeof(USER_EVENT);
|
|
UserEvent.Header.Flags = WNODE_FLAG_TRACED_GUID;
|
|
UserEvent.Header.Guid = TransactionGuid;
|
|
if (bPersistData)
|
|
UserEvent.Header.Flags |= WNODE_FLAG_PERSIST_EVENT;
|
|
|
|
RtlZeroMemory(&UserInstanceEvent, sizeof(UserInstanceEvent));
|
|
UserInstanceEvent.Header.Size = sizeof(UserInstanceEvent);
|
|
UserInstanceEvent.Header.Flags = WNODE_FLAG_TRACED_GUID;
|
|
if (bPersistData)
|
|
UserInstanceEvent.Header.Flags |= WNODE_FLAG_PERSIST_EVENT;
|
|
|
|
RtlZeroMemory(&UserMofEvent, sizeof(UserMofEvent));
|
|
Wnode = (PWNODE_HEADER) &UserMofEvent;
|
|
UserMofEvent.Header.Size = sizeof(UserMofEvent);
|
|
UserMofEvent.Header.Flags = WNODE_FLAG_TRACED_GUID;
|
|
UserMofEvent.Header.Guid = TransactionGuid;
|
|
// end_sdk
|
|
if (bPersistData)
|
|
UserMofEvent.Header.Flags |= WNODE_FLAG_PERSIST_EVENT;
|
|
// begin_sdk
|
|
if (bUseGuidPtr) {
|
|
UserEvent.Header.Flags |= WNODE_FLAG_USE_GUID_PTR;
|
|
UserEvent.Header.GuidPtr = (ULONGLONG)&TransactionGuid;
|
|
UserMofEvent.Header.Flags |= WNODE_FLAG_USE_GUID_PTR;
|
|
UserMofEvent.Header.GuidPtr = (ULONGLONG)&TransactionGuid;
|
|
}
|
|
|
|
i = 0;
|
|
while (TraceOnFlag) {
|
|
if ((i % 4) == 0) {
|
|
UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_START;
|
|
UserInstanceEvent.Header.Class.Type = EVENT_TRACE_TYPE_START;
|
|
UserMofEvent.Header.Class.Type = 3;
|
|
}
|
|
else if ((i % 4) == 1) {
|
|
UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_END;
|
|
UserInstanceEvent.Header.Class.Type = EVENT_TRACE_TYPE_END;
|
|
UserMofEvent.Header.Class.Type = 4;
|
|
}
|
|
else if ((i % 4) == 2) {
|
|
UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_START;
|
|
UserInstanceEvent.Header.Class.Type = EVENT_TRACE_TYPE_START;
|
|
UserMofEvent.Header.Class.Type = 5;
|
|
}
|
|
else {
|
|
UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_END;
|
|
UserInstanceEvent.Header.Class.Type = EVENT_TRACE_TYPE_END;
|
|
UserMofEvent.Header.Class.Type = 6;
|
|
}
|
|
|
|
switch (EventType)
|
|
{
|
|
case TYPE_INSTANCE_EVENT:
|
|
if (UserInstanceEvent.Header.Class.Type == EVENT_TRACE_TYPE_START) {
|
|
status = CreateTraceInstanceId(
|
|
(PVOID) TraceGuidReg[0].RegHandle,
|
|
& InstInfo);
|
|
|
|
if (status != ERROR_SUCCESS) {
|
|
TCHAR ErrorMsg[MAXSTR];
|
|
fprintf(stderr,
|
|
"CreatTraceInstanceId() status=%d, %ws\n",
|
|
status, DecodeStatus(status, ErrorMsg, MAXSTR)
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
status = TraceEventInstance(
|
|
LoggerHandle,
|
|
(PEVENT_INSTANCE_HEADER) & UserInstanceEvent,
|
|
& InstInfo,
|
|
NULL);
|
|
break;
|
|
|
|
case TYPE_USER_EVENT:
|
|
UserEvent.EventInfo = InterlockedIncrement(&EventCount);
|
|
status = TraceEvent(
|
|
LoggerHandle,
|
|
(PEVENT_TRACE_HEADER) & UserEvent);
|
|
break;
|
|
|
|
case TYPE_MOF_EVENT:
|
|
UserMofEvent.Header.Flags |= WNODE_FLAG_USE_MOF_PTR;
|
|
mofField = (PMOF_FIELD) & UserMofEvent.mofData;
|
|
if (UserMofEvent.Header.Class.Type == 4) {
|
|
mofField->DataPtr = (ULONGLONG) (&ise);
|
|
mofField->Length = sizeof(INTEGER_SAMPLE_EVENT);
|
|
}
|
|
else if (UserMofEvent.Header.Class.Type == 5) {
|
|
mofField->DataPtr = (ULONGLONG) (&fse);
|
|
mofField->Length = sizeof(FLOAT_SAMPLE_EVENT);
|
|
}
|
|
else if (UserMofEvent.Header.Class.Type == 6) {
|
|
mofField->DataPtr = (ULONGLONG) (&ase);
|
|
mofField->Length = sizeof(ARRAY_SAMPLE_EVENT);
|
|
}
|
|
else {
|
|
mofField->DataPtr = (ULONGLONG) (sse);
|
|
mofField->Length = nStrEventSize;
|
|
}
|
|
if (bUseNullPtr)
|
|
mofField->DataPtr = (ULONGLONG) (NULL);
|
|
if (bIncorrect)
|
|
mofField->Length += 1000;
|
|
|
|
status = TraceEvent(
|
|
LoggerHandle,
|
|
(PEVENT_TRACE_HEADER) & UserMofEvent);
|
|
if (status != ERROR_SUCCESS) {
|
|
fprintf(stderr, "Error(%d) while writing event.\n", status);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
status = ERROR_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
// logger buffers out of memory should not prevent provider from
|
|
// generating events. This will only cause events lost.
|
|
//
|
|
if (status == ERROR_NOT_ENOUGH_MEMORY) {
|
|
status = ERROR_SUCCESS;
|
|
}
|
|
|
|
if (status != ERROR_SUCCESS) {
|
|
TCHAR ErrorMsg[MAXSTR];
|
|
_ftprintf(stderr, _T("\nError %s while writing event\n"),
|
|
DecodeStatus(status, ErrorMsg, MAXSTR));
|
|
_ftprintf( stderr, _T("Logging terminated due to error\n"));
|
|
free(sse);
|
|
return;
|
|
}
|
|
|
|
i++;
|
|
if (i >= MaxEvents)
|
|
break;
|
|
|
|
if (!(i % 100))
|
|
_tprintf(_T("."));
|
|
_sleep(1);
|
|
}
|
|
|
|
free(sse);
|
|
}
|
|
|