|
|
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.