[Box Backup-dev] COMMIT r526 - in box/chris/general: infrastructure lib/win32

boxbackup-dev@fluffy.co.uk boxbackup-dev@fluffy.co.uk
Sun, 26 Feb 2006 19:44:12 +0000 (GMT)


Author: chris
Date: 2006-02-26 19:44:06 +0000 (Sun, 26 Feb 2006)
New Revision: 526

Added:
   box/chris/general/lib/win32/MSG00001.bin
   box/chris/general/lib/win32/messages.h
   box/chris/general/lib/win32/messages.mc
   box/chris/general/lib/win32/messages.rc
Modified:
   box/chris/general/infrastructure/makebuildenv.pl
   box/chris/general/lib/win32/emu.cpp
   box/chris/general/lib/win32/emu.h
Log:
Fixed the "Description for event ID ... cannot be found" error in the 
Windows event log:

* infrastructure/makebuildenv.pl
- Added ability to detect, build and link Windows resource files (.rc),
  needed to fix this problem.

* lib/win32/messages.mc
- Added the raw message file to the repository. This must be compiled
  to a .rc file with Microsoft's message compiler (MC).

* lib/win32/messages.rc
* lib/win32/messages.h
* lib/win32/MSG00001.bin
- Added precompiled output from message compiler, for those who don't
  have it (e.g. using MinGW instead of MSVC)

* lib/win32/emu.h
* lib/win32/emu.cpp
- Added the ability to add a new event source to the Windows Registry
- Moved openlog() and closelog() from inline to emu.cpp, made openlog()
  add and register a proper event source.


Modified: box/chris/general/infrastructure/makebuildenv.pl
===================================================================
--- box/chris/general/infrastructure/makebuildenv.pl	2006-02-26 19:37:42 UTC (rev 525)
+++ box/chris/general/infrastructure/makebuildenv.pl	2006-02-26 19:44:06 UTC (rev 526)
@@ -372,6 +372,7 @@
 
 print "done\n\nGenerating Makefiles...\n";
 
+my %module_resources_win32;
 
 # Then write a makefile for each module
 for my $mod (@modules, $implicit_dep)
@@ -544,7 +545,7 @@
 		@items = (@items, @autogen_items);
 	}
 	
-	# first, obtain a list of depenencies within the .h files
+	# first, obtain a list of dependencies within the .h files
 	my %headers;
 	for my $h (grep /\.h\Z/i, @items)
 	{
@@ -564,19 +565,30 @@
 	
 	# then... do the cpp files...
 	my @obj_base;
-	for my $cpp (@items)
+	for my $file (@items)
 	{
-		next unless $cpp =~ m/\A(.+)\.cpp\Z/i;
-		next if $cpp =~ /\A\._/;	# Temp Mac OS Resource hack
+		my $is_cpp = $file =~ m/\A(.+)\.cpp\Z/i;
+		my $is_rc  = $file =~ m/\A(.+)\.rc\Z/i;
 
+		if ($target_os eq "mingw32")
+		{
+			next if not $is_cpp and not $is_rc;
+		}
+		else
+		{
+			next if not $is_rc;
+		}
+
+		next if $file =~ /\A\._/; # Temp Mac OS Resource hack
+
 		# store for later
 		my $base = $1;
-		push @obj_base,$base;
+		push @obj_base,$base unless $is_rc;
 	
 		# get the file...
-		open FL,"$mod/$cpp";
+		open FL,"$mod/$file";
 		my $f;
-		read FL,$f,-s "$mod/$cpp";
+		read FL,$f,-s "$mod/$file";
 		close FL;
 		
 		my %dep;
@@ -590,10 +602,29 @@
 		my $out_name = '$(OUTDIR)/'.$base.'.o';
 		
 		# write the line for this cpp file
-		$make .= $out_name.': '.join(' ',$cpp,map
-			{ ($hfiles{$_} eq $mod)?$_:'../../'.$hfiles{$_}."/$_" } keys %dep)."\n";
-		$make .= "\t\$(CXX) \$(CXXFLAGS) $compile_line_extra -c $cpp -o $out_name\n\n";
+		my @dep_paths = map 
+		{ 
+			($hfiles{$_} eq $mod)
+			? $_ 
+			: '../../'.$hfiles{$_}."/$_"
+		}
+		keys %dep;
 
+		$make .= $out_name.': '.join(' ',$file,@dep_paths)."\n";
+
+		if ($is_cpp)
+		{
+			$make .= "\t\$(CXX) \$(CXXFLAGS) $compile_line_extra ".
+				"-c $file -o $out_name\n\n";
+		}
+		elsif ($is_rc)
+		{
+			$make .= "\twindres $file $out_name\n\n";
+			my $res_list = $module_resources_win32{$mod};
+			$res_list ||= [];
+			push @$res_list, $base.'.o';
+			$module_resources_win32{$mod} = $res_list;
+		}
 	}
 
 	my $has_deps = ($#{$module_dependency{$mod}} >= 0);
@@ -645,11 +676,23 @@
 	additional_objects_from_make_fragment("$mod/Makefile.extra.$build_os", \@objs, \@makefile_includes);
 
 	my $o_file_list = join(' ',map {'$(OUTDIR)/'.$_.'.o'} @objs);
+
 	print MAKE $end_target,': ',$o_file_list;
 	print MAKE ' dep_modules' if $has_deps and not $bsd_make;
 	print MAKE " ",$lib_files unless $target_is_library;
 	print MAKE "\n";
 	
+	if ($target_os eq "mingw32")
+	{
+		foreach my $dep (@all_deps_for_module)
+		{
+			my $res_list = $module_resources_win32{$dep};
+			next unless $res_list;
+			$o_file_list .= ' '.join(' ', 
+				map {'$(OUTBASE)/'.$dep."/$_"} @$res_list);
+		}
+	}
+
 	# stuff to make the final target...
 	if($target_is_library)
 	{

Added: box/chris/general/lib/win32/MSG00001.bin
===================================================================
(Binary files differ)


Property changes on: box/chris/general/lib/win32/MSG00001.bin
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:mime-type
   + application/octet-stream

Modified: box/chris/general/lib/win32/emu.cpp
===================================================================
--- box/chris/general/lib/win32/emu.cpp	2006-02-26 19:37:42 UTC (rev 525)
+++ box/chris/general/lib/win32/emu.cpp	2006-02-26 19:44:06 UTC (rev 526)
@@ -7,11 +7,8 @@
 
 #ifdef WIN32
 
-// #include "emu.h"
-
 #include <windows.h>
 #include <fcntl.h>
-// #include <atlenc.h>
 
 #ifdef HAVE_UNISTD_H
 	#include <unistd.h>
@@ -23,6 +20,10 @@
 #include <string>
 #include <list>
 
+// message resource definitions for syslog()
+
+#include "messages.h"
+
 // our implementation for a timer, based on a 
 // simple thread which sleeps for a period of time
 
@@ -1002,9 +1003,147 @@
 	return -1;
 }
 
-HANDLE gSyslogH = 0;
+// copied from MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/eventlog/base/adding_a_source_to_the_registry.asp
+
+BOOL AddEventSource
+(
+	LPTSTR pszSrcName, // event source name
+	DWORD  dwNum       // number of categories
+)
+{
+	// Work out the executable file name, to register ourselves
+	// as the event source
+
+	char cmd[MAX_PATH];
+	if (GetModuleFileName(NULL, cmd, sizeof(cmd)-1) == 0)
+	{
+		::syslog(LOG_ERR, "Failed to get the program file name: "
+			"error %d", GetLastError());
+		return FALSE;
+	}
+	cmd[sizeof(cmd)-1] = 0;
+ 	std::string exepath(cmd);
+
+	// Create the event source as a subkey of the log. 
+
+	std::string regkey("SYSTEM\\CurrentControlSet\\Services\\EventLog\\"
+		"Application\\");
+	regkey += pszSrcName; 
+ 
+	HKEY hk;
+	DWORD dwDisp;
+
+	if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, regkey.c_str(), 
+			 0, NULL, REG_OPTION_NON_VOLATILE,
+			 KEY_WRITE, NULL, &hk, &dwDisp)) 
+	{
+		::syslog(LOG_ERR, "Failed to create the registry key: "
+			"error %d", GetLastError()); 
+		return FALSE;
+	}
+
+	// Set the name of the message file. 
+ 
+	if (RegSetValueEx(hk,                // subkey handle 
+			 "EventMessageFile", // value name 
+			 0,                  // must be zero 
+			 REG_EXPAND_SZ,      // value type 
+			 (LPBYTE) exepath.c_str(),  // pointer to value data 
+			 (DWORD) (exepath.size()))) // data size
+	{
+		::syslog(LOG_ERR, "Failed to set the event message file: "
+			"error %d", GetLastError()); 
+		RegCloseKey(hk); 
+		return FALSE;
+	}
+ 
+	// Set the supported event types. 
+ 
+	DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | 
+		  EVENTLOG_INFORMATION_TYPE; 
+ 
+	if (RegSetValueEx(hk,               // subkey handle 
+			  "TypesSupported", // value name 
+			  0,                // must be zero 
+			  REG_DWORD,        // value type 
+			  (LPBYTE) &dwData, // pointer to value data 
+			  sizeof(DWORD)))   // length of value data 
+	{
+		::syslog(LOG_ERR, "Failed to set the supported types: "
+			"error %d", GetLastError()); 
+		RegCloseKey(hk); 
+		return FALSE;
+	}
+ 
+	// Set the category message file and number of categories.
+
+	if (RegSetValueEx(hk,                        // subkey handle 
+			  "CategoryMessageFile",     // value name 
+			  0,                         // must be zero 
+			  REG_EXPAND_SZ,             // value type 
+			  (LPBYTE) exepath.c_str(),  // pointer to value data 
+			  (DWORD) (exepath.size()))) // data size
+	{
+		::syslog(LOG_ERR, "Failed to set the category message file: "
+			"error %d", GetLastError());
+		RegCloseKey(hk); 
+		return FALSE;
+	}
+ 
+	if (RegSetValueEx(hk,              // subkey handle 
+			  "CategoryCount", // value name 
+			  0,               // must be zero 
+			  REG_DWORD,       // value type 
+			  (LPBYTE) &dwNum, // pointer to value data 
+			  sizeof(DWORD)))  // length of value data 
+	{
+		::syslog(LOG_ERR, "Failed to set the category count: "
+			"error %d", GetLastError());
+		RegCloseKey(hk); 
+		return FALSE;
+	}
+
+	RegCloseKey(hk); 
+	return TRUE;
+}
+
+static HANDLE gSyslogH = 0;
 static bool sHaveWarnedEventLogFull = false;
 
+void openlog(const char * daemonName, int, int)
+{
+	// register a default event source, so that we can
+	// log errors with the process of adding or registering our own.
+	gSyslogH = RegisterEventSource(
+		NULL,        // uses local computer 
+		daemonName); // source name
+	if (gSyslogH == NULL) 
+	{
+	}
+
+	if (!AddEventSource("Box Backup", 0))
+	{
+		::syslog(LOG_ERR, "Failed to add our own event source");
+		return;
+	}
+
+	HANDLE newSyslogH = RegisterEventSource(NULL, "Box Backup");
+	if (newSyslogH == NULL)
+	{
+		::syslog(LOG_ERR, "Failed to register our own event source: "
+			"error %d", GetLastError());
+		return;
+	}
+
+	DeregisterEventSource(gSyslogH);
+	gSyslogH = newSyslogH;
+}
+
+void closelog(void)
+{
+	DeregisterEventSource(gSyslogH); 
+}
+
 void syslog(int loglevel, const char *frmt, ...)
 {
 	WORD errinfo;
@@ -1054,7 +1193,7 @@
 	if (!ReportEvent(gSyslogH, // event log handle 
 		errinfo,               // event type 
 		0,                     // category zero 
-		MSG_ERR_EXIST,	       // event identifier - 
+		MSG_ERR,	       // event identifier - 
 		                       // we will call them all the same
 		NULL,                  // no user security identifier 
 		1,                     // one substitution string 

Modified: box/chris/general/lib/win32/emu.h
===================================================================
--- box/chris/general/lib/win32/emu.h	2006-02-26 19:37:42 UTC (rev 525)
+++ box/chris/general/lib/win32/emu.h	2006-02-26 19:44:06 UTC (rev 526)
@@ -276,25 +276,10 @@
 #define LOG_PID 0
 #define LOG_LOCAL6 0
 
-extern HANDLE gSyslogH;
-void MyReportEvent(LPCTSTR *szMsg, DWORD errinfo);
-inline void openlog(const char * daemonName, int, int)
-{
-	gSyslogH = RegisterEventSource(
-		NULL,  // uses local computer 
-		daemonName);    // source name
-	if (gSyslogH == NULL) 
-	{
-	}
-}
+void openlog (const char * daemonName, int, int);
+void closelog(void);
+void syslog  (int loglevel, const char *fmt, ...);
 
-inline void closelog(void)
-{
-	DeregisterEventSource(gSyslogH); 
-}
-
-void syslog(int loglevel, const char *fmt, ...);
-
 #ifndef __MINGW32__
 #define strtoll _strtoi64
 #endif
@@ -417,13 +402,6 @@
 bool ConvertUtf8ToConsole(const char* pString, std::string& rDest);
 bool ConvertConsoleToUtf8(const char* pString, std::string& rDest);
 
-//
-// MessageId: MSG_ERR_EXIST
-// MessageText:
-//  Box Backup.
-//
-#define MSG_ERR_EXIST                         ((DWORD)0xC0000004L)
-
 // replacement for _cgetws which requires a relatively recent C runtime lib
 int console_read(char* pBuffer, size_t BufferSize);
 

Added: box/chris/general/lib/win32/messages.h
===================================================================
--- box/chris/general/lib/win32/messages.h	2006-02-26 19:37:42 UTC (rev 525)
+++ box/chris/general/lib/win32/messages.h	2006-02-26 19:44:06 UTC (rev 526)
@@ -0,0 +1,57 @@
+ // Message source file, to be compiled to a resource file with
+ // Microsoft Message Compiler (MC), to an object file with a Resource
+ // Compiler, and linked into the application.
+
+ // The main reason for this file is to work around Windows' stupid
+ // messages in the Event Log, which say:
+
+ // The description for Event ID ( 4 ) in Source ( Box Backup (bbackupd) ) 
+ // cannot be found. The local computer may not have the necessary 
+ // registry information or message DLL files to display messages from a 
+ // remote computer. The following information is part of the event:
+ // Message definitions follow
+//
+//  Values are 32 bit values layed out as follows:
+//
+//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+//  +---+-+-+-----------------------+-------------------------------+
+//  |Sev|C|R|     Facility          |               Code            |
+//  +---+-+-+-----------------------+-------------------------------+
+//
+//  where
+//
+//      Sev - is the severity code
+//
+//          00 - Success
+//          01 - Informational
+//          10 - Warning
+//          11 - Error
+//
+//      C - is the Customer code flag
+//
+//      R - is a reserved bit
+//
+//      Facility - is the facility code
+//
+//      Code - is the facility's status code
+//
+//
+// Define the facility codes
+//
+
+
+//
+// Define the severity codes
+//
+
+
+//
+// MessageId: MSG_ERR
+//
+// MessageText:
+//
+//  %1
+//
+#define MSG_ERR                          ((DWORD)0x40000001L)
+


Property changes on: box/chris/general/lib/win32/messages.h
___________________________________________________________________
Name: svn:executable
   + *

Added: box/chris/general/lib/win32/messages.mc
===================================================================
--- box/chris/general/lib/win32/messages.mc	2006-02-26 19:37:42 UTC (rev 525)
+++ box/chris/general/lib/win32/messages.mc	2006-02-26 19:44:06 UTC (rev 526)
@@ -0,0 +1,22 @@
+; // Message source file, to be compiled to a resource file with
+; // Microsoft Message Compiler (MC), to an object file with a Resource
+; // Compiler, and linked into the application.
+;
+; // The main reason for this file is to work around Windows' stupid
+; // messages in the Event Log, which say:
+;
+; // The description for Event ID ( 4 ) in Source ( Box Backup (bbackupd) ) 
+; // cannot be found. The local computer may not have the necessary 
+; // registry information or message DLL files to display messages from a 
+; // remote computer. The following information is part of the event:
+
+MessageIdTypedef = DWORD
+
+; // Message definitions follow
+
+MessageId = 0x1
+Severity = Informational
+SymbolicName = MSG_ERR
+Language = English
+%1
+.

Added: box/chris/general/lib/win32/messages.rc
===================================================================
--- box/chris/general/lib/win32/messages.rc	2006-02-26 19:37:42 UTC (rev 525)
+++ box/chris/general/lib/win32/messages.rc	2006-02-26 19:44:06 UTC (rev 526)
@@ -0,0 +1,2 @@
+LANGUAGE 0x9,0x1
+1 11 MSG00001.bin


Property changes on: box/chris/general/lib/win32/messages.rc
___________________________________________________________________
Name: svn:executable
   + *