⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.pas

📁 源代码
💻 PAS
📖 第 1 页 / 共 5 页
字号:

function GetRealShellFolder(const Common: Boolean; const ID: TShellFolderID;
  ReadOnly: Boolean): String;

  procedure GetFolder(const Common: Boolean);
  const
    CSIDL_COMMON_STARTMENU = $0016;
    CSIDL_COMMON_PROGRAMS = $0017;
    CSIDL_COMMON_STARTUP = $0018;
    CSIDL_COMMON_DESKTOPDIRECTORY = $0019;
    CSIDL_APPDATA = $001A;
    CSIDL_LOCAL_APPDATA = $001C;
    CSIDL_COMMON_FAVORITES = $001F;
    CSIDL_COMMON_APPDATA = $0023;
    CSIDL_COMMON_TEMPLATES = $002D;
    CSIDL_COMMON_DOCUMENTS = $002E;
    FolderIDs: array[Boolean, TShellFolderID] of Integer = (
      { User }
      (CSIDL_DESKTOPDIRECTORY, CSIDL_STARTMENU, CSIDL_PROGRAMS, CSIDL_STARTUP,
       CSIDL_SENDTO, CSIDL_FONTS, CSIDL_APPDATA, CSIDL_PERSONAL,
       CSIDL_TEMPLATES, CSIDL_FAVORITES, CSIDL_LOCAL_APPDATA),
      { Common }
      (CSIDL_COMMON_DESKTOPDIRECTORY, CSIDL_COMMON_STARTMENU, CSIDL_COMMON_PROGRAMS, CSIDL_COMMON_STARTUP,
       CSIDL_SENDTO, CSIDL_FONTS, CSIDL_COMMON_APPDATA, CSIDL_COMMON_DOCUMENTS,
       CSIDL_COMMON_TEMPLATES, CSIDL_COMMON_FAVORITES, CSIDL_LOCAL_APPDATA));
  var
    Z: String;
  begin
    if not ShellFoldersRead[Common, ID] then begin
      { Note: Must pass Create=True or else SHGetFolderPath fails if the
        specified CSIDL is valid but doesn't currently exist. }
      Z := GetShellFolderByCSIDL(FolderIDs[Common, ID], not ReadOnly);
      ShellFolders[Common, ID] := Z;
      if not ReadOnly or (Z <> '') then
        ShellFoldersRead[Common, ID] := True;
    end;
    Result := ShellFolders[Common, ID];
  end;

begin
  Result := '';
  GetFolder(Common);
  if (Result = '') and Common then
    { If it failed to get the path of a Common CSIDL, try getting the
      User version of the CSIDL instead. (Many of the Common CSIDLS are
      unsupported by Win9x.) }
    GetFolder(False);
end;

function GetShellFolder(Common: Boolean; const ID: TShellFolderID;
  ReadOnly: Boolean): String;
begin
  { If the user isn't an administrator, or is running Windows 9x, always fall
    back to user folders, except in the case of sfAppData (which is writable
    by Users on XP) and sfDocs (which is writable by Users on 2000 & XP) }
  if Common and (not IsAdmin or not IsNT) and
     not(ID in [sfAppData, sfDocs]) then
    Common := False;
  Result := GetRealShellFolder(Common, ID, ReadOnly);
end;

function InstallOnThisVersion(const MinVersion: TSetupVersionData;
  const OnlyBelowVersion: TSetupVersionData): TInstallOnThisVersionResult;
var
  Ver, Ver2, MinVer, OnlyBelowVer: Cardinal;
begin
  Ver := WindowsVersion;
  if IsNT then begin
    MinVer := MinVersion.NTVersion;
    OnlyBelowVer := OnlyBelowVersion.NTVersion;
  end
  else begin
    MinVer := MinVersion.WinVersion;
    OnlyBelowVer := OnlyBelowVersion.WinVersion;
  end;
  Result := irInstall;
  if MinVer = 0 then
    Result := irNotOnThisPlatform
  else begin
    if (Ver < MinVer) or
       (IsNT and (LongRec(Ver).Hi = LongRec(MinVer).Hi) and
        (NTServicePackLevel < MinVersion.NTServicePack)) then
      Result := irVerTooLow
    else begin
      if OnlyBelowVer <> 0 then begin
        Ver2 := Ver;
        { A build number of 0 on OnlyBelowVersion means 'match any build' }
        if LongRec(OnlyBelowVer).Lo = 0 then
          Ver2 := Ver2 and $FFFF0000;  { set build number to zero on Ver2 also }
        if not IsNT then begin
          if Ver2 >= OnlyBelowVer then
            Result := irVerTooHigh;
        end
        else begin
          if (Ver2 > OnlyBelowVer) or
             ((LongRec(Ver).Hi = LongRec(OnlyBelowVer).Hi) and
              (NTServicePackLevel >= OnlyBelowVersion.NTServicePack)) then
            Result := irVerTooHigh;
        end;
      end;
    end;
  end;
end;

function GetSizeOfComponent(const ComponentName: String; const ExtraDiskSpaceRequired: Integer64): Integer64;
var
  ComponentNameAsList: TStringList;
  FileEntry: PSetupFileEntry;
  I: Integer;
begin
  Result := ExtraDiskSpaceRequired;

  ComponentNameAsList := TStringList.Create();
  try
    ComponentNameAsList.Add(ComponentName);
    for I := 0 to Entries[seFile].Count-1 do begin
      FileEntry := PSetupFileEntry(Entries[seFile][I]);
      with FileEntry^ do begin
        if (Components <> '') and
           ((Tasks = '') and (Check = '')) then begin {don't count tasks or scripted entries}
          if ShouldProcessFileEntry(ComponentNameAsList, nil, FileEntry, True) then begin
            if LocationEntry <> -1 then
              Inc6464(Result, PSetupFileLocationEntry(Entries[seFileLocation][LocationEntry])^.OriginalSize)
            else
              Inc6464(Result, ExternalSize);
            end;
        end;
      end;
    end;
  finally
    ComponentNameAsList.Free();
  end;
end;

function GetSizeOfType(const TypeName: String; const IsCustom: Boolean): Integer64;
var
  ComponentTypes: TStringList;
  I: Integer;
begin
  Result.Hi := 0;
  Result.Lo := 0;
  ComponentTypes := TStringList.Create();

  for I := 0 to Entries[seComponent].Count-1 do begin
    with PSetupComponentEntry(Entries[seComponent][I])^ do begin
      ComponentTypes.CommaText := Types;
      { For custom types, only count fixed components. Otherwise count all. }
      if IsCustom then begin
        if (coFixed in Options) and ListContains(ComponentTypes, TypeName) then
          Inc6464(Result, Size);
      end else begin
        if ListContains(ComponentTypes, TypeName) then
          Inc6464(Result, Size);
      end;
    end;
  end;

  ComponentTypes.Free();
end;

function IsRecurseableDirectory(const FindData: TWin32FindData): Boolean;
{ Returns True if FindData is a directory that may be recursed into.
  Intended only for use when processing external+recursesubdirs file entries. }
begin
  Result :=
    (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and
    (FindData.dwFileAttributes and FILE_ATTRIBUTE_HIDDEN = 0) and
    (StrComp(FindData.cFileName, '.') <> 0) and
    (StrComp(FindData.cFileName, '..') <> 0);
end;

procedure EnumProc(const Filename: String; Param: Pointer);
begin
  TStringList(Param).Add(PathLowercase(Filename));
end;

function PreviousInstallNotCompleted: Boolean;
var
  SL: TStringList;

  function CheckForFile(Filename: String): Boolean;
  var
    J: Integer;
  begin
    if UsingWinNT then
      Filename := PathLowercase(Filename)
    else
      Filename := PathLowercase(GetShortName(Filename));
    for J := 0 to SL.Count-1 do begin
      if SL[J] = Filename then begin
        LogFmt('Found pending rename or delete that matches one of our files: %s', [Filename]);
        Result := True;
        Exit;
      end;
    end;
    Result := False;
  end;

  function RecurseExternalCheckForFile(const SearchBaseDir, SearchSubDir,
    SearchWildcard: String; const SourceIsWildcard: Boolean;
    const CurFile: PSetupFileEntry): Boolean;
  var
    SearchFullPath, DestName: String;
    H: THandle;
    FindData: TWin32FindData;
  begin
    SearchFullPath := SearchBaseDir + SearchSubDir + SearchWildcard;
    Result := False;

    H := FindFirstFile(PChar(SearchFullPath), FindData);
    if H <> INVALID_HANDLE_VALUE then begin
      try
        repeat
          if FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 then begin

            if SourceIsWildcard then
              if FindData.dwFileAttributes and FILE_ATTRIBUTE_HIDDEN <> 0 then
                Continue;

            DestName := ExpandConst(CurFile^.DestName);
            if not(foCustomDestName in CurFile^.Options) then
              DestName := DestName + SearchSubDir + FindData.cFileName
            else if SearchSubDir <> '' then
              DestName := PathExtractPath(DestName) + SearchSubDir + PathExtractName(DestName);
            if CheckForFile(DestName) then begin
              Result := True;
              Exit;
            end;
          end;
        until not FindNextFile(H, FindData);
      finally
        Windows.FindClose(H);
      end;
    end;

    if foRecurseSubDirsExternal in CurFile^.Options then begin
      H := FindFirstFile(PChar(SearchBaseDir + SearchSubDir + '*'), FindData);
      if H <> INVALID_HANDLE_VALUE then begin
        try
          repeat
            if IsRecurseableDirectory(FindData) then
              if RecurseExternalCheckForFile(SearchBaseDir,
                 SearchSubDir + FindData.cFileName + '\', SearchWildcard,
                 SourceIsWildcard, CurFile) then begin
                Result := True;
                Exit;
              end;
          until not FindNextFile(H, FindData);
        finally
          Windows.FindClose(H);
        end;
      end;
    end;
  end;

var
  I: Integer;
  CurFile: PSetupFileEntry;
  SourceWildcard: String;
begin
  Result := False;
  if Entries[seFile].Count = 0 then
    Exit;
  SL := TStringList.Create;
  try
    EnumFileReplaceOperationsFilenames(EnumProc, SL);
    if SL.Count = 0 then
      Exit;
    for I := 0 to Entries[seFile].Count-1 do begin
      CurFile := PSetupFileEntry(Entries[seFile][I]);
      if (CurFile^.FileType = ftUserFile) and
         ShouldProcessFileEntry(WizardComponents, WizardTasks, CurFile, False) then begin
        if CurFile^.LocationEntry <> -1 then begin
          { Non-external file }
          if CheckForFile(ExpandConst(CurFile^.DestName)) then begin
            Result := True;
            Exit;
          end;
        end
        else begin
          { External file }
          SourceWildcard := ExpandConst(CurFile^.SourceFilename);
          if RecurseExternalCheckForFile(PathExtractPath(SourceWildcard), '',
             PathExtractName(SourceWildcard), IsWildcard(SourceWildcard), CurFile) then begin
            Result := True;
            Exit;
          end;
        end;
      end;
    end;
  finally
    SL.Free;
  end;
end;

procedure DebugNotifyEntry(EntryType: TEntryType; Number: Integer);
var
  Kind: TDebugEntryKind;
  B: Boolean;
begin
  if not Debugging then Exit;
  case EntryType of
    seDir: Kind := deDir;
    seFile: Kind := deFile;
    seIcon: Kind := deIcon;
    seIni: Kind := deIni;
    seRegistry: Kind := deRegistry;
    seInstallDelete: Kind := deInstallDelete;
    seUninstallDelete: Kind := deUninstallDelete;
    seRun: Kind := deRun;
    seUninstallRun: Kind := deUninstallRun;
  else
    Exit;
  end;
  DebugNotify(Kind, Integer(OriginalEntryIndexes[EntryType][Number]), B);
end;

procedure InternalError(const Id: String);
begin
  raise Exception.Create(FmtSetupMessage1(msgErrorInternal2, Id));
end;

procedure CodeRunnerOnDllImport(var DllName: String; var ForceDelayLoad: Boolean);
var
  BaseName: String;
begin
  while True do begin
    if Pos('setup:', DllName) = 1 then begin
      if IsUninstaller then begin
        DllName := '';
        ForceDelayLoad := True;
        Exit;
      end;
      Delete(DllName, 1, Length('setup:'));
    end
    else if Pos('uninstall:', DllName) = 1 then begin
      if not IsUninstaller then begin
        DllName := '';
        ForceDelayLoad := True;
        Exit;
      end;
      Delete(DllName, 1, Length('uninstall:'));
    end
    else
      Break;
  end;

  if Pos('files:', DllName) = 1 then begin
    if IsUninstaller then begin
      { Uninstall doesn't do 'files:' }
      DllName := '';
      ForceDelayLoad := True;
    end
    else begin
      BaseName := ExpandConst(Copy(DllName, Length('files:')+1, Maxint));
      DllName := AddBackslash(TempInstallDir) + BaseName;
      if not NewFileExists(DllName) then
        ExtractTemporaryFile(BaseName);
    end;
  end
  else
    DllName := ExpandConst(DllName);
end;

procedure CodeRunnerOnDebug(const Position: LongInt; var ContinueStepOver: Boolean);
begin
  DebugNotify(deCodeLine, Position, ContinueStepOver);
end;

procedure CodeRunnerOnDebugIntermediate(const Position: LongInt);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -