Browse Source

Merge branch 'winsxs' into main. Redid XpTheme.res during merge.

Martijn Laan 2 years ago
parent
commit
686367e67b
5 changed files with 113 additions and 7 deletions
  1. 69 5
      .github/workflows/build.yml
  2. 40 2
      Projects/CompExeUpdate.pas
  3. 3 0
      Projects/Compile.pas
  4. 1 0
      Projects/XPTheme.manifest
  5. BIN
      Projects/XPTheme.res

+ 69 - 5
.github/workflows/build.yml

@@ -12,7 +12,7 @@ jobs:
     if: contains(github.event.repository.topics, 'has-issrc-build-env')
     runs-on: windows-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
         with:
           submodules: true
       - name: initialize build environment
@@ -66,22 +66,86 @@ jobs:
           copy license.txt Projects/ISPP/Help/Staging
           copy license.txt ISHelp/Staging
       - name: upload Files
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: Files
           path: Files
       - name: upload installer
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: Output
           path: Output
       - name: upload ISPP/Help
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: Help
           path: Projects/ISPP/Help/Staging
       - name: upload ISHelp
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: ISHelp
           path: ISHelp/Staging
+      - name: find mt.exe
+        shell: bash
+        run: |
+          set -x &&
+          mt=$(ls -t /c/Program\ Files*/Windows\ Kits/10/bin/*/x64/mt.exe) &&
+          test -n "$mt" &&
+          echo "${mt%%/mt.exe*}" >>$GITHUB_PATH
+      - name: verify MinVersion=6.0 (to support Vista)
+        shell: bash
+        run: |
+          set -x &&
+          sed '/^\[Setup\]/a\
+          MinVersion=6.0\
+          OutputBaseFilename=mysetup-vista
+          ' <setup.iss >setup-vista.iss &&
+          files/ISCC.exe setup-vista.iss &&
+          mt '-inputresource:Output\mysetup-vista.exe' -out:mysetup-vista.manifest &&
+          cat mysetup-vista.manifest
+      - name: verify installer
+        shell: bash
+        run: |
+          set -x &&
+          ver="$(sed -n 's/^set VER=//p' <build.bat)" &&
+          mt '-inputresource:Output\innosetup-'$ver.exe -out:innosetup-$ver.manifest &&
+          cat innosetup-$ver.manifest &&
+          mkdir -p Output/innosetup-$ver.exe.Local &&
+          cp -R "$(cygpath -au "$SYSTEMROOT")"/WinSxS/x86_microsoft.windows.common-controls_* Output/innosetup-$ver.exe.Local/ &&
+          mkdir Output/innosetup-$ver.en-US &&
+          mkdir Output/innosetup-$ver.en &&
+          mkdir Output/innosetup-$ver.ENU &&
+          mkdir -p trace &&
+          echo "$ver" >trace/ver &&
+          curl -LO https://download.sysinternals.com/files/ProcessMonitor.zip &&
+          unzip ProcessMonitor.zip &&
+          # Need to start the background process via PowerShell because it would
+          # block for some reason if started as a Bash background process.
+          powershell -command 'start-process -NoNewWindow -FilePath .\Procmon.exe -ArgumentList "-AcceptEula -Quiet -BackingFile trace/procmon.pml -RunTime 60"' &&
+          test $? = 0 &&
+          ps -W &&
+          ./Procmon.exe -AcceptEula -WaitForIdle &&
+          ./Output/innosetup-$ver.exe //verysilent //dir=InnoSetup //noicons \
+            //tasks= //portable=1 &&
+          test -x InnoSetup/ISCC.exe &&
+          ./Procmon.exe -Terminate -Quiet &&
+          powershell -command 'start-process -NoNewWindow -Wait -FilePath .\Procmon.exe -ArgumentList "-OpenLog trace\procmon.pml -SaveAs trace\procmon.csv"'
+      - name: upload trace
+        uses: actions/upload-artifact@v3
+        with:
+          name: trace
+          path: trace
+      - name: check trace
+        shell: bash
+        run: |
+          set -x &&
+          curdir="$(cygpath -aw Output | sed 's/\\/&&/g')" &&
+          ver="$(sed 's/\./\\&/g' <trace/ver)" &&
+          sed -ne '/"'$curdir'\\innosetup-'$ver'\.\(exe\|exe\.Config\|en-US\|en\|ENU\|EN\)"/d' -e '/"'$curdir'\\/p' \
+            trace/procmon.csv >trace/filtered.csv &&
+          if test -s trace/filtered.csv
+          then
+            echo ":error:Unexpected filesystem access" >&2
+            cat trace/filtered.csv >&2
+            exit 1
+          fi

+ 40 - 2
Projects/CompExeUpdate.pas

@@ -25,6 +25,7 @@ procedure UpdateVersionInfo(const F: TCustomFile;
   NewProductName, NewTextProductVersion, NewOriginalFileName: String;
   const SetFileVersionAndDescription: Boolean);
 procedure RemoveManifestDllHijackProtection(const F: TCustomFile; const TestBlockOnly: Boolean);
+procedure PreventCOMCTL32Sideloading(const F: TCustomFile);
 
 implementation
 
@@ -502,7 +503,7 @@ end;
 procedure RemoveManifestDllHijackProtection(const F: TCustomFile; const TestBlockOnly: Boolean);
 const
   BlockStartText: AnsiString = '<file name="';
-  BlockLength = 313;
+  BlockLength = 380;
 var
   S: AnsiString;
   Offset: Integer64;
@@ -518,7 +519,7 @@ begin
   if P = 0 then
     ResUpdateError('Block not found');
   if Copy(S, P+BlockLength, 11) <> '</assembly>' then
-    ResUpdateError('Block too short');
+    ResUpdateError('Block too short (BlockLength should be '+string(IntToStr(Pos('</assembly>', string(S))-P)+'): '+string(Copy(S, P+BlockLength, 11))));
 
   if TestBlockOnly then
     Exit;
@@ -528,4 +529,41 @@ begin
   F.WriteAnsiString(AnsiString(Format('%*s', [BlockLength, ' '])));
 end;
 
+procedure PreventCOMCTL32Sideloading(const F: TCustomFile);
+const
+  DependencyStartTag: AnsiString = '<dependency>';
+  DependencyEndTag: AnsiString = '</dependency>';
+  FileStartTag: AnsiString = '<file name="';
+  COMCTL32Entry: AnsiString = '<file name="comctl32.dll" loadFrom="%SystemRoot%\system32\" />'#13#10;
+var
+  S: AnsiString;
+  Offset: Integer64;
+  P,Q,R: Integer;
+begin
+  { Read the manifest resource into a string }
+  SetString(S, nil, SeekToResourceData(F, 24, 1));
+  Offset := F.Position;
+  F.ReadBuffer(S[1], Length(S));
+
+  { Locate and update the <dependency> tag }
+  P := Pos(DependencyStartTag, S);
+  if P = 0 then
+    ResUpdateError('<dependency> tag not found');
+  Q := Pos(DependencyEndTag, S);
+  if Q <= P then
+    ResUpdateError('<dependency> end tag not found');
+  Q := Q+Length(DependencyEndTag);
+  if Length(COMCTL32Entry) > Q-P then
+    ResUpdateError('<dependency> tag shorter than replacement');
+  R := Pos(FileStartTag, S);
+  if R <= Q then
+    ResUpdateError('<dependency> end tag after <file>?');
+
+  Inc64(Offset, P-1);
+  F.Seek64(Offset);
+  F.WriteAnsiString(AnsiString(Format('%*s', [Q-P-Length(COMCTL32Entry), ' '])));
+  F.WriteAnsiString(AnsiString(Copy(S, Q, R-Q)));
+  F.WriteAnsiString(COMCTL32Entry);
+end;
+
 end.

+ 3 - 0
Projects/Compile.pas

@@ -9096,6 +9096,9 @@ begin
             if RemoveManifestDllHijackProtection then begin
               AddStatus(Format(SCompilerStatusUpdatingManifest, ['SETUP.EXE']));
               CompExeUpdate.RemoveManifestDllHijackProtection(ExeFile, False);
+            end else if UseSetupLdr then begin
+              AddStatus(Format(SCompilerStatusUpdatingManifest, ['SETUP.EXE']));
+              CompExeUpdate.PreventCOMCTL32Sideloading(ExeFile);
             end;
 
             { For some reason, on Win95 the date/time of the EXE sometimes

+ 1 - 0
Projects/XPTheme.manifest

@@ -42,6 +42,7 @@
 <file name="mpr.dll" loadFrom="%SystemRoot%\system32\" />
 <file name="netapi32.dll" loadFrom="%SystemRoot%\system32\" />
 <file name="netutils.dll" loadFrom="%SystemRoot%\system32\" />
+<file name="textshaping.dll" loadFrom="%SystemRoot%\system32\" />
 <file name="version.dll" loadFrom="%SystemRoot%\system32\" />
 <file name="winhttp.dll" loadFrom="%SystemRoot%\system32\" />
 </assembly>

BIN
Projects/XPTheme.res