Sync to trunk (r44371)
authorSamuel Serapion <samuel.serapion@gmail.com>
Thu, 3 Dec 2009 07:28:23 +0000 (07:28 +0000)
committerSamuel Serapion <samuel.serapion@gmail.com>
Thu, 3 Dec 2009 07:28:23 +0000 (07:28 +0000)
svn path=/branches/ros-amd64-bringup/; revision=44373

22 files changed:
1  2 
reactos/Makefile
reactos/ReactOS-amd64.rbuild
reactos/ReactOS-arm.rbuild
reactos/config-amd64.template.rbuild
reactos/subsystems/win32/csrss/win32csr/win32csr.rbuild
reactos/subsystems/win32/win32k/include/msgqueue.h
reactos/subsystems/win32/win32k/ldr/loader.c
reactos/subsystems/win32/win32k/ntuser/class.c
reactos/subsystems/win32/win32k/ntuser/clipboard.c
reactos/subsystems/win32/win32k/ntuser/kbdlayout.c
reactos/subsystems/win32/win32k/ntuser/keyboard.c
reactos/subsystems/win32/win32k/ntuser/message.c
reactos/subsystems/win32/win32k/ntuser/msgqueue.c
reactos/subsystems/win32/win32k/win32k.pspec
reactos/subsystems/win32/win32k/win32k.rbuild
reactos/tools/rbuild/backend/mingw/modulehandler.cpp
reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp
reactos/tools/rsym/log2lines.c
reactos/tools/widl/header.c
reactos/tools/widl/parser.tab.c
reactos/tools/widl/parser.y
reactos/tools/widl/typegen.c

Simple merge
        <compilerflag>-Wno-multichar</compilerflag>
        <compilerflag>-Wno-format</compilerflag>
        <!-- compilerflag>-H</compilerflag>    enable this for header traces -->
 -              <linkerflag>-disable-stdcall-fixup</linkerflag>
 -              <linkerflag>-static</linkerflag>
 -              <linkerflag>--unique=.eh_frame</linkerflag>
 -              <linkerflag>-file-alignment=0x1000</linkerflag>
 -              <linkerflag>-section-alignment=0x1000</linkerflag>
+       <group linkerset="ld">
 +      <linkerflag>-disable-stdcall-fixup</linkerflag>
 +      <linkerflag>-static</linkerflag>
 +      <linkerflag>--unique=.eh_frame</linkerflag>
++      <linkerflag>-file-alignment=0x1000</linkerflag>
++      <linkerflag>-section-alignment=0x1000</linkerflag>
+       </group>
  
  <!-- Here starts <xi:include href="ReactOS-generic.rbuild" /> -->
  
                        <xi:include href="drivers/ksfilter/directory.rbuild" />
                </directory>
  
--              <!-- directory name="multimedia">
++              <directory name="multimedia">
                        <xi:include href="drivers/multimedia/directory.rbuild" />
--              </directory -->
++              </directory >
  
                <directory name="network">
                        <xi:include href="drivers/network/directory.rbuild" />
                        <xi:include href="drivers/setup/directory.rbuild" />
                </directory>
                <directory name="storage">
--            <xi:include href="drivers/storage/directory.rbuild" />
++                              <xi:include href="drivers/storage/directory.rbuild" />
                </directory>
 -              <directory name="usb">
 +              <directory name="usb">  
                        <xi:include href="drivers/usb/directory.rbuild" />
                </directory>
                <directory name="video">
                                <xi:include href="lib/3rdparty/zlib/zlib.rbuild" />
                        </directory>
                </directory>
++              <if property="USERMODE" value="1">
++              <directory name="atl">
++                      <xi:include href="lib/atl/atl.rbuild" />
++              </directory>
++              </if>
                <directory name="sdk">
                        <xi:include href="lib/sdk/sdk.rbuild" />
                </directory>
        <define name="_ARM_" />
        <define name="__arm__" />
        <define name="TARGET_arm" host="true" />
 -
 +    
      <define name="USE_COMPILER_EXCEPTIONS" />
 -
 +    
-     <property name="NTOSKRNL_SHARED" value="-file-alignment=0x1000 -section-alignment=0x1000 -shared"/>
      <property name="WINEBUILD_FLAGS" value="--kill-at"/>
 -
 +        
      <include>include/reactos/arm</include>
  
        <if property="SARCH" value="versatile">
@@@ -65,7 -65,7 +65,7 @@@
        enable this (except they/you purchased a license from the patent owner).
        This settings is disabled (0) by default.
  -->
--<property name="NSWPAT" value="1" />
++<property name="NSWPAT" value="0" />
  
  <!--
        Whether to compile with the KD protocol. This will disable support for KDBG
@@@ -188,7 -188,7 +188,7 @@@ co_IntSendMessageTimeout(HWND hWnd
  LRESULT FASTCALL
  IntDispatchMessage(MSG* Msg);
  BOOL FASTCALL
--IntTranslateKbdMessage(LPMSG lpMsg, HKL dwhkl);
++IntTranslateKbdMessage(LPMSG lpMsg, UINT flags);
  
  VOID FASTCALL
  co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
@@@ -261,28 -255,10 +255,10 @@@ EngUnloadImage ( IN HANDLE hModule 
    }
    else
    {
-         /* remove from the list */
-         if( !IsListEmpty(&GlobalDriverListHead) )
-         {
-                 PLIST_ENTRY CurrentEntry = GlobalDriverListHead.Flink;
-                 PDRIVERS Current;
-                 /* probably the driver was already loaded, let's try to find it out */
-                 while( CurrentEntry != &GlobalDriverListHead )
-                 {
-                         Current = CONTAINING_RECORD(CurrentEntry, DRIVERS, ListEntry);
-                         if( Current ) {
-                                 if(Current->ImageHandle == hModule) {
-                                         ExFreePool(Current->DriverName.Buffer);
-                                         RemoveEntryList(&Current->ListEntry);
-                                         ExFreePool(Current);
-                                         break;
+     ExFreePool(DriverInfo->DriverName.Buffer);
+     RemoveEntryList(&DriverInfo->ListEntry);
+     ExFreePool(DriverInfo);
 -  }
 -}
 +                                }
 +                        }
-                         CurrentEntry = CurrentEntry->Flink;
-                 };
-         }
-   }
- }
  
  /* EOF */
@@@ -581,10 -581,10 +581,10 @@@ NtUserEmptyClipboard(VOID
      return ret;
  }
  
--HANDLE APIENTRY
++DWORD_PTR APIENTRY
  NtUserGetClipboardData(UINT uFormat, PVOID pBuffer)
  {
--    HANDLE ret = NULL;
++    DWORD_PTR ret = 0;
  
      UserEnterShared();
  
                          co_IntSendMessage(ClipboardOwnerWindow->hSelf, WM_RENDERFORMAT, (WPARAM)uFormat, 0);
                          data = intIsFormatAvailable(uFormat);
                          ASSERT(data->size);
--                        ret = (HANDLE)(ULONG_PTR)data->size;
++                        ret = data->size;
                      }
                  }
                  else
                      }
  
                  }
--                ret = (HANDLE)(ULONG_PTR)data->size;
++                ret = data->size;
              }
              else
              {
                  /* there is no data in this format */
--                //ret = (HANDLE)FALSE;
++                //ret = FALSE;
              }
          }
          else
                              PCLIPBOARDELEMENT data = intIsFormatAvailable(CF_DIB);
                              if (data)
                              {
--                                ret = renderBITMAPfromDIB(data->hData);
++                                ret = (DWORD_PTR)renderBITMAPfromDIB(data->hData);
                              }
                          }
                          else
                          {
--                            ret = (HANDLE)pBuffer;
++                            ret = (DWORD_PTR)pBuffer;
  
                              _SEH2_TRY
                              {
                              }
                              _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                              {
--                                ret = NULL;
++                                ret = 0;
                              }
                              _SEH2_END
  
                      }
                      else
                      {
--                        ret = (HANDLE)pBuffer;
++                        ret = (DWORD_PTR)pBuffer;
  
                          _SEH2_TRY
                          {
                          }
                          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
                          {
--                            ret = NULL;
++                            ret = 0;
                          }
                          _SEH2_END
                      }
@@@ -419,7 -419,7 +419,7 @@@ CLEANUP
  
  BOOL FASTCALL
  IntTranslateKbdMessage(LPMSG lpMsg,
--                       HKL dwhkl)
++                       UINT Flags)
  {
     PTHREADINFO pti;
     static INT dead_char = 0;
@@@ -482,7 -513,7 +513,7 @@@ NtUserDispatchMessage(PMSG UnsafeMsgInf
  
  BOOL APIENTRY
  NtUserTranslateMessage(LPMSG lpMsg,
--                       HKL dwhkl)
++                       UINT Flags)
  {
     NTSTATUS Status;
     MSG SafeMsg;
        RETURN( FALSE);
     }
  
--   RETURN( IntTranslateKbdMessage(&SafeMsg, dwhkl));
++   RETURN( IntTranslateKbdMessage(&SafeMsg, Flags));
  
  CLEANUP:
     DPRINT("Leave NtUserTranslateMessage: ret=%i\n",_ret_);
@@@ -1396,7 -1426,15 +1426,15 @@@ UserPostMessage(HWND Wnd
        {
           return FALSE;
        }
 -      if ( Window->Status & WINDOWSTATUS_DESTROYING )
+       pti = Window->Wnd->head.pti;
+       if ( pti->TIF_flags & TIF_INCLEANUP )
+       {
+          DPRINT1("Attempted to post message to window 0x%x when the thread is in cleanup!\n", Wnd);
+          return FALSE;
+       }
 +      if(Window->Status & WINDOWSTATUS_DESTROYING)
        {
           DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
           /* FIXME - last error code? */
@@@ -462,7 -462,7 +462,7 @@@ co_MsqTranslateMouseMessage(PUSER_MESSA
  
     *ScreenPoint = Message->Msg.pt;
  
--   if((Window != NULL && (int)Window != 1 && CaptureWindow->hSelf != Window->hSelf) ||
++   if((Window != NULL && PtrToInt(Window) != 1 && CaptureWindow->hSelf != Window->hSelf) ||
           ((FilterLow != 0 || FilterHigh != 0) && (Msg < FilterLow || Msg > FilterHigh)))
     {
        /* Reject the message because it doesn't match the filter */
@@@ -1383,7 -1383,7 +1383,7 @@@ co_MsqFindMessage(IN PUSER_MESSAGE_QUEU
     {
        CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
                                           ListEntry);
--      if ((!Window || (int)Window == 1 || Window->hSelf == CurrentMessage->Msg.hwnd) &&
++      if ((!Window || PtrToInt(Window) == 1 || Window->hSelf == CurrentMessage->Msg.hwnd) &&
              ((MsgFilterLow == 0 && MsgFilterHigh == 0) ||
               (MsgFilterLow <= CurrentMessage->Msg.message &&
                MsgFilterHigh >= CurrentMessage->Msg.message)))
@@@ -1997,7 -1997,7 +1997,7 @@@ MsqGetFirstTimerExpiry(PUSER_MESSAGE_QU
        Timer = CONTAINING_RECORD(MessageQueue->TimerListHead.Flink,
                                  TIMER_ENTRY, ListEntry);
        EnumEntry = EnumEntry->Flink;
--      if ((NULL == WndFilter || (int)WndFilter == 1 || Timer->Wnd == WndFilter->hSelf) &&
++      if ((NULL == WndFilter || PtrToInt(WndFilter) == 1 || Timer->Wnd == WndFilter->hSelf) &&
              ((MsgFilterMin == 0 && MsgFilterMax == 0) ||
               (MsgFilterMin <= Timer->Msg &&
                Timer->Msg <= MsgFilterMax)))
@@@ -1,10 -1,9 +1,9 @@@
--#include "include/reactos/msvctarget.h"
 +#undef i386
  
 -@ stdcall FLOATOBJ_AddFloatObj(ptr ptr) FLOATOBJ_Add
 -@ stdcall FLOATOBJ_DivFloatObj(ptr ptr) FLOATOBJ_Div
 -@ stdcall FLOATOBJ_MulFloatObj(ptr ptr) FLOATOBJ_Mul
 -@ stdcall FLOATOBJ_SubFloatObj(ptr ptr) FLOATOBJ_Sub
 +@ stdcall -arch=i386 FLOATOBJ_AddFloatObj(ptr ptr) FLOATOBJ_Add
 +@ stdcall -arch=i386 FLOATOBJ_DivFloatObj(ptr ptr) FLOATOBJ_Div
 +@ stdcall -arch=i386 FLOATOBJ_MulFloatObj(ptr ptr) FLOATOBJ_Mul
 +@ stdcall -arch=i386 FLOATOBJ_SubFloatObj(ptr ptr) FLOATOBJ_Sub
  @ stdcall BRUSHOBJ_hGetColorTransform(ptr)
  @ stdcall BRUSHOBJ_pvAllocRbrush(ptr long)
  @ stdcall BRUSHOBJ_pvGetRbrush(ptr)
@@@ -1,10 -1,17 +1,17 @@@
  <?xml version="1.0"?>
  <!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">
  <group>
- <module name="win32k_base" type="objectlibrary" allowwarnings="true">
-       <include base="win32k_base">.</include>
-       <include base="win32k_base">include</include>
-       <include base="win32k_base" root="intermediate">.</include>
 -<module name="win32k" type="kernelmodedriver" installbase="system32" installname="win32k.sys" crt="libcntpr">
++<module name="win32k" type="kernelmodedriver" installbase="system32" installname="win32k.sys" crt="libcntpr" allowwarnings="true">
+       <importlibrary definition="win32k.pspec" />
+       <library>pseh</library>
+       <library>ntoskrnl</library>
+       <library>hal</library>
+       <library>ftfd</library>
+       <library>dxguid</library>
+       <file>win32k.rc</file>
+       <include base="win32k">.</include>
+       <include base="win32k">include</include>
+       <include base="win32k" root="intermediate">.</include>
        <include base="ntoskrnl">include</include>
        <include base="freetype">include</include>
        <include base="ReactOS">include/reactos/subsys</include>
@@@ -1438,160 -1420,63 +1420,63 @@@ MingwModuleHandler::GenerateCleanObject
  }
  
  void
- MingwModuleHandler::GenerateRunRsymCode () const
- {
-       fprintf ( fMakefile, "# RUN RSYM CODE\n" );
-       fprintf ( fMakefile,
-              "ifneq ($(ROS_GENERATE_RSYM),no)\n" );
-       fprintf ( fMakefile,
-                 "\t$(ECHO_RSYM)\n" );
-       fprintf ( fMakefile,
-                 "\t$(Q)$(RSYM_TARGET) $@ $@\n\n" );
-       fprintf ( fMakefile,
-              "endif\n" );
- }
- void
- MingwModuleHandler::GenerateRunStripCode () const
- {
-       fprintf ( fMakefile, "# RUN STRIP CODE\n" );
-       fprintf ( fMakefile,
-                 "ifeq ($(ROS_LEAN_AND_MEAN),yes)\n" );
-       fprintf ( fMakefile,
-                 "\t$(ECHO_STRIP)\n" );
-       fprintf ( fMakefile,
-                 "\t${strip} -s -x -X $@\n\n" );
-       fprintf ( fMakefile,
-                 "endif\n" );
- }
- void
- MingwModuleHandler::GenerateLinkerCommand (
-       const string& dependencies,
-       const string& linkerParameters,
-       const string& pefixupParameters )
+ MingwModuleHandler::GenerateLinkerCommand () const
  {
-       const FileLocation *target_file = GetTargetFilename ( module, NULL );
-       const FileLocation *definitionFilename = GetDefinitionFilename ();
-       string linker = "${ld}";
-       string objectsMacro = GetObjectsMacro ( module );
-       string libsMacro = GetLibsMacro ();
+       string definitionFilename;
 -      
 +
-       fprintf ( fMakefile, "# LINKER COMMAND\n" );
+       const FileLocation *DefinitionFilename = GetDefinitionFilename ();
  
-       string target_macro ( GetTargetMacro ( module ) );
-       string target_folder ( backend->GetFullPath ( *target_file ) );
+       if ( DefinitionFilename ) {
+               definitionFilename = backend->GetFullName (*DefinitionFilename);
+               delete DefinitionFilename;
 -      }
++}
  
        string linkerScriptArgument;
-       if ( module.linkerScript != NULL )
+       if ( module.linkerScript != NULL ) {
+               if ( module.project.configuration.Linker == GnuLd )
                        linkerScriptArgument = ssprintf ( " -T %s", backend->GetFullName ( *module.linkerScript->file ).c_str () );
                else
-               linkerScriptArgument = "";
-       /* check if we need to add default C++ libraries, ie if we have
-        * a C++ user-mode module without the -nostdlib linker flag
-        */
-       bool link_defaultlibs = module.cplusplus &&
-                               linkerParameters.find ("-nostdlib") == string::npos &&
-                               !(module.type == KernelModeDLL || module.type == KernelModeDriver);
-       if ( !module.HasImportLibrary() )
-       {
-               fprintf ( fMakefile,
-                       "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
-                       target_macro.c_str (),
-                       definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
-                       dependencies.c_str (),
-                       target_folder.c_str () );
-               fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
+                       fprintf ( stderr,
+                                         "Linker doesn't support linker scripts: linker script %s ignored for module %s\n",
+                                         backend->GetFullName ( *module.linkerScript->file ).c_str (),
+                                         module.name.c_str() );
+       }
+       string extraLibraries;
+       if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse ) {
+               if ( module.cplusplus ) {
+                       switch ( module.type )
 -                      {
++      {
+                       case Win32DLL:
+                       case Win32OCX:
+                       case Win32CUI:
+                       case Win32GUI:
+                       case Win32SCR:
+                               extraLibraries = "$$(PROJECT_CXXLIBS)";
+                               break;
  
-               fprintf ( fMakefile,
-                         "\t%s %s%s %s %s %s %s -o %s\n",
-                         linker.c_str (),
-                         linkerParameters.c_str (),
-                         linkerScriptArgument.c_str (),
-                         objectsMacro.c_str (),
-                         link_defaultlibs ? "$(PROJECT_LPPFLAGS) " : "",
-                         libsMacro.c_str (),
-                         GetLinkerMacro ().c_str (),
-                         target_macro.c_str () );
+                       default:
+                               extraLibraries = "$$(PROJECT_CCLIBS)";
+                               break;
 -                      }
++      }
+               } else
+                       extraLibraries = "$$(PROJECT_CCLIBS)";
        }
-       else
-       {
-               FileLocation temp_exp ( IntermediateDirectory,
-                                       module.output->relative_path,
-                                       module.name + ".exp" );
-               CLEAN_FILE ( temp_exp );
-               fprintf ( fMakefile,
-                       "%s: %s | %s\n",
-                       backend->GetFullName ( temp_exp ).c_str (),
-                       definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
-                       backend->GetFullPath ( temp_exp ).c_str () );
-               fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" );
-               fprintf ( fMakefile,
-                         "\t${dlltool} --dllname %s --def %s --output-exp $@%s%s\n",
-                         module.GetDllName ().c_str (),
-                         definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "",
-                         module.mangledSymbols ? "" : " --kill-at",
-                         module.underscoreSymbols ? " --add-underscore" : "" );
  
-               fprintf ( fMakefile,
-                       "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n",
-                       target_macro.c_str (),
-                       backend->GetFullName ( temp_exp ).c_str (),
-                       dependencies.c_str (),
-                       target_folder.c_str () );
-               fprintf ( fMakefile, "\t$(ECHO_LD)\n" );
+       delete PassThruCacheDirectory ( new FileLocation ( module.output->directory, module.output->relative_path, "" ) );
+       delete PassThruCacheDirectory ( new FileLocation ( IntermediateDirectory, module.output->relative_path, "" ) );
  
 -      fprintf ( fMakefile,
 +              fprintf ( fMakefile,
-                         "\t%s %s%s %s %s %s %s %s -o %s\n",
-                         linker.c_str (),
-                         linkerParameters.c_str (),
+                         "$(eval $(call RBUILD_LINK_RULE,%s,%s,%s,%s,%s,%s,%s))\n",
+                         module.name.c_str(),
+                         definitionFilename.c_str(),
+                         module.xmlbuildFile.c_str(),
 -                        linkerScriptArgument.c_str(),
 +                        linkerScriptArgument.c_str (),
-                         backend->GetFullName ( temp_exp ).c_str (),
-                         objectsMacro.c_str (),
-                         link_defaultlibs ? "$(PROJECT_LPPFLAGS) " : "",
-                         libsMacro.c_str (),
-                         GetLinkerMacro ().c_str (),
-                         target_macro.c_str () );
-               fprintf ( fMakefile,
-                         "\t$(Q)$(PEFIXUP_TARGET) %s -exports%s\n",
-                         target_macro.c_str (),
-                         pefixupParameters.c_str() );
+                         extraLibraries.c_str(),
+                         module.GetEntryPoint().c_str(),
+                         module.baseaddress.c_str() );
 -}
 +      }
  
-       GenerateBuildMapCode ();
-       GenerateBuildNonSymbolStrippedCode ();
-       GenerateRunRsymCode ();
-       GenerateRunStripCode ();
-       GenerateCleanObjectsAsYouGoCode ();
-       if ( definitionFilename )
-               delete definitionFilename;
-       delete target_file;
- }
- void
- MingwModuleHandler::GeneratePhonyTarget() const
- {
-       string targetMacro ( GetTargetMacro ( module ) );
-       const FileLocation *target_file = GetTargetFilename ( module, NULL );
-       fprintf ( fMakefile, "# PHONY TARGET\n" );
-       fprintf ( fMakefile,
-                 ".PHONY: %s\n\n",
-                 targetMacro.c_str ());
-       fprintf ( fMakefile, "%s: | %s\n",
-                 targetMacro.c_str (),
-                 backend->GetFullPath ( *target_file ).c_str () );
-       delete target_file;
- }
  void
  MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data )
  {
@@@ -1957,7 -1814,9 +1814,9 @@@ MingwModuleHandler::GenerateRules (
        if ( !ReferenceObjects ( module ) )
        {
                const FileLocation* ar_target = GenerateArchiveTarget ();
 -                      delete ar_target;
+               if ( ar_target )
 +              delete ar_target;
        }
  
  
@@@ -2402,31 -2206,9 +2206,9 @@@ MingwKernelModuleHandler::Process (
  void
  MingwKernelModuleHandler::GenerateKernelModuleTarget ()
  {
-       string targetMacro ( GetTargetMacro ( module ) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string libsMacro = GetLibsMacro ();
-       GenerateImportLibraryTargetIfNeeded ();
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
 -      GenerateRules ();
 +              GenerateRules ();
-               string dependencies = libsMacro + " " + objectsMacro;
-               string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters + " $(NTOSKRNL_SHARED)",
-                                       " -sections" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
+       GenerateLinkerCommand ();
 -}
 +      }
- }
  
  
  MingwKernelModeDLLModuleHandler::MingwKernelModeDLLModuleHandler (
@@@ -2453,30 -2235,9 +2235,9 @@@ MingwKernelModeDLLModuleHandler::Proces
  void
  MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()
  {
-       string targetMacro ( GetTargetMacro ( module ) );
-       string workingDirectory = GetWorkingDirectory ();
-       string libsMacro = GetLibsMacro ();
-       GenerateImportLibraryTargetIfNeeded ();
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
 -      GenerateRules ();
 +              GenerateRules ();
-               string dependencies = libsMacro + " " + objectsMacro;
-               string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       " -sections" );
+       GenerateLinkerCommand ();
 -}
 +      }
-       else
-       {
-               GeneratePhonyTarget();
-       }
- }
  
  
  MingwNativeDLLModuleHandler::MingwNativeDLLModuleHandler (
@@@ -2502,30 -2263,9 +2263,9 @@@ MingwNativeDLLModuleHandler::Process (
  void
  MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ()
  {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string libsMacro = GetLibsMacro ();
-       GenerateImportLibraryTargetIfNeeded ();
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
 -      GenerateRules ();
 +              GenerateRules ();
-               string dependencies = libsMacro + " " + objectsMacro;
-               string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
+       GenerateLinkerCommand ();
 -}
 +      }
- }
  
  
  MingwNativeCUIModuleHandler::MingwNativeCUIModuleHandler (
@@@ -2551,30 -2291,9 +2291,9 @@@ MingwNativeCUIModuleHandler::Process (
  void
  MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget ()
  {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string libsMacro = GetLibsMacro ();
-       GenerateImportLibraryTargetIfNeeded ();
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
 -      GenerateRules ();
 +              GenerateRules ();
-               string dependencies = libsMacro + " " + objectsMacro;
-               string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
+       GenerateLinkerCommand ();
 -}
 +      }
- }
  
  
  MingwWin32DLLModuleHandler::MingwWin32DLLModuleHandler (
@@@ -2641,30 -2360,9 +2360,9 @@@ MingwWin32DLLModuleHandler::Process (
  void
  MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ()
  {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string libsMacro = GetLibsMacro ();
-       GenerateImportLibraryTargetIfNeeded ();
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
 -      GenerateRules ();
 +              GenerateRules ();
-               string dependencies = libsMacro + " " + objectsMacro;
-               string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
+       GenerateLinkerCommand ();
 -}
 +      }
- }
  
  
  void
@@@ -2682,30 -2380,9 +2380,9 @@@ MingwWin32OCXModuleHandler::Process (
  void
  MingwWin32OCXModuleHandler::GenerateWin32OCXModuleTarget ()
  {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string libsMacro = GetLibsMacro ();
-       GenerateImportLibraryTargetIfNeeded ();
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
 -      GenerateRules ();
 +              GenerateRules ();
-               string dependencies = libsMacro + " " + objectsMacro;
-               string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
+       GenerateLinkerCommand ();
 -}
 +      }
-       else
-       {
-               GeneratePhonyTarget();
-       }
- }
  
  
  MingwWin32CUIModuleHandler::MingwWin32CUIModuleHandler (
@@@ -2730,30 -2407,9 +2407,9 @@@ MingwWin32CUIModuleHandler::Process (
  void
  MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget ()
  {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string libsMacro = GetLibsMacro ();
-       GenerateImportLibraryTargetIfNeeded ();
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
 -      GenerateRules ();
 +              GenerateRules ();
-               string dependencies = libsMacro + " " + objectsMacro;
-               string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
+       GenerateLinkerCommand ();
 -}
 +      }
- }
  
  
  MingwWin32GUIModuleHandler::MingwWin32GUIModuleHandler (
@@@ -2778,30 -2434,9 +2434,9 @@@ MingwWin32GUIModuleHandler::Process (
  void
  MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ()
  {
-       string targetMacro ( GetTargetMacro (module) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string libsMacro = GetLibsMacro ();
-       GenerateImportLibraryTargetIfNeeded ();
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
 -      GenerateRules ();
 +              GenerateRules ();
-               string dependencies = libsMacro + " " + objectsMacro;
-               string linkerParameters = ssprintf ( "-subsystem=windows -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
+       GenerateLinkerCommand ();
 -}
 +      }
- }
  
  
  MingwBootLoaderModuleHandler::MingwBootLoaderModuleHandler (
@@@ -3400,30 -3035,9 +3035,9 @@@ MingwTestModuleHandler::GetModuleSpecif
  void
  MingwTestModuleHandler::GenerateTestModuleTarget ()
  {
-       string targetMacro ( GetTargetMacro ( module ) );
-       string workingDirectory = GetWorkingDirectory ( );
-       string libsMacro = GetLibsMacro ();
-       GenerateImportLibraryTargetIfNeeded ();
-       if ( module.non_if_data.compilationUnits.size () > 0 )
-       {
 -      GenerateRules ();
 +              GenerateRules ();
-               string dependencies = libsMacro + " " + objectsMacro;
-               string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000",
-                                                    module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (),
-                                                    module.baseaddress.c_str () );
-               GenerateLinkerCommand ( dependencies,
-                                       linkerParameters,
-                                       "" );
-       }
-       else
-       {
-               GeneratePhonyTarget();
+       GenerateLinkerCommand ();
 -}
 +      }
- }
  
  
  MingwAliasModuleHandler::MingwAliasModuleHandler (
@@@ -269,620 -534,475 +534,475 @@@ void MSVCBackend::_generate_standard_co
                                module.output->relative_path );
        }
  
-       fprintf ( OUT, "\t<Configurations>\r\n" );
-       for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ )
-       {
-               const MSVCConfiguration& cfg = *m_configurations[icfg];
+       string module_type = GetExtension(*module.output);
+       
+       // Set the configuration type for this config
+       ConfigurationType CfgType;
+       if ( binaryType == Exe )
+               CfgType = ConfigApp;
+       else if ( binaryType == Lib )
+               CfgType = ConfigLib;
+       else if ( binaryType == Dll || binaryType == Sys )
+               CfgType = ConfigDll;
+       else
+               CfgType = ConfigUnknown;
+       if ( intenv == "obj-i386" )
+               intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */
+       else
+               intdir = intenv;
+       if ( outenv == "output-i386" )
+               outdir = path_basedir + "output-i386";
+       else
+               outdir = outenv;
  
-               bool debug = ( cfg.optimization == Debug );
-               bool release = ( cfg.optimization == Release );
-               bool speed = ( cfg.optimization == Speed );
+       if ( configuration.UseVSVersionInPath )
+       {
+               vcdir = DEF_SSEP + _get_vc_dir();
+       }
  
 -      fprintf ( OUT, "\t\t<Configuration\r\n" );
 -      fprintf ( OUT, "\t\t\tName=\"%s|Win32\"\r\n", cfg.name.c_str() );
 +              fprintf ( OUT, "\t\t<Configuration\r\n" );
 +              fprintf ( OUT, "\t\t\tName=\"%s|Win32\"\r\n", cfg.name.c_str() );
  
 -      if ( configuration.UseConfigurationInPath )
 -      {
 -              fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s%s\\%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str (), cfg.name.c_str() );
 -              fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str (), cfg.name.c_str() );
 -      }
 -      else
 -      {
 -              fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () );
 -              fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () );
 -      }
 +              if ( configuration.UseConfigurationInPath )
 +              {
 +                      fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s%s\\%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str (), cfg.name.c_str() );
 +                      fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str (), cfg.name.c_str() );
 +              }
 +              else
 +              {
 +                      fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () );
 +                      fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () );
 +              }
  
-               fprintf ( OUT, "\t\t\tConfigurationType=\"%d\"\r\n", exe ? 1 : dll ? 2 : lib ? 4 : -1 );
-               fprintf ( OUT, "\t\t\tCharacterSet=\"2\">\r\n" );
+       fprintf ( OUT, "\t\t\tConfigurationType=\"%d\"\r\n", CfgType );
+       fprintf ( OUT, "\t\t\tCharacterSet=\"2\"\r\n" );
+       fprintf ( OUT, "\t\t\t>\r\n" );
  
 -      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -      fprintf ( OUT, "\t\t\t\tName=\"VCCLCompilerTool\"\r\n" );
 +              fprintf ( OUT, "\t\t\t<Tool\r\n" );
 +              fprintf ( OUT, "\t\t\t\tName=\"VCCLCompilerTool\"\r\n" );
 -      fprintf ( OUT, "\t\t\t\tOptimization=\"%d\"\r\n", release ? 2 : 0 );
 +              fprintf ( OUT, "\t\t\t\tOptimization=\"%d\"\r\n", release ? 2 : 0 );
  
 -      fprintf ( OUT, "\t\t\t\tAdditionalIncludeDirectories=\"" );
 -      bool multiple_includes = false;
 -      fprintf ( OUT, "./;" );
 -      for ( i = 0; i < includes.size(); i++ )
 -      {
 -              const std::string& include = includes[i];
 -              if ( strcmp ( include.c_str(), "." ) )
 +              fprintf ( OUT, "\t\t\t\tAdditionalIncludeDirectories=\"" );
 +              bool multiple_includes = false;
 +              fprintf ( OUT, "./;" );
 +              for ( i = 0; i < includes.size(); i++ )
 +              {
 +                      const std::string& include = includes[i];
 +                      if ( strcmp ( include.c_str(), "." ) )
 +                      {
 +                              if ( multiple_includes )
 +                                      fprintf ( OUT, ";" );
 +                              fprintf ( OUT, "%s", include.c_str() );
 +                              include_string += " /I " + include;
 +                              multiple_includes = true;
 +                      }
 +              }
 +              if ( include_idl )
                {
                        if ( multiple_includes )
                                fprintf ( OUT, ";" );
 -                      fprintf ( OUT, "%s", include.c_str() );
 -                      include_string += " /I " + include;
 -                      multiple_includes = true;
 -              }
 -      }
 -      if ( include_idl )
 -      {
 -              if ( multiple_includes )
 -                      fprintf ( OUT, ";" );
  
 -              if ( configuration.UseConfigurationInPath )
 -              {
 -                      fprintf ( OUT, "%s\\include\\reactos\\idl%s\\%s\r\n", intdir.c_str (), vcdir.c_str (), cfg.name.c_str() );
 -              }
 -              else
 -              {
 -                      fprintf ( OUT, "%s\\include\\reactos\\idl\r\n", intdir.c_str () );
 +                      if ( configuration.UseConfigurationInPath )
 +                      {
 +                              fprintf ( OUT, "%s\\include\\reactos\\idl%s\\%s\r\n", intdir.c_str (), vcdir.c_str (), cfg.name.c_str() );
 +                      }
 +                      else
 +                      {
 +                              fprintf ( OUT, "%s\\include\\reactos\\idl\r\n", intdir.c_str () );
 +                      }
                }
 -      }
 -      if ( cfg.headers == ReactOSHeaders )
 -      {
 -              for ( i = 0; i < includes_ros.size(); i++ )
 +              if ( cfg.headers == ReactOSHeaders )
                {
 -                      const std::string& include = includes_ros[i];
 -                      if ( multiple_includes )
 -                              fprintf ( OUT, ";" );
 -                      fprintf ( OUT, "%s", include.c_str() );
 -                      //include_string += " /I " + include;
 -                      multiple_includes = true;
 +                      for ( i = 0; i < includes_ros.size(); i++ )
 +                      {
 +                              const std::string& include = includes_ros[i];
 +                              if ( multiple_includes )
 +                                      fprintf ( OUT, ";" );
 +                              fprintf ( OUT, "%s", include.c_str() );
 +                              //include_string += " /I " + include;
 +                              multiple_includes = true;
 +                      }
                }
 -      }
 -      else
 -      {
 -              // Add WDK or PSDK paths, if user provides them
 -              if (getenv ( "BASEDIR" ) != NULL &&
 -                      (module.type == Kernel ||
 -                       module.type == KernelModeDLL ||
 -                       module.type == KernelModeDriver ||
 -                       module.type == KeyboardLayout))
 +              else
                {
 -                      string WdkBase, SdkPath, CrtPath, DdkPath;
 -                      WdkBase = getenv ( "BASEDIR" );
 -                      SdkPath = WdkBase + "\\inc\\api";
 -                      CrtPath = WdkBase + "\\inc\\crt";
 -                      DdkPath = WdkBase + "\\inc\\ddk";
 -
 -                      if ( multiple_includes )
 -                              fprintf ( OUT, ";" );
 -
 -                      fprintf ( OUT, "%s;", SdkPath.c_str() );
 -                      fprintf ( OUT, "%s;", CrtPath.c_str() );
 -                      fprintf ( OUT, "%s", DdkPath.c_str() );
 -                      multiple_includes = true;
 +                      // Add WDK or PSDK paths, if user provides them
 +                      if (getenv ( "BASEDIR" ) != NULL &&
 +                              (module.type == Kernel ||
 +                               module.type == KernelModeDLL ||
 +                               module.type == KernelModeDriver ||
 +                               module.type == KeyboardLayout))
 +                      {
 +                              string WdkBase, SdkPath, CrtPath, DdkPath;
 +                              WdkBase = getenv ( "BASEDIR" );
 +                              SdkPath = WdkBase + "\\inc\\api";
 +                              CrtPath = WdkBase + "\\inc\\crt";
 +                              DdkPath = WdkBase + "\\inc\\ddk";
 +
 +                              if ( multiple_includes )
 +                                      fprintf ( OUT, ";" );
 +
 +                              fprintf ( OUT, "%s;", SdkPath.c_str() );
 +                              fprintf ( OUT, "%s;", CrtPath.c_str() );
 +                              fprintf ( OUT, "%s", DdkPath.c_str() );
 +                              multiple_includes = true;
 +                      }
                }
 -      }
 -      fprintf ( OUT, "\"\r\n" );
 +              fprintf ( OUT, "\"\r\n" );
  
 -      StringSet defines = common_defines;
 +              StringSet defines = common_defines;
  
 -      // Always add _CRT_SECURE_NO_WARNINGS to disable warnings about not
 -      // using the safe functions introduced in MSVC8.
 -      defines.insert ( "_CRT_SECURE_NO_WARNINGS" );
 +              // Always add _CRT_SECURE_NO_WARNINGS to disable warnings about not
 +              // using the safe functions introduced in MSVC8.
 +              defines.insert ( "_CRT_SECURE_NO_WARNINGS" );
  
 -      if ( debug )
 -      {
 -              defines.insert ( "_DEBUG" );
 -      }
 +              if ( debug )
 +              {
 +                      defines.insert ( "_DEBUG" );
 +              }
  
 -      if ( cfg.headers == MSVCHeaders )
 -      {
 -              // this is a define in MinGW w32api, but not Microsoft's headers
 -              defines.insert ( "STDCALL=__stdcall" );
 -      }
 +              if ( cfg.headers == MSVCHeaders )
 +              {
 +                      // this is a define in MinGW w32api, but not Microsoft's headers
 +                      defines.insert ( "STDCALL=__stdcall" );
 +              }
  
-               if ( lib || exe )
+       if ( binaryType == Lib || binaryType == Exe )
 -      {
 -              defines.insert ( "_LIB" );
 -      }
 -      else
 -      {
 -              defines.insert ( "_WINDOWS" );
 -              defines.insert ( "_USRDLL" );
 -      }
 -
 -      fprintf ( OUT, "\t\t\t\tPreprocessorDefinitions=\"" );
 -      for ( StringSet::iterator it1=defines.begin(); it1!=defines.end(); it1++ )
 -      {
 -              if ( i > 0 )
 -                      fprintf ( OUT, ";" );
 +              {
 +                      defines.insert ( "_LIB" );
 +              }
 +              else
 +              {
 +                      defines.insert ( "_WINDOWS" );
 +                      defines.insert ( "_USRDLL" );
 +              }
  
 -              string unescaped = *it1;
 -              fprintf ( OUT, "%s", _replace_str(unescaped, "\"","").c_str() );
 -      }
 -      fprintf ( OUT, "\"\r\n" );
 -      fprintf ( OUT, "\t\t\t\tForcedIncludeFiles=\"%s\"\r\n", "warning.h");
 -      fprintf ( OUT, "\t\t\t\tMinimalRebuild=\"%s\"\r\n", speed ? "TRUE" : "FALSE" );
 -      fprintf ( OUT, "\t\t\t\tBasicRuntimeChecks=\"0\"\r\n" );
 -      fprintf ( OUT, "\t\t\t\tRuntimeLibrary=\"%d\"\r\n", debug ? 3 : 2 );    // 3=/MDd 2=/MD
 -      fprintf ( OUT, "\t\t\t\tBufferSecurityCheck=\"FALSE\"\r\n" );
 -      fprintf ( OUT, "\t\t\t\tEnableFunctionLevelLinking=\"FALSE\"\r\n" );
 -
 -      if ( module.pch != NULL )
 -      {
 -              fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" );
 -              string pch_path = Path::RelativeFromDirectory (
 -                      module.pch->file->name,
 -                      module.output->relative_path );
 -              string::size_type pos = pch_path.find_last_of ("/");
 -              if ( pos != string::npos )
 -                      pch_path.erase(0, pos+1);
 -              fprintf ( OUT, "\t\t\t\tPrecompiledHeaderThrough=\"%s\"\r\n", pch_path.c_str() );
 -
 -              // Only include from the same module
 -              pos = pch_path.find("../");
 -              if (pos == string::npos && std::find(header_files.begin(), header_files.end(), pch_path) == header_files.end())
 -                      header_files.push_back(pch_path);
 -      }
 -      else
 -      {
 -              fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"0\"\r\n" );
 -      }
 +              fprintf ( OUT, "\t\t\t\tPreprocessorDefinitions=\"" );
 +              for ( StringSet::iterator it1=defines.begin(); it1!=defines.end(); it1++ )
 +              {
 +                      if ( i > 0 )
 +                              fprintf ( OUT, ";" );
  
 -      fprintf ( OUT, "\t\t\t\tWholeProgramOptimization=\"%s\"\r\n", release ? "FALSE" : "FALSE");
 -      if ( release )
 -      {
 -              fprintf ( OUT, "\t\t\t\tFavorSizeOrSpeed=\"1\"\r\n" );
 -              fprintf ( OUT, "\t\t\t\tStringPooling=\"true\"\r\n" );
 -      }
 +                      string unescaped = *it1;
 +                      fprintf ( OUT, "%s", _replace_str(unescaped, "\"","").c_str() );
 +              }
 +              fprintf ( OUT, "\"\r\n" );
 +              fprintf ( OUT, "\t\t\t\tForcedIncludeFiles=\"%s\"\r\n", "warning.h");
 +              fprintf ( OUT, "\t\t\t\tMinimalRebuild=\"%s\"\r\n", speed ? "TRUE" : "FALSE" );
 +              fprintf ( OUT, "\t\t\t\tBasicRuntimeChecks=\"0\"\r\n" );
 +              fprintf ( OUT, "\t\t\t\tRuntimeLibrary=\"%d\"\r\n", debug ? 3 : 2 );    // 3=/MDd 2=/MD
 +              fprintf ( OUT, "\t\t\t\tBufferSecurityCheck=\"FALSE\"\r\n" );
 +              fprintf ( OUT, "\t\t\t\tEnableFunctionLevelLinking=\"FALSE\"\r\n" );
 +
 +              if ( module.pch != NULL )
 +              {
 +                      fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" );
 +                      string pch_path = Path::RelativeFromDirectory (
 +                              module.pch->file->name,
 +                              module.output->relative_path );
 +                      string::size_type pos = pch_path.find_last_of ("/");
 +                      if ( pos != string::npos )
 +                              pch_path.erase(0, pos+1);
 +                      fprintf ( OUT, "\t\t\t\tPrecompiledHeaderThrough=\"%s\"\r\n", pch_path.c_str() );
 +
 +                      // Only include from the same module
 +                      pos = pch_path.find("../");
 +                      if (pos == string::npos && std::find(header_files.begin(), header_files.end(), pch_path) == header_files.end())
 +                              header_files.push_back(pch_path);
 +              }
 +              else
 +              {
 +                      fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"0\"\r\n" );
 +              }
  
 -      fprintf ( OUT, "\t\t\t\tWarningLevel=\"%s\"\r\n", speed ? "0" : "3" );
 -      fprintf ( OUT, "\t\t\t\tDetect64BitPortabilityProblems=\"%s\"\r\n", "FALSE");
 -      if ( !module.cplusplus )
 -              fprintf ( OUT, "\t\t\t\tCompileAs=\"1\"\r\n" );
 +              fprintf ( OUT, "\t\t\t\tWholeProgramOptimization=\"%s\"\r\n", release ? "FALSE" : "FALSE");
 +              if ( release )
 +              {
 +                      fprintf ( OUT, "\t\t\t\tFavorSizeOrSpeed=\"1\"\r\n" );
 +                      fprintf ( OUT, "\t\t\t\tStringPooling=\"true\"\r\n" );
 +              }
  
 -      if ( module.type == Win32CUI || module.type == Win32GUI )
 -      {
 -              fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 0 );     // 0=__cdecl
 -      }
 -      else
 -      {
 -              fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 2 );     // 2=__stdcall
 -      }
 +              fprintf ( OUT, "\t\t\t\tWarningLevel=\"%s\"\r\n", speed ? "0" : "3" );
 +              fprintf ( OUT, "\t\t\t\tDetect64BitPortabilityProblems=\"%s\"\r\n", "FALSE");
 +              if ( !module.cplusplus )
 +                      fprintf ( OUT, "\t\t\t\tCompileAs=\"1\"\r\n" );
  
 -      fprintf ( OUT, "\t\t\t\tDebugInformationFormat=\"%s\"/>\r\n", speed ? "0" : release ? "3": "4");        // 3=/Zi 4=ZI
 +              if ( module.type == Win32CUI || module.type == Win32GUI )
 +              {
 +                      fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 0 );     // 0=__cdecl
 +              }
 +              else
 +              {
 +                      fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 2 );     // 2=__stdcall
 +              }
  
 -      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -      fprintf ( OUT, "\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n" );
 +              fprintf ( OUT, "\t\t\t\tDebugInformationFormat=\"%s\"/>\r\n", speed ? "0" : release ? "3": "4");        // 3=/Zi 4=ZI
  
 -      if ( binaryType == Lib )
 -      {
                fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -              fprintf ( OUT, "\t\t\t\tName=\"VCLibrarianTool\"\r\n" );
 -              fprintf ( OUT, "\t\t\t\tOutputFile=\"$(OutDir)/%s.lib\"/>\r\n", module.name.c_str() );
 -      }
 -      else
 -      {
 -              fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -              fprintf ( OUT, "\t\t\t\tName=\"VCLinkerTool\"\r\n" );
 -              if (module.GetEntryPoint() == "0" && binaryType != Sys )
 -                      fprintf ( OUT, "AdditionalOptions=\"/noentry\"" );
 +              fprintf ( OUT, "\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n" );
  
-               if ( lib )
 -              if (configuration.VSProjectVersion == "9.00")
++      if ( binaryType == Lib )
                {
 -                      fprintf ( OUT, "\t\t\t\tRandomizedBaseAddress=\"0\"\r\n" );
 -                      fprintf ( OUT, "\t\t\t\tDataExecutionPrevention=\"0\"\r\n" );
 +                      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 +                      fprintf ( OUT, "\t\t\t\tName=\"VCLibrarianTool\"\r\n" );
 +                      fprintf ( OUT, "\t\t\t\tOutputFile=\"$(OutDir)/%s.lib\"/>\r\n", module.name.c_str() );
                }
-                       if (module.GetEntryPoint(false) == "0" && sys == false)
 +              else
 +              {
 +                      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 +                      fprintf ( OUT, "\t\t\t\tName=\"VCLinkerTool\"\r\n" );
++              if (module.GetEntryPoint() == "0" && binaryType != Sys )
 +                              fprintf ( OUT, "AdditionalOptions=\"/noentry\"" );
 +
 +                      if (configuration.VSProjectVersion == "9.00")
 +                      {
 +                              fprintf ( OUT, "\t\t\t\tRandomizedBaseAddress=\"0\"\r\n" );
 +                              fprintf ( OUT, "\t\t\t\tDataExecutionPrevention=\"0\"\r\n" );
 +                      }
  
 -              if (module.importLibrary != NULL)
 -                      fprintf ( OUT, "\t\t\t\tModuleDefinitionFile=\"%s\"\r\n", importLib.c_str());
 +                      if (module.importLibrary != NULL)
 +                              fprintf ( OUT, "\t\t\t\tModuleDefinitionFile=\"%s\"\r\n", importLib.c_str());
  
 -              fprintf ( OUT, "\t\t\t\tAdditionalDependencies=\"" );
 -              bool use_msvcrt_lib = false;
 -              for ( i = 0; i < libraries.size(); i++ )
 -              {
 -                      if ( i > 0 )
 -                              fprintf ( OUT, " " );
 -                      string libpath = libraries[i].c_str();
 -                      libpath = libpath.erase (0, libpath.find_last_of ("\\") + 1 );
 -                      if ( libpath == "msvcrt.lib" )
 +                      fprintf ( OUT, "\t\t\t\tAdditionalDependencies=\"" );
 +                      bool use_msvcrt_lib = false;
 +                      for ( i = 0; i < libraries.size(); i++ )
                        {
 -                              use_msvcrt_lib = true;
 +                              if ( i > 0 )
 +                                      fprintf ( OUT, " " );
 +                              string libpath = libraries[i].c_str();
 +                              libpath = libpath.erase (0, libpath.find_last_of ("\\") + 1 );
 +                              if ( libpath == "msvcrt.lib" )
 +                              {
 +                                      use_msvcrt_lib = true;
 +                              }
 +                              fprintf ( OUT, "%s", libpath.c_str() );
                        }
 -                      fprintf ( OUT, "%s", libpath.c_str() );
 -              }
 -              fprintf ( OUT, "\"\r\n" );
 +                      fprintf ( OUT, "\"\r\n" );
  
 -              fprintf ( OUT, "\t\t\t\tAdditionalLibraryDirectories=\"" );
 +                      fprintf ( OUT, "\t\t\t\tAdditionalLibraryDirectories=\"" );
  
 -              // Add WDK libs paths, if needed
 -              if (getenv ( "BASEDIR" ) != NULL &&
 -                      (module.type == Kernel ||
 -                       module.type == KernelModeDLL ||
 -                       module.type == KernelModeDriver ||
 -                       module.type == KeyboardLayout))
 -              {
 -                      string WdkBase, CrtPath, DdkPath;
 -                      WdkBase = getenv ( "BASEDIR" );
 -                      CrtPath = WdkBase + "\\lib\\crt\\i386";
 -                      DdkPath = WdkBase + "\\lib\\wnet\\i386";
 +                      // Add WDK libs paths, if needed
 +                      if (getenv ( "BASEDIR" ) != NULL &&
 +                              (module.type == Kernel ||
 +                               module.type == KernelModeDLL ||
 +                               module.type == KernelModeDriver ||
 +                               module.type == KeyboardLayout))
 +                      {
 +                              string WdkBase, CrtPath, DdkPath;
 +                              WdkBase = getenv ( "BASEDIR" );
 +                              CrtPath = WdkBase + "\\lib\\crt\\i386";
 +                              DdkPath = WdkBase + "\\lib\\wnet\\i386";
  
 -                      fprintf ( OUT, "%s;", CrtPath.c_str() );
 -                      fprintf ( OUT, "%s", DdkPath.c_str() );
 +                              fprintf ( OUT, "%s;", CrtPath.c_str() );
 +                              fprintf ( OUT, "%s", DdkPath.c_str() );
  
 -                      if (libraries.size () > 0)
 -                              fprintf ( OUT, ";" );
 -              }
 +                              if (libraries.size () > 0)
 +                                      fprintf ( OUT, ";" );
 +                      }
  
 -              // Add conventional libraries dirs
 -              for (i = 0; i < libraries.size (); i++)
 -              {
 -                      if ( i > 0 )
 -                              fprintf ( OUT, ";" );
 +                      // Add conventional libraries dirs
 +                      for (i = 0; i < libraries.size (); i++)
 +                      {
 +                              if ( i > 0 )
 +                                      fprintf ( OUT, ";" );
  
 -                      string libpath = libraries[i].c_str();
 -                      libpath.replace (libpath.find("---"), 3, cfg.name);
 -                      libpath = libpath.substr (0, libpath.find_last_of ("\\") );
 -                      fprintf ( OUT, "%s", libpath.c_str() );
 -              }
 +                              string libpath = libraries[i].c_str();
 +                              libpath.replace (libpath.find("---"), 3, cfg.name);
 +                              libpath = libpath.substr (0, libpath.find_last_of ("\\") );
 +                              fprintf ( OUT, "%s", libpath.c_str() );
 +                      }
  
 -              fprintf ( OUT, "\"\r\n" );
 +                      fprintf ( OUT, "\"\r\n" );
  
 -              fprintf ( OUT, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module.name.c_str(), module_type.c_str() );
 -              fprintf ( OUT, "\t\t\t\tLinkIncremental=\"%d\"\r\n", debug ? 2 : 1 );
 -              fprintf ( OUT, "\t\t\t\tGenerateDebugInformation=\"%s\"\r\n", speed ? "FALSE" : "TRUE" );
 -              fprintf ( OUT, "\t\t\t\tLinkTimeCodeGeneration=\"%d\"\r\n", release? 0 : 0);    // whole program optimization
 +                      fprintf ( OUT, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module.name.c_str(), module_type.c_str() );
 +                      fprintf ( OUT, "\t\t\t\tLinkIncremental=\"%d\"\r\n", debug ? 2 : 1 );
 +                      fprintf ( OUT, "\t\t\t\tGenerateDebugInformation=\"%s\"\r\n", speed ? "FALSE" : "TRUE" );
 +                      fprintf ( OUT, "\t\t\t\tLinkTimeCodeGeneration=\"%d\"\r\n", release? 0 : 0);    // whole program optimization
  
 -              if ( debug )
 -                      fprintf ( OUT, "\t\t\t\tProgramDatabaseFile=\"$(OutDir)/%s.pdb\"\r\n", module.name.c_str() );
 +                      if ( debug )
 +                              fprintf ( OUT, "\t\t\t\tProgramDatabaseFile=\"$(OutDir)/%s.pdb\"\r\n", module.name.c_str() );
  
-                       if ( sys )
+               if ( binaryType == Sys )
 -              {
 -                      if (module.GetEntryPoint() == "0")
 -                              fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /noentry /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" );
 -                      else
 -                              fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" );
 -                      fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
 -                      fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
 -                      fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 );
 -                      fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 );
 -                      fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint() == "" ? "DriverEntry" : module.GetEntryPoint().c_str ());
 -                      fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x10000" : baseaddr.c_str ());
 -              }
 -              else if ( binaryType == Exe )
 -              {
 -                      if ( module.type == Kernel )
                        {
-                               if (module.GetEntryPoint(false) == "0")
 -                              fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /SECTION:INIT,D /ALIGN:0x80\"\r\n" );
++                      if (module.GetEntryPoint() == "0")
 +                                      fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /noentry /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" );
 +                              else
 +                                      fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" );
                                fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
                                fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
                                fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 );
                                fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 );
-                               fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint(false) == "" ? "DriverEntry" : module.GetEntryPoint(false).c_str ());
 -                              fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"KiSystemStartup\"\r\n" );
 -                              fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ());
 -                      }
 -                      else if ( module.type == NativeCUI )
 -                      {
 -                              fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20\"\r\n" );
 -                              fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 1 );
 -                              fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
 -                              fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
 -                              fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"NtProcessStartup\"\r\n" );
 -                              fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ());
++                      fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint() == "" ? "DriverEntry" : module.GetEntryPoint().c_str ());
 +                              fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x10000" : baseaddr.c_str ());
                        }
-                       else if ( exe )
 -                      else if ( module.type == Win32CUI || module.type == Win32GUI || module.type == Win32SCR)
++              else if ( binaryType == Exe )
                        {
 -                              if ( use_msvcrt_lib )
 +                              if ( module.type == Kernel )
 +                              {
 +                                      fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /SECTION:INIT,D /ALIGN:0x80\"\r\n" );
 +                                      fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
 +                                      fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
 +                                      fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 );
 +                                      fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 );
 +                                      fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"KiSystemStartup\"\r\n" );
 +                                      fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ());
 +                              }
 +                              else if ( module.type == NativeCUI )
                                {
 +                                      fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20\"\r\n" );
 +                                      fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 1 );
 +                                      fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
                                        fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
 +                                      fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"NtProcessStartup\"\r\n" );
 +                                      fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ());
                                }
-                                       fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", console ? 1 : 2 );
 +                              else if ( module.type == Win32CUI || module.type == Win32GUI || module.type == Win32SCR)
 +                              {
 +                                      if ( use_msvcrt_lib )
 +                                      {
 +                                              fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
 +                                      }
+                               fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 2 );
 +                              }
                        }
-                       else if ( dll )
 -              }
+               else if ( binaryType == Dll )
 -              {
 -                      if (module.GetEntryPoint() == "0")
 -                              fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"\"\r\n" );
 -                      else
                        {
-                               if (module.GetEntryPoint(false) == "0")
 -                              // get rid of DllMain@12 because MSVC needs to link to _DllMainCRTStartup@12
 -                              // when using CRT
 -                              if (module.GetEntryPoint() == "DllMain@12")
++                      if (module.GetEntryPoint() == "0")
                                        fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"\"\r\n" );
                                else
-                                       if (module.GetEntryPoint(false) == "DllMain@12")
 +                              {
 +                                      // get rid of DllMain@12 because MSVC needs to link to _DllMainCRTStartup@12
 +                                      // when using CRT
-                                               fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint(false).c_str ());
++                              if (module.GetEntryPoint() == "DllMain@12")
 +                                              fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"\"\r\n" );
 +                                      else
+                                       fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint().c_str ());
 +                              }
 +                              fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x40000" : baseaddr.c_str ());
 +                              if ( use_msvcrt_lib )
 +                              {
 +                                      fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
 +                              }
                        }
 -                      fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x40000" : baseaddr.c_str ());
 -                      if ( use_msvcrt_lib )
 -                      {
 -                              fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
 -                      }
 +                      fprintf ( OUT, "\t\t\t\tTargetMachine=\"%d\"/>\r\n", 1 );
                }
 -              fprintf ( OUT, "\t\t\t\tTargetMachine=\"%d\"/>\r\n", 1 );
 -      }
  
 -      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -      fprintf ( OUT, "\t\t\t\tName=\"VCResourceCompilerTool\"\r\n" );
 -      fprintf ( OUT, "\t\t\t\tAdditionalIncludeDirectories=\"" );
 -      multiple_includes = false;
 -      fprintf ( OUT, "./;" );
 -      for ( i = 0; i < includes.size(); i++ )
 -      {
 -              const std::string& include = includes[i];
 -              if ( strcmp ( include.c_str(), "." ) )
 +              fprintf ( OUT, "\t\t\t<Tool\r\n" );
 +              fprintf ( OUT, "\t\t\t\tName=\"VCResourceCompilerTool\"\r\n" );
 +              fprintf ( OUT, "\t\t\t\tAdditionalIncludeDirectories=\"" );
 +              multiple_includes = false;
 +              fprintf ( OUT, "./;" );
 +              for ( i = 0; i < includes.size(); i++ )
                {
 -                      if ( multiple_includes )
 -                              fprintf ( OUT, ";" );
 -                      fprintf ( OUT, "%s", include.c_str() );
 -                      multiple_includes = true;
 +                      const std::string& include = includes[i];
 +                      if ( strcmp ( include.c_str(), "." ) )
 +                      {
 +                              if ( multiple_includes )
 +                                      fprintf ( OUT, ";" );
 +                              fprintf ( OUT, "%s", include.c_str() );
 +                              multiple_includes = true;
 +                      }
                }
 -      }
 -      if ( cfg.headers == ReactOSHeaders )
 -      {
 -              for ( i = 0; i < includes_ros.size(); i++ )
 +              if ( cfg.headers == ReactOSHeaders )
                {
 -                      const std::string& include = includes_ros[i];
 -                      if ( multiple_includes )
 -                              fprintf ( OUT, ";" );
 -                      fprintf ( OUT, "%s", include.c_str() );
 -                      multiple_includes = true;
 +                      for ( i = 0; i < includes_ros.size(); i++ )
 +                      {
 +                              const std::string& include = includes_ros[i];
 +                              if ( multiple_includes )
 +                                      fprintf ( OUT, ";" );
 +                              fprintf ( OUT, "%s", include.c_str() );
 +                              multiple_includes = true;
 +                      }
                }
 -      }
 -      fprintf ( OUT, "\"/>\r\n " );
 +              fprintf ( OUT, "\"/>\r\n " );
  
 -      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -      fprintf ( OUT, "\t\t\t\tName=\"VCMIDLTool\"/>\r\n" );
 -      if (configuration.VSProjectVersion == "8.00")
 -      {
                fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -              fprintf ( OUT, "\t\t\t\tName=\"VCManifestTool\"\r\n" );
 -              fprintf ( OUT, "\t\t\t\tEmbedManifest=\"false\"/>\r\n" );
 +              fprintf ( OUT, "\t\t\t\tName=\"VCMIDLTool\"/>\r\n" );
 +              if (configuration.VSProjectVersion == "8.00")
 +              {
 +                      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 +                      fprintf ( OUT, "\t\t\t\tName=\"VCManifestTool\"\r\n" );
 +                      fprintf ( OUT, "\t\t\t\tEmbedManifest=\"false\"/>\r\n" );
 +              }
 +              fprintf ( OUT, "\t\t\t<Tool\r\n" );
 +              fprintf ( OUT, "\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n" );
 +              fprintf ( OUT, "\t\t\t<Tool\r\n" );
 +              fprintf ( OUT, "\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n" );
 +              fprintf ( OUT, "\t\t\t<Tool\r\n" );
 +              fprintf ( OUT, "\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n" );
 +              fprintf ( OUT, "\t\t\t<Tool\r\n" );
 +              fprintf ( OUT, "\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n" );
 +              fprintf ( OUT, "\t\t\t<Tool\r\n" );
 +              fprintf ( OUT, "\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n" );
 +              fprintf ( OUT, "\t\t</Configuration>\r\n" );
-               n++;
        }
-       fprintf ( OUT, "\t</Configurations>\r\n" );
 -      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -      fprintf ( OUT, "\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n" );
 -      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -      fprintf ( OUT, "\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n" );
 -      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -      fprintf ( OUT, "\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n" );
 -      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -      fprintf ( OUT, "\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n" );
 -      fprintf ( OUT, "\t\t\t<Tool\r\n" );
 -      fprintf ( OUT, "\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n" );
 -      fprintf ( OUT, "\t\t</Configuration>\r\n" );
 -}
  
-       fprintf ( OUT, "\t<Files>\r\n" );
  
-       // Source files
-       fprintf ( OUT, "\t\t<Filter\r\n" );
-       fprintf ( OUT, "\t\t\tName=\"Source Files\"\r\n" );
-       fprintf ( OUT, "\t\t\tFilter=\"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;S\">\r\n" );
+ void
+ MSVCBackend::_generate_makefile_configuration( FILE* OUT, const Module& module, const MSVCConfiguration& cfg )
+ {
+       string path_basedir = module.GetPathToBaseDir ();
+       string intenv = Environment::GetIntermediatePath ();
+       string outenv = Environment::GetOutputPath ();
  
-       std::sort(source_files.begin(), source_files.end(), SortFilesAscending());
-       vector<string> last_folder;
-       vector<string> split_path;
-       string indent_tab("\t\t\t");
+       string outdir;
+       string intdir;
+       string vcdir;
  
-       for ( size_t isrcfile = 0; isrcfile < source_files.size(); isrcfile++ )
-       {
-               string source_file = DosSeparator(source_files[isrcfile]);
  
-               Path::Split(split_path, source_file, false);
-               size_t same_folder_index = 0;
-               for ( size_t ifolder = 0; ifolder < last_folder.size(); ifolder++ )
-               {
-                       if ( ifolder < split_path.size() && last_folder[ifolder] == split_path[ifolder] )
-                               ++same_folder_index;
+       if ( intenv == "obj-i386" )
+               intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */
 -      else
 +                      else
-                               break;
-               }
-               if ( same_folder_index < split_path.size() || last_folder.size() > split_path.size() )
-               {
-                       int tabStart = 1;
-                       if ( split_path.size() > last_folder.size() )
-                       {
-                               for ( size_t ifolder = last_folder.size(); ifolder < split_path.size(); ifolder++ )
-                                       indent_tab.push_back('\t');
-                               tabStart = split_path.size() - last_folder.size() + 1;
-                       }
-                       else if ( split_path.size() < last_folder.size() )
-                       {
-                               indent_tab.resize( split_path.size() + 3 );
-                               tabStart = split_path.size() - last_folder.size() + 1;
-                       }
+               intdir = intenv;
  
-                       for ( size_t ifolder = last_folder.size(), itab = tabStart; ifolder > same_folder_index; ifolder--, itab++ )
-                       {
-                               fprintf ( OUT, "%s</Filter>\r\n", indent_tab.substr(0, indent_tab.size() - itab).c_str() );
-                       }
+       if ( outenv == "output-i386" )
+               outdir = path_basedir + "output-i386";
+       else
+               outdir = outenv;
  
-                       for ( size_t ifolder = same_folder_index, itab = split_path.size() - same_folder_index; ifolder < split_path.size(); ifolder++, itab-- )
+       if ( configuration.UseVSVersionInPath )
 -      {
 +                      {
-                               const string tab = indent_tab.substr(0, indent_tab.size() - itab);
-                               fprintf ( OUT, "%s<Filter\r\n", tab.c_str() );
-                               fprintf ( OUT, "%s\tName=\"%s\">\r\n", tab.c_str(), split_path[ifolder].c_str() );
+               vcdir = DEF_SSEP + _get_vc_dir();
 -      }
 +                      }
  
-                       last_folder = split_path;
-               }
-               fprintf ( OUT, "%s<File\r\n", indent_tab.c_str() );
-               fprintf ( OUT, "%s\tRelativePath=\"%s\">\r\n", indent_tab.c_str(), source_file.c_str() );
+       fprintf ( OUT, "\t\t<Configuration\r\n" );
+       fprintf ( OUT, "\t\t\tName=\"%s|Win32\"\r\n", cfg.name.c_str() );
  
-               for ( size_t iconfig = 0; iconfig < m_configurations.size(); iconfig++ )
+       if ( configuration.UseConfigurationInPath )
 -      {
 +              {
-                       const MSVCConfiguration& config = *m_configurations[iconfig];
-                       if (( isrcfile == 0 ) && ( module.pch != NULL ))
-                       {
-                               /* little hack to speed up PCH */
-                               fprintf ( OUT, "%s\t<FileConfiguration\r\n", indent_tab.c_str() );
-                               fprintf ( OUT, "%s\t\tName=\"", indent_tab.c_str() );
-                               fprintf ( OUT, config.name.c_str() );
-                               fprintf ( OUT, "|Win32\">\r\n" );
-                               fprintf ( OUT, "%s\t\t<Tool\r\n", indent_tab.c_str() );
-                               fprintf ( OUT, "%s\t\t\tName=\"VCCLCompilerTool\"\r\n", indent_tab.c_str() );
-                               fprintf ( OUT, "%s\t\t\tUsePrecompiledHeader=\"1\"/>\r\n", indent_tab.c_str() );
-                               fprintf ( OUT, "%s\t</FileConfiguration>\r\n", indent_tab.c_str() );
+               fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s\\%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str (), cfg.name.c_str() );
+               fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), cfg.name.c_str() );
 -      }
 -      else
 -      {
 +                      }
-                       //if (configuration.VSProjectVersion < "8.00") {
-                               if ((source_file.find(".idl") != string::npos) || ((source_file.find(".asm") != string::npos || tolower(source_file.at(source_file.size() - 1)) == 's')))
-                               {
-                                       fprintf ( OUT, "%s\t<FileConfiguration\r\n", indent_tab.c_str() );
-                                       fprintf ( OUT, "%s\t\tName=\"", indent_tab.c_str() );
-                                       fprintf ( OUT, config.name.c_str() );
-                                       fprintf ( OUT, "|Win32\">\r\n" );
-                                       fprintf ( OUT, "%s\t\t<Tool\r\n", indent_tab.c_str() );
-                                       if (source_file.find(".idl") != string::npos)
-                                       {
-                                               string src = source_file.substr (0, source_file.find(".idl"));
-                                               if ( src.find (".\\") != string::npos )
-                                                       src.erase (0, 2);
-                                               fprintf ( OUT, "%s\t\t\tName=\"VCCustomBuildTool\"\r\n", indent_tab.c_str() );
-                                               if ( module.type == RpcClient )
-                                               {
-                                                       fprintf ( OUT, "%s\t\t\tCommandLine=\"midl.exe /cstub %s_c.c /header %s_c.h /server none &quot;$(InputPath)&quot; /out &quot;$(IntDir)&quot;", indent_tab.c_str(), src.c_str (), src.c_str () );
-                                                       fprintf ( OUT, "&#x0D;&#x0A;");
-                                                       fprintf ( OUT, "cl.exe /Od /D &quot;WIN32&quot; /D &quot;_DEBUG&quot; /D &quot;_WINDOWS&quot; /D &quot;_WIN32_WINNT=0x502&quot; /D &quot;_UNICODE&quot; /D &quot;UNICODE&quot; /Gm /EHsc /RTC1 /MDd /Fo&quot;$(IntDir)\\%s.obj&quot; /W3 /c /Wp64 /ZI /TC &quot;$(IntDir)\\%s_c.c&quot; /nologo /errorReport:prompt", src.c_str (), src.c_str () );
-                                               }
 +                                              else
 +                                              {
-                                                       fprintf ( OUT, "%s\t\t\tCommandLine=\"midl.exe /sstub %s_s.c /header %s_s.h /client none &quot;$(InputPath)&quot; /out &quot;$(IntDir)&quot;", indent_tab.c_str(), src.c_str (), src.c_str () );
-                                                       fprintf ( OUT, "&#x0D;&#x0A;");
-                                                       fprintf ( OUT, "cl.exe /Od /D &quot;WIN32&quot; /D &quot;_DEBUG&quot; /D &quot;_WINDOWS&quot; /D &quot;_WIN32_WINNT=0x502&quot; /D &quot;_UNICODE&quot; /D &quot;UNICODE&quot; /Gm /EHsc /RTC1 /MDd /Fo&quot;$(IntDir)\\%s.obj&quot; /W3 /c /Wp64 /ZI /TC &quot;$(IntDir)\\%s_s.c&quot; /nologo /errorReport:prompt", src.c_str (), src.c_str () );
+               fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str () );
+               fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str () );
 -      }
 +                                              }
-                                               fprintf ( OUT, "&#x0D;&#x0A;");
-                                               fprintf ( OUT, "lib.exe /OUT:&quot;$(OutDir)\\%s.lib&quot; &quot;$(IntDir)\\%s.obj&quot;&#x0D;&#x0A;\"\r\n", module.name.c_str (), src.c_str () );
-                                               fprintf ( OUT, "%s\t\t\tOutputs=\"$(IntDir)\\$(InputName).obj\"/>\r\n", indent_tab.c_str() );
-                                       }
-                                       else if ((source_file.find(".asm") != string::npos))
-                                       {
-                                               fprintf ( OUT, "%s\t\t\tName=\"VCCustomBuildTool\"\r\n", indent_tab.c_str() );
-                                               fprintf ( OUT, "%s\t\t\tCommandLine=\"nasmw $(InputPath) -f coff -o &quot;$(OutDir)\\$(InputName).obj&quot;\"\r\n", indent_tab.c_str() );
-                                               fprintf ( OUT, "%s\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"/>\r\n", indent_tab.c_str() );
-                                       }
-                                       else if ((tolower(source_file.at(source_file.size() - 1)) == 's'))
-                                       {
-                                               fprintf ( OUT, "%s\t\t\tName=\"VCCustomBuildTool\"\r\n", indent_tab.c_str() );
-                                               fprintf ( OUT, "%s\t\t\tCommandLine=\"cl /E &quot;$(InputPath)&quot; %s /D__ASM__ | as -o &quot;$(OutDir)\\$(InputName).obj&quot;\"\r\n", indent_tab.c_str(), include_string.c_str() );
-                                               fprintf ( OUT, "%s\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"/>\r\n", indent_tab.c_str() );
-                                       }
-                                       fprintf ( OUT, "%s\t</FileConfiguration>\r\n", indent_tab.c_str() );
-                               }
-                       //}
-               }
-               fprintf ( OUT, "%s</File>\r\n", indent_tab.c_str() );
-       }
-       for ( size_t ifolder = last_folder.size(); ifolder > 0; ifolder-- )
-       {
-               indent_tab.resize( ifolder + 2 );
-               fprintf ( OUT, "%s</Filter>\r\n", indent_tab.c_str() );
-       }
  
-       fprintf ( OUT, "\t\t</Filter>\r\n" );
+       fprintf ( OUT, "\t\t\tConfigurationType=\"0\"\r\n");
+       fprintf ( OUT, "\t\t\t>\r\n" );
  
-       // Header files
-       fprintf ( OUT, "\t\t<Filter\r\n" );
-       fprintf ( OUT, "\t\t\tName=\"Header Files\"\r\n" );
-       fprintf ( OUT, "\t\t\tFilter=\"h;hpp;hxx;hm;inl\">\r\n" );
-       for ( i = 0; i < header_files.size(); i++ )
-       {
-               const string& header_file = header_files[i];
-               fprintf ( OUT, "\t\t\t<File\r\n" );
-               fprintf ( OUT, "\t\t\t\tRelativePath=\"%s\">\r\n", header_file.c_str() );
-               fprintf ( OUT, "\t\t\t</File>\r\n" );
-       }
-       fprintf ( OUT, "\t\t</Filter>\r\n" );
+       fprintf ( OUT, "\t\t\t<Tool\r\n" );
  
-       // Resource files
-       fprintf ( OUT, "\t\t<Filter\r\n" );
-       fprintf ( OUT, "\t\t\tName=\"Resource Files\"\r\n" );
-       fprintf ( OUT, "\t\t\tFilter=\"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\">\r\n" );
-       for ( i = 0; i < resource_files.size(); i++ )
-       {
-               const string& resource_file = resource_files[i];
-               fprintf ( OUT, "\t\t\t<File\r\n" );
-               fprintf ( OUT, "\t\t\t\tRelativePath=\"%s\">\r\n", resource_file.c_str() );
-               fprintf ( OUT, "\t\t\t</File>\r\n" );
-       }
-       fprintf ( OUT, "\t\t</Filter>\r\n" );
+       fprintf ( OUT, "\t\t\t\tName=\"VCNMakeTool\"\r\n" );
+       fprintf ( OUT, "\t\t\t\tBuildCommandLine=\"%srosbuild.bat build %s\"\r\n", path_basedir.c_str (), module.name.c_str ());
+       fprintf ( OUT, "\t\t\t\tReBuildCommandLine=\"%srosbuild.bat rebuild %s\"\r\n", path_basedir.c_str (), module.name.c_str ());
+       fprintf ( OUT, "\t\t\t\tCleanCommandLine=\"%srosbuild.bat clean %s\"\r\n", path_basedir.c_str (), module.name.c_str ());
+       fprintf ( OUT, "\t\t\t\tOutput=\"\"\r\n");
+       fprintf ( OUT, "\t\t\t\tPreprocessorDefinitions=\"\"\r\n");
+       fprintf ( OUT, "\t\t\t\tIncludeSearchPath=\"\"\r\n");
+       fprintf ( OUT, "\t\t\t\tForcedIncludes=\"\"\r\n");
+       fprintf ( OUT, "\t\t\t\tAssemblySearchPath=\"\"\r\n");
+       fprintf ( OUT, "\t\t\t\tForcedUsingAssemblies=\"\"\r\n");
+       fprintf ( OUT, "\t\t\t\tCompileAsManaged=\"\"\r\n");
  
-       fprintf ( OUT, "\t</Files>\r\n" );
-       fprintf ( OUT, "\t<Globals>\r\n" );
-       fprintf ( OUT, "\t</Globals>\r\n" );
-       fprintf ( OUT, "</VisualStudioProject>\r\n" );
-       fclose ( OUT );
-       /* User configuration file */
-       if (vcproj_file_user != "")
-       {
-               OUT = fopen ( vcproj_file_user.c_str(), "wb" );
-               fprintf ( OUT, "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\r\n" );
-               fprintf ( OUT, "<VisualStudioUserFile\r\n" );
-               fprintf ( OUT, "\tProjectType=\"Visual C++\"\r\n" );
-               fprintf ( OUT, "\tVersion=\"%s\"\r\n", configuration.VSProjectVersion.c_str() );
-               fprintf ( OUT, "\tShowAllFiles=\"false\"\r\n" );
-               fprintf ( OUT, "\t>\r\n" );
-               fprintf ( OUT, "\t<Configurations>\r\n" );
-               for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ )
-               {
-                       const MSVCConfiguration& cfg = *m_configurations[icfg];
-                       fprintf ( OUT, "\t\t<Configuration\r\n" );
-                       fprintf ( OUT, "\t\t\tName=\"%s|Win32\"\r\n", cfg.name.c_str() );
-                       fprintf ( OUT, "\t\t\t>\r\n" );
-                       fprintf ( OUT, "\t\t\t<DebugSettings\r\n" );
-                       if ( module_type == ".cpl" )
-                       {
-                               fprintf ( OUT, "\t\t\t\tCommand=\"rundll32.exe\"\r\n" );
-                               fprintf ( OUT, "\t\t\t\tCommandArguments=\" shell32,Control_RunDLL &quot;$(TargetPath)&quot;,@\"\r\n" );
-                       }
-                       else
-                       {
-                               fprintf ( OUT, "\t\t\t\tCommand=\"$(TargetPath)\"\r\n" );
-                               fprintf ( OUT, "\t\t\t\tCommandArguments=\"\"\r\n" );
-                       }
-                       fprintf ( OUT, "\t\t\t\tAttach=\"false\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tDebuggerType=\"3\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tRemote=\"1\"\r\n" );
-                       string remote_machine = "\t\t\t\tRemoteMachine=\"" + computername + "\"\r\n";
-                       fprintf ( OUT, remote_machine.c_str() );
-                       fprintf ( OUT, "\t\t\t\tRemoteCommand=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tHttpUrl=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tPDBPath=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tSQLDebugging=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tEnvironment=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tEnvironmentMerge=\"true\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tDebuggerFlavor=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tMPIRunCommand=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tMPIRunArguments=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tMPIRunWorkingDirectory=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tApplicationCommand=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tApplicationArguments=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tShimCommand=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tMPIAcceptMode=\"\"\r\n" );
-                       fprintf ( OUT, "\t\t\t\tMPIAcceptFilter=\"\"\r\n" );
 -      fprintf ( OUT, "\t\t\t/>\r\n" );
 -      fprintf ( OUT, "\t\t</Configuration>\r\n" );
 -}
 +                      fprintf ( OUT, "\t\t\t/>\r\n" );
 +                      fprintf ( OUT, "\t\t</Configuration>\r\n" );
 +              }
-               fprintf ( OUT, "\t</Configurations>\r\n" );
-               fprintf ( OUT, "</VisualStudioUserFile>\r\n" );
-               fclose ( OUT );
-       }
  
- }
  
  std::string
  MSVCBackend::_strip_gcc_deffile(std::string Filename, std::string sourcedir, std::string objdir)
@@@ -79,22 -82,36 +82,36 @@@ struct cache_struc
  
  struct summ_struct
  {
 -    int translated;
 -    int undo;
 -    int redo;
 -    int skipped;
 -    int diff;
 +    int     translated;
 +    int     undo;
 +    int     redo;
 +    int     skipped;
 +    int     diff;
+     int majordiff;
 -    int offset_errors;
 -    int total;
 +    int     offset_errors;
 +    int     total;
  };
  
+ struct lineinfo_struct
+ {
+     int     valid; 
+     char    file1[LINESIZE];
+     char    func1[NAMESIZE];
+     int     nr1;
+     char    file2[LINESIZE];
+     char    func2[NAMESIZE];
+     int     nr2;
+ };
  typedef struct cache_struct CACHE;
 -typedef struct summ_struct SUMM;
 +typedef struct summ_struct  SUMM;
+ typedef struct lineinfo_struct LINEINFO;
  
 -static CACHE cache;
 -static SUMM summ;
 +static CACHE    cache;
 +static SUMM     summ;
+ static LINEINFO lastLine;
  
- static char *optchars  = "bcd:fFhl:mMrstTuUvz:";
+ static char *optchars  = "bcd:fFhl:mMrsS:tTuUvz:";
  static int opt_buffered= 0;         // -b
  static int opt_help    = 0;         // -h
  static int opt_force   = 0;         // -f
@@@ -152,11 -227,11 +227,11 @@@ find_rossym_section(PIMAGE_FILE_HEADER 
  }
  
  static PROSSYM_ENTRY
- find_offset(void *data, size_t offset, char *toString)
+ find_offset(void *data, size_t offset)
  {
 -    PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
 -    PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char *)data + RosSymHeader->SymbolsOffset);
 -    size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
 +    PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER) data;
 +    PROSSYM_ENTRY Entries = (PROSSYM_ENTRY) ((char *)data + RosSymHeader->SymbolsOffset);
 +    size_t symbols = RosSymHeader->SymbolsLength / sizeof (ROSSYM_ENTRY);
      size_t i;
  
      for (i = 0; i < symbols; i++)
  static int
  print_offset(void *data, size_t offset, char *toString)
  {
 -    PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
 +    PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER) data;
      PROSSYM_ENTRY e = NULL;
      PROSSYM_ENTRY e2 = NULL;
+     int bFileOffsetChanged = 0;
+     char fmt[LINESIZE];
      char *Strings = (char *)data + RosSymHeader->StringsOffset;
  
-     
-     e = find_offset(data, offset, toString);
+     fmt[0] = '\0';
+     e = find_offset(data, offset);
      if (opt_twice)
      {
-         e2 = find_offset(data, offset-1, toString);
+         e2 = find_offset(data, offset - 1);
 -
 -        if (e == e2)
 +        
 +        if (  e == e2 )
              e2 = NULL;
+         else
+             summ.diff++;
  
 -        if (opt_Twice && e2)
 +        if ( opt_Twice &&  e2 )
          {
              e = e2;
              e2 = NULL;
-             /* replaced (transparantly), but update stats: */
-             summ.diff ++;
+             /* replaced (transparantly), but updated stats */
          }
      }
 -    if (e || e2)
 +    if ( e || e2 )
      {
 -            if (toString)
 -            {   // put in toString if provided
+         strcpy(lastLine.file1, &Strings[e->FileOffset]);
+         strcpy(lastLine.func1, &Strings[e->FunctionOffset]);
+         lastLine.nr1 = e->SourceLine;
+         lastLine.valid = 1;
+         if (e2)
+         {
+             strcpy(lastLine.file2, &Strings[e2->FileOffset]);
+             strcpy(lastLine.func2, &Strings[e2->FunctionOffset]);
+             lastLine.nr2 = e2->SourceLine;
+             bFileOffsetChanged = e->FileOffset != e2->FileOffset;
+             if (e->FileOffset != e2->FileOffset || e->FunctionOffset != e2->FunctionOffset)
+                 summ.majordiff++;
+             /*
+             * - "%.0s" displays nothing, but processes argument
+             * - bFileOffsetChanged implies always display 2nd SourceLine even if the same
+             * - also for FunctionOffset
+             */
+             strcat(fmt, "%s");
+             if (bFileOffsetChanged)
+                 strcat(fmt, "[%s]");
+             else
+                 strcat(fmt, "%.0s");
+             strcat(fmt, ":%u");
+             if (e->SourceLine != e2->SourceLine || bFileOffsetChanged)
+                 strcat(fmt, "[%u]");
+             else
+                 strcat(fmt, "%.0u");
+             strcat(fmt, " (%s");
+             if (e->FunctionOffset != e2->FunctionOffset || bFileOffsetChanged)
+                 strcat(fmt, "[%s])");
+             else
+                 strcat(fmt, "%.0s)");
-             if ( e2 )
-             {
-                 snprintf(toString, LINESIZE, "%s:%u (%s) [%s:%u (%s)]",
 +        if (toString)
 +        {  // put in toString if provided
 -                    &Strings[e->FileOffset],
+                 snprintf(toString, LINESIZE, fmt,
 -                    (unsigned int)e->SourceLine,
 +                         &Strings[e->FileOffset],
+                     &Strings[e2->FileOffset],
 -                    &Strings[e->FunctionOffset],
 -                    &Strings[e2->FunctionOffset]);
 +                         (unsigned int)e->SourceLine,
+                     (unsigned int)e2->SourceLine,
-                          &Strings[e2->FileOffset],
-                          (unsigned int)e2->SourceLine,
 +                         &Strings[e->FunctionOffset],
-                 summ.diff ++;
 +                         &Strings[e2->FunctionOffset]);
              }
              else
              {
-                 snprintf(toString, LINESIZE, "%s:%u (%s)",
+                 strcat(fmt, "\n");
+                 printf(fmt,
 -                    &Strings[e->FileOffset],
 +                         &Strings[e->FileOffset],
+                     &Strings[e2->FileOffset],
 -                    (unsigned int)e->SourceLine,
 +                         (unsigned int)e->SourceLine,
-                          &Strings[e->FunctionOffset]);
+                     (unsigned int)e2->SourceLine,
+                     &Strings[e->FunctionOffset],
+                     &Strings[e2->FunctionOffset]);
              }
-             return 0;
          }
          else
-         {  // to stdout
-             if ( e2 )
 -        {
 +            {
-                 printf("%s:%u (%s) [%s:%u (%s)]\n",
+             if (toString)
+             {   // put in toString if provided
+                 snprintf(toString, LINESIZE, "%s:%u (%s)",
 -                    &Strings[e->FileOffset],
 -                    (unsigned int)e->SourceLine,
 +                       &Strings[e->FileOffset],
 +                       (unsigned int)e->SourceLine,
-                        &Strings[e->FunctionOffset],
-                        &Strings[e2->FileOffset],
-                        (unsigned int)e2->SourceLine,
-                        &Strings[e2->FunctionOffset]);
-                 summ.diff ++;
+                     &Strings[e->FunctionOffset]);
              }
              else
              {
                  printf("%s:%u (%s)\n",
 -                    &Strings[e->FileOffset],
 -                    (unsigned int)e->SourceLine,
 -                    &Strings[e->FunctionOffset]);
 +                        &Strings[e->FileOffset],
 +                       (unsigned int)e->SourceLine,
 +                       &Strings[e->FunctionOffset]);
              }
 -        return 0;
 -    }
+         }
-     }
 +            return 0;
 +        }
      return 1;
  }
  
@@@ -799,25 -934,21 +934,21 @@@ translate_line(FILE *outFile, char *Lin
              if (cnt == 3 && ch == ' ')
              {
                  tail = strchr(s, '>');
 -                tail = tail ? tail - 1 : tail;
 +                tail = tail ? tail-1 : tail;
-                 if (tail && (tail[0] == ')') && (tail[1] == '>') )
+                 if (tail && tail[0] == ')' && tail[1] == '>')
                  {
                      res = 0;
                      tail += 2;
                      mark = opt_mark ? "* " : "";
                      if (opt_redo && !(res = translate_file(path, offset, LineOut)))
                      {
-                         fprintf(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
-                         if (logFile)
-                             fprintf(logFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
+                         log(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
 -                        summ.redo++;
 +                        summ.redo ++;
                      }
                      else
                      {
-                         fprintf(outFile, "%s<%s:%x>%s", mark, path, offset, tail);
-                         if (logFile)
-                             fprintf(logFile, "%s<%s:%x>%s", mark, path, offset, tail);
+                         log(outFile, "%s<%s:%x>%s", mark, path, offset, tail);
 -                        summ.undo++;
 +                        summ.undo ++;
                      }
                  }
                  else
                  if (!(res = translate_file(path, offset, LineOut)))
                  {
                      mark = opt_mark ? "* " : "";
-                     fprintf(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
-                     if (logFile)
-                         fprintf(logFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
+                     log(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail);
 -                    summ.translated++;
 +                    summ.translated ++;
                  }
                  else
                  {
@@@ -868,17 -995,18 +995,18 @@@ print_summary(FILE * outFile
      if (outFile)
      {
          fprintf(outFile, "\n*** LOG2LINES SUMMARY ***\n");
 -        fprintf(outFile, "Translated:               %d\n", summ.translated);
 -        fprintf(outFile, "Reverted:                 %d\n", summ.undo);
 -        fprintf(outFile, "Retranslated:             %d\n", summ.redo);
 -        fprintf(outFile, "Skipped:                  %d\n", summ.skipped);
 -        fprintf(outFile, "Differ:                   %d\n", summ.diff);
 +        fprintf(outFile, "Translated:   %d\n", summ.translated);
 +        fprintf(outFile, "Reverted:     %d\n", summ.undo);
 +        fprintf(outFile, "Retranslated: %d\n", summ.redo);
 +        fprintf(outFile, "Skipped:      %d\n", summ.skipped);
 +        fprintf(outFile, "Differ:       %d\n", summ.diff);
+         fprintf(outFile, "Differ (function/source): %d\n", summ.majordiff);
 -        fprintf(outFile, "Offset error:             %d\n", summ.offset_errors);
 -        fprintf(outFile, "Total:                    %d\n", summ.total);
 +        fprintf(outFile, "Offset error: %d\n", summ.offset_errors);
 +        fprintf(outFile, "Total:        %d\n", summ.total);
          fprintf(outFile, "-------------------------------\n");
          fprintf(outFile, "Log2lines version: " LOG2LINES_VERSION "\n");
 -        fprintf(outFile, "Directory:         %s\n", opt_dir);
 -        fprintf(outFile, "Passed options:    %s\n", opt_scanned);
 +        fprintf(outFile, "Directory:         %s\n",opt_dir);
 +        fprintf(outFile, "Passed options:    %s\n",opt_scanned);
          fprintf(outFile, "-------------------------------\n");
      }
  }
@@@ -993,9 -1120,12 +1120,12 @@@ translate_files(FILE * inFile, FILE * o
  static char *verboseUsage =
  "\n"
  "Description:\n"
- "  When <exefile> <offset> are given, log2lines works just like raddr2line\n"
+ "  When <exefile> <offset> are given, log2lines works like raddr2line:\n"
+ "      - The <exefile> <offset> combination can be repeated\n"
+ "      - Also, <offset> can be repeated for each <exefile>\n"
+ "      - NOTE: some of the options below will have no effect in this form.\n"
  "  Otherwise it reads stdin and tries to translate lines of the form:\n"
 -"      <IMAGENAME:ADDRESS>\n\n"
 +"  <IMAGENAME:ADDRESS>\n\n"
  "  The result is written to stdout.\n"
  "  log2lines uses a cache in order to avoid a directory scan at each\n"
  "  image lookup, greatly increasing performance. Only image path and its\n"
  "  -r   Raw output without translation.\n\n"
  "  -s   Statistics. A summary with the following info is printed after EOF:\n"
  "       *** LOG2LINES SUMMARY ***\n"
 -"       - Translated:      Translated lines.\n"
 -"       - Reverted:        Lines translated back. See -u option\n"
 -"       - Retranslated:    Lines retranslated. See -U option\n"
 -"       - Skipped:         Lines not translated.\n"
 -"       - Differ:          Lines where (addr-1) info differs. See -tT options\n"
 +"       - Translated:   Translated lines.\n"
 +"       - Reverted:     Lines translated back. See -u option\n"
 +"       - Retranslated: Lines retranslated. See -U option\n"
 +"       - Skipped:      Lines not translated.\n"
 +"       - Differ:       Lines where (addr-1) info differs. See -tT options\n"
+ "       - Differ(func/src):Lines where also function or source info differ.\n"
 -"       - Offset error:    Image exists, but error retrieving offset info.\n"
 -"       - Total:           Total number of lines attempted to translate.\n"
 +"       - Offset error: Image exists, but error retrieving offset info.\n"
 +"       - Total:        Total number of lines attempted to translate.\n"
  "       Also some version info is displayed.\n\n"
- "  -t   Translate twice. The address itself and for (address - 1)\n"
- "       Display extra filename and linenumber between [..] if they differ\n\n"
- "  -T   As -t, but the original filename+linenumber gets replaced\n\n"
+ "  -S <context>\n"
+ "       Source lines. Display up to <context> lines until linenumber.\n"
+ "       The environment variable _ROSBE_ROSSOURCEDIR should be correctly set.\n"
+ "       For a reliable result, these sources should be up to date with\n"
+ "       the revision you test.\n"
+ "       Can be combined with -tT.\n"
+ "       Implies -U. Retranslation needed for retrieving source info.\n\n"
+ "  -t   Translate twice. The address itself and for (address - 1).\n"
+ "       Show extra filename, func and linenumber between [..] if they differ\n"
+ "       So if only the linenumbers differ, then only show the extra\n"
+ "       linenumber.\n\n"
+ "  -T   As -t, but show only filename+func+linenumber for (address - 1.)\n\n"
  "  -u   Undo translations.\n"
  "       Lines are translated back (reverted) to the form <IMAGENAME:ADDRESS>\n"
- "       Overrides console mode -c.\n\n"
+ "       Also removes all lines previously added by this tool (see -S)\n\n"
  "  -U   Undo and reprocess.\n"
  "       Reverted to the form <IMAGENAME:ADDRESS>, and then retranslated\n"
- "       Overrides console mode -c, implies -u.\n\n"
+ "       Implies -u.\n\n"
  "  -v   Show detailed errors and tracing.\n"
  "       Repeating this option adds more verbosity.\n"
- "       Default: only (major) errors\n" "\n\n"
+ "       Default: only (major) errors\n\n"
  "  -z <path to 7z>\n"
  "       Specify path to 7z. See also option -d.\n"
  "       Default: '7z'\n"
@@@ -1185,9 -1384,17 +1384,17 @@@ main(int argc, const char **argv
      int opt;
      int optCount = 0;
      int i;
+     char *s;
+     strcpy(sources_path, "");
+     if ((s = getenv(SOURCES_ENV)))
+     {
+         strcpy(sources_path, s);
+         strcat(sources_path, PATH_STR);
+     }
  
      strcpy(opt_scanned, "");
 -    for (i = 1; i < argc; i++)
 +    for (i=1; i<argc; i++)
      {
          strcat(opt_scanned, argv[i]);
          strcat(opt_scanned, " ");
          else
          {
              fprintf(stderr, "Could not open logfile %s (%s)\n", opt_logFile, strerror(errno));
-             exit(2);
+             return 2;
+         }
+     }
  
 -                }
+     if (argc > 1)
+     {   // translate {<exefile> <offset>}
+         int i = 1;
+         const char *base = NULL;
+         const char *offset = NULL;
+         while (i < argc)
+         {
+             offset = argv[optCount + i++];
+             if (isOffset(offset))
+             {
+                 if (base)
+                 {
+                     if (opt_verbose > 1)
+                         fprintf(stderr, "translating %s %s\n", base, offset);
+                     translate_file(base, my_atoi(offset), NULL);
+                     reportSource(stdout);
 -                }
 -            }
 -            else
 +        }
+                 else
+                 {
+                     fprintf(stderr, "<exefile> expected\n");
+                     res = 3;
+                     break;
-     if (argc == 3)
-     {  // translate <exefile> <offset>
-         translate_file(argv[optCount + 1], my_atoi(argv[optCount + 2]), NULL);
 +    }
++    }
++    else
+             {
+                 // Must be exefile
+                 base = offset;
+             }
+         }
      }
      else
 -    {   // translate logging from stdin
 +    {  // translate logging from stdin
          translate_files(stdin, stdout);
      }
  
@@@ -307,16 -311,39 +311,39 @@@ void write_type_right(FILE *h, type_t *
  {
    if (!h) return;
  
-   if (type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t)) {
-     if (is_conformant_array(t)) {
+   switch (type_get_type(t))
+   {
+   case TYPE_ARRAY:
+     if (!type_array_is_decl_as_ptr(t))
+     {
+       if (is_conformant_array(t))
+       {
 -        fprintf(h, "[%s]", is_field ? "1" : "");
 -        t = type_array_get_element(t);
 -      }
 -      for ( ;
 -           type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t);
 -           t = type_array_get_element(t))
 -        fprintf(h, "[%u]", type_array_get_dim(t));
 +      fprintf(h, "[%s]", is_field ? "1" : "");
 +      t = type_array_get_element(t);
      }
 -  }
 +    for ( ;
 +         type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t);
 +         t = type_array_get_element(t))
 +      fprintf(h, "[%u]", type_array_get_dim(t));
 +  }
+     break;
+   case TYPE_BITFIELD:
+     fprintf(h, " : %lu", type_bitfield_get_bits(t)->cval);
+     break;
+   case TYPE_VOID:
+   case TYPE_BASIC:
+   case TYPE_ENUM:
+   case TYPE_STRUCT:
+   case TYPE_ENCAPSULATED_UNION:
+   case TYPE_UNION:
+   case TYPE_ALIAS:
+   case TYPE_MODULE:
+   case TYPE_COCLASS:
+   case TYPE_FUNCTION:
+   case TYPE_INTERFACE:
+   case TYPE_POINTER:
+     break;
++}
  }
  
  static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const char *name)
  
    if (!h) return;
  
 -    for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++)
 -      ;
 -
 -    if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
 -      int i;
 -      const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
 -      if (!callconv) callconv = "";
 -      if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
 -      write_type_left(h, type_function_get_rettype(pt), declonly);
 -      fputc(' ', h);
 -      if (ptr_level) fputc('(', h);
 -      fprintf(h, "%s ", callconv);
 -      for (i = 0; i < ptr_level; i++)
 -        fputc('*', h);
 -    } else
 -      write_type_left(h, t, declonly);
+   if (t) {
 +  for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++)
 +    ;
 +
 +  if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
 +    int i;
 +    const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
 +    if (!callconv) callconv = "";
 +    if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
 +    write_type_left(h, type_function_get_rettype(pt), declonly);
 +    fputc(' ', h);
 +    if (ptr_level) fputc('(', h);
 +    fprintf(h, "%s ", callconv);
 +    for (i = 0; i < ptr_level; i++)
 +      fputc('*', h);
 +  } else
 +    write_type_left(h, t, declonly);
+   }
  
-   if (name) fprintf(h, "%s%s", needs_space_after(t) ? " " : "", name );
+   if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
  
 -    if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
 -      const var_list_t *args = type_function_get_args(pt);
 -
 -      if (ptr_level) fputc(')', h);
 -      fputc('(', h);
 -      if (args)
 -          write_args(h, args, NULL, 0, FALSE);
 -      else
 -          fprintf(h, "void");
 -      fputc(')', h);
 -    } else
 -      write_type_right(h, t, is_field);
 -  }
+   if (t) {
 +  if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
 +    const var_list_t *args = type_function_get_args(pt);
 +
 +    if (ptr_level) fputc(')', h);
 +    fputc('(', h);
 +    if (args)
 +        write_args(h, args, NULL, 0, FALSE);
 +    else
 +        fprintf(h, "void");
 +    fputc(')', h);
 +  } else
 +    write_type_right(h, t, is_field);
 +}
+ }
  
  void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name)
  {
@@@ -5174,11 -5540,12 +5540,12 @@@ static type_t *append_ptrchain_type(typ
    return ptrchain;
  }
  
- static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
+ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
 -                       int top)
 +                     int top)
  {
-   expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
-   expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS);
+   var_t *v = decl->var;
+   expr_list_t *sizes = get_attrp(attrs, ATTR_SIZEIS);
+   expr_list_t *lengs = get_attrp(attrs, ATTR_LENGTHIS);
    int sizeless;
    expr_t *dim;
    type_t **ptype;
         error_loc("%s: pointer attribute applied to non-pointer type\n", v->name);
    }
  
-   if (is_attr(v->attrs, ATTR_STRING) && !is_ptr(v->type) && !arr)
+   if (is_attr(v->attrs, ATTR_STRING))
+   {
+     type_t *t = type;
+     if (!is_ptr(v->type) && !arr)
 -      error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
 -                v->name);
 +    error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
 +              v->name);
  
+     while (is_ptr(t))
+       t = type_pointer_get_ref(t);
+     if (type_get_type(t) != TYPE_BASIC &&
+         (get_basic_fc(t) != RPC_FC_CHAR &&
+          get_basic_fc(t) != RPC_FC_BYTE &&
+          get_basic_fc(t) != RPC_FC_WCHAR))
+     {
+       error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n",
+                 v->name);
+     }
+   }
    if (is_attr(v->attrs, ATTR_V1ENUM))
    {
      if (type_get_type_detect_alias(v->type) != TYPE_ENUM)
@@@ -6306,6 -6703,16 +6703,16 @@@ static void check_remoting_args(const v
  
          check_field_common(func->type, funcname, arg);
      }
 -    }
+     if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID)
+     {
+         var_t var;
+         var = *func;
+         var.type = type_function_get_rettype(func->type);
+         var.name = xstrdup("return value");
+         check_field_common(func->type, funcname, &var);
+         free(var.name);
++}
  }
  
  static void add_explicit_handle_if_necessary(var_t *func)
@@@ -1249,11 -1375,12 +1375,12 @@@ static type_t *append_ptrchain_type(typ
    return ptrchain;
  }
  
- static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
+ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
 -                       int top)
 +                     int top)
  {
-   expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
-   expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS);
+   var_t *v = decl->var;
+   expr_list_t *sizes = get_attrp(attrs, ATTR_SIZEIS);
+   expr_list_t *lengs = get_attrp(attrs, ATTR_LENGTHIS);
    int sizeless;
    expr_t *dim;
    type_t **ptype;
         error_loc("%s: pointer attribute applied to non-pointer type\n", v->name);
    }
  
-   if (is_attr(v->attrs, ATTR_STRING) && !is_ptr(v->type) && !arr)
+   if (is_attr(v->attrs, ATTR_STRING))
+   {
+     type_t *t = type;
+     if (!is_ptr(v->type) && !arr)
 -      error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
 -                v->name);
 +    error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
 +              v->name);
  
+     while (is_ptr(t))
+       t = type_pointer_get_ref(t);
+     if (type_get_type(t) != TYPE_BASIC &&
+         (get_basic_fc(t) != RPC_FC_CHAR &&
+          get_basic_fc(t) != RPC_FC_BYTE &&
+          get_basic_fc(t) != RPC_FC_WCHAR))
+     {
+       error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n",
+                 v->name);
+     }
+   }
    if (is_attr(v->attrs, ATTR_V1ENUM))
    {
      if (type_get_type_detect_alias(v->type) != TYPE_ENUM)
@@@ -2381,6 -2538,16 +2538,16 @@@ static void check_remoting_args(const v
  
          check_field_common(func->type, funcname, arg);
      }
 -    }
+     if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID)
+     {
+         var_t var;
+         var = *func;
+         var.type = type_function_get_rettype(func->type);
+         var.name = xstrdup("return value");
+         check_field_common(func->type, funcname, &var);
+         free(var.name);
++}
  }
  
  static void add_explicit_handle_if_necessary(var_t *func)
@@@ -3197,22 -3228,31 +3228,31 @@@ void print_phase_basetype(FILE *file, i
      if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL)
          return;
  
-     ref = is_ptr(type) ? type_pointer_get_ref(type) : type;
-     if (type_get_type(ref) == TYPE_ENUM)
+     if (type_get_type(type) == TYPE_ENUM ||
+         (type_get_type(type) == TYPE_BASIC &&
+          type_basic_get_type(type) == TYPE_BASIC_INT3264 &&
+          pointer_size != 4))
      {
-         if (get_enum_fc(ref) == RPC_FC_ENUM32)
-         {
-             size = 4;
-             alignment = 4;
-         }
-         else /* RPC_FC_ENUM16 */
-         {
-             size = 2;
-             alignment = 2;
+         unsigned char fc;
+         if (type_get_type(type) == TYPE_ENUM)
+             fc = get_enum_fc(type);
+         else
+             fc = get_basic_fc(type);
+         if (phase == PHASE_MARSHAL)
+             print_file(file, indent, "NdrSimpleTypeMarshall(\n");
+         else
+             print_file(file, indent, "NdrSimpleTypeUnmarshall(\n");
+         print_file(file, indent+1, "&__frame->_StubMsg,\n");
+         print_file(file, indent+1, "(unsigned char *)&%s%s,\n",
+                    local_var_prefix,
+                    var->name);
+         print_file(file, indent+1, "0x%02x /* %s */);\n", fc, string_of_type(fc));
 -    }
 +        }
-     }
      else
      {
+         const type_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : type;
          switch (get_basic_fc(ref))
          {
          case RPC_FC_BYTE:
                    var->name, get_basic_fc(ref));
              size = 0;
          }
-     }
  
 -        if (phase == PHASE_MARSHAL)
 -            print_file(file, indent, "MIDL_memset(__frame->_StubMsg.Buffer, 0, (0x%x - (ULONG_PTR)__frame->_StubMsg.Buffer) & 0x%x);\n", alignment, alignment - 1);
 -        print_file(file, indent, "__frame->_StubMsg.Buffer = (unsigned char *)(((ULONG_PTR)__frame->_StubMsg.Buffer + %u) & ~0x%x);\n",
 -                    alignment - 1, alignment - 1);
 -
 -        if (phase == PHASE_MARSHAL)
 -        {
 -            print_file(file, indent, "*(");
 -            write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
 -            if (is_ptr(type))
 -                fprintf(file, " *)__frame->_StubMsg.Buffer = *");
 -            else
 -                fprintf(file, " *)__frame->_StubMsg.Buffer = ");
 -            fprintf(file, "%s%s", local_var_prefix, varname);
 -            fprintf(file, ";\n");
 -        }
 -        else if (phase == PHASE_UNMARSHAL)
 -        {
 -            print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof(");
 -            write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
 -            fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n");
 -            print_file(file, indent, "{\n");
 -            print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
 -            print_file(file, indent, "}\n");
 -            print_file(file, indent, "%s%s%s",
 -                       (pass == PASS_IN || pass == PASS_RETURN) ? "" : "*",
 -                       local_var_prefix, varname);
 -            if (pass == PASS_IN && is_ptr(type))
 -                fprintf(file, " = (");
 -            else
 -                fprintf(file, " = *(");
 -            write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
 -            fprintf(file, " *)__frame->_StubMsg.Buffer;\n");
 -        }
 +    if (phase == PHASE_MARSHAL)
 +        print_file(file, indent, "MIDL_memset(__frame->_StubMsg.Buffer, 0, (0x%x - (ULONG_PTR)__frame->_StubMsg.Buffer) & 0x%x);\n", alignment, alignment - 1);
 +    print_file(file, indent, "__frame->_StubMsg.Buffer = (unsigned char *)(((ULONG_PTR)__frame->_StubMsg.Buffer + %u) & ~0x%x);\n",
 +                alignment - 1, alignment - 1);
  
 -        print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof(");
 +    if (phase == PHASE_MARSHAL)
 +    {
 +        print_file(file, indent, "*(");
          write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
 -        fprintf(file, ");\n");
 +        if (is_ptr(type))
 +            fprintf(file, " *)__frame->_StubMsg.Buffer = *");
 +        else
 +            fprintf(file, " *)__frame->_StubMsg.Buffer = ");
 +        fprintf(file, "%s%s", local_var_prefix, varname);
 +        fprintf(file, ";\n");
      }
 +    else if (phase == PHASE_UNMARSHAL)
 +    {
 +        print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof(");
 +        write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
 +        fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n");
 +        print_file(file, indent, "{\n");
 +        print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
 +        print_file(file, indent, "}\n");
 +        print_file(file, indent, "%s%s%s",
 +                   (pass == PASS_IN || pass == PASS_RETURN) ? "" : "*",
 +                   local_var_prefix, varname);
 +        if (pass == PASS_IN && is_ptr(type))
 +            fprintf(file, " = (");
 +        else
 +            fprintf(file, " = *(");
 +        write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
 +        fprintf(file, " *)__frame->_StubMsg.Buffer;\n");
 +    }
 +
 +    print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof(");
 +    write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
 +    fprintf(file, ");\n");
 +}
+ }
  
  /* returns whether the MaxCount, Offset or ActualCount members need to be
   * filled in for the specified phase */
@@@ -3546,21 -3589,33 +3589,33 @@@ static void write_remoting_arg(FILE *fi
          break;
      }
      case TGT_BASIC:
-         if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
 -        print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
 +            print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
          break;
      case TGT_ENUM:
-         if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
-         {
-             if (phase == PHASE_MARSHAL)
-                 print_file(file, indent, "NdrSimpleTypeMarshall(\n");
-             else
-                 print_file(file, indent, "NdrSimpleTypeUnmarshall(\n");
-             print_file(file, indent+1, "&__frame->_StubMsg,\n");
-             print_file(file, indent+1, "(unsigned char *)&%s%s,\n",
-                        local_var_prefix,
-                        var->name);
-             print_file(file, indent+1, "0x%02x /* %s */);\n", get_enum_fc(type), string_of_type(get_enum_fc(type)));
+         print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
+         break;
+     case TGT_RANGE:
+         print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
+         /* Note: this goes beyond what MIDL does - it only supports arguments
+          * with the [range] attribute in Oicf mode */
+         if (phase == PHASE_UNMARSHAL)
+         {
+             const expr_t *range_min;
+             const expr_t *range_max;
+             expr_list_t *range_list = get_attrp(var->attrs, ATTR_RANGE);
+             if (!range_list)
+                 range_list = get_aliaschain_attrp(type, ATTR_RANGE);
+             range_min = LIST_ENTRY(list_head(range_list), const expr_t, entry);
+             range_max = LIST_ENTRY(list_next(range_list, list_head(range_list)), const expr_t, entry);
+             print_file(file, indent, "if ((%s%s < (", local_var_prefix, var->name);
+             write_type_decl(file, var->type, NULL);
+             fprintf(file, ")0x%lx) || (%s%s > (", range_min->cval, local_var_prefix, var->name);
+             write_type_decl(file, var->type, NULL);
+             fprintf(file, ")0x%lx))\n", range_max->cval);
+             print_file(file, indent, "{\n");
+             print_file(file, indent+1, "RpcRaiseException(RPC_S_INVALID_BOUND);\n");
+             print_file(file, indent, "}\n");
          }
          break;
      case TGT_STRUCT:
      case TGT_POINTER:
      {
          const type_t *ref = type_pointer_get_ref(type);
-         if (pointer_type == RPC_FC_RP && !is_user_type(ref)) switch (type_get_type(ref))
+         if (pointer_type == RPC_FC_RP) switch (typegen_detect_type(ref, NULL, TDT_ALL_TYPES))
          {
-         case TYPE_BASIC:
-             /* base types have known sizes, so don't need a sizing pass
-              * and don't have any memory to free and so don't need a
-              * freeing pass */
-             if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
+         case TGT_BASIC:
 -            print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
 +                print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
              break;
-         case TYPE_ENUM:
+         case TGT_ENUM:
              /* base types have known sizes, so don't need a sizing pass
               * and don't have any memory to free and so don't need a
               * freeing pass */