Annotation of q_a/samples/logging/log.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.