//////////////// // info de debug procedure DBG(Msg: String); begin // mettre la ligne suivante en commentaire pour ne plus avoir les infos de debug // MsgBox(Msg, mbInformation, MB_OK); end; ///////////////////////// // affichage d'un message function AffMsg(NumMsg: Integer): Integer; begin if CompareStr(ActiveLanguage(), 'Francais') = 0 then begin Result := MsgBox(InternalMsgs[NumMsg].TextFR, InternalMsgs[NumMsg].Typ, InternalMsgs[NumMsg].Buttons); end else begin Result := MsgBox(InternalMsgs[NumMsg].TextEN, InternalMsgs[NumMsg].Typ, InternalMsgs[NumMsg].Buttons); end; end; //////////////////////////////////// // Charge des lignes dans un tableau // (la fct Inno LoadStringsFromFile ne marche pas tjrs) procedure Strings2Array(Str: String; var arr: array of String); var Idx1: Integer; Idx2: Integer; begin Idx1 := Pos(#13#10, Str); Idx2 := Pos(#10, Str); if (Idx1 > 0) and ((Idx2 = 0) or (Idx1 < Idx2)) then begin SetArrayLength(arr, GetArrayLength(arr)+1); arr[GetArrayLength(arr)-1] := Copy(Str, 1, Idx1-1); Strings2Array(Copy(Str, Idx1+2, Length(Str)), arr); end else begin if (Idx2 > 0) and ((Idx1 = 0) or (Idx2 < Idx1)) then begin SetArrayLength(arr, GetArrayLength(arr)+1); arr[GetArrayLength(arr)-1] := Copy(Str, 1, Idx2-1); Strings2Array(Copy(Str, Idx2+1, Length(Str)), arr); end else begin if Length(Str) > 0 then begin SetArrayLength(arr, GetArrayLength(arr)+1); arr[GetArrayLength(arr)-1] := Copy(Str, 1, Length(Str)); end; end; end; end; /////////////////////////////////////// // Transforme une chaine au format scol // '\' devient '\\' et ' ' devient '\ ' function Str2Scol(Str: String): String; var Idx: Integer; Car: Char; begin Result := ''; Idx := 1; while Idx <= Length(Str) do begin Car := StrGet(Str, Idx); if Car = '\' then begin Result := Result + '\\'; end else if Car = ' ' then begin Result := Result + '\ '; end else begin Result := Result + Car; end; Idx := Idx + 1; end; end; //////////////////////////////////////////////////////// // Recupere le 1er mot d'une chaine (sans saut de ligne) // NextIdx est la position la suite // Si Trans=True on transforme les '/' en '\', les '\\' en '\' et les '\ ' en ' ' function GetFirstWord(Str: String; Trans: Boolean; var NextIdx: Integer): String; var Fin: Boolean; Idx: Integer; Car: Char; begin Result := ''; Fin := False; Idx := 1; while Fin = False do begin if Idx > Length(Str) then begin Fin := True; end else begin Car := StrGet(Str, Idx); Idx := Idx + 1; if Car = '/' then begin if Trans then begin Result := Result + '\'; end else begin Result := Result + '/'; end; end else if Car = '\' then begin if Idx > Length(Str) then begin // error de syntaxe Result := ''; Fin := True; end else begin Car := StrGet(Str, Idx); Idx := Idx + 1; if Car = '\' then begin if Trans then begin Result := Result + '\'; end else begin Result := Result + '\\'; end; end else if Car = ' ' then begin if Trans then begin Result := Result + ' '; end else begin Result := Result + '\ '; end; end else begin // error de syntaxe Result := ''; Fin := True; Idx := Length(Str) + 1; end; end; end else if Car = ' ' then begin Fin := True; end else begin Result := Result + Car; end; end; end; NextIdx := Idx; DBG('firstWord='+Result); DBG('nextIdx='+IntToStr(NextIdx)); end; ///////////////////////////////////////////////// // Recupere la 1ere ligne d'un tableau de chaines // qui commence par First // StartIdx est la position où commencer // Compact à True pour ne pas tenir compte des blancs au début // Renvoie l'indice si trouvé ou -1 sinon function SearchFirstLine(Arr: array of String; First: String; StartIdx: Integer; Compact: Boolean): Integer; var Idx: Integer; Fin: Boolean; Str: String; begin Result := -1; Fin := False; Idx := StartIdx; while (Fin = False) and (Idx < GetArrayLength(Arr)) do begin if Compact = True then begin Str := Copy(TrimLeft(Arr[Idx]), 1, Length(First)); end else begin Str := Copy(Arr[Idx], 1, Length(First)); end; if CompareStr(First, Str) = 0 then begin Fin := True; end else begin Idx := Idx + 1; end; end; if Fin = True then begin Result := Idx; end; end; /////////////////////////////// // Repertoire d'install de scol function GetScolDir(Default: String): String; var Value: String; begin RegQueryStringValue(HKEY_CLASSES_ROOT, '.scol', '', Value); RegQueryStringValue(HKEY_CLASSES_ROOT, Value + '\shell\open\command', '', Value); if Pos('\usmwin.exe', Value) = 0 then begin Value := Copy(Value, 2, Pos('\scol.exe', Value) -2); end else begin Value := Copy(Value, 2, Pos('\usmwin.exe', Value) -2); end; DBG('ScolDir='+Value); Result := Value; end; /////////////////////////////////////////// // 1ere partition de scol (à part le cache) function GetScolPart(Default: String): String; var ScolDir: String; UsmIni: String; ArrUsmIni: array of String; Disk: String; Part: String; Idx: Integer; begin Result := ''; ScolDir := GetScolDir(''); LoadStringFromFile(ScolDir + '\usm.ini', UsmIni); // chargement en tableau SetArrayLength(ArrUsmIni, 0); Strings2Array(UsmIni, ArrUsmIni); // on saute le cache et on prend la partition suivante Idx := SearchFirstLine(ArrUsmIni, 'diska ', 0, True); if Idx >= 0 then begin Disk := TrimLeft(ArrUsmIni[Idx]); // on enlève le mot diska Disk := Copy(Disk, Length('diska '), Length(Disk)); Disk := TrimLeft(Disk); // on récupère la partition Part := GetFirstWord(Disk, True, Idx); // on remplace '.\' par '\' if Pos('.\', Part) = 1 then begin Part := ScolDir + Copy(Part, 2, Length(Part)); end // on n'ajoute pas ScolDir s'il s'agit d'une unité de lecteur else if (Length(Part) > 0) and ((Length(Part) = 1) or (StrGet(Part, 2) <> ':')) then begin Part := ScolDir + '\' + Part; end; Result := Part; end; DBG('ScolPart='+Result); end; ///////////////////////////////// // Recherche si scol est installé function isScolInstalled(): Boolean; var ScolDir: String; begin Result := False; ScolDir := GetScolDir(''); if Length(ScolDir) > 0 then begin if FileExists(ScolDir + '\usmwin.exe') then begin Result := FileExists(ScolDir + '\usmwin.exe'); end else begin Result := FileExists(ScolDir + '\scol.exe'); end; end; end; ////////////////////////////// // Recherche si scol est lancé function isScolRunning(): Boolean; var ScolDir: String; begin Result := False; ScolDir := GetScolDir(''); if Length(ScolDir) > 0 then begin Result := FileExists(ScolDir + '\usmwin.exe'); if Result then begin FileCopy(ScolDir + '\usmwin.exe', ScolDir + '\usmwin.exe.tmp', False); if not DeleteFile(ScolDir + '\usmwin.exe') then begin DeleteFile(ScolDir + '\usmwin.exe.tmp'); Result := True; end else begin RenameFile(ScolDir + '\usmwin.exe.tmp', ScolDir + '\usmwin.exe'); Result := False; end; end else begin FileCopy(ScolDir + '\scol.exe', ScolDir + '\scol.exe.tmp', False); if not DeleteFile(ScolDir + '\scol.exe') then begin DeleteFile(ScolDir + '\scol.exe.tmp'); Result := True; end else begin RenameFile(ScolDir + '\scol.exe.tmp', ScolDir + '\scol.exe'); Result := False; end; end; end; end; ////////////////////////////////////// // Argument /FORCE pour install forcée function isForced(): Boolean; var Idx: Integer; begin Result := False; Idx := 0; while (Length(ParamStr(Idx)) > 0) and (Result = False) do begin if CompareText(ParamStr(Idx), '/FORCE') = 0 then begin Result := True; end else begin Idx := Idx + 1; end; end; if (Result) then DBG('isForced=True') else DBG('isForced=False'); end; //////////////////////////////////////// // Construction du custom.txt en tableau procedure BuildCustom(customtxt: array of String; var custom: TCustom); var FirstLine: String; Idx: Integer; Car: Char; currIdx: Integer; levelIdx: Integer; lastIdx: Integer; tabIdx: array of Integer; Key: String; ValIdx: Integer; Val: String; begin currIdx := 0; levelIdx := 0; lastIdx := 0; SetArrayLength(tabIdx, 1); tabIdx[0] := 0; Idx := 0; while Idx < GetArrayLength(customtxt) do begin FirstLine := Trim(customtxt[Idx]); Car := StrGet(FirstLine, 1); // nouveau bloc if Car = '>' then begin SetArrayLength(custom[currIdx].Childs, GetArrayLength(custom[currIdx].Childs)+1); custom[currIdx].Childs[GetArrayLength(custom[currIdx].Childs)-1] := lastIdx + 1; if levelIdx+2 > GetArrayLength(tabIdx) then SetArrayLength(tabIdx, GetArrayLength(tabIdx) + 1); lastIdx := lastIdx + 1; levelIdx := levelIdx + 1; tabIdx[levelIdx] := lastIdx; currIdx := lastIdx; SetArrayLength(custom, GetArrayLength(custom) + 1); custom[lastIdx].BlocName := FirstLine; custom[lastIdx].Fathers := custom[tabIdx[levelIdx-1]].Fathers + custom[tabIdx[levelIdx-1]].BlocName; SetArrayLength(custom[lastIdx].Lines, 0); end // fin d'un bloc else if Car = '<' then begin currIdx := tabIdx[levelIdx-1]; levelIdx := levelIdx - 1; end // ligne normale else begin Key := GetFirstWord(FirstLine, False, ValIdx); Val := GetFirstWord(Copy(FirstLine, ValIdx, Length(FirstLine)), False, ValIdx); SetArrayLength(custom[currIdx].Lines, GetArrayLength(custom[currIdx].Lines) + 1); custom[currIdx].Lines[GetArrayLength(custom[currIdx].Lines)-1].Key := Key; custom[currIdx].Lines[GetArrayLength(custom[currIdx].Lines)-1].Val := Val; end; Idx := Idx + 1; end; end; ///////////////////// // Debugage du custom procedure printcust(custom: TCustom); var i, j: Integer; begin i := 0; while i < GetArrayLength(custom) do begin DBG('BLOCNAME='+custom[i].BlocName); DBG('fathers='+custom[i].Fathers); j := 0; while j < GetArrayLength(custom[i].Childs) do begin DBG('child'+IntToStr(j)+'='+IntToStr(custom[i].Childs[j])); j := j + 1; end; j := 0; while j < GetArrayLength(custom[i].Lines) do begin DBG('key'+IntToStr(j)+'='+custom[i].Lines[j].Key); j := j + 1; end; i := i + 1; end; end; ////////////////////// // Recherche d'un bloc // (même nom, mêmes pères) // -1 si non trouvé function FindCustBloc(currcustom: TCustom; custBloc: TBloc): Integer; var i: Integer; begin Result := -1; i := 0; while (i < GetArrayLength(currcustom)) and (Result = -1) do begin if (CompareStr(currcustom[i].BlocName, custBloc.BlocName) = 0) and (CompareStr(currcustom[i].Fathers, custBloc.Fathers) = 0) then begin Result := i; end else i := i + 1; end; end; ////////////////////// // Recherche d'une clé // -1 si non trouvé function FindCustKey(currcustlines: array of TLine; Key: String): Integer; var i: Integer; begin Result := -1; i := 0; while (i < GetArrayLength(currcustlines)) and (Result = -1) do begin if CompareStr(currcustlines[i].Key, Key) = 0 then begin Result := i; end else i := i + 1; end; end; //////////////////////////////// // Merge de deux tableaux custom procedure MergeCustomBloc(var currcustom: TCustom; custom: TCustom); var i, j: Integer; IdxBloc: Integer; IdxLine: Integer; Father: TBloc; begin i := 0; while i < GetArrayLength(custom) do begin // recherche du bloc IdxBloc := FindCustBloc(currcustom, custom[i]); // si bloc trouvé, on cherche les clés if IdxBloc >= 0 then begin j := 0 while j < GetArrayLength(custom[i].Lines) do begin IdxLine := FindCustKey(currcustom[IdxBloc].Lines, custom[i].Lines[j].Key); // si clé non trouvée, on l'ajoute if IdxLine < 0 then begin SetArrayLength(currcustom[IdxBloc].Lines, GetArrayLength(currcustom[IdxBloc].Lines)+1); currcustom[IdxBloc].Lines[GetArrayLength(currcustom[IdxBloc].Lines)-1].Key := custom[i].Lines[j].Key; currcustom[IdxBloc].Lines[GetArrayLength(currcustom[IdxBloc].Lines)-1].Val := custom[i].Lines[j].Val; end else j := j + 1; end; end // si bloc non trouvé else begin // on l'ajoute SetArrayLength(currcustom, GetArrayLength(currcustom)+1); currcustom[GetArrayLength(currcustom)-1].BlocName := custom[i].BlocName; currcustom[GetArrayLength(currcustom)-1].Fathers := custom[i].Fathers; SetArrayLength(currcustom[GetArrayLength(currcustom)-1].Childs, 0); SetArrayLength(currcustom[GetArrayLength(currcustom)-1].Lines, GetArrayLength(custom[i].Lines)); j := 0; while j < GetArrayLength(custom[i].Lines) do begin currcustom[GetArrayLength(currcustom)-1].Lines[j].Key := custom[i].Lines[j].Key; currcustom[GetArrayLength(currcustom)-1].Lines[j].Val := custom[i].Lines[j].Val; j := j + 1; end; // on s'ajoute dans la liste des fils de son père j := Length(custom[i].Fathers); while (j > 0) and (StrGet(custom[i].Fathers, j) <> '>') do j := j - 1; Father.BlocName := Copy(custom[i].Fathers, j, Length(custom[i].Fathers)); Father.Fathers := Copy(custom[i].Fathers, 1, j-1); IdxBloc := FindCustBloc(currcustom, Father); SetArrayLength(currcustom[IdxBloc].Childs, GetArrayLength(currcustom[IdxBloc].Childs)+1); currcustom[IdxBloc].Childs[GetArrayLength(currcustom[IdxBloc].Childs)-1] := GetArrayLength(currcustom)-1; end; i := i + 1; end; end; ///////////////////////////////////////////// // Transformation du tableau custom en string function BlocToString(custom: TCustom; idx: Integer): String; var i: Integer; begin if Length(custom[idx].BlocName) > 0 then begin Result := custom[idx].BlocName + #13#10; end else begin Result := ''; end; i := 0; while i < GetArrayLength(custom[idx].Childs) do begin Result := Result + BlocToString(custom, custom[idx].Childs[i]); i := i + 1; end; i := 0; while i < GetArrayLength(custom[idx].Lines) do begin Result := Result + custom[idx].Lines[i].Key + ' ' + custom[idx].Lines[i].Val + #13#10; i := i + 1; end; if Length(custom[idx].BlocName) > 0 then begin Result := Result + '<' + #13#10; end; end; ////////////////////////////////////////////////////////// // Ajoute une dll plugin dans usm.ini si version le permet // Retourne True si dll ajoutée function InstallPluginDll(var ArrUsmIni: array of String; Prefix: String; Dll: String; IniFuncs: String): Boolean; var Idx: Integer; Fin: Boolean; Plugin: String; DllIdx: Integer; begin Result := False; Fin := False; Idx := -1; while Fin = False do begin // recherche des plugins Idx := SearchFirstLine(ArrUsmIni, 'plugin ', Idx+1, True); if Idx >= 0 then begin DllIdx := Pos(Uppercase(Prefix), Uppercase(ArrUsmIni[Idx])); // dll trouvée if DllIdx > 0 then begin Fin := True; Plugin := GetFirstWord(Copy(ArrUsmIni[Idx], DllIdx, Length(ArrUsmIni[Idx])), False, DllIdx); // si dll à installer plus récente if CompareText(Plugin, Dll) < 0 then begin // on remplace dans usm.ini par nouvelle dll ArrUsmIni[Idx] := 'plugin plugins/' + Dll + ' ' + IniFuncs; Result := True; end; end; end else Fin := True; end; // si dll non trouvée, on l'ajoute if Idx < 0 then begin SetArrayLength(ArrUsmIni, GetArrayLength(ArrUsmIni)+1); ArrUsmIni[GetArrayLength(ArrUsmIni)-1] := 'plugin plugins/' + Dll + ' ' + IniFuncs; Result := True; end; If Result then DBG('InstallPluginDll '+Dll+' True') else DBG('InstallPluginDll '+Dll+' False'); end;