|
|
1.1 root 1: /* Microsoft Developer Support Copyright (c) 1993 Microsoft Corporation. */
2:
3: #include <stdio.h>
4: #include <windows.h>
5: #include <string.h>
6: #include <stdlib.h>
7: #include "messages.h"
8:
9: #define PERR(bSuccess, api) {if(!(bSuccess)) printf("%s: Error %d from %s \
10: on line %d\n", __FILE__, GetLastError(), api, __LINE__);}
11:
12: #define MAX_MSG_LENGTH 1024
13: #define MSG_ID_MASK 0x0000FFFF
14: #define MAX_INSERT_STRS 8
15:
16: /*********************************************************************
17: * FUNCTION: addSourceToRegistry(void) *
18: * *
19: * PURPOSE: Add a source name key, message DLL name value, and *
20: * message type supported value to the registry *
21: * *
22: * INPUT: source name, path of message DLL *
23: * *
24: * RETURNS: none *
25: *********************************************************************/
26:
27: void addSourceToRegistry(LPSTR pszAppname, LPSTR pszMsgDLL)
28: {
29: HKEY hk; /* registry key handle */
30: DWORD dwData;
31: BOOL bSuccess;
32:
33: /* When an application uses the RegisterEventSource or OpenEventLog
34: function to get a handle of an event log, the event loggging service
35: searches for the specified source name in the registry. You can add a
36: new source name to the registry by opening a new registry subkey
37: under the Application key and adding registry values to the new
38: subkey. */
39:
40: /* Create a new key for our application */
41: bSuccess = RegCreateKey(HKEY_LOCAL_MACHINE,
42: "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\log", &hk);
43: PERR(bSuccess == ERROR_SUCCESS, "RegCreateKey");
44:
45: /* Add the Event-ID message-file name to the subkey. */
46: bSuccess = RegSetValueEx(hk, /* subkey handle */
47: "EventMessageFile", /* value name */
48: 0, /* must be zero */
49: REG_EXPAND_SZ, /* value type */
50: (LPBYTE) pszMsgDLL, /* address of value data */
51: strlen(pszMsgDLL) + 1); /* length of value data */
52: PERR(bSuccess == ERROR_SUCCESS, "RegSetValueEx");
53:
54: /* Set the supported types flags and addit to the subkey. */
55: dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
56: EVENTLOG_INFORMATION_TYPE;
57: bSuccess = RegSetValueEx(hk, /* subkey handle */
58: "TypesSupported", /* value name */
59: 0, /* must be zero */
60: REG_DWORD, /* value type */
61: (LPBYTE) &dwData, /* address of value data */
62: sizeof(DWORD)); /* length of value data */
63: PERR(bSuccess == ERROR_SUCCESS, "RegSetValueEx");
64: RegCloseKey(hk);
65: return;
66: }
67:
68: /*********************************************************************
69: * FUNCTION: reportAnEvent(DWORD dwIdEvent, WORD cStrings, *
70: * LPTSTR *ppszStrings); *
71: * *
72: * PURPOSE: add the event to the event log *
73: * *
74: * INPUT: the event ID to report in the log, the number of insert *
75: * strings, and an array of null-terminated insert strings *
76: * *
77: * RETURNS: none *
78: *********************************************************************/
79:
80: void reportAnEvent(DWORD dwIdEvent, WORD cStrings, LPTSTR *pszStrings)
81: {
82: HANDLE hAppLog;
83: BOOL bSuccess;
84:
85: /* Get a handle to the Application event log */
86: hAppLog = RegisterEventSource(NULL, /* use local machine */
87: "log"); /* source name */
88: PERR(hAppLog, "RegisterEventSource");
89:
90: /* Now report the event, which will add this event to the event log */
91: bSuccess = ReportEvent(hAppLog, /* event-log handle */
92: EVENTLOG_ERROR_TYPE, /* event type */
93: 0, /* category zero */
94: dwIdEvent, /* event ID */
95: NULL, /* no user SID */
96: cStrings, /* number of substitution strings */
97: 0, /* no binary data */
98: pszStrings, /* string array */
99: NULL); /* address of data */
100: PERR(bSuccess, "ReportEvent");
101: DeregisterEventSource(hAppLog);
102: return;
103: }
104:
105: /*********************************************************************
106: * FUNCTION: queryEventLog(void) *
107: * *
108: * PURPOSE: dump out some of the data for each event in the event log *
109: * *
110: * INPUT: none *
111: * *
112: * RETURNS: none *
113: *********************************************************************/
114:
115: void queryEventLog(void)
116: {
117: EVENTLOGRECORD *pevlr;
118: BYTE bBuffer[512]; /* hold the event log record raw data */
119: DWORD dwRead, dwNeeded, dwThisRecord = 0;
120: HANDLE hAppLog; /* handle to the application log */
121: BOOL bSuccess;
122: DWORD cRecords; /* number of event records in the log */
123: LONG lSuccess;
124: DWORD dwType;
125: char szMsgDll[MAX_PATH]; /* the name of the message DLL */
126: DWORD dwcbData;
127: HKEY hk;
128: HINSTANCE hLib; /* handle to the messagetable DLL */
129: char szTemp[MAX_PATH];
130: LPTSTR msgBuf; /* hold text of the error message that we
131: build */
132: DWORD cchDest;
133: char *aInsertStrs[MAX_INSERT_STRS]; /* array of pointers to insert
134: strings */
135: int i;
136: char *p;
137:
138: /* Open the Application log. */
139: hAppLog = OpenEventLog(NULL, /* use local machine */
140: "Application"); /* source name */
141: PERR(hAppLog, "OpenEventLog");
142:
143: /* Get the number of records in the Application log. */
144: bSuccess = GetNumberOfEventLogRecords(hAppLog, &cRecords);
145: PERR(bSuccess, "GetNumberOfEventLogRecords");
146: printf("There are %d records in the Application log.\n", cRecords);
147:
148: pevlr = (EVENTLOGRECORD *) &bBuffer;
149:
150: /* Opening the log positions the file pointer for this handle at the
151: beginning of the log. Read records sequentially until there are no
152: more records. */
153: while (bSuccess = ReadEventLog(hAppLog, /* event-log handle */
154: EVENTLOG_FORWARDS_READ | /* read forward */
155: EVENTLOG_SEQUENTIAL_READ, /* sequential read */
156: 0, /* ignored for sequential reads */
157: bBuffer, /* address of buffer */
158: sizeof(bBuffer), /* size of buffer */
159: &dwRead, /* count of bytes read */
160: &dwNeeded)) /* bytes in next record */
161: {
162: while (dwRead > 0)
163: {
164: /* Print the event ID, type, and source name. The source name is
165: just past the end of the formal structure. */
166: printf("%03d Event ID: 0x%08X ", dwThisRecord++, pevlr->EventID);
167: printf("EventType: %d Source: %s\n", pevlr->EventType,
168: (LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD)));
169:
170: /* From the event log source name, we know the name of the registry
171: key to look under for the name of the message DLL that contains
172: the messages we need to extract with FormatMessage. So first get
173: the event log source name... */
174: strcpy(szTemp, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\");
175: /* The source name follows the EVENTLOGRECORD structure */
176: strcat(szTemp, (char *)((LPBYTE) pevlr + sizeof(EVENTLOGRECORD)));
177:
178: /* Now open this key and get the EventMessageFile value, which is
179: the name of the message DLL. */
180: lSuccess = RegOpenKey(HKEY_LOCAL_MACHINE, szTemp, &hk);
181: PERR(lSuccess == ERROR_SUCCESS, "RegOpenKey");
182: dwcbData = MAX_PATH;
183: bSuccess = RegQueryValueEx(hk, /* handle of key to query */
184: "EventMessageFile", /* value name */
185: NULL, /* must be NULL */
186: &dwType, /* address of type value */
187: szTemp, /* address of value data */
188: &dwcbData); /* length of value data */
189: PERR(bSuccess == ERROR_SUCCESS, "RegQueryValueEx");
190:
191: /* Expand environment variable strings in the message DLL path name,
192: in case any are there. */
193: cchDest = ExpandEnvironmentStrings(szTemp, szMsgDll, MAX_PATH);
194: PERR(cchDest != 0, "ExpandEnvironmentStrings");
195: PERR(cchDest < MAX_PATH, "ExpandEnvironmentStrings");
196:
197: /* Now we've got the message DLL name, load the DLL. */
198: hLib = LoadLibraryEx(szMsgDll, NULL, DONT_RESOLVE_DLL_REFERENCES);
199: PERR(hLib != NULL, "LoadLibraryEx");
200: if (!hLib)
201: {
202: puts("Can't find or load message DLL... terminating.");
203: puts("Message DLL must be in path or in current directory.");
204: exit(1);
205: }
206: /* prepare the array of insert strings for FormatMessage - the
207: insert strings are in the log entry. */
208: p = (char *)((LPBYTE) pevlr + pevlr->StringOffset);
209: for (i = 0; i < pevlr->NumStrings && i < MAX_INSERT_STRS; i++)
210: {
211: aInsertStrs[i] = p;
212: p += strlen(p) + 1; /* point to next string */
213: }
214:
215: /* Format the message from the message DLL with the insert strings */
216: bSuccess = FormatMessage(
217: FORMAT_MESSAGE_FROM_HMODULE | /* get the message from the DLL */
218: FORMAT_MESSAGE_ALLOCATE_BUFFER | /* allocate the msg buffer
219: for us */
220: FORMAT_MESSAGE_ARGUMENT_ARRAY | /* lpArgs is an array of
221: pointers */
222: 60, /* line length for the mesages */
223: hLib, /* the messagetable DLL handle */
224: pevlr->EventID, /* message ID */
225: MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), /* language ID */
226: (LPTSTR) &msgBuf, /* address of pointer to buffer for
227: message */
228: MAX_MSG_LENGTH, /* maximum size of the message buffer */
229: aInsertStrs); /* array of insert strings for the message */
230: PERR(bSuccess, "FormatMessage");
231:
232: /* mask off the actual message number and show it */
233: printf(" Message ID: %d ", pevlr->EventID & MSG_ID_MASK);
234: printf("Message: %s\n", msgBuf);
235:
236: /* Free the buffer that FormatMessage allocated for us. */
237: LocalFree((HLOCAL) msgBuf);
238:
239: /* Subtract the size of the event log record we just read */
240: dwRead -= pevlr->Length;
241: /* Point to the next event log record in the buffer */
242: pevlr = (EVENTLOGRECORD *) ((LPBYTE) pevlr + pevlr->Length);
243:
244: /* free the message DLL since we don't know if we'll need it again */
245: FreeLibrary(hLib);
246: RegCloseKey(hk);
247: }
248: /* reset our event log record pointer back to the beginning of the
249: buffer in preparation for reading the next record. */
250: pevlr = (EVENTLOGRECORD *) &bBuffer;
251: }
252: if (GetLastError()!= ERROR_HANDLE_EOF)
253: PERR(bSuccess, "ReadEventLog");
254: CloseEventLog(hAppLog);
255: RegCloseKey(hk);
256: return;
257: }
258:
259: int main()
260: {
261: char szMsgPath[MAX_PATH];
262: char *aInsertStrs[MAX_INSERT_STRS]; /* array of pointers to insert
263: strings */
264:
265: /* Check to make sure we are running on Windows NT */
266: if (GetVersion() & 0x80000000)
267: {
268: MessageBox(NULL, "Sorry, this application requires Windows NT.\n"
269: "This application will now terminate.",
270: "Error: Windows NT Required to Run", MB_OK);
271: return (1);
272: }
273: /* Set the Event-ID message-file name. We assume that the message DLL is
274: in the same directory as this application. */
275: GetCurrentDirectory(sizeof(szMsgPath), szMsgPath);
276: strcat(szMsgPath, "\\messages.dll");
277: addSourceToRegistry("log", szMsgPath);
278:
279: /* Set up our array of insert strings for our error message */
280: aInsertStrs[0] = "foo.c";
281: aInsertStrs[1] = "BAR";
282: reportAnEvent(MSG_CMD_DELETE, /* the message to log */
283: 2, /* number of insert strings */
284: aInsertStrs); /* the array of insert strings */
285:
286: queryEventLog();
287: return (0);
288: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.