1515#include <windows.h>
1616#include <olectl.h>
1717#include <string.h>
18+ #include <stdio.h>
19+ #include <stdlib.h>
1820
1921/* Global variables */
2022HANDLE g_module = NULL ;/* hModule of DLL */
2123
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+
2231/* Prototypes */
23- STDAPI
24- DllRegisterServer (void );
32+ HRESULT DllInstall ( BOOL bInstall , __in_opt LPCWSTR pszCmdLine );
33+ STDAPI DllRegisterServer (void );
2534STDAPI DllUnregisterServer (void );
2635BOOL WINAPI DllMain (HANDLE hModule ,DWORD ul_reason_for_call ,LPVOID lpReserved );
2736
37+ /*
38+ * DllInstall --- Passes the command line argument to DLL
39+ */
40+
41+ HRESULT
42+ DllInstall (BOOL bInstall ,
43+ __in_opt LPCWSTR pszCmdLine )
44+ {
45+ size_t ret ;
46+
47+ if (pszCmdLine && * pszCmdLine != '\0' )
48+ wcstombs_s (& ret ,event_source ,sizeof (event_source ),
49+ pszCmdLine ,sizeof (event_source ));
50+
51+ /*
52+ * This is an ugly hack due to the strange behavior of "regsvr32 /i".
53+ *
54+ * When installing, regsvr32 calls DllRegisterServer before DllInstall.
55+ * When uninstalling (i.e. "regsvr32 /u /i"), on the other hand, regsvr32
56+ * calls DllInstall and then DllUnregisterServer as expected.
57+ *
58+ * This strange behavior forces us to specify -n (i.e. "regsvr32 /n /i").
59+ * Without -n, DllRegisterServer called before DllInstall would mistakenly
60+ * overwrite the default "PostgreSQL" event source registration.
61+ */
62+ if (bInstall )
63+ DllRegisterServer ();
64+ return S_OK ;
65+ }
66+
2867/*
2968 * DllRegisterServer --- Instructs DLL to create its registry entries
3069 */
@@ -35,6 +74,7 @@ DllRegisterServer(void)
3574HKEY key ;
3675DWORD data ;
3776char buffer [_MAX_PATH ];
77+ char key_name [400 ];
3878
3979/* Set the name of DLL full path name. */
4080if (!GetModuleFileName ((HMODULE )g_module ,buffer ,sizeof (buffer )))
@@ -47,7 +87,10 @@ DllRegisterServer(void)
4787 * Add PostgreSQL source name as a subkey under the Application key in the
4888 * EventLog registry key.
4989 */
50- if (RegCreateKey (HKEY_LOCAL_MACHINE ,"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\PostgreSQL" ,& key ))
90+ _snprintf (key_name ,sizeof (key_name ),
91+ "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s" ,
92+ event_source );
93+ if (RegCreateKey (HKEY_LOCAL_MACHINE ,key_name ,& key ))
5194{
5295MessageBox (NULL ,"Could not create the registry key." ,"PostgreSQL error" ,MB_OK |MB_ICONSTOP );
5396return SELFREG_E_TYPELIB ;
@@ -72,7 +115,7 @@ DllRegisterServer(void)
72115"TypesSupported" ,
731160 ,
74117REG_DWORD ,
75- (LPBYTE )& data ,
118+ (LPBYTE )& data ,
76119sizeof (DWORD )))
77120{
78121MessageBox (NULL ,"Could not set the supported types." ,"PostgreSQL error" ,MB_OK |MB_ICONSTOP );
@@ -90,12 +133,17 @@ DllRegisterServer(void)
90133STDAPI
91134DllUnregisterServer (void )
92135{
136+ char key_name [400 ];
137+
93138/*
94139 * Remove PostgreSQL source name as a subkey under the Application key in
95140 * the EventLog registry key.
96141 */
97142
98- if (RegDeleteKey (HKEY_LOCAL_MACHINE ,"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\PostgreSQL" ))
143+ _snprintf (key_name ,sizeof (key_name ),
144+ "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s" ,
145+ event_source );
146+ if (RegDeleteKey (HKEY_LOCAL_MACHINE ,key_name ))
99147{
100148MessageBox (NULL ,"Could not delete the registry key." ,"PostgreSQL error" ,MB_OK |MB_ICONSTOP );
101149return SELFREG_E_TYPELIB ;