2013-07-25 Keith Marshall <keithmarshall@users.sourceforge.net>
+ Implement setup tool installer "plugin".
+
+ * src/setup.h (SETUP_HOOK_RUN_INSTALLER): Define request code.
+
+ * src/dllhook.cpp (run_basic_system_installer): Implement handler...
+ (setup_hook) [SETUP_HOOK_RUN_INSTALLER]: ...and invoke it.
+ (setup_hook) [default]: Collect diagnostics in common message digest.
+ (AppWindowMaker::SetupHookInvoked): Define and initialise it; in this
+ context, which does not conflict with prior definition in guimain.exe,
+ it must always remain true.
+
+ * src/setup.cpp (SetupTool) [constructor]: Invoke...
+ (SetupTool::DispatchSetupHookRequest): ...this, on user's request...
+ (SETUP_HOOK_RUN_INSTALLER): ...with this action code; this replaces...
+ (SetupTool::RunInstalledProgram): ...one reference instance for this
+ external program fork, leaving only one such reference remaining;
+ declare it to be "inline".
+
+ * Makefile.in (GUIMAIN_LIB_OBJECTS): New macro; define it. It
+ abstracts a subset of the object modules originally enumerated...
+ (GUIMAIN_OBJECTS): ...here, whence use it; also incorporate into...
+ (SETUP_DLL_OBJECTS): ...this.
+ (SETUP_DLL_LIBS): Make it equivalent to...
+ (GUIMAIN_LIBS): ...this.
+ (mingw-get-setup-0.dll): Use...
+ (GUI_LDFLAGS): ...this, to specify linking options, rather than...
+ (LDFLAGS): ...this.
+
+2013-07-25 Keith Marshall <keithmarshall@users.sourceforge.net>
+
Add "Basic Setup" as a built-in standard package group.
* src/guimain.h (AppWindowMaker::SetupToolInvoked): New private
clistub.$(OBJEXT) version.$(OBJEXT) approot.$(OBJEXT) getopt.$(OBJEXT)
GUIMAIN_OBJECTS = \
- guimain.$(OBJEXT) guiexec.$(OBJEXT) dmhguix.$(OBJEXT) \
- approot.$(OBJEXT) pkgview.$(OBJEXT) pkgtree.$(OBJEXT) pkglist.$(OBJEXT) \
- pkgdata.$(OBJEXT) pkgnget.$(OBJEXT) guimain.res.$(OBJEXT)
+ guimain.$(OBJEXT) dmhguix.$(OBJEXT) $(GUIMAIN_LIB_OBJECTS) \
+ approot.$(OBJEXT) guimain.res.$(OBJEXT)
+
+GUIMAIN_LIB_OBJECTS = \
+ guiexec.$(OBJEXT) pkgview.$(OBJEXT) pkgtree.$(OBJEXT) pkglist.$(OBJEXT) \
+ pkgdata.$(OBJEXT) pkgnget.$(OBJEXT)
GUIMAIN_LIBS = -lwtklite -lcomctl32
SETUP_TOOL_OBJECTS = setup.$(OBJEXT) setup.res.$(OBJEXT) apihook.$(OBJEXT)
SETUP_TOOL_LIBS = -lwtklite -lwininet -lcomctl32 -lole32 -Wl,-Bstatic -llzma
-SETUP_DLL_OBJECTS = dllhook.$(OBJEXT)
-SETUP_DLL_LIBS =
+SETUP_DLL_OBJECTS = \
+ dllhook.$(OBJEXT) $(GUIMAIN_LIB_OBJECTS) guimain.res.$(OBJEXT)
+
+SETUP_DLL_LIBS = $(GUIMAIN_LIBS)
script_srcdir = ${srcdir}/scripts/libexec
$(CXX) -shared -o $@ $(CXXFLAGS) $(LDFLAGS) $+ $(LIBS)
mingw-get-setup-0.dll: $(SETUP_DLL_OBJECTS) mingw-get-0.dll
- $(CXX) -shared -o $@ $(CXXFLAGS) $(LDFLAGS) $+ $(SETUP_DLL_LIBS)
+ $(CXX) -shared -o $@ $(CXXFLAGS) $(GUI_LDFLAGS) $+ $(SETUP_DLL_LIBS)
# The following recursive invocation hook provides a mechanism for
# accessing make's facility for reporting what it is doing, even when
#include <sys/stat.h>
#include <fcntl.h>
+/* This file implements the plugin variant of the mingw-get
+ * GUI installer, for use by the setup tool; in this context
+ * this AppWindowMaker static attribute must be initialised
+ * to indicate this mode of use.
+ */
+bool AppWindowMaker::SetupToolInvoked = true;
+
static const char *internal_error = "internal error";
#define MSG_INTERNAL_ERROR(MSG) "%s: "MSG_##MSG"\n", internal_error
free( (void *)(dfile) );
}
+static inline
+int run_basic_system_installer( const wchar_t *dll_name )
+{
+ /* Hook to emulate a subset of the mingw-get GUI installer
+ * capabilities, via an embedded subset of its functions.
+ */
+ try
+ { /* Identify the DLL module, whence we may retrieve resources
+ * similar to those of the free-standing GUI application, and
+ * create a clone of that application's main window.
+ */
+ HINSTANCE instance;
+ AppWindowMaker MainWindow( instance = GetModuleHandleW( dll_name ) );
+ MainWindow.Create( WTK::StringResource( instance, ID_MAIN_WINDOW_CLASS ),
+ WTK::StringResource( instance, ID_MAIN_WINDOW_CAPTION )
+ );
+
+ /* Show this window, and paint its initial content...
+ */
+ MainWindow.Show( SW_SHOW );
+ MainWindow.Update();
+
+ /* ...then invoke its message loop, ultimately returning the
+ * status code which prevails, when the user closes it.
+ */
+ return MainWindow.Invoked();
+ }
+ catch( dmh_exception &e )
+ {
+ /* Here, we handle any fatal exception which has been raised
+ * and identified by the diagnostic message handler...
+ */
+ MessageBox( NULL, e.what(), "WinMain", MB_ICONERROR );
+ return EXIT_FAILURE;
+ }
+ catch( WTK::runtime_error &e )
+ {
+ /* ...while here, we diagnose any other error which was captured
+ * during the creation of the application's window hierarchy, or
+ * processing of its message loop...
+ */
+ MessageBox( NULL, e.what(), "WinMain", MB_ICONERROR );
+ return EXIT_FAILURE;
+ }
+ catch(...)
+ { /* ...and here, we diagnose any other error which we weren't
+ * able to explicitly identify.
+ */
+ MessageBox( NULL, "Unknown exception", "WinMain", MB_ICONERROR );
+ return EXIT_FAILURE;
+ }
+}
+
EXTERN_C __declspec(dllexport)
void setup_hook( unsigned int request, va_list argv )
{
update_catalogue( va_arg( argv, HWND ) );
break;
+ case SETUP_HOOK_RUN_INSTALLER:
+ /* This hook invokes the mingw-get GUI, in setup tool mode, to
+ * facilitate installation of a user configured basic system.
+ */
+ run_basic_system_installer( va_arg( argv, const wchar_t * ) );
+ break;
+
default:
/* We should never get to here; it's a programming error in
* the setup tool, if we do.
*/
+ dmh_control( DMH_BEGIN_DIGEST );
dmh_notify( DMH_ERROR, MSG_INTERNAL_ERROR( INVALID_REQUEST ) );
dmh_notify( DMH_ERROR, MSG_INTERNAL_ERROR( NOTIFY_MAINTAINER ) );
+ dmh_control( DMH_END_DIGEST );
}
}
( HWND, unsigned, WPARAM, LPARAM );
static const wchar_t *gui_program;
- int RunInstalledProgram( const wchar_t * );
+ inline int RunInstalledProgram( const wchar_t * );
inline wchar_t *setup_dll( void )
{ /* Helper function to ensure that the static "approot_path" buffer
MAKEINTRESOURCE( IDD_SETUP_BEGIN ), NULL, OpeningDialogue
);
+ /* When the user has requested progression to package installation...
+ */
+ if( Status == EXIT_CONTINUE )
+ {
+ /* ...then delegate that to the embedded mingw-get plugin, before
+ * reasserting successful completion status for the setup tool.
+ */
+ DispatchSetupHookRequest( SETUP_HOOK_RUN_INSTALLER, setup_dll() );
+ Status = EXIT_SUCCESS;
+ }
+
/* If the mingw-get-0.dll and mingw-get-setup-0.dll libraries
* were successfully loaded, to complete the installation process,
* then we must now unload them; we also have no further use for
/* We're done with the COM subsystem; release it.
*/
CoUninitialize();
-
- /* When the user has requested progression to advanced installation...
- */
- if( Status == EXIT_CONTINUE )
- {
- /* ...the delegate that to mingw-get itself, before reasserting
- * the successful completion status for the setup tool.
- */
- RunInstalledProgram( gui_program );
- Status = EXIT_SUCCESS;
- }
}
}
*/
const wchar_t *SetupTool::gui_program = L"libexec\\mingw-get\\guimain.exe";
-int SetupTool::RunInstalledProgram( const wchar_t *program )
+inline int SetupTool::RunInstalledProgram( const wchar_t *program )
{
/* Helper method to spawn an external process, into which a
* specified program image is loaded; (typically this will be
* serviced by mingw-get-setup-0.dll
*/
SETUP_HOOK_DMH_BIND = 0,
- SETUP_HOOK_POST_INSTALL
+ SETUP_HOOK_POST_INSTALL,
+ SETUP_HOOK_RUN_INSTALLER
};
class pkgSetupAction