Annotation of q_a/samples/logging/log.c, revision 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.