|
Does anybody has an idea how to extract the description string of an event, which is diplayed when opening the properties dialog?
Thanks!
Ralph
|
|
|
|
|
ive just copied the code from my program, i dont have much time so i havent modified. As u can see i save the information into a fiel, but i guess u can ignore it. If u have any problem understanding my writing just write back.
All right??
Mariajo
int GetString(EVENTLOGRECORD *pRecord, FILE **xmlFile, LPSTR source)
{
BOOL f;
FILE *xml;
TCHAR szEvent[256],szBuffer[256], **first_sz;
HMODULE hEvt;
LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};
LPTSTR lpBuf, lib;
LPBYTE pStr;
xml = *xmlFile;
//LPSTR *final_str;
//final_str = (LPSTR *)malloc(pRecord->NumStrings);
if (pRecord->NumStrings )
pStr = (LPBYTE)pRecord + pRecord->StringOffset;
if ( pStr )
{
DWORD i;
for ( i = 0; i < pRecord->NumStrings; i++ )
{
// final_str[i] = pStr;
lpP[i] = pStr;
pStr = strchr( pStr, '\0' ) + 1;
}
}
f = ReadEventSourceInfo( source, szEvent);
if(strchr(szEvent, ';'))
{
int i=0, j, k, num_files=0, last=0;
char *aux, *cad;
aux = szEvent;
while(aux = strchr(aux, ';'))
{
num_files++;
aux++;
}
aux = szEvent;
for(j=0; j<= num_files; j++)
{
int counter =0;
while((szEvent[i]!= ';') && i<sizeof(szevent))
{
="" i++;
="" counter++;
="" }
="" first_sz="(TCHAR" **)malloc(num_files="" *="" (sizeof(szevent)));
="" cad="(char" *)="" malloc(counter+1);
="" for(k="0;" k<counter;="" k++)
="" cad[k]="szEvent[last+k];
" cad[counter]="\0" ;
="" first_sz[j]="cad;
" last="i;
" expandenvironmentstrings(first_sz[j],szbuffer,="" 257);
="" hevt="LoadLibraryEx(szBuffer," null,="" dont_resolve_dll_references="" );
="" load="" the="" event="" message="" file="" dll=""
="" if="" (="" )
="" int="" i="0;
" get="" with="" paramater="" strings="" inserted="" lpbuf="GetEventMessage(" hevt,="" precord-="">EventID,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
if ( lpBuf )
{
for(i=0; i<strlen(lpbuf); i++)
="" {
="" if((lpbuf[i]="="<")" ||="" (lpbuf[i]="="">"))
{
lpBuf[i]='"';
}
}
fprintf(xml, "<description> ");
fputs( lpBuf, xml );
LocalFree( lpBuf );
fprintf(xml, "\n");
return 1;
}
FreeLibrary( hEvt );
}
}
return 1;
}
else
{
ExpandEnvironmentStrings(szEvent,szBuffer, 257);
hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
/* Load the event message file DLL */
if ( hEvt )
{
int i;
/* Get the event message with the paramater strings inserted */
lpBuf = GetEventMessage( hEvt, pRecord->EventID,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
if ( lpBuf )
{
for(i=0; i<strlen(lpbuf); i++)
="" {
=""
="" if((lpbuf[i]="='<')" ||="" (lpbuf[i]="='">'))
lpBuf[i]='"';
}
fprintf(xml, "\n <description> ");
fprintf(xml,"%s\n",lpBuf);
//LocalFree( lpBuf );
fprintf(xml, "\n");
return 1;
}
FreeLibrary( hEvt );
}
}
}
BOOL ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent)
{
BOOL fResult = FALSE;
HANDLE hKey;
LONG lResult;
DWORD dwBytesReturned;
TCHAR szKeyName[128];
/* Find the event source key */
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\Security\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\System\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\application\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
goto Exit_ReadEventSourceInfo;
}
}
}
fResult = TRUE; /* Found the registered event source key */
dwBytesReturned = 256;
if ( RegQueryValueEx( hKey, "EventMessageFile", NULL, NULL,
lpszEvent, &dwBytesReturned ) != ERROR_SUCCESS )
lpszEvent[0] = '\0';
Exit_ReadEventSourceInfo:
return( fResult );
}
|
|
|
|
|
// I needed the description text.
// Here is a (hacked) example to print out the full text messages.
// Compiles on VC71
////////////////////////////////////////////////////////////////////
//
// Event_Test.cpp : Defines the entry point for the console application.
//
#define _WIN32_WINNT 0x0400 //Target NT and greater OS
#include <iostream>
#include <tchar.h>
#include <iostream>
#include <afx.h>
using namespace std;
LPSTR GetString(EVENTLOGRECORD *pRecord, LPSTR source);
BOOL ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent);
LPSTR GetEventMessage(
HMODULE hDll, /* Handle to the event message file */
DWORD dwEventIndex, /* Index of the event description message */
DWORD dwLanguageID, /* Language ID of the message to retrieve */
LPTSTR *lpInserts );
int _tmain(int argc, _TCHAR* argv[])
{
#define BUFFER_SIZE 40960
HANDLE h;
EVENTLOGRECORD *pevlr;
BYTE bBuffer[BUFFER_SIZE];
DWORD dwRead, dwNeeded, dwThisRecord;
LPSTR lpmessagetext="";
// Open the Application event log.
h = OpenEventLog( NULL, // use local computer
"System"); // System Log name
if (h == NULL) {
printf("Could not open the System event log.");
return 1;
}
pevlr = (EVENTLOGRECORD *) &bBuffer;
// Get the record number of the oldest event log record.
GetOldestEventLogRecord(h, &dwThisRecord);
// Opening the event log positions the file pointer for this
// handle at the beginning of the log. Read the event log records
// sequentially until the last record has been read.
while (ReadEventLog(h, // event log handle
EVENTLOG_BACKWARDS_READ | // reads from most recent
EVENTLOG_SEQUENTIAL_READ, // sequential read
0, // ignored for sequential reads
pevlr, // pointer to buffer
BUFFER_SIZE, // size of buffer
&dwRead, // number of bytes read
&dwNeeded)) // bytes in next record
{
while (dwRead > 0)
{
printf("%02d Event ID: %i ",
dwThisRecord++, (short)pevlr->EventID);
printf("EventType: %d Source: %s\n",
pevlr->EventType, (LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD)));
lpmessagetext = GetString(pevlr, ((LPSTR) ((LPBYTE) pevlr +
sizeof(EVENTLOGRECORD))));
printf("%s\n", lpmessagetext);
dwRead -= pevlr->Length;
pevlr = (EVENTLOGRECORD *)
((LPBYTE) pevlr + pevlr->Length);
}
pevlr = (EVENTLOGRECORD *) &bBuffer;
}
CloseEventLog(h);
return 0;
}
LPSTR GetString(EVENTLOGRECORD *pRecord, LPSTR source)
{
BOOL f;
TCHAR szEvent[256],szBuffer[256], **first_sz;
HMODULE hEvt;
LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};
LPSTR lpBuf="";
LPTSTR lpstrlpBuf = "";
char* pStr;
if (pRecord->NumStrings ) {
pStr = (char*)((LPBYTE)pRecord + pRecord->StringOffset);
} else {
pStr = "";
}
if ( pStr )
{
DWORD i;
for ( i = 0; i < pRecord->NumStrings; i++ )
{
lpP[i] = (LPSTR)pStr;
pStr = strchr( (char*)pStr, '\0' ) + 1;
}
}
//Get the file name(s) from the registry
f = ReadEventSourceInfo( source, szEvent);
if(strchr(szEvent, ';'))
{
int i=0, j, k, num_files=0, last=0;
char *aux, *cad;
aux = szEvent;
while(aux = strchr(aux, ';'))
{
num_files++;
aux++;
}
aux = szEvent;
for(j=0; j<= num_files; j++)
{
int counter =0;
while((szEvent[i]!= ';') && i ){
i++;
counter++;
}
first_sz= (TCHAR **)malloc(num_files * (sizeof(szEvent)));
cad = (char *) malloc(counter+1);
for(k = 0; k < counter; k++ ){
cad[k] = szEvent[last+k];
}
cad[counter]= '\0';
first_sz[j] = cad;
i++;
last = i;
//Convert the %SystemRoot% stuff
ExpandEnvironmentStrings(first_sz[j],szBuffer, 257);
//We actually have to load an .exe or what not to read the messages
hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
/* Load the event message file DLL */
if ( hEvt )
{
/* Get the event message with the paramater strings inserted */
lpBuf = GetEventMessage( hEvt, pRecord->EventID,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
FreeLibrary( hEvt );
}
}
return (lpBuf);
}
else
{
ExpandEnvironmentStrings(szEvent,szBuffer, 257);
hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
/* Load the event message file DLL */
if ( hEvt )
{
/* Get the event message with the paramater strings inserted */
lpBuf = GetEventMessage( hEvt, pRecord->EventID,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
FreeLibrary( hEvt );
}
}
return (lpBuf);
}
//
BOOL ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent)
{
BOOL fResult = FALSE;
HKEY hKey;
DWORD dwBytesReturned;
TCHAR szKeyName[128];
/* Find the event source key */
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\Security\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\System\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\application\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
goto Exit_ReadEventSourceInfo;
}
}
}
fResult = TRUE; /* Found the registered event source key */
dwBytesReturned = 256;
if ( RegQueryValueEx( hKey, "EventMessageFile", NULL, NULL,
(LPBYTE)lpszEvent, &dwBytesReturned ) != ERROR_SUCCESS )
lpszEvent[0] = '\0';
Exit_ReadEventSourceInfo:
return( fResult );
}
//Format the message
LPSTR GetEventMessage(
HMODULE hDll, /* Handle to the event message file */
DWORD dwEventIndex, /* Index of the event description message */
DWORD dwLanguageID, /* Language ID of the message to retrieve */
LPTSTR *lpInserts ) /* Array of insertion strings */
{
DWORD dwReturn;
LPSTR lpMsgBuf = NULL;
DWORD dwFlags = FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_ALLOCATE_BUFFER;
if ( lpInserts )
dwFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;
dwReturn = FormatMessage(
dwFlags,
hDll,
dwEventIndex,
dwLanguageID,
(LPTSTR) &lpMsgBuf,
0,
lpInserts );
return( lpMsgBuf );
}
"Never leave your Wingman!"
|
|
|
|
|
For the love of God, close the friggin registry key in the "ReadEventSourceInfo" routine above (unless you like a lot of open handles in your bloated app!)
Add the following line in the "ReadEventSourceInfo" routine above:
}
RegCloseKey(hKey);
fResult = TRUE; /* Found the registered event source key */
"Never leave your Wingman!"
|
|
|
|
|
//found memory was not being free'ed in the example code provided, here is some that works, and I have tested it good. and the loop for the multiple dll's works also (a bug in the example code)
//CEventView is the name of my custom MFC class in case your wondering
void CEventView::DisplayEntries()
{
HANDLE h;
EVENTLOGRECORD *pevlr;
BYTE bBuffer[1024];
DWORD dwRead, dwNeeded, dwThisRecord;
LPSTR lpmessagetext = "";
// Open the Application event log.
h = OpenEventLog( ".", // use local computer
"System"); // source name
if (h == NULL)
{TRACE("ERROR COULD NOT OPEN LOG FILE\n");}
// ErrorExit("Could not open the Application event log.");
pevlr = (EVENTLOGRECORD *) &bBuffer;
// Get the record number of the oldest event log record.
GetOldestEventLogRecord(h, &dwThisRecord);
// Opening the event log positions the file pointer for this
// handle at the beginning of the log. Read the event log records
// sequentially until the last record has been read.
TRACE("\n");
while (ReadEventLog(h, // event log handle
EVENTLOG_FORWARDS_READ | // reads forward
EVENTLOG_SEQUENTIAL_READ, // sequential read
0, // ignored for sequential reads
pevlr, // pointer to buffer
1024, // size of buffer
&dwRead, // number of bytes read
&dwNeeded)) // bytes in next record
{
while (dwRead > 0)
{
// Print the record number, event identifier, type,
// and source name.
lpmessagetext = GetString(pevlr, ((LPSTR) ((LPBYTE) pevlr +
sizeof(EVENTLOGRECORD))));
TRACE("-------------------\n");
TRACE("MSG: %s\n",lpmessagetext);
TRACE("%02d Event ID: 0x%08X ",
dwThisRecord++, pevlr->EventID);
TRACE("EventType: %d Source: %s\n",
pevlr->EventType, (LPSTR) ((LPBYTE) pevlr +
sizeof(EVENTLOGRECORD)));
TRACE("-------------------\n");
dwRead -= pevlr->Length;
pevlr = (EVENTLOGRECORD *)
((LPBYTE) pevlr + pevlr->Length);
}
pevlr = (EVENTLOGRECORD *) &bBuffer;
}
CloseEventLog(h);
}
LPSTR CEventView::GetString(EVENTLOGRECORD *pRecord, LPSTR source)
{
BOOL f;
TCHAR szEvent[256],szBuffer[256];//, **first_sz;
ZeroMemory(szEvent,256);
ZeroMemory(szBuffer,256);
HMODULE hEvt;
LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};
LPSTR lpBuf="";
LPTSTR lpstrlpBuf = "";
char* pStr;
if (pRecord->NumStrings ) {
pStr = (char*)((LPBYTE)pRecord + pRecord->StringOffset);
} else {
pStr = "";
}
if ( pStr )
{
DWORD i;
for ( i = 0; i < pRecord->NumStrings; i++ )
{
lpP[i] = (LPSTR)pStr;
pStr = strchr( (char*)pStr, '\0' ) + 1;
}
}
//Get the file name(s) from the registry
f = ReadEventSourceInfo( source, szEvent);
if(strchr(szEvent, ';'))//we have more than 1 dll to resolve
{
CStringArray array;
CString sEntry;
CString s = szEvent;
s += ";";
int iLast=0,iCur=0;
while(iLast != -1)
{
iLast = s.Find(';',iCur);
if(iLast == -1){break;}
sEntry = s.Mid(iCur,iLast-iCur);
array.Add(sEntry);
iCur=iLast+1;
}
for(int i=0; i<array.getcount(); i++)
="" {
="" expandenvironmentstrings(array[i],szbuffer,="" 257);
="" hevt="LoadLibraryEx(szBuffer," null,="" dont_resolve_dll_references="" );
="" *="" load="" the="" event="" message="" file="" dll=""
="" if="" (="" )
="" get="" with="" paramater="" strings="" inserted="" lpbuf="GetEventMessage(" hevt,="" precord-="">EventID,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
FreeLibrary( hEvt );
return (lpBuf);
}
}
}
else
{
ExpandEnvironmentStrings(szEvent,szBuffer, 257);
hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
// Load the event message file DLL
if ( hEvt )
{
// Get the event message with the paramater strings inserted
lpBuf = GetEventMessage( hEvt, pRecord->EventID,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
FreeLibrary( hEvt );
}
}
return (lpBuf);
}
//
BOOL CEventView::ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent)
{
BOOL fResult = FALSE;
HKEY hKey;
DWORD dwBytesReturned;
TCHAR szKeyName[128];
/* Find the event source key */
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\Security\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\System\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\application\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
goto Exit_ReadEventSourceInfo;
}
}
}
fResult = TRUE; /* Found the registered event source key */
dwBytesReturned = 256;
if ( RegQueryValueEx( hKey, "EventMessageFile", NULL, NULL,
(LPBYTE)lpszEvent, &dwBytesReturned ) != ERROR_SUCCESS )
lpszEvent[0] = '\0';
Exit_ReadEventSourceInfo:
RegCloseKey(hKey);
return( fResult );
}
//Format the message
LPSTR CEventView::GetEventMessage(
HMODULE hDll, /* Handle to the event message file */
DWORD dwEventIndex, /* Index of the event description message */
DWORD dwLanguageID, /* Language ID of the message to retrieve */
LPTSTR *lpInserts ) /* Array of insertion strings */
{
DWORD dwReturn;
LPSTR lpMsgBuf = NULL;
DWORD dwFlags = FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_ALLOCATE_BUFFER;
if ( lpInserts )
dwFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;
dwReturn = FormatMessage(
dwFlags,
hDll,
dwEventIndex,
dwLanguageID,
(LPTSTR) &lpMsgBuf,
0,
lpInserts );
return( lpMsgBuf );
}
|
|
|
|
|
Do somone try to run the code for the "security-log"? I got: "Run-Time Check Failure #2 - Stack around the variable 'lpP' was corrupted."
Any idea, what causes the problem?
Here is the code:
>>>>
#include <windows.h>
#include <stdio.h>
#define BUFFER_SIZE 1024*64
static char g_szLogfile[80];
BOOL ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent) ;
LPSTR GetEventMessage(
HMODULE hDll, /* Handle to the event message file */
DWORD dwEventIndex, /* Index of the event description message */
DWORD dwLanguageID, /* Language ID of the message to retrieve */
LPTSTR *lpInserts ) /* Array of insertion strings */
{
DWORD dwReturn;
LPSTR lpMsgBuf = NULL;
DWORD dwFlags = FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_ALLOCATE_BUFFER;
if ( lpInserts )
dwFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;
dwReturn = FormatMessage(
dwFlags,
hDll,
dwEventIndex,
dwLanguageID,
(LPTSTR) &lpMsgBuf,
0,
lpInserts );
return( lpMsgBuf );
}
LPSTR GetStringEx(EVENTLOGRECORD *pRecord, LPSTR source)
{
BOOL f;
TCHAR szEvent[256],szBuffer[256], **first_sz;
HMODULE hEvt;
LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};
LPSTR lpBuf="";
LPTSTR lpstrlpBuf = "";
char* pStr;
if (pRecord->NumStrings ) {
pStr = (char*)((LPBYTE)pRecord + pRecord->StringOffset);
} else {
pStr = "";
}
if ( pStr )
{
DWORD i;
for ( i = 0; i < pRecord->NumStrings; i++ )
{
lpP[i] = (LPSTR)pStr;
pStr = strchr( (char*)pStr, '\0' ) + 1;
}
}
//Get the file name(s) from the registry
f = ReadEventSourceInfo( source, szEvent);
if(strchr(szEvent, ';'))
{
int i=0, j, k, num_files=0, last=0;
char *aux, *cad;
aux = szEvent;
while(aux = strchr(aux, ';'))
{
num_files++;
aux++;
}
aux = szEvent;
for(j=0; j<= num_files; j++)
{
int counter =0;
while((szEvent[i]!= ';') && i ){
i++;
counter++;
}
first_sz= (TCHAR **)malloc(num_files * (sizeof(szEvent)));
cad = (char *) malloc(counter+1);
for(k = 0; k < counter; k++ ){
cad[k] = szEvent[last+k];
}
cad[counter]= '\0';
first_sz[j] = cad;
i++;
last = i;
//Convert the %SystemRoot% stuff
ExpandEnvironmentStrings(first_sz[j],szBuffer, 257);
//We actually have to load an .exe or what not to read the messages
hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
/* Load the event message file DLL */
if ( hEvt )
{
/* Get the event message with the paramater strings inserted */
lpBuf = GetEventMessage( hEvt, pRecord->EventID,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
FreeLibrary( hEvt );
}
}
return (lpBuf);
}
else
{
ExpandEnvironmentStrings(szEvent,szBuffer, 257);
hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
/* Load the event message file DLL */
if ( hEvt )
{
/* Get the event message with the paramater strings inserted */
lpBuf = GetEventMessage( hEvt, pRecord->EventID,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
FreeLibrary( hEvt );
}
}
return (lpBuf);
}
BOOL ReadEventSourceInfo(LPCSTR lpszESName, LPSTR lpszEvent)
{
BOOL fResult = FALSE;
HANDLE hKey;
LONG lResult;
DWORD dwBytesReturned;
TCHAR szKeyName[128];
/* Find the event source key */
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\Security\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\System\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
lstrcpy( szKeyName,
"System\\CurrentControlSet\\Services\\EventLog\\application\\" );
lstrcat( szKeyName, lpszESName );
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_ALL_ACCESS,
&hKey ) != ERROR_SUCCESS )
{
goto Exit_ReadEventSourceInfo;
}
}
}
fResult = TRUE; /* Found the registered event source key */
dwBytesReturned = 256;
if ( RegQueryValueEx( hKey, "EventMessageFile", NULL, NULL,
lpszEvent, &dwBytesReturned ) != ERROR_SUCCESS )
lpszEvent[0] = '\0';
Exit_ReadEventSourceInfo:
return( fResult );
}
void DisplayEntries( )
{
HANDLE h;
EVENTLOGRECORD *pevlr;
BYTE bBuffer[BUFFER_SIZE];
DWORD dwRead, dwNeeded, dwThisRecord;
LPSTR lpmessagetext = "";
char* pStr;
LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};
// Open the Application event log.
h = OpenEventLog( NULL, // use local computer
g_szLogfile); // source name
if (h == NULL)
{
printf("Could not open the Application event log.");
return;
}
pevlr = (EVENTLOGRECORD *) &bBuffer;
// Get the record number of the oldest event log record.
GetOldestEventLogRecord(h, &dwThisRecord);
// Opening the event log positions the file pointer for this
// handle at the beginning of the log. Read the event log records
// sequentially until the last record has been read.
while (ReadEventLog(h, // event log handle
EVENTLOG_FORWARDS_READ | // reads forward
EVENTLOG_SEQUENTIAL_READ, // sequential read
0, // ignored for sequential reads
pevlr, // pointer to buffer
BUFFER_SIZE, // size of buffer
&dwRead, // number of bytes read
&dwNeeded)) // bytes in next record
{
while (dwRead > 0)
{
// Print the record number, event identifier, type,
// and source name.
lpmessagetext = GetStringEx(pevlr, ((LPSTR) ((LPBYTE) pevlr +
sizeof(EVENTLOGRECORD))));
printf("Event source/text/num: [%s]/[%s]/[%d]\n",
(LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD)), lpmessagetext,
pevlr->NumStrings);
if (pevlr->NumStrings ) {
pStr = (char*)((LPBYTE)pevlr + pevlr->StringOffset);
} else {
pStr = "";
}
if ( pStr )
{
DWORD i;
for ( i = 0; i < pevlr->NumStrings; i++ )
{
lpP[i] = (LPSTR)pStr;
pStr = strchr( (char*)pStr, '\0' ) + 1;
printf("--> [%s]\n", pStr);
}
}
dwRead -= pevlr->Length;
pevlr = (EVENTLOGRECORD *)
((LPBYTE) pevlr + pevlr->Length);
}
pevlr = (EVENTLOGRECORD *) &bBuffer;
}
CloseEventLog(h);
}
int main(int argc, char * argv[])
{
if (argc!=2)
{
printf("%s [logfile]\n", argv[0]);
exit (0);
}
strcpy(g_szLogfile, argv[1]);
DisplayEntries();
return 1;
}
#if 0
LPSTR GetString(EVENTLOGRECORD *pRecord, LPSTR source)
{
BOOL f;
TCHAR szEvent[256],szBuffer[256];//, **first_sz;
ZeroMemory(szEvent,256);
ZeroMemory(szBuffer,256);
HMODULE hEvt;
LPTSTR lpP[] = { "", "", "", "", "", "","", "", "","", "", "","", "", "","", "", "","", "", ""};
LPSTR lpBuf="";
LPTSTR lpstrlpBuf = "";
char* pStr;
if (pRecord->NumStrings ) {
pStr = (char*)((LPBYTE)pRecord + pRecord->StringOffset);
} else {
pStr = "";
}
if ( pStr )
{
DWORD i;
for ( i = 0; i < pRecord->NumStrings; i++ )
{
lpP[i] = (LPSTR)pStr;
pStr = strchr( (char*)pStr, '\0' ) + 1;
}
}
//Get the file name(s) from the registry
f = ReadEventSourceInfo( source, szEvent);
if(strchr(szEvent, ';'))//we have more than 1 dll to resolve
{
CStringArray array;
CString sEntry;
CString s = szEvent;
s += ";";
int iLast=0,iCur=0;
while(iLast != -1)
{
iLast = s.Find(';',iCur);
if(iLast == -1){break;}
sEntry = s.Mid(iCur,iLast-iCur);
array.Add(sEntry);
iCur=iLast+1;
}
for(int i=0; i
{
ExpandEnvironmentStrings(array[i],szBuffer, 257);
hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
/* Load the event message file DLL */
if ( hEvt )
{
/* Get the event message with the paramater strings inserted */
lpBuf = GetEventMessage( hEvt, pRecord->EventID,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
FreeLibrary( hEvt );
return (lpBuf);
}
}
}
else
{
ExpandEnvironmentStrings(szEvent,szBuffer, 257);
hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
// Load the event message file DLL
if ( hEvt )
{
// Get the event message with the paramater strings inserted
lpBuf = GetEventMessage( hEvt, pRecord->EventID,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
FreeLibrary( hEvt );
}
}
return (lpBuf);
}
#endif
<<<< End code
|
|
|
|
|
Torben_Surmer wrote: for(int i=0; i
{
ExpandEnvironmentStrings(array[i],szBuffer, 257);
hEvt = LoadLibraryEx(szBuffer, NULL, DONT_RESOLVE_DLL_REFERENCES );
/* Load the event message file DLL */
if ( hEvt )
{
/* Get the event message with the paramater strings inserted */
lpBuf = GetEventMessage( hEvt, pRecord->EventID,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), lpP );
FreeLibrary( hEvt );
return (lpBuf);
}
Theres a mangled FOR loop in this code...
it should probably be this:
for(int i=0; i < array.GetCount(); i++)
but other than that this code works, and best of all DOESNT LEAK!
Ivan Bohannon
|
|
|
|
|
Hello!
Actually, I need to know with Visual Basic 6.0 how to watch a printer for documents that have been printed o deleted from the spooler.
I thouhgt that accessing the Windows 2000 Event Log file I could obtain that information, but I can only get a few data and I need more, like document's name, page numbers, user, printer, etc.
Does anyone have an example for me about that?
Thank you!!
|
|
|
|
|
Actually Event log does track some (I don't think all) spooler events. If you want to get more data, I suggest you to query directly the printer(s) targeted.
|
|
|
|
|
I did query directly the printer, but I couldn't know what happend with the document in the spooler, I don't know if it has been deleted, printed, paused, etc. after it disapears from the spooler.
With the info in the Event Log file (SysEvent.Evt), I could do it, but I can only obtain the event, not the info about the document...
I keep on trying...
Thanks!!!!
|
|
|
|
|
I write a code to log events using vc++.The code is working fine and the events could be logged and viewed in the EventViewer's Application log file. But I want to log my event to some separate custom logfile.Could anybody tell me how to do it? And how could I get my custom logfile listed in the file dropdown list of the event viewer?
|
|
|
|
|
1. Creating custom log files.
Create a new key in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog named as you desire. Of course, you may want to provide several informations under this new key as values (among them may be DisplayNameFile, File, MaxSize, PrimaryModule). You may register then sources by opening this custom log and call RegisterEventSource with the appropriate input.
Here is what MSDN says about custom log files:
[MSDN Excerpt 1]
Logfiles
The event-logging service uses the information stored in the EventLog registry key. The EventLog key (shown in the following example) contains several subkeys, called logfiles. Logfile information in the registry is used to locate resources that the event logging service needs when an application writes to and reads from the event log. The default logfiles are Application, Security, and System. You can also create custom logfiles. The structure is as follows:
HKEY_LOCAL_MACHINE
SYSTEM
CurrentControlSet
Services
EventLog
Application
Security
System
CustomLog
Applications and services use the Application logfile. Device drivers use the System logfile. The system will generate success and failure audit events in the Security logfile when auditing is turned on. For more information about auditing security events, see the documentation for User Manager.
Windows 2000/XP: Applications can also create custom logfiles by adding an entry to the EventLog key. These logs will appear in the Event Viewer with the default logfiles. This enables applications to control the size of the log file or attach SACLs for security purposes, without affecting other applications.
[End MSDN Excerpt 1]
[MSDN Excerpt 2]
OpenEventLog
The OpenEventLog function opens a handle to an event log.
HANDLE OpenEventLog(
LPCTSTR lpUNCServerName, // server name
LPCTSTR lpSourceName // file name
);
Parameters
lpUNCServerName
[in] Pointer to a null-terminated string that specifies the Universal Naming Convention (UNC) name of the server on which the event log is to be opened. If this parameter is NULL, the operation is performed on the local computer.
lpSourceName
[in] Pointer to a null-terminated string that specifies the name of the logfile that the returned handle will reference. This can be the Application, Security, or System logfile, or a custom logfile. If a custom registered logfile name cannot be found, the event logging service opens the Application logfile; however, there will be no associated message or category string file.
[End MSDN Excerpt 2]
2. Enumerating: simply go to the key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog and enumerate its subkeys.
|
|
|
|
|
I have problems using ReadEventLog with Visual Basic.
Does anyone have an example for me?
Thank you in advance I am desperate!!
|
|
|
|
|
Describe me your problem. I think the problem is VB , however using event log in VB requires dll manipulation - or, better - write an ATL component manipulating the event log and you can use it VB like any other component.
|
|
|
|
|
I just sent you a mail with a sample project. Call me and I'll help you if the time will let me do it.
|
|
|
|
|
Hi. Can anyone pls let me know what constant value is to be used for EVENTLOG_FORWARDS_READ Or EVENTLOG_SEQUENTIAL_READ in VB?? There is nothing in API constants for this and this is prob why ReadEventLog function in VB is failing!!!
|
|
|
|
|
//
// Defines for the READ flags for Eventlogging
//
#define EVENTLOG_SEQUENTIAL_READ 0x0001
#define EVENTLOG_SEEK_READ 0x0002
#define EVENTLOG_FORWARDS_READ 0x0004
#define EVENTLOG_BACKWARDS_READ 0x0008
(full file: WinNT.h, Platform SDK - located in Include folder).
Define your appropriate constants inside your VB module.
|
|
|
|
|
I can define them but what should be the value?? This is what I want to know abt..
|
|
|
|
|
I don't know very much VB, but I think I already told you the values (if you read the #define statements they are all followed by the value). Anyway:
Const EVENTLOG_SEQUENTIAL_READ As Long = 1
Const EVENTLOG_SEEK_READ As Long = 2
Const EVENTLOG_FORWARDS_READ As Long = 4
Const EVENTLOG_BACKWARDS_READ As Long = 8
|
|
|
|
|
Thanks for reply, Sardaukar! I had tried these values before putting my query on the forum. But it doesnt work. The error I get is Wrong Parameters. So I am dead sure that there is soemthing which is being passed wrong. Since I had doubt on these parameters, I posted the query. But now after your replies I know the values were correct. There must be something else then. I will post the line if I am able to get it right!! Meanwhile if u crack it just let us know..
|
|
|
|
|
Here u go i know these ones work i use them myself...
Private Const EVENTLOG_SUCCESS = &H0
Private Const EVENTLOG_ERROR_TYPE = &H1
Private Const EVENTLOG_WARNING_TYPE = &H2
Private Const EVENTLOG_INFORMATION_TYPE = &H4
Private Const EVENTLOG_AUDIT_SUCCESS = &H8
Private Const EVENTLOG_AUDIT_FAILURE = &H10
Private Const EVENTLOG_SEQUENTIAL_READ = &H1
Private Const EVENTLOG_SEEK_READ = &H2
Private Const EVENTLOG_FORWARDS_READ = &H4
Private Const EVENTLOG_BACKWARDS_READ = &H8
|
|
|
|
|
I Have the same problem, I need a sample of readeventlog using Visual Basic.
I think the problem is how make a pointer in Visual Basic for the structure returned
|
|
|
|
|
I'm including an Event Log reader into a generic network computer scanner I'm building, and I've gotten it mostly done. To get the structure I use the EVENTLOGRECORD struct (this was pulled from an article on www.experts-exchange.com):
Private Type EVENTLOGRECORD
Length As Long ' Length of full record
Reserved As Long ' Used by the service
RecordNumber As Long ' Absolute record number
TimeGenerated As Long ' Seconds since 1-1-1970
TimeWritten As Long 'Seconds since 1-1-1970
EventID As Long
EventType As Integer
NumStrings As Integer
EventCategory As Integer
ReservedFlags As Integer ' For use with paired events (auditing)
ClosingRecordNumber As Long 'For use with paired events (auditing)
StringOffset As Long ' Offset from beginning of record
UserSidLength As Long
UserSidOffset As Long
DataLength As Long
DataOffset As Long ' Offset from beginning of record
End Type
The call to read it looks like (evt is of type Byt, otherwise I'm using the "standard" VB naming conventions (meaning, I rarely see them outside of books) - i.e. lng = Long, etc.):
ReadEventLog lngEvntLog, EVENTLOG_FORWARDS_READ Or EVENTLOG_SEQUENTIAL_READ, 1, evt(0), 0, lngBytesRead, lngBytesNeeded
If err.LastDllError = ERROR_INSUFFICIENT_BUFFER Then
lngBytes = lngBytesNeeded
ReadEventLog lngEvntLog, EVENTLOG_FORWARDS_READ Or EVENTLOG_SEQUENTIAL_READ, 1, evt(0), lngBytes, lngBytesRead, lngBytesNeeded
End If
The "1" there is the event record - in this case I'm just reading the first event. The biggest annoyance I've found here is that for me err.LastDllError will return ERROR_IO_PENDING (997) instead of ERROR_SUCCESS (0) - I just test the IO_PENDING as I would a success. (Does anyone know what this means?)
Next, the event is copied to the EVENTLOGRECORD variable "elrRecord" using the CopyMemory function (Let me know if you need the VB decl for CopyMemory):
CopyMemory ByVal elrRecord, evt(0), LenB(elrRecord)
It'll take some work to parse out the vars - let me know if you would like help with that as well.
I have a question as well on this. I've gotten everything down but retrieving the SID and the FormatMessage call. I'm pretty sure I can get the SID if I hack at it long enough, but the FormatMessage has me going insane. What I have looks like:
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER Or FORMAT_MESSAGE_FROM_HMODULE Or FORMAT_MESSAGE_FROM_SYSTEM, LoadLibrary(strData), elrRecord.EventID, 0, strTemp, BUFFER_LEN, ByVal Strings(0))
strData is the library name pulled from the registry - I know that's loading OK. I'm not too sure on the EventID - it seems to contain some extra stuff that I strip off later to get the ID it's supposed to show. The thing that's throwing me is the Strings. I've pulled all the strings out of the record into a string array, but I don't think that's what it's looking for. Any help would be much appreciated.
JS
|
|
|
|
|
1. ERROR_IO_PENDING
This is 99% an indication of a network timeout error. Functions like TransactNamedPipe often return this king of error, but also calls like TransmitPackets or CreateFile. This does not mean necessarily an error, but rather a timeout.
2. Error (in general) returned by ReadEventLog. There are several causes for this, either known (as Q177199 - BUG: ReadEventLog Fails with Error 87) or hidden. Anyway, the most important things to consider are:
- avoid EVENTLOG_SEEK_READ flag and use EVENTLOG_SEQUENTIAL_READ instead; the "seek" flag seems to have some bugs in implementations (although MSDN states this happens only on NT 3.5, 3.51 and 4.0 machines, I've seen this also on 2000 and XP computers);
- the event logging service is (usually) running in LocalSystem account; this means that on local machine is one of the most powerful accounts (if not the most) but in network is almost nothing. So it has to use various techniques to communicate with clients as null session handles (as OpenBackupEventLog describes in Remarks section); there is no "dedicated" or "privileged" channel for this. The authentification takes time, and also you may query the event log exactly when another service or program writes in Event Log on the target computer. This can be another cause of ERROR_IO_PENDING, especially if the query of event log is established using named pipes. My suggestion is to check the error, but if GetLastError is not returning NO_ERROR, neither ERROR_INSUFFICIENT_BUFFER, then examine the output parameter pnBytesRead (DWORD *) to check how many bytes were actually read by the function. In this way, you can check the output buffer lpBuffer (LPVOID) and the read op size (pnBytesRead); using these two you know the LPBYTE buffer and its size and from now on you can get the number of EVENTLOGRECORD read (even in the case of an ERROR_IO_PENDING). I did not tested this, but it seems correct to me. Take that that also other error may occur (RPC_E_...); RPC, registry, event logging, file, networking, buffers - almost anything can call SetLastError if fails. Do not rely on ERROR_IO_PENDING or another error code you may get often as a result.
|
|
|
|
|
Sardaukar wrote:
1. ERROR_IO_PENDING
This is 99% an indication of a network timeout error. Functions like TransactNamedPipe often return this king of error, but also calls like TransmitPackets or CreateFile. This does not mean necessarily an error, but rather a timeout.
I thought the same thing at first, but the response is the same whether it's on the local machine or on the network. There is also no "timeout" period - the response returned is immediate.
When querying NT machines, the number of bytes read is as little as half of that requested, but 2000 machines will return the same number out as in. Both NT and 2000 point to a complete record though - I am able to retrieve everything up to the padding at the end. I'll have to do more testing reading NT machines to see what's going on (and make sure I'm not pulling more than one event at once from them).
JS
|
|
|
|
|