* Implement <autoregister>
authorCasper Hornstrup <chorns@users.sourceforge.net>
Sat, 26 Nov 2005 18:43:46 +0000 (18:43 +0000)
committerCasper Hornstrup <chorns@users.sourceforge.net>
Sat, 26 Nov 2005 18:43:46 +0000 (18:43 +0000)
* Autogenerate syssetup.inf

svn path=/trunk/; revision=19650

reactos/media/inf/syssetup.inf.tpl [moved from reactos/media/inf/syssetup.inf with 100% similarity]
reactos/tools/rbuild/backend/mingw/mingw.cpp
reactos/tools/rbuild/backend/mingw/mingw.h
reactos/tools/rbuild/doc/rbuild.txt
reactos/tools/rbuild/module.cpp
reactos/tools/rbuild/rbuild.h
reactos/tools/rbuild/rbuild.mak
reactos/tools/rbuild/syssetupgenerator.cpp [new file with mode: 0644]

index 36380ec..7b4ceb3 100644 (file)
@@ -237,6 +237,7 @@ MingwBackend::ProcessNormal ()
        UnpackWineResources ();
        GenerateTestSupportCode ();
        GenerateCompilationUnitSupportCode ();
+       GenerateSysSetup ();
        GenerateProxyMakefiles ();
        CheckAutomaticDependencies ();
        CloseMakefile ();
@@ -578,6 +579,15 @@ MingwBackend::GenerateCompilationUnitSupportCode ()
        }
 }
 
+void
+MingwBackend::GenerateSysSetup ()
+{
+       printf ( "Generating syssetup.inf..." );
+       SysSetupGenerator sysSetupGenerator ( ProjectNode );
+       sysSetupGenerator.Generate ();
+       printf ( "done\n" );
+}
+
 string
 MingwBackend::GetProxyMakefileTree () const
 {
index 45db183..4c392d2 100644 (file)
@@ -78,6 +78,7 @@ private:
        void UnpackWineResources ();
        void GenerateTestSupportCode ();
        void GenerateCompilationUnitSupportCode ();
+       void GenerateSysSetup ();
        std::string GetProxyMakefileTree () const;
        void GenerateProxyMakefiles ();
        void CheckAutomaticDependencies ();
index 75cf87c..46f40c2 100644 (file)
@@ -129,7 +129,7 @@ Value:
        None.
 
 Elements:
-       bootstrap, component, compilationunit, define, dependency, directory, file, if, importlibrary, include, invoke, library, linkerscript, property.
+       autoregister, bootstrap, component, compilationunit, define, dependency, directory, file, if, importlibrary, include, invoke, library, linkerscript, property.
 
 
 Module types
@@ -154,6 +154,24 @@ The module type determines the actions that is to be carried out to process the
        alias - Module is an alias for another module. This module type is the only module type for which the aliasof attribute is applicable. Only the module install functionality is aliased.
 
 
+Autoregister element
+--------------------
+An autoregister element specifies that the generated executable should be registered in the registry during second stage setup.
+
+Syntax:
+       <autoregister infsection="OleControlDlls" type="Both" />
+
+Attributes:
+       infsection - Name of section in syssetup.inf.
+       type - Type of registration. Can be either DllRegisterServer, DllInstall, or Both.
+
+Value:
+       None.
+
+Elements:
+       None.
+
+
 Bootstrap element
 -----------------
 A bootstrap element specifies that the generated file should be put on the bootable CD as a bootstrap file.
index 1073fb1..3bd1a5e 100644 (file)
@@ -187,6 +187,14 @@ GetBooleanValue ( const string& value )
                return false;
 }
 
+string
+ToLower ( string filename )
+{
+       for ( size_t i = 1; i < filename.length (); i++ )
+               filename[i] = tolower ( filename[i] );
+       return filename;
+}
+
 IfableData::~IfableData()
 {
        size_t i;
@@ -232,6 +240,7 @@ Module::Module ( const Project& project,
          node (moduleNode),
          importLibrary (NULL),
          bootstrap (NULL),
+         autoRegister(NULL),
          linkerScript (NULL),
          pch (NULL),
          cplusplus (false),
@@ -440,6 +449,8 @@ Module::ProcessXML()
                linkerScript->ProcessXML();
        if ( pch )
                pch->ProcessXML();
+       if ( autoRegister )
+               autoRegister->ProcessXML();
 }
 
 void
@@ -647,6 +658,17 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                }
                subs_invalid = false;
        }
+       else if ( e.name == "autoregister" )
+       {
+               if ( autoRegister != NULL)
+               {
+                       throw InvalidBuildFileException ( e.location,
+                                                         "there can be only one <%s> element for a module",
+                                                         e.name.c_str() );
+               }
+               autoRegister = new AutoRegister ( project, this, e );
+               subs_invalid = true;
+       }
        if ( subs_invalid && e.subElements.size() > 0 )
                throw InvalidBuildFileException (
                        e.location,
@@ -1260,3 +1282,85 @@ void
 PchFile::ProcessXML()
 {
 }
+
+
+AutoRegister::AutoRegister ( const Project& project_,
+                             const Module* module_,
+                             const XMLElement& node_ )
+       : project(project_),
+         module(module_),
+         node(node_)
+{
+       Initialize();
+}
+
+AutoRegister::~AutoRegister ()
+{
+}
+
+bool
+AutoRegister::IsSupportedModuleType ( ModuleType type )
+{
+       switch ( type )
+       {
+               case Win32DLL:
+                       return true;
+               case Kernel:
+               case KernelModeDLL:
+               case NativeDLL:
+               case NativeCUI:
+               case Win32CUI:
+               case Win32GUI:
+               case KernelModeDriver:
+               case BootSector:
+               case BootLoader:
+               case BuildTool:
+               case StaticLibrary:
+               case ObjectLibrary:
+               case Iso:
+               case LiveIso:
+               case Test:
+               case RpcServer:
+               case RpcClient:
+               case Alias:
+                       return false;
+       }
+       throw InvalidOperationException ( __FILE__,
+                                         __LINE__ );
+}
+
+AutoRegisterType
+AutoRegister::GetAutoRegisterType( string type )
+{
+       if ( type == "DllRegisterServer" )
+               return DllRegisterServer;
+       if ( type == "DllInstall" )
+               return DllInstall;
+       if ( type == "Both" )
+               return Both;
+       throw InvalidBuildFileException (
+               node.location,
+               "<autoregister> type attribute must be DllRegisterServer, DllInstall or Both." );
+}
+
+void
+AutoRegister::Initialize ()
+{
+       if ( !IsSupportedModuleType ( module->type ) )
+       {
+               throw InvalidBuildFileException (
+                       node.location,
+                       "<autoregister> is not applicable for this module type." );
+       }
+
+       const XMLAttribute* att = node.GetAttribute ( "infsection", true );
+       infSection = att->value;
+
+       att = node.GetAttribute ( "type", true );
+       type = GetAutoRegisterType ( att->value );
+}
+
+void
+AutoRegister::ProcessXML()
+{
+}
index 80357cf..c9cd879 100644 (file)
@@ -38,6 +38,7 @@
 #include "ssprintf.h"
 #include "exception.h"
 #include "XML.h"
+#include <infhost.h>
 
 typedef std::vector<std::string> string_list;
 
@@ -94,6 +95,7 @@ class StubbedComponent;
 class StubbedSymbol;
 class CompilationUnit;
 class FileLocation;
+class AutoRegister;
 
 class SourceFileTest;
 
@@ -276,6 +278,7 @@ public:
        bool mangledSymbols;
        bool isUnicode;
        Bootstrap* bootstrap;
+       AutoRegister* autoRegister;
        IfableData non_if_data;
        std::vector<Invoke*> invocations;
        std::vector<Dependency*> dependencies;
@@ -866,6 +869,48 @@ public:
 };
 
 
+enum AutoRegisterType
+{
+       DllRegisterServer,
+       DllInstall,
+       Both
+};
+
+class AutoRegister
+{
+public:
+       const Project& project;
+       const Module* module;
+       const XMLElement& node;
+       std::string infSection;
+       AutoRegisterType type;
+       AutoRegister ( const Project& project_,
+                      const Module* module_,
+                      const XMLElement& node_ );
+       ~AutoRegister ();
+       void ProcessXML();
+private:
+       bool IsSupportedModuleType ( ModuleType type );
+       AutoRegisterType GetAutoRegisterType( std::string type );
+       void Initialize ();
+};
+
+
+class SysSetupGenerator
+{
+public:
+       const Project& project;
+       SysSetupGenerator ( const Project& project );
+       ~SysSetupGenerator ();
+       void Generate ();
+private:
+       std::string GetDirectoryId ( const Module& module );
+       std::string GetFlags ( const Module& module );
+       void Generate ( HINF inf,
+                       const Module& module );
+};
+
+
 extern void
 InitializeEnvironment ();
 
@@ -912,4 +957,7 @@ GetFilename ( const std::string& filename );
 extern std::string
 NormalizeFilename ( const std::string& filename );
 
+extern std::string
+ToLower ( std::string filename );
+
 #endif /* __RBUILD_H */
index 94cfb69..f3fbc3b 100644 (file)
@@ -172,6 +172,7 @@ RBUILD_COMMON_SOURCES = \
                project.cpp \
                ssprintf.cpp \
                stubbedcomponent.cpp \
+               syssetupgenerator.cpp \
                testsupportcode.cpp \
                wineresource.cpp \
                XML.cpp \
@@ -250,16 +251,16 @@ RBUILD_TEST_OBJECTS = \
        $(RBUILD_COMMON_OBJECTS) \
        $(RBUILD_TEST_SPECIAL_OBJECTS)
 
-RBUILD_HOST_CXXFLAGS = -I$(RBUILD_BASE) $(TOOLS_CPPFLAGS)
+RBUILD_HOST_CXXFLAGS = -I$(RBUILD_BASE) -I$(INFLIB_BASE) $(TOOLS_CPPFLAGS)
 
 RBUILD_HOST_LFLAGS = $(TOOLS_LFLAGS)
 
 .PHONY: rbuild
 rbuild: $(RBUILD_TARGET)
 
-$(RBUILD_TARGET): $(RBUILD_OBJECTS) | $(RBUILD_OUT)
+$(RBUILD_TARGET): $(RBUILD_OBJECTS) $(INFLIB_HOST_TARGET) | $(RBUILD_OUT)
        $(ECHO_LD)
-       ${host_gpp} $(RBUILD_OBJECTS) $(RBUILD_HOST_LFLAGS) -o $@
+       ${host_gpp} $(RBUILD_OBJECTS) $(INFLIB_HOST_TARGET) $(RBUILD_HOST_LFLAGS) -o $@
 
 $(RBUILD_INT_)global.o: $(RBUILD_BASE_)global.cpp $(RBUILD_HEADERS) | $(RBUILD_INT)
        $(ECHO_CC)
@@ -345,6 +346,10 @@ $(RBUILD_INT_)stubbedcomponent.o: $(RBUILD_BASE_)stubbedcomponent.cpp $(RBUILD_H
        $(ECHO_CC)
        ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
 
+$(RBUILD_INT_)syssetupgenerator.o: $(RBUILD_BASE_)syssetupgenerator.cpp $(RBUILD_HEADERS) | $(RBUILD_INT)
+       $(ECHO_CC)
+       ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
+
 $(RBUILD_INT_)wineresource.o: $(RBUILD_BASE_)wineresource.cpp $(RBUILD_HEADERS) | $(RBUILD_INT)
        $(ECHO_CC)
        ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
@@ -379,7 +384,7 @@ $(RBUILD_DEVCPP_INT_)devcpp.o: $(RBUILD_DEVCPP_BASE_)devcpp.cpp $(RBUILD_HEADERS
 
 $(RBUILD_MSVC_INT_)genguid.o: $(RBUILD_MSVC_BASE_)genguid.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT)
        $(ECHO_CC)
-       ${host_gpp} $(RBUILD_HOST_CFLAGS) -c $< -o $@
+       ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
 
 $(RBUILD_MSVC_INT_)msvc.o: $(RBUILD_MSVC_BASE_)msvc.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT)
        $(ECHO_CC)
@@ -393,9 +398,9 @@ $(RBUILD_MSVC_INT_)vcprojmaker.o: $(RBUILD_MSVC_BASE_)vcprojmaker.cpp $(RBUILD_H
        $(ECHO_CC)
        ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
 
-$(RBUILD_TEST_TARGET): $(RBUILD_TEST_OBJECTS) $(RBUILD_HEADERS) | $(RBUILD_OUT)
+$(RBUILD_TEST_TARGET): $(RBUILD_TEST_OBJECTS) $(INFLIB_HOST_TARGET) $(RBUILD_HEADERS) | $(RBUILD_OUT)
        $(ECHO_LD)
-       ${host_gpp} $(RBUILD_TEST_OBJECTS) $(RBUILD_HOST_LFLAGS) -o $@
+       ${host_gpp} $(RBUILD_TEST_OBJECTS) $(INFLIB_HOST_TARGET) $(RBUILD_HOST_LFLAGS) -o $@
 
 $(RBUILD_TESTS_INT_)cdfiletest.o: $(RBUILD_TESTS_BASE_)cdfiletest.cpp $(RBUILD_HEADERS) | $(RBUILD_TESTS_INT)
        $(ECHO_CC)
diff --git a/reactos/tools/rbuild/syssetupgenerator.cpp b/reactos/tools/rbuild/syssetupgenerator.cpp
new file mode 100644 (file)
index 0000000..a60f960
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2005 Casper S. Hornstrup
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "pch.h"
+#include <assert.h>
+
+#include "rbuild.h"
+
+using std::string;
+using std::vector;
+
+SysSetupGenerator::SysSetupGenerator ( const Project& project )
+       : project ( project )
+{
+}
+
+SysSetupGenerator::~SysSetupGenerator ()
+{
+}
+
+void
+SysSetupGenerator::Generate ()
+{
+       HINF inf;
+       unsigned long errorLine;
+
+       string syssetupTemplate = "media" + sSep + "inf" + sSep + "syssetup.inf.tpl";
+       string syssetup = "media" + sSep + "inf" + sSep + "syssetup.inf";
+
+       if ( 0 != InfHostOpenFile ( &inf, syssetupTemplate.c_str (), &errorLine ) )
+               throw new FileNotFoundException ( syssetupTemplate );
+
+       for ( size_t i = 0; i < project.modules.size (); i++ )
+       {
+               const Module& module = *project.modules[i];
+               if ( module.autoRegister != NULL )
+                       Generate ( inf, module );
+       }
+
+       if ( 0 != InfHostWriteFile ( inf, syssetup.c_str (), "" ) )
+       {
+               InfHostCloseFile ( inf );
+               throw new AccessDeniedException ( syssetup );
+       }
+
+       InfHostCloseFile ( inf );
+}
+
+#define DIRECTORYID_SYSTEM32   "11"
+
+string
+SysSetupGenerator::GetDirectoryId ( const Module& module )
+{
+       if ( ToLower ( module.installBase ) == "system32" )
+               return DIRECTORYID_SYSTEM32;
+       throw InvalidOperationException ( __FILE__,
+                                         __LINE__ );
+}
+
+#define FLG_REGSVR_DLLREGISTER "1"
+#define FLG_REGSVR_DLLINSTALL  "2"
+#define FLG_REGSVR_BOTH        "3"
+
+string
+SysSetupGenerator::GetFlags ( const Module& module )
+{
+       if ( module.autoRegister->type == DllRegisterServer )
+               return FLG_REGSVR_DLLREGISTER;
+       if ( module.autoRegister->type == DllInstall )
+               return FLG_REGSVR_DLLINSTALL;
+       if ( module.autoRegister->type == Both )
+               return FLG_REGSVR_BOTH;
+       throw InvalidOperationException ( __FILE__,
+                                         __LINE__ );
+}
+
+void
+SysSetupGenerator::Generate ( HINF inf,
+                              const Module& module )
+{
+       PINFCONTEXT context;
+
+       string infSection = module.autoRegister->infSection;
+       if ( 0 != InfHostFindOrAddSection ( inf, infSection.c_str (), &context ) )
+       {
+               throw new Exception ( ".inf section '%s' not found", infSection.c_str () );
+               InfHostCloseFile ( inf );
+       }
+
+      if ( 0 != InfHostAddLine ( context, NULL ) ||
+           0 != InfHostAddField ( context, GetDirectoryId ( module ).c_str () ) ||
+           0 != InfHostAddField ( context, "" ) ||
+           0 != InfHostAddField ( context, module.installName.c_str () ) ||
+           0 != InfHostAddField ( context, GetFlags ( module ).c_str () ) )
+        {
+               InfHostFreeContext ( context );
+               InfHostCloseFile ( inf );
+               throw InvalidOperationException ( __FILE__,
+                                                 __LINE__ );
+       }
+
+       InfHostFreeContext ( context );
+}