GetNumberOfEventLogRecords returns incorrect numbe

2019-01-29 13:52发布

问题:

I have this C++ code to read the event log records

DWORD GetLogRecords(LPCWSTR wsLogFile)
{
  HANDLE hEvt = OpenEventLog(NULL, wsLogFile);
  if (hEvt==NULL) return 0;

  DWORD dwTotalRecords;
  BOOL res = GetNumberOfEventLogRecords(hEvt, &dwTotalRecords);
  CloseEventLog(hEvt);

  return (res != 0) ? dwTotalRecords : 0;
}

Result

atlTraceGeneral - C:\Windows\system32\winevt\logs\ACEEventLog.evtx - 23499 Total Records
atlTraceGeneral - C:\Windows\system32\winevt\logs\Application.evtx - 23499 Total Records
atlTraceGeneral - C:\Windows\system32\winevt\logs\ConnectionInfo.evtx - 23499 Total Records
atlTraceGeneral - C:\Windows\system32\winevt\logs\Error.evtx - 23499 Total Records
atlTraceGeneral - C:\Windows\system32\winevt\logs\HardwareEvents.evtx - 23499 Total Records
atlTraceGeneral - C:\Windows\system32\winevt\logs\Internet Explorer.evtx - 23499 Total Records
atlTraceGeneral - C:\Windows\system32\winevt\logs\Key Management Service.evtx - 23499 Total Records
 ...

I have called this function with the full path of all the .EVTX log files on my computer (150 log files). And each time it returns 23499 ! My log files have different sizes and some 0, why I always get 23499 ?

UPDATE2: After I have cleared the Application logs now I get 0 for all the .evtx log files. I think it always gets the application log instead of the specified .evtx file.

UPDATE: As Remy Lebeau suggested, but still the same result.

回答1:

For the benefit of others, the solution to this problem is that OpenEventLog doesn't accept a pathname. Instead you have to give it the source name of the event log (something like "HardwareEvents").

If you call OpenEventLog with an invalid source name (which includes providing a pathname), then as documented it will open the Application log instead:

If you specify a custom log and it cannot be found, the event logging service opens the Application log.



回答2:

You are not checking the result of GetNumberOfEventLogRecords() for an error. And you are leaking the log handle. Try this instead:

DWORD GetLogRecords(LPCWSTR wsLogFile)
{
  HANDLE hEvt = OpenEventLog(NULL, wsLogFile);
  if (hEvt==NULL) return 0;

  DWORD dwTotalRecords;
  BOOL res = GetNumberOfEventLogRecords(hEvt, &dwTotalRecords);
  CloseEventLog(hEvt);

  return (res != 0) ? dwTotalRecords : 0;
}