]> granicus.if.org Git - postgresql/blob - src/bin/pgevent/pgevent.c
6a667812fba98e7a36038dbc0ffdf72ccd4d6eab
[postgresql] / src / bin / pgevent / pgevent.c
1 /*-------------------------------------------------------------------------
2  *
3  * pgevent.c
4  *              Defines the entry point for pgevent dll.
5  *              The DLL defines event source for backend
6  *
7  *
8  * IDENTIFICATION
9  *        src/bin/pgevent/pgevent.c
10  *
11  *-------------------------------------------------------------------------
12  */
13
14
15 #include <windows.h>
16 #include <olectl.h>
17 #include <string.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 /* Global variables */
22 HANDLE          g_module = NULL;        /* hModule of DLL */
23
24 /*
25  * The event source is stored as a registry key.
26  * The maximum length of a registry key is 255 characters.
27  * http://msdn.microsoft.com/en-us/library/ms724872(v=vs.85).aspx
28  */
29 char            event_source[256] = "PostgreSQL";
30
31 /* Prototypes */
32 HRESULT         DllInstall(BOOL bInstall, LPCWSTR pszCmdLine);
33 STDAPI          DllRegisterServer(void);
34 STDAPI          DllUnregisterServer(void);
35 BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved);
36
37 /*
38  * DllInstall --- Passes the command line argument to DLL
39  */
40
41 HRESULT
42 DllInstall(BOOL bInstall,
43                    LPCWSTR pszCmdLine)
44 {
45         if (pszCmdLine && *pszCmdLine != '\0')
46                 wcstombs(event_source, pszCmdLine, sizeof(event_source));
47
48         /*
49          * This is an ugly hack due to the strange behavior of "regsvr32 /i".
50          *
51          * When installing, regsvr32 calls DllRegisterServer before DllInstall.
52          * When uninstalling (i.e. "regsvr32 /u /i"), on the other hand, regsvr32
53          * calls DllInstall and then DllUnregisterServer as expected.
54          *
55          * This strange behavior forces us to specify -n (i.e. "regsvr32 /n /i").
56          * Without -n, DllRegisterServer called before DllInstall would mistakenly
57          * overwrite the default "PostgreSQL" event source registration.
58          */
59         if (bInstall)
60                 DllRegisterServer();
61         return S_OK;
62 }
63
64 /*
65  * DllRegisterServer --- Instructs DLL to create its registry entries
66  */
67
68 STDAPI
69 DllRegisterServer(void)
70 {
71         HKEY            key;
72         DWORD           data;
73         char            buffer[_MAX_PATH];
74         char            key_name[400];
75
76         /* Set the name of DLL full path name. */
77         if (!GetModuleFileName((HMODULE) g_module, buffer, sizeof(buffer)))
78         {
79                 MessageBox(NULL, "Could not retrieve DLL filename", "PostgreSQL error", MB_OK | MB_ICONSTOP);
80                 return SELFREG_E_TYPELIB;
81         }
82
83         /*
84          * Add PostgreSQL source name as a subkey under the Application key in the
85          * EventLog registry key.
86          */
87         _snprintf(key_name, sizeof(key_name),
88                         "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s",
89                           event_source);
90         if (RegCreateKey(HKEY_LOCAL_MACHINE, key_name, &key))
91         {
92                 MessageBox(NULL, "Could not create the registry key.", "PostgreSQL error", MB_OK | MB_ICONSTOP);
93                 return SELFREG_E_TYPELIB;
94         }
95
96         /* Add the name to the EventMessageFile subkey. */
97         if (RegSetValueEx(key,
98                                           "EventMessageFile",
99                                           0,
100                                           REG_EXPAND_SZ,
101                                           (LPBYTE) buffer,
102                                           strlen(buffer) + 1))
103         {
104                 MessageBox(NULL, "Could not set the event message file.", "PostgreSQL error", MB_OK | MB_ICONSTOP);
105                 return SELFREG_E_TYPELIB;
106         }
107
108         /* Set the supported event types in the TypesSupported subkey. */
109         data = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
110
111         if (RegSetValueEx(key,
112                                           "TypesSupported",
113                                           0,
114                                           REG_DWORD,
115                                           (LPBYTE) &data,
116                                           sizeof(DWORD)))
117         {
118                 MessageBox(NULL, "Could not set the supported types.", "PostgreSQL error", MB_OK | MB_ICONSTOP);
119                 return SELFREG_E_TYPELIB;
120         }
121
122         RegCloseKey(key);
123         return S_OK;
124 }
125
126 /*
127  * DllUnregisterServer --- Instructs DLL to remove only those entries created through DllRegisterServer
128  */
129
130 STDAPI
131 DllUnregisterServer(void)
132 {
133         char            key_name[400];
134
135         /*
136          * Remove PostgreSQL source name as a subkey under the Application key in
137          * the EventLog registry key.
138          */
139
140         _snprintf(key_name, sizeof(key_name),
141                         "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s",
142                           event_source);
143         if (RegDeleteKey(HKEY_LOCAL_MACHINE, key_name))
144         {
145                 MessageBox(NULL, "Could not delete the registry key.", "PostgreSQL error", MB_OK | MB_ICONSTOP);
146                 return SELFREG_E_TYPELIB;
147         }
148         return S_OK;
149 }
150
151 /*
152  * DllMain --- is an optional entry point into a DLL.
153  */
154
155 BOOL            WINAPI
156 DllMain(HANDLE hModule,
157                 DWORD ul_reason_for_call,
158                 LPVOID lpReserved
159 )
160 {
161         if (ul_reason_for_call == DLL_PROCESS_ATTACH)
162                 g_module = hModule;
163         return TRUE;
164 }