www.pudn.com > win2ksrc.rar > eltest.c


/*++ 
 
Copyright (c) 1990  Microsoft Corporation 
 
Module Name: 
 
    ELTEST.C 
 
Abstract: 
 
    Test Routines for the EventLog. 
 
THINGS I WANT THIS TO DO... 
    AddReg     
           
           - Creates A Registry Entry. 
 
        eltest addreg application mytest mf= eltest.dll cat= 
 
    CreateMessageFile  
 
    WriteEvent       
           
 
    ReadLog      
        If LogFile isn't one of the popular ones, then it could be a backup 
        logfile. 
 
    GetNumEvents   
 
    GetOldest   
 
    Clear   
 
    Backup    
 
 
    LOOPTESTS.... 
    I should be able to run this test like mprtest such that it doesn't leave 
    the test process until told.  This way we can register an event source, 
    then if we call WriteEvent without a specified EventSource, it will use 
    the stored source.  Calling RegisterEventSource twice without calling 
    DeRegisterSource would be an error.  (Or better yet, I could keep a table 
    of sources and handles). 
 
    RegisterEventSource  
    DeRegisterSource  
 
 
 
 
PROTOTYPES FOR FUNCTION.... 
 
BOOL 
CloseEventLog ( 
    HANDLE hEventLog 
    ) 
BOOL 
DeregisterEventSource ( 
    HANDLE hEventLog 
    ) 
 
BOOL 
NotifyChangeEventLog( 
    HANDLE  hEventLog, 
    HANDLE  hEvent 
    ) 
BOOL 
GetNumberOfEventLogRecords ( 
    HANDLE hEventLog, 
    PDWORD NumberOfRecords 
    ) 
BOOL 
GetOldestEventLogRecord ( 
    HANDLE hEventLog, 
    PDWORD OldestRecord 
    ) 
BOOL 
ClearEventLogW ( 
    HANDLE hEventLog, 
    LPCWSTR BackupFileName 
    ) 
BOOL 
BackupEventLogW ( 
    HANDLE hEventLog, 
    LPCWSTR BackupFileName 
    ) 
HANDLE 
OpenEventLogW ( 
    LPCWSTR  UNCServerName, 
    LPCWSTR  ModuleName 
    ) 
HANDLE 
RegisterEventSourceW ( 
    LPCWSTR  UNCServerName, 
    LPCWSTR  ModuleName 
    ) 
HANDLE 
OpenBackupEventLogW ( 
    LPCWSTR  UNCServerName, 
    LPCWSTR  FileName 
    ) 
BOOL 
ReadEventLogW ( 
    HANDLE      hEventLog, 
    DWORD       dwReadFlags, 
    DWORD       dwRecordOffset, 
    LPVOID      lpBuffer, 
    DWORD       nNumberOfBytesToRead, 
    DWORD       *pnBytesRead, 
    DWORD       *pnMinNumberOfBytesNeeded 
    ) 
BOOL 
ReportEventW ( 
    HANDLE      hEventLog, 
    WORD        wType, 
    WORD        wCategory       OPTIONAL, 
    DWORD       dwEventID, 
    PSID        lpUserSid       OPTIONAL, 
    WORD        wNumStrings, 
    DWORD       dwDataSize, 
    LPCWSTR     *lpStrings      OPTIONAL, 
    LPVOID      lpRawData       OPTIONAL 
    ) 
 
 
 
 
Author: 
 
    Dan Lafferty    (danl)  09-March-1994 
 
Environment: 
 
    User Mode - Win32 
 
Revision History: 
 
    09-Mar-1994     danl 
        created 
 
--*/ 
 
// 
// INCLUDES 
// 
#define UNICODE 1 
#include          // DbgPrint prototype 
#include       // DbgPrint prototype 
#include      // needed for winbase.h 
 
 
#include      // atoi 
#include       // printf 
#include       // getch 
#include      // strcmp 
#include     // win32 typedefs 
#include        // Unicode 
#include    // FORMAT_LPTSTR 
 
//------------------ 
// DEFINES 
//------------------ 
#define APPLICATION_LOG     "Application" 
#define SYSTEM_LOG          "System" 
#define SECURITY_LOG        "Security" 
 
#define REG_APPLICATION_KEY "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\" 
#define REG_SYSTEM_KEY      "SYSTEM\\CurrentControlSet\\Services\\EventLog\\System\\" 
#define REG_SECURITY_KEY    "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Security\\" 
 
#define EVENT_SOURCE_NAME       "tevent" 
#define MSG_DLL                 "%SystemRoot%\\System32\\tevent.dll" 
 
#define VALUE_EVENT_MF          TEXT("EventMessageFile") 
#define VALUE_CATEGORY_MF       TEXT("CategoryMessageFile") 
#define VALUE_PARAMETER_MF      TEXT("ParameterMessageFile") 
#define VALUE_TYPES_SUPPORTED   TEXT("TypesSupported") 
#define VALUE_CATEGORY_COUNT    TEXT("CategoryCount") 
 
#define TYPES_SUPPORTED        (EVENTLOG_ERROR_TYPE     |   \ 
                                EVENTLOG_WARNING_TYPE   |   \ 
                                EVENTLOG_INFORMATION_TYPE) 
//---------------------- 
// GLOBALS 
//---------------------- 
    LPTSTR  ApplLogRegName=TEXT(REG_APPLICATION_KEY); 
    LPTSTR  SysLogRegName =TEXT(REG_SYSTEM_KEY); 
    LPTSTR  SecLogRegName =TEXT(REG_SECURITY_KEY); 
    LPTSTR  ApplLogName   = TEXT(APPLICATION_LOG); 
    LPTSTR  SysLogName    = TEXT(SYSTEM_LOG); 
    LPTSTR  SecLogName    = TEXT(SECURITY_LOG); 
 
//---------------------- 
// FUNCTION PROTOTYPES 
//---------------------- 
 
VOID 
AddRegUsage(VOID); 
 
DWORD 
AddSourceToRegistry( 
    IN  LPTSTR  ServerName, 
    IN  LPTSTR  LogName, 
    IN  LPTSTR  EventSourceName, 
    IN  LPTSTR  *argv, 
    IN  DWORD   argc 
    ); 
 
BOOL 
ConvertToUnicode( 
    OUT LPWSTR  *UnicodeOut, 
    IN  LPSTR   AnsiIn 
    ); 
 
DWORD 
DelSourceInRegistry( 
    IN  LPTSTR  ServerName, 
    IN  LPTSTR  LogName, 
    IN  LPTSTR  EventSourceName 
    ); 
 
VOID 
DisplayStatus ( 
    IN  LPTSTR              ServiceName, 
    IN  LPTSTR              DisplayName, 
    IN  LPSERVICE_STATUS    ServiceStatus 
    ); 
 
BOOL 
MakeArgsUnicode ( 
    DWORD           argc, 
    PCHAR           argv[] 
    ); 
 
BOOL 
ProcessArgs ( 
    LPTSTR      ServerName, 
    DWORD       argc, 
    LPTSTR      argv[] 
    ); 
 
VOID 
Usage( 
    VOID); 
 
VOID 
ConfigUsage(VOID); 
 
VOID 
CreateUsage(VOID); 
 
VOID 
QueryUsage(VOID); 
 
LONG 
wtol( 
    IN LPWSTR string 
    ); 
 
VOID 
UserInputLoop( 
    LPTSTR  ServerName 
    ); 
DWORD 
ReadLogFile( 
    LPTSTR  ServerName, 
    LPTSTR  LogName, 
    IN  LPTSTR  *argv, 
    IN  DWORD   argc 
    ); 
VOID 
ReadLogUsage(VOID); 
 
VOID 
DisplayRecord( 
    PEVENTLOGRECORD     pElRecord, 
    BOOL                PrintTheHeader 
    ); 
 
/****************************************************************************/ 
VOID __cdecl 
main ( 
    DWORD           argc, 
    PCHAR           argvAnsi[] 
    ) 
 
/*++ 
 
Routine Description: 
 
    Allows manual testing of the EVENTLOG API. 
 
        eltest 
 
 
 
Arguments: 
 
 
 
Return Value: 
 
 
 
--*/ 
{ 
    UCHAR   i; 
    DWORD   j; 
    DWORD   argIndex; 
    LPTSTR  pServerName=NULL; 
    LPTSTR  *argv; 
 
    if (argc <2) { 
        Usage(); 
        return; 
    } 
 
    // 
    // Make the arguments unicode if necessary. 
    // 
#ifdef UNICODE 
    if (!MakeArgsUnicode(argc, argvAnsi)) { 
        return; 
    } 
#endif 
 
    argv = (LPTSTR *)argvAnsi; 
 
    argIndex = 1; 
    if (STRNCMP (argv[1], TEXT("\\\\"), 2) == 0) { 
        pServerName = argv[1]; 
        argIndex = 2;               // skip over servername. 
    } 
 
    // 
    // Check to see if we are to run in Loop Mode, or in single function 
    // mode.  In Loop Mode, we go into a loop, and ask the user for 
    // input until the user decides to quit. 
    // 
    // Process Arguments: 
    // 
    // INDEX   0       1            2              3 
    //         EL    
    // 
 
    if (STRICMP (argv[argIndex], TEXT("Loop")) == 0) { 
        UserInputLoop(pServerName); 
    } 
    else { 
        ProcessArgs(pServerName, argc-argIndex, &(argv[argIndex])); 
    } 
 
 
#ifdef UNICODE 
    // 
    // Free up the unicode strings if there are any 
    // 
    for(j=0; j 0) { 
            //-------------------------------------- 
            // put the string in argv/argc format. 
            //-------------------------------------- 
            buffer[1]+=2;       // make this an end offset 
            argc=0; 
            for (i=2,j=0; idwServiceType); 
 
    switch(ServiceStatus->dwServiceType){ 
    case SERVICE_WIN32_OWN_PROCESS: 
        printf("WIN32_OWN_PROCESS \n"); 
        break; 
    case SERVICE_WIN32_SHARE_PROCESS: 
        printf("WIN32_SHARE_PROCESS \n"); 
        break; 
    case SERVICE_WIN32: 
        printf("WIN32 \n"); 
        break; 
    case SERVICE_ADAPTER: 
        printf("ADAPTER \n"); 
        break; 
    case SERVICE_KERNEL_DRIVER: 
        printf("KERNEL_DRIVER \n"); 
        break; 
    case SERVICE_FILE_SYSTEM_DRIVER: 
        printf("FILE_SYSTEM_DRIVER \n"); 
        break; 
    case SERVICE_DRIVER: 
        printf("DRIVER \n"); 
        break; 
    default: 
        printf(" ERROR \n"); 
    } 
 
    printf("        STATE              : %lx  ", ServiceStatus->dwCurrentState); 
 
    switch(ServiceStatus->dwCurrentState){ 
        case SERVICE_STOPPED: 
            printf("STOPPED "); 
            break; 
        case SERVICE_START_PENDING: 
            printf("START_PENDING "); 
            break; 
        case SERVICE_STOP_PENDING: 
            printf("STOP_PENDING "); 
            break; 
        case SERVICE_RUNNING: 
            printf("RUNNING "); 
            break; 
        case SERVICE_CONTINUE_PENDING: 
            printf("CONTINUE_PENDING "); 
            break; 
        case SERVICE_PAUSE_PENDING: 
            printf("PAUSE_PENDING "); 
            break; 
        case SERVICE_PAUSED: 
            printf("PAUSED "); 
            break; 
        default: 
            printf(" ERROR "); 
    } 
 
    // 
    // Print Controls Accepted Information 
    // 
 
    if (ServiceStatus->dwControlsAccepted & SERVICE_ACCEPT_STOP) { 
        printf("\n                                (STOPPABLE,"); 
    } 
    else { 
        printf("\n                                (NOT_STOPPABLE,"); 
    } 
 
    if (ServiceStatus->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) { 
        printf("PAUSABLE,"); 
    } 
    else { 
        printf("NOT_PAUSABLE,"); 
    } 
 
    if (ServiceStatus->dwControlsAccepted & SERVICE_ACCEPT_SHUTDOWN) { 
        printf("ACCEPTS_SHUTDOWN)\n"); 
    } 
    else { 
        printf("IGNORES_SHUTDOWN)\n"); 
    } 
 
    // 
    // Print Exit Code 
    // 
    printf("        WIN32_EXIT_CODE    : %d\t(0x%lx)\n", 
        ServiceStatus->dwWin32ExitCode, 
        ServiceStatus->dwWin32ExitCode); 
    printf("        SERVICE_EXIT_CODE  : %d\t(0x%lx)\n", 
        ServiceStatus->dwServiceSpecificExitCode, 
        ServiceStatus->dwServiceSpecificExitCode  ); 
 
    // 
    // Print CheckPoint & WaitHint Information 
    // 
 
    printf("        CHECKPOINT         : 0x%lx\n", ServiceStatus->dwCheckPoint); 
    printf("        WAIT_HINT          : 0x%lx\n", ServiceStatus->dwWaitHint  ); 
 
    return; 
} 
 
VOID 
Usage( 
    VOID) 
{ 
    printf("DESCRIPTION:\n"); 
    printf("\tEL is a command line program used for testing the eventlog \n"); 
    printf("USAGE:\n"); 
    printf("\tEL  [Function]  \n\n"); 
    printf("\tThe option  has the form \"\\\\ServerName\"\n"); 
    printf("\tFurther help on Functions can be obtained by typing: \"el [Function]\"\n"); 
    printf("\tFunctions:\n" 
           "\t  AddReg-----------Creates a registry entry for an event source.\n" 
           "\t  DelReg-----------Deletes a registry entry.\n" 
           "\t  WriteEvent-------Writes an event.\n" 
           "\t  ReadLog----------Reads from the logfile.\n" 
           "\t  GetNumEvents-----Gets the number of events in the specified log.\n" 
           "\t  GetOldest--------Gets the record number for the oldest record" 
           "\t                   in the log\n" 
           "\t  ClearLog---------Clears the specified Log.\n" 
           "\t  Backup-----------Copies the specified log to a new file.\n" 
           "\t  RegisterSource---Registers a name for the event source.\n" 
           "\t                   The handle is stored internally.\n" 
           "\t  DeRegisterSource-Closes handle opened with RegSource.\n" 
           "\t  NotifyChange-----A thread is created which gets notified of EL changes.\n"); 
 
    printf("\n"); 
} 
 
VOID 
AddRegUsage(VOID) 
{ 
 
    printf("\nAdds a subkey under one of the logfiles listed in the registry.\n"); 
    printf("SYNTAX: \n  eltest addreg  logfile   ...\n"); 
    printf("ADDREG OPTIONS:\n"); 
    printf("NOTE: The option name includes the equal sign.\n"); 
 
    printf("    MsgFile=    Name of Event Message File\n" 
           "    CatFile=    Name of Category Message File\n" 
           "    ParamFile=  Name of Parameter Message File\n" 
           "    CatCount=   Category Count\n" 
           "    Type=       \n"); 
    printf("EXAMPLE:\n   eltest addreg application myapp MsgFile= MyMsgs.dll" 
           " Type= error Type= warning\n"); 
 
} 
 
VOID 
ConfigUsage(VOID) 
{ 
    printf("Modifies a service entry in the registry and Service Database.\n"); 
    printf("SYNTAX: \nsc config   ...\n"); 
    printf("CONFIG OPTIONS:\n"); 
    printf("NOTE: The option name includes the equal sign.\n" 
        " type= \n" 
        " start= \n" 
        " error= \n" 
        " binPath= \n" 
        " group= \n" 
        " tag= \n" 
        " depend= \n" 
        " obj= \n" 
        " DisplayName= \n" 
        " password=  \n"); 
} 
VOID 
CreateUsage(VOID) 
{ 
    printf("Creates a service entry in the registry and Service Database.\n"); 
    printf("SYNTAX: \nsc create   ...\n"); 
    printf("CREATE OPTIONS:\n"); 
    printf("NOTE: The option name includes the equal sign.\n" 
        " type= \n" 
        " start= \n" 
        " error= \n" 
        " binPath= \n" 
        " group= \n" 
        " tag= \n" 
        " depend= \n" 
        " obj= \n" 
        " DisplayName= \n" 
        " password=  \n"); 
} 
 
VOID 
ReadLogUsage(VOID) 
{ 
 
    printf("\nReads a logfile and dumps the contents.\n"); 
    printf("SYNTAX: \n  eltest readlog  logfile  ...\n"); 
    printf("READLOG OPTIONS:\n"); 
    printf("NOTE: The option name includes the equal sign.\n"); 
 
    printf("    ReadFlag=   (default = fwd) \n" 
           "    RecordNum=  record number where read should start (default=0)\n" 
           "    BufSize=    size of the buffer (default = 10000)\n"); 
    printf("EXAMPLE:\n   eltest addreg application myapp MsgFile= MyMsgs.dll" 
           " Type= error Type= warning\n"); 
} 
 
DWORD 
AddSourceToRegistry( 
    IN  LPTSTR  ServerName, 
    IN  LPTSTR  LogName, 
    IN  LPTSTR  EventSourceName, 
    IN  LPTSTR  *argv, 
    IN  DWORD   argc 
    ) 
 
/*++ 
 
Routine Description: 
 
    This function writes to the registry all the information to register 
    this application as an event source. 
 
Arguments: 
 
 
Return Value: 
 
 
--*/ 
{ 
    TCHAR   tempName[MAX_PATH]; 
    HKEY    hKey; 
    DWORD   dwStatus=NO_ERROR; 
    HKEY    hRegistry=HKEY_LOCAL_MACHINE; 
 
    LPTSTR  EventMessageFile=NULL; 
    LPTSTR  CategoryMessageFile=NULL; 
    LPTSTR  ParameterMessageFile=NULL; 
    DWORD   dwTypes=0; 
    DWORD   dwCategoryCount=0; 
    DWORD   i; 
 
    // 
    // Look at the LogName, and generate the appropriate registry key 
    // path for that log. 
    // 
    if (STRICMP(LogName, ApplLogName) == 0) { 
        STRCPY(tempName, ApplLogRegName); 
    } 
    else if (STRICMP(LogName, SysLogName) == 0) { 
        STRCPY(tempName, SysLogRegName); 
    } 
    else if (STRICMP(LogName, SecLogName) == 0) { 
        STRCPY(tempName, SecLogRegName); 
    } 
    else { 
        printf("AddSourceToRegistry: Invalid LogName\n"); 
        return(ERROR_INVALID_PARAMETER); 
    } 
    STRCAT(tempName, EventSourceName); 
 
 
    // 
    // Get Variable Arguments 
    // 
    for (i=0; iLength); 
            } 
        } 
        switch(GetLastError()) { 
        case ERROR_INSUFFICIENT_BUFFER: 
            // 
            // Increase the size of the buffer and try again 
            // 
            if (numBytesReqd > BufSize) { 
                LocalFree(pElBuffer); 
                BufSize = numBytesReqd; 
                pElBuffer = LocalAlloc(LPTR, BufSize); 
                if (!pElBuffer) { 
                    printf("ReadLogFile: LocalAlloc Failed %d\n",GetLastError()); 
                } 
                goto TryAgain; 
            } 
            else { 
                printf("ReadLogFile #1: THIS SHOULD NEVER HAPPEN\n"); 
            } 
            break; 
        case ERROR_EVENTLOG_FILE_CHANGED: 
            // 
            // The current read position for this handle has been overwritten. 
            // Reopen the file and print a message to the effect that some 
            // records may have been missed. 
            // 
            printf("ReadLogFile: Current Read position has been overwritten\n"); 
 
            hEventLog = OpenEventLog(ServerName,LogName); 
            if (hEventLog == NULL) { 
                printf("OpenEventLog failed %d\n",GetLastError()); 
                goto CleanExit; 
            } 
            goto TryAgain; 
        case ERROR_HANDLE_EOF: 
            printf("EOF\n"); 
            break; 
        default: 
            printf("UnknownError: %d\n",GetLastError()); 
            break; 
        } 
    } 
CleanExit: 
    if (pElBuffer != NULL) { 
        LocalFree(pElBuffer); 
    } 
    if (hEventLog != NULL) { 
        CloseEventLog(hEventLog); 
    } 
    return(0); 
} 
 
VOID 
DisplayRecord( 
    PEVENTLOGRECORD     pElRecord, 
    BOOL                PrintTheHeader 
    ) 
 
/*++ 
 
Routine Description: 
 
 
Arguments: 
 
 
Return Value: 
 
 
--*/ 
{ 
    if (PrintTheHeader) { 
        printf("RecNum/tTimeGen/tWriteTime/tEventID/tType/tNumStr/tCat/n"); 
    } 
    printf("%d/t%d/t%d/t%d/t%d/t%d/t%d\n", 
        pElRecord->RecordNumber, 
        pElRecord->TimeGenerated, 
        pElRecord->TimeWritten, 
        pElRecord->EventID, 
        pElRecord->EventType, 
        pElRecord->NumStrings, 
        pElRecord->EventCategory); 
} 
 
LONG 
wtol( 
    IN LPWSTR string 
    ) 
{ 
    LONG value = 0; 
 
    while((*string != L'\0')  && 
            (*string >= L'0') && 
            ( *string <= L'9')) { 
        value = value * 10 + (*string - L'0'); 
        string++; 
    } 
 
    return(value); 
}