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