windows-nt/Source/XPSP1/NT/base/wmi/drt/tracelog/provider/provider.c
2020-09-26 16:20:57 +08:00

429 lines
12 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <ole2.h>
#include <wmistr.h>
#include <evntrace.h>
#include <time.h>
#include <tchar.h>
#define DEBUG
#define MAXEVENTS 5000
#define MAXSTR 1024
TRACEHANDLE LoggerHandle;
#define ResourceName _T("MofResource")
TCHAR ImagePath[MAXSTR];
GUID TransactionGuid[2] =
{
{0xce5b1020, 0x8ea9, 0x11d0, 0xa4, 0xec, 0x00, 0xa0, 0xc9, 0x06, 0x29, 0x10},
{0xf684e86f, 0xba1d, 0x11d2, 0x8b, 0xbf, 0x00, 0x00, 0xf8, 0x06, 0xef, 0xe0}
};
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[2] =
{
{ (LPGUID)&TransactionGuid[0],
NULL
},
{ (LPGUID)&TransactionGuid[1],
NULL
}
};
typedef struct _USER_EVENT {
EVENT_TRACE_HEADER Header;
MOF_FIELD mofData;
} USER_EVENT, *PUSER_EVENT;
typedef struct _USER_INSTANCE_EVENT {
EVENT_INSTANCE_HEADER Header;
MOF_FIELD mofData;
} USER_INSTANCE_EVENT, *PUSER_INSTANCE_EVENT;
TRACEHANDLE RegistrationHandle[2];
BOOLEAN RegistrationSuccess;
ULONG EnableLevel = 0;
ULONG EnableFlags = 0;
ULONG InitializeTrace(
IN LPTSTR ExePath, FILE* fp
);
ULONG
ControlCallback(
IN WMIDPREQUESTCODE RequestCode,
IN PVOID Context,
IN OUT ULONG *InOutBufferSize,
IN OUT PVOID Buffer
);
GUID StringToGuid(TCHAR *str);
LPTSTR Decodestatus(IN ULONG Status);
HANDLE ghTraceOnEvent;
ULONG TraceOnFlag;
UINT nSleepTime = 0;
TCHAR ErrorMsg[MAXSTR];
ULONG gnMultiReg=1;
int __cdecl _tmain(int argc, _TCHAR **argv)
{
ULONG status;
USER_EVENT UserEvent;
USER_INSTANCE_EVENT UserInstanceEvent;
EVENT_INSTANCE_INFO InstInfo;
ULONG i;
ULONG MaxEvents;
//ULONG InstanceId;
PWNODE_HEADER Wnode;
TCHAR *str;
int err;
BOOL bInstanceTrace=0, bUseGuidPtr=0, bUseMofPtr=0;
BOOL bIncorrect = FALSE;
BOOL bUseNullPtr = FALSE;
PMOF_FIELD mofField;
TCHAR strMofData[MAXSTR];
FILE *fp;
fp = _tfopen(_T("provider.log"), _T("a+")); if(fp==NULL) {_tprintf(_T("pf=NULL\n"));};
MaxEvents = MAXEVENTS;
TraceOnFlag = 0;
if (argc > 1)
MaxEvents = _ttoi(argv[1]);
if(argc > 2)
ControlGuid[0] = StringToGuid(argv[2]);
if(argc > 3)
nSleepTime = _ttoi(argv[3]);
err = UuidToString(&ControlGuid[0], &str);
if(RPC_S_OK == err)
_tprintf(_T("The ControlGuid is : %s\n"), str);
else
_tprintf(_T("Error(%d) converting uuid\n"), err);
_ftprintf(fp, _T("The ControlGuid is : %s\n"), str);
if(argc > 4) {
if(!_tcscmp(_T("TraceInstance"), argv[4]))
bInstanceTrace = TRUE;
}
if(argc > 5) {
if(!_tcscmp(_T("GuidPtr"), argv[5]))
bUseGuidPtr = TRUE;
else if(!_tcscmp(_T("MofPtr"), argv[5]))
bUseMofPtr = TRUE;
else if(!_tcscmp(_T("GuidPtrMofPtr"), argv[5])) {
bUseGuidPtr = TRUE;
bUseMofPtr = TRUE;
}
else if (!_tcscmp(_T("InCorrectMofPtr"), argv[5])) {
bUseMofPtr = TRUE;
bIncorrect = TRUE;
}
else if (!_tcscmp(_T("NullMofPtr"), argv[5])) {
bUseMofPtr = TRUE;
bUseNullPtr = TRUE;
bIncorrect = TRUE;
}
}
if(argc > 6) {
if(!_tcscmp(_T("MultiReg"), argv[6]))
gnMultiReg=2; //use 2 registrations for now
}
status = InitializeTrace(_T("tracedp.exe"), fp);
if (status != ERROR_SUCCESS) {
_ftprintf(fp, _T("InitializeTrace failed, status=%d, %s\n"), status, Decodestatus(status));
return 0;
}
_tprintf(_T("Testing Logger with %d events\n"), MaxEvents);
RtlZeroMemory(&UserEvent, sizeof(UserEvent));
Wnode = (PWNODE_HEADER) &UserEvent;
UserEvent.Header.Size = sizeof(USER_EVENT);
UserEvent.Header.Flags = WNODE_FLAG_TRACED_GUID;
if(bUseGuidPtr) {
_tprintf(_T("\n********Use Guid Pointer**********\n"));
UserEvent.Header.Flags |= WNODE_FLAG_USE_GUID_PTR;
UserEvent.Header.GuidPtr = (ULONGLONG)&TransactionGuid[0];
}
else
UserEvent.Header.Guid = TransactionGuid[0];
RtlZeroMemory(&UserInstanceEvent, sizeof(UserInstanceEvent));
UserInstanceEvent.Header.Size = sizeof(USER_INSTANCE_EVENT);
UserInstanceEvent.Header.Flags = WNODE_FLAG_TRACED_GUID;
if(bUseMofPtr) {
_tprintf(_T("\n=======Use Mof Pointer========\n"));
_tcscpy(strMofData, str);
UserEvent.Header.Flags |= WNODE_FLAG_USE_MOF_PTR;
mofField = (PMOF_FIELD) & UserEvent.mofData;
if (bUseNullPtr)
mofField->DataPtr = (ULONGLONG) (NULL);
else
mofField->DataPtr = (ULONGLONG) (strMofData);
if (bIncorrect)
mofField->Length = sizeof(TCHAR) * (_tcslen(strMofData) + 1000);
else
mofField->Length = sizeof(TCHAR) * (_tcslen(strMofData) + 1);
UserInstanceEvent.Header.Flags |= WNODE_FLAG_USE_MOF_PTR;
mofField = (PMOF_FIELD) & UserInstanceEvent.mofData;
if (bUseNullPtr)
mofField->DataPtr = (ULONGLONG) (NULL);
else
mofField->DataPtr = (ULONGLONG) (strMofData);
if (bIncorrect)
mofField->Length = sizeof(TCHAR) * (_tcslen(strMofData) + 10000);
else
mofField->Length = sizeof(TCHAR) * (_tcslen(strMofData) + 1);
}
if(bInstanceTrace) {
status = CreateTraceInstanceId((PVOID)TraceGuidReg[0].RegHandle, &InstInfo);
_tprintf(_T("\n-------TraceEventInstance-----\n"));
if (status != ERROR_SUCCESS) {
_ftprintf(fp, _T("CreatTraceInstanceId() failed. status=%d, %s\n"), status, Decodestatus(status));
}
}
_ftprintf(fp, _T("%d Events, %s, %s, %s, %s, sleep time=%d\n"), MaxEvents,
bInstanceTrace? _T("TraceEventInstance"): _T("TraceEvent"),
bUseGuidPtr? _T("Use GuidPtr"): _T("Use Guid"),
bUseMofPtr? _T("Use MofPtr"): _T("Not use MofPtr"),
gnMultiReg==1 ? _T("Single Registration"): _T("Multiple Registrations"),
nSleepTime);
i = 0;
while (1) {
if(WAIT_FAILED == WaitForSingleObject(ghTraceOnEvent, INFINITE))
{
_tprintf(_T("Error(%d) waiting for ghTraceOnEvent object\n"), GetLastError());
}
if (TraceOnFlag == 1 && i < MaxEvents) {
i++;
if (i == ((i/2) * 2) ) {
UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_START;
UserInstanceEvent.Header.Class.Type = EVENT_TRACE_TYPE_START;
}
else {
UserEvent.Header.Class.Type = EVENT_TRACE_TYPE_END;
UserInstanceEvent.Header.Class.Type = EVENT_TRACE_TYPE_END;
}
if(bInstanceTrace) {
status = TraceEventInstance(LoggerHandle, (PEVENT_INSTANCE_HEADER)&UserInstanceEvent, &InstInfo, NULL);
if (status != ERROR_SUCCESS) {
_tprintf(_T("%d TraceEventInstance() failed, status=%d %s\n"), i, status, Decodestatus(status));
_ftprintf(fp, _T("\ni=%d TraceEventInstance() failed, break! status=%d %s\n"), i, status, Decodestatus(status));
return 0;
}
}
else {
status = TraceEvent(LoggerHandle, (PEVENT_TRACE_HEADER) &UserEvent);
if (status != ERROR_SUCCESS) {
fprintf(stderr, "Error(%d) while writing event.\n", status);
_ftprintf(fp, _T("\ni=%d TraceEvent() failed, break!\nstatus=%d %s\n"), i, status, Decodestatus(status));
return 0;
}
}
if (i >= MaxEvents) {
_ftprintf(fp, _T("\ni=%d MaxEvents=%d break!\n\n"), i, MaxEvents);
}
else if (!(i % 100)) {
_ftprintf(fp, _T("."));
_tprintf(_T("."));
if(nSleepTime)
_sleep(nSleepTime);
}
}
if (TraceOnFlag == 2) {
_ftprintf(fp, _T("\ni=%d TraceOnFlag == 2 break!\n\n"), i);
break;
}
}
fclose(fp);
CloseHandle(ghTraceOnEvent);
for(i=0; i< gnMultiReg; i++)
UnregisterTraceGuids(RegistrationHandle[i]);
return (0);
}
ULONG InitializeTrace(
IN LPTSTR ExePath, FILE* fp
)
{
ULONG Status;
ULONG i, j;
Status = GetModuleFileName(NULL, &ImagePath[0], MAXSTR*sizeof(TCHAR));
if (Status == 0) {
return (ERROR_FILE_NOT_FOUND);
}
ghTraceOnEvent = CreateEvent(
NULL, // security attributes
TRUE, // manual reset
FALSE, // initial state
NULL // pointer to event-object
);
if(NULL == ghTraceOnEvent)
{
Status=GetLastError();
_tprintf(_T("Error(%d) creating TraceOnEvent\n"), Status);
return Status;
}
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) {
_tprintf(_T("Trace registration failed\n"));
RegistrationSuccess = FALSE;
if(i>0)
for (j=0; j<i; j++)
UnregisterTraceGuids(RegistrationHandle[i]);
_ftprintf(fp, _T("InitializeTrace failed. i=%d, status=%d, %s\n"), i, Status, Decodestatus(Status));
return(Status);
}
else {
_tprintf(_T("Trace registered successfully\n"));
RegistrationSuccess = TRUE;
}
}
return(Status);
}
ULONG
ControlCallback(
IN WMIDPREQUESTCODE RequestCode,
IN PVOID Context,
IN OUT ULONG *InOutBufferSize,
IN OUT PVOID Buffer
)
{
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 %I64u\n"), LoggerHandle);
TraceOnFlag = 1;
SetEvent(ghTraceOnEvent);
break;
}
case WMI_DISABLE_EVENTS:
{
TraceOnFlag = 2;
RetSize = 0;
LoggerHandle = 0;
_tprintf(_T("\nLogging Disabled\n"));
SetEvent(ghTraceOnEvent);
break;
}
default:
{
RetSize = 0;
Status = ERROR_INVALID_PARAMETER;
break;
}
}
*InOutBufferSize = RetSize;
return(Status);
}
GUID StringToGuid(TCHAR *str)
{
GUID guid;
TCHAR temp[10];
int i, n;
_tprintf(_T("sizeof GUID = %d GUID=%s\n"), sizeof(guid), str);
temp[8]=_T('\0');
_tcsncpy(temp, str, 8);
_stscanf(temp, _T("%x"), &(guid.Data1));
temp[4]=_T('\0');
_tcsncpy(temp, &str[9], 4);
_stscanf(temp, _T("%x"), &(guid.Data2));
_tcsncpy(temp, &str[14], 4);
_stscanf(temp, _T("%x"), &(guid.Data3));
temp[2]=_T('\0');
for(i=0;i<8;i++)
{
temp[0]=str[19+((i<2)?2*i:2*i+1)]; // to accomodate the minus sign after
temp[1]=str[20+((i<2)?2*i:2*i+1)]; // the first two chars
_stscanf(temp, _T("%x"), &n); // if directly used more than byte alloc
guid.Data4[i]=(unsigned char)n; // causes overrun of memory
}
return guid;
}
LPTSTR
Decodestatus(
IN ULONG Status
)
{
memset( ErrorMsg, 0, MAXSTR );
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
Status,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) ErrorMsg,
MAXSTR,
NULL );
return ErrorMsg;
}