我想在一个实例上打印缓冲区数据,避免所有其他wprintf实例,但无法使用缓冲区转换兼容类型的数据。
看看代码:
请告诉我如何度过难关:
DWORD PrintEvent(EVT_HANDLE hEvent)
{
DWORD status = ERROR_SUCCESS;
PEVT_VARIANT pRenderedValues = NULL;
WCHAR wsGuid[50];
LPWSTR pwsSid = NULL;
//
// Beginning of functional Logic
//
for (;;)
{
if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount))
{
if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
{
dwBufferSize = dwBufferUsed;
dwBytesToWrite = dwBufferSize;
pRenderedValues = (PEVT_VARIANT)malloc(dwBufferSize);
if (pRenderedValues)
{
EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount);
}
else
{
printf("malloc failed\n");
status = ERROR_OUTOFMEMORY;
break;
}
}
}
Buffer = (wchar_t*) malloc (1*wcslen(pRenderedValues[EvtSystemProviderName].StringVal));
//
// Print the values from the System section of the element.
wcscpy(Buffer,pRenderedValues[EvtSystemProviderName].StringVal);
int i = wcslen(Buffer);
if (NULL != pRenderedValues[EvtSystemProviderGuid].GuidVal)
{
StringFromGUID2(*(pRenderedValues[EvtSystemProviderGuid].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wcscpy(Buffer+i,(wchar_t*)pRenderedValues[EvtSystemProviderGuid].GuidVal);
wprintf(L"Provider Guid: %s\n", wsGuid);
}
//获取“??????”包含guidval后在屏幕上告诉我正确的复制方式??
wprintf(L"Buffer = %ls",Buffer);
//还告诉将无符号值复制到缓冲区
的方法 wprintf(L"EventID: %lu\n", EventID);
wprintf(L"Version: %u\n", pRenderedValues[EvtSystemVersion].ByteVal);
wprintf(L"Level: %u\n", pRenderedValues[EvtSystemLevel].ByteVal);
wprintf(L"EventRecordID: %I64u\n", pRenderedValues[EvtSystemEventRecordId].UInt64Val);
if (EvtVarTypeNull != pRenderedValues[EvtSystemActivityID].Type)
{
StringFromGUID2(*(pRenderedValues[EvtSystemActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Correlation ActivityID: %s\n", wsGuid);
}
if (EvtVarTypeNull != pRenderedValues[EvtSystemRelatedActivityID].Type)
{
StringFromGUID2(*(pRenderedValues[EvtSystemRelatedActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Correlation RelatedActivityID: %s\n", wsGuid);
}
wprintf(L"Execution ProcessID: %lu\n", pRenderedValues[EvtSystemProcessID].UInt32Val);
wprintf(L"Execution ThreadID: %lu\n", pRenderedValues[EvtSystemThreadID].UInt32Val);
wprintf(L"Channel: %s\n",pRenderedValues[EvtSystemChannel].StringVal);
wprintf(L"Computer: %s\n", pRenderedValues[EvtSystemComputer].StringVal);
//
// Final Break Point
//
break;
}
}
答案 0 :(得分:1)
第一个错误是开始写入缓冲区时:
Buffer = (wchar_t*) malloc (1*wcslen(pRenderedValues[EvtSystemProviderName].StringVal));
wcscpy(Buffer,pRenderedValues[EvtSystemProviderName].StringVal);
StringVal指向带有尾随空字节的宽字符串,因此您应该
Buffer = malloc (sizeof(wchar_t)*(wcslen(pRenderedValues[EvtSystemProviderName].StringVal)+1));
甚至更好
Buffer = wcsdup(pRenderedValues[EvtSystemProviderName].StringVal);
第二个错误是在追加GUID时。
你没有分配足够的内存,你只是附加到已经完整的缓冲区。并且您要附加原始GUID,而不是GUID字符串。你应该替换
int i = wcslen(Buffer);
wcscpy(Buffer+i,(wchar_t*)pRenderedValues[EvtSystemProviderGuid].GuidVal);
类似
// Attention: memory leak if realloc returns NULL! So better use a second variable for the return code and check that before assigning to Buffer.
Buffer = realloc(Buffer, wcslen(Buffer) + wcslen(wsGuid) + 1);
wcscat(Buffer,wsGuid);
同时强>
此外,您应该为EvtRender做更好的错误检查。你应该在访问pRenderedValues [i]之前检查dwPropertyCount。
BTW,wprintf(L"Buffer = %s",Buffer);
(使用%s代替%ls)就足够wprintf。
关于你的上一个问题:如果要将无符号值附加到缓冲区,可以使用wsprintf
写入字符串。如果你能做到C ++ - 那么你应该考虑使用std::wstring
。关于分配正确大小的缓冲区,这对您来说要容易得多。