-1

我想在一个实例上打印缓冲区数据,避免所有其他 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;
    }
}
4

1 回答 1

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。

顺便说一句,wprintf(L"Buffer = %s",Buffer);(使用 %s 而不是 %ls)使用 wprintf 就足够了。

对于您的最后一个问题:如果您想将无符号值附加到缓冲区,您可以使用它wsprintf来写入字符串。如果你能做到 C++-only 那么你应该考虑使用std::wstring. 在分配正确大小的缓冲区方面,这对您来说要容易得多。

于 2013-10-01T10:02:56.513 回答