1e18a033bSKonstantin Ananyev/*
2e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
3e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
4e18a033bSKonstantin Ananyev */
5e18a033bSKonstantin Ananyev
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev#include <ngx_config.h>
8e18a033bSKonstantin Ananyev#include <ngx_core.h>
9e18a033bSKonstantin Ananyev
10e18a033bSKonstantin Ananyev
11e18a033bSKonstantin Ananyev#define NGX_MAX_ERROR_STR   2048
12e18a033bSKonstantin Ananyev
13e18a033bSKonstantin Ananyev
14e18a033bSKonstantin Ananyevvoid ngx_cdecl
15e18a033bSKonstantin Ananyevngx_event_log(ngx_err_t err, const char *fmt, ...)
16e18a033bSKonstantin Ananyev{
17e18a033bSKonstantin Ananyev    u_char         *p, *last;
18e18a033bSKonstantin Ananyev    long            types;
19e18a033bSKonstantin Ananyev    HKEY            key;
20e18a033bSKonstantin Ananyev    HANDLE          ev;
21e18a033bSKonstantin Ananyev    va_list         args;
22e18a033bSKonstantin Ananyev    u_char          text[NGX_MAX_ERROR_STR];
23e18a033bSKonstantin Ananyev    const char     *msgarg[9];
24e18a033bSKonstantin Ananyev    static u_char   netmsg[] = "%SystemRoot%\\System32\\netmsg.dll";
25e18a033bSKonstantin Ananyev
26e18a033bSKonstantin Ananyev    last = text + NGX_MAX_ERROR_STR;
27e18a033bSKonstantin Ananyev    p = text + GetModuleFileName(NULL, (char *) text, NGX_MAX_ERROR_STR - 50);
28e18a033bSKonstantin Ananyev
29e18a033bSKonstantin Ananyev    *p++ = ':';
30e18a033bSKonstantin Ananyev    ngx_linefeed(p);
31e18a033bSKonstantin Ananyev
32e18a033bSKonstantin Ananyev    va_start(args, fmt);
33e18a033bSKonstantin Ananyev    p = ngx_vslprintf(p, last, fmt, args);
34e18a033bSKonstantin Ananyev    va_end(args);
35e18a033bSKonstantin Ananyev
36e18a033bSKonstantin Ananyev    if (err) {
37e18a033bSKonstantin Ananyev        p = ngx_log_errno(p, last, err);
38e18a033bSKonstantin Ananyev    }
39e18a033bSKonstantin Ananyev
40e18a033bSKonstantin Ananyev    if (p > last - NGX_LINEFEED_SIZE - 1) {
41e18a033bSKonstantin Ananyev        p = last - NGX_LINEFEED_SIZE - 1;
42e18a033bSKonstantin Ananyev    }
43e18a033bSKonstantin Ananyev
44e18a033bSKonstantin Ananyev    ngx_linefeed(p);
45e18a033bSKonstantin Ananyev
46e18a033bSKonstantin Ananyev    *p = '\0';
47e18a033bSKonstantin Ananyev
48e18a033bSKonstantin Ananyev    /*
49e18a033bSKonstantin Ananyev     * we do not log errors here since we use
50e18a033bSKonstantin Ananyev     * Event Log only to log our own logs open errors
51e18a033bSKonstantin Ananyev     */
52e18a033bSKonstantin Ananyev
53e18a033bSKonstantin Ananyev    if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
54e18a033bSKonstantin Ananyev           "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\nginx",
55e18a033bSKonstantin Ananyev           0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &key, NULL)
56e18a033bSKonstantin Ananyev        != 0)
57e18a033bSKonstantin Ananyev    {
58e18a033bSKonstantin Ananyev        return;
59e18a033bSKonstantin Ananyev    }
60e18a033bSKonstantin Ananyev
61e18a033bSKonstantin Ananyev    if (RegSetValueEx(key, "EventMessageFile", 0, REG_EXPAND_SZ,
62e18a033bSKonstantin Ananyev                      netmsg, sizeof(netmsg) - 1)
63e18a033bSKonstantin Ananyev        != 0)
64e18a033bSKonstantin Ananyev    {
65e18a033bSKonstantin Ananyev        return;
66e18a033bSKonstantin Ananyev    }
67e18a033bSKonstantin Ananyev
68e18a033bSKonstantin Ananyev    types = EVENTLOG_ERROR_TYPE;
69e18a033bSKonstantin Ananyev
70e18a033bSKonstantin Ananyev    if (RegSetValueEx(key, "TypesSupported", 0, REG_DWORD,
71e18a033bSKonstantin Ananyev                      (u_char *) &types, sizeof(long))
72e18a033bSKonstantin Ananyev        != 0)
73e18a033bSKonstantin Ananyev    {
74e18a033bSKonstantin Ananyev        return;
75e18a033bSKonstantin Ananyev    }
76e18a033bSKonstantin Ananyev
77e18a033bSKonstantin Ananyev    RegCloseKey(key);
78e18a033bSKonstantin Ananyev
79e18a033bSKonstantin Ananyev    ev = RegisterEventSource(NULL, "nginx");
80e18a033bSKonstantin Ananyev
81e18a033bSKonstantin Ananyev    msgarg[0] = (char *) text;
82e18a033bSKonstantin Ananyev    msgarg[1] = NULL;
83e18a033bSKonstantin Ananyev    msgarg[2] = NULL;
84e18a033bSKonstantin Ananyev    msgarg[3] = NULL;
85e18a033bSKonstantin Ananyev    msgarg[4] = NULL;
86e18a033bSKonstantin Ananyev    msgarg[5] = NULL;
87e18a033bSKonstantin Ananyev    msgarg[6] = NULL;
88e18a033bSKonstantin Ananyev    msgarg[7] = NULL;
89e18a033bSKonstantin Ananyev    msgarg[8] = NULL;
90e18a033bSKonstantin Ananyev
91e18a033bSKonstantin Ananyev    /*
92e18a033bSKonstantin Ananyev     * the 3299 event id in netmsg.dll has the generic message format:
93e18a033bSKonstantin Ananyev     *     "%1 %2 %3 %4 %5 %6 %7 %8 %9"
94e18a033bSKonstantin Ananyev     */
95e18a033bSKonstantin Ananyev
96e18a033bSKonstantin Ananyev    ReportEvent(ev, EVENTLOG_ERROR_TYPE, 0, 3299, NULL, 9, 0, msgarg, NULL);
97e18a033bSKonstantin Ananyev
98e18a033bSKonstantin Ananyev    DeregisterEventSource(ev);
99e18a033bSKonstantin Ananyev}