  {--------------------------------------------------------------------}

  {-                          LFN.IN6 v1.10                           -}

  {-         Funktionen zur Initalisierung fr LFN.PAS v1.10          -}

  {--------------------------------------------------------------------}



  procedure GetProcPtr;

    {-Ermittelt die Pointer der zu patchenden Routinen}

  label

    lMkDir, lRmDir, lChDir, lGetDir,

    lFReset, lFRewrite, lErase, lRename,

    lAssignText,

  {$IFDEF UseDos}

    lGetFAttr_D, lSetFAttr_D, lGetFTime_D, lSetFTime_D,

    lFSearch,                                                          {!!.08}

    lGetEnv,                                                           {!!.09}

  {$ENDIF}

    lParamCount, lParamStr,                                            {!!.04}

    lAssignFile,                                                       {!!.05}

    lFClose,                                                           {!!.05}

    {!!.06 begin}

  {$IFDEF UseWinDos}

    lCreateDir, lRemoveDir, lSetCurDir, lGetCurDir,

    lGetFAttr_W, lSetFAttr_W, lGetFTime_W, lSetFTime_W,

    lGetArgCount, lGetArgStr, lFileExpand, lFileSplit,

    lFileSearch,                                                       {!!.08}

  {$ENDIF}

    {!!.06 end}

    Start;

  var

    S : String[1];

    F : file;

    T : Text;

    W : Word;

    L : LongInt;

    P : PChar;

  begin

    goto Start;

    System.MkDir(''); lMkDir:

    System.RmDir(''); lRmDir:

    System.ChDir(''); lChDir:

    System.GetDir(0, S); lGetDir:

    System.Reset(F, 1); lFReset:

    System.Rewrite(F, 1); lFRewrite:

    System.Erase(F); lErase:

    System.Rename(F, S); lRename:

    System.Assign(T, S); lAssignText:

  {$IFDEF UseDos}

    Dos.GetFAttr(F, W); lGetFAttr_D:

    Dos.SetFAttr(F, W); lSetFAttr_D:

    Dos.GetFTime(F, L); lGetFTime_D:

    Dos.SetFTime(F, L); lSetFTime_D:

lFSearch: if Dos.FSearch('', '') = '' then ;                           {!!.08}

lGetEnv: if Dos.GetEnv('') = '' then ;                                 {!!.09}

  {$ENDIF}

lParamCount: if System.ParamCount = 0 then ;                           {!!.04}

lParamStr: if System.ParamStr(1) = '' then ;                           {!!.04}

    System.Assign(F, S); lAssignFile:                                  {!!.05}

    System.Close(F); lFClose:                                          {!!.05}

    {!!.06 begin}

  {$IFDEF UseWinDos}

    WinDos.CreateDir(P); lCreateDir:

    WinDos.RemoveDir(P); lRemoveDir:

    WinDos.SetCurDir(P); lSetCurDir:

lGetCurDir: P := WinDos.GetCurDir(P, 0);

    WinDos.GetFAttr(F, W); lGetFAttr_W:

    WinDos.SetFAttr(F, W); lSetFAttr_W:

    WinDos.GetFTime(F, L); lGetFTime_W:

    WinDos.SetFTime(F, L); lSetFTime_W:

lGetArgCount: if WinDos.GetArgCount = 0 then ;

lGetArgStr: P := WinDos.GetArgStr(P, 0, 0);

lFileExpand: P := WinDos.FileExpand(P, P);

lFileSplit: if WinDos.FileSplit(P, P, P, P) = 0 then ;

lFileSearch: if WinDos.FileSearch(P,P,P) = nil then;                   {!!.08}

  {$ENDIF}

    {!!.06 end}

Start:

    PatchAddr[pDummy] := @PatchAddr[pDummy];                           {!!.06}

    asm

      mov     si, pMkDir

      mov     bx, offset lMkDir

      call    @StorePtr



      mov     si, pRmDir

      mov     bx, offset lRmDir

      call    @StorePtr



      mov     si, pChDir

      mov     bx, offset lChDir

      call    @StorePtr



      mov     si, pGetDir

      mov     bx, offset lGetDir

      call    @StorePtr



      mov     si, pFReset

      mov     bx, offset lFReset

      call    @StorePtr



      mov     si, pFRewrite

      mov     bx, offset lFRewrite

      call    @StorePtr



      mov     si, pErase

      mov     bx, offset lErase

      call    @StorePtr



      mov     si, pRename

      mov     bx, offset lRename

      call    @StorePtr



      mov     si, pAssignText

      mov     bx, offset lAssignText

      call    @StorePtr



    {$IFDEF UseDos}

      mov     si, pGetFAttr_D

      mov     bx, offset lGetFAttr_D

      call    @StorePtr



      mov     si, pSetFAttr_D

      mov     bx, offset lSetFAttr_D

      call    @StorePtr



      mov     si, pGetFTime_D

      mov     bx, offset lGetFTime_D

      call    @StorePtr



      mov     si, pSetFTime_D

      mov     bx, offset lSetFTime_D

      call    @StorePtr



      {!!.08 begin}

      mov     si, pFSearch

      mov     bx, offset lFSearch

      mov     cx, offset lGetEnv

      call    @SearchStorePtr

      {!!.08 end}



      {!!.09 begin}

      mov     si, pGetEnv

      mov     bx, offset lGetEnv

      mov     cx, offset lParamCount

      call    @SearchStorePtr

      {!!.09 end}

    {$ENDIF}



      {!!.04 begin}

      mov     si, pParamCount

      mov     bx, offset lParamCount

      mov     cx, offset lParamStr

      call    @SearchStorePtr



      mov     si, pParamStr

      mov     bx, offset lParamStr

      mov     cx, offset lAssignFile                                   {!!.05}

      call    @SearchStorePtr

      {!!.04 end}



      {!!.05 begin}

      mov     si, pAssignFile

      mov     bx, offset lAssignFile

      call    @StorePtr



      mov     si, pFClose

      mov     bx, offset lFClose

      call    @StorePtr

      {!!.05 end}



      {!!.06 begin}

    {$IFDEF UseWinDos}

      mov     si, pCreateDir

      mov     bx, offset lCreateDir

      call    @StorePtr



      mov     si, pRemoveDir

      mov     bx, offset lRemoveDir

      call    @StorePtr



      mov     si, pSetCurDir

      mov     bx, offset lSetCurDir

      call    @StorePtr



      mov     si, pGetCurDir

      mov     bx, offset lGetCurDir

      mov     cx, offset lGetFAttr_W

      call    @SearchStorePtr



      mov     si, pGetFAttr_W

      mov     bx, offset lGetFAttr_W

      call    @StorePtr



      mov     si, pSetFAttr_W

      mov     bx, offset lSetFAttr_W

      call    @StorePtr



      mov     si, pGetFTime_W

      mov     bx, offset lGetFTime_W

      call    @StorePtr



      mov     si, pSetFTime_W

      mov     bx, offset lSetFTime_W

      call    @StorePtr



      mov     si, pGetArgCount

      mov     bx, offset lGetArgCount

      mov     cx, offset lGetArgStr

      call    @SearchStorePtr



      mov     si, pGetArgStr

      mov     bx, offset lGetArgStr

      mov     cx, offset lFileExpand

      call    @SearchStorePtr



      mov     si, pFileExpand

      mov     bx, offset lFileExpand

      mov     cx, offset lFileSplit

      call    @SearchStorePtr



      mov     si, pFileSplit

      mov     bx, offset lFileSplit

      mov     cx, offset lFileSearch                                   {!!.08}

      call    @SearchStorePtr



      {!!.08 begin}

      mov     si, pFileSearch

      mov     bx, offset lFileSearch

      mov     cx, offset Start

      call    @SearchStorePtr

      {!!.08 end}

    {$ENDIF}

      {!!.06 end}



      jmp     @Done



@StorePtr:

      shl     si, 2               {-Index im Array berechnen}

      sub     bx, 4               {-Position auf die Adresse des CALL FAR}

      lea     di, PatchAddr[si]   {-Adresse des Array holen}

      mov     ax, cs:[bx]         {-OFS des CALL FAR lesen}

      mov     [di], ax            {-Im Array speichern}

      mov     ax, cs:[bx+2]       {-SEG des CALL FAR lesen}

      mov     [di+2], ax          {-Im Array speichern}

      retn



      {!!.04 begin}

@SearchStorePtr:

      mov     ax, cs              {-ES:DI => Zeiger auf den Code}

      mov     es, ax

      mov     di, bx

      sub     cx, bx              {-CX = Bytes bis zum nchtes Label}

      mov     al, 9Ah             {-$9A = erstes Byte des CALL FAR...}

      cld                         {-...vorwrts...}

      repne   scasb               {-...suchen}

      mov     bx, di              {-CS:[BX] = erstes Bytes nach $9A}

      shl     si, 2               {-Index im Array berechnen}

      lea     di, PatchAddr[si]   {-Adresse des Array holen}

      mov     ax, cs:[bx]         {-OFS des CALL FAR lesen}

      mov     [di], ax            {-Im Array speichern}

      mov     ax, cs:[bx+2]       {-SEG des CALL FAR lesen}

      mov     [di+2], ax          {-Im Array speichern}

      retn

      {!!.04 end}

@Done:

    end;

  end;



type

  OS = record

         O, S : Word;

       end;



  procedure Initialize;

  var

    P : PatchType;

  begin

    {-Pointer der zu patchenden Routinen in SYSTEM und DOS ermitteln}

    GetProcPtr;



    {-Sicherung des alten Codes}

    for P := LowPatchType to Pred(HighPatchType) do

      case P of                                                        {!!.07}

        pAssignText, pAssignFile :                                     {!!.07}

          Move(PatchAddr[P]^, SpecialSavePatch[P],                     {!!.07}

               SizeOf(SpecialPatchRec));                               {!!.07}

      else

        Move(PatchAddr[P]^, SavePatch[P], SizeOf(PatchRec));

      end;



    {$IFDEF Dpmi}

    {-Korretur der Adressen fr Patch}

    for P:= LowPatchType to Pred(HighPatchType) do

      OS(PatchAddr[P]).S:= OS(PatchAddr[P]).S+SelectorInc;

    {$ENDIF}

  end;



  procedure EnableLFNFunc(Which : PatchType);                          {!!.04}

    {-Aktiviert die gewnschte Funktion dieser Unit}

  var

    Patch : PatchRec;

    SpecialPatch : SpecialPatchRec;

    Save : Pointer;

  begin

    Patch.Code := $EA;            {-JMP FAR}

    with Patch do

      case Which of

        pMkDir : Addr := @Win95MkDir;

        pRmDir : Addr := @Win95RmDir;

        pChDir : Addr := @Win95ChDir;

        pGetDir : Addr := @Win95GetDir;

        pFReset : Addr := @Win95FReset;

        pFRewrite : Addr := @Win95FRewrite;

        pErase : Addr := @Win95Erase;

        pRename : Addr := @Win95Rename;



      {$IFDEF UseDos}

        pGetFAttr_D : Addr := @Win95GetFAttr;

        pSetFAttr_D : Addr := @Win95SetFAttr;

        pGetFTime_D : Addr := @Win95GetFTime;

        pSetFTime_D : Addr := @Win95SetFTime;

        pFSearch : Addr := @Win95FSearch;

        pGetEnv : Addr := @Win95GetEnv;

      {$ENDIF}

        pParamCount : Addr := @Win95ParamCount;                        {!!.04}

        pParamStr : Addr := @Win95ParamStr;                            {!!.04}

        pFClose : Addr := @FILECLOSE;                                  {!!.05}



        {!!.06 begin}

      {$IFDEF UseWinDos}

        pGetArgCount : Addr := @Win95ParamCount;

        pGetArgStr : Addr := @Win95GetArgStr;

        pFileExpand : Addr := @Win95FileExpand;

        pFileSplit : Addr := @Win95FileSplit;

        pGetFAttr_W : Addr := @Win95GetFAttr;

        pSetFAttr_W : Addr := @Win95SetFAttr;

        pGetFTime_W : Addr := @Win95GetFTime;

        pSetFTime_W : Addr := @Win95SetFTime;

        pCreateDir : Addr := @Win95CreateDir;

        pRemoveDir : Addr := @Win95RemoveDir;

        pSetCurDir : Addr := @Win95SetCurDir;

        pGetCurDir : Addr := @Win95GetCurDir;

        pFileSearch : Addr:= @Win95FileSearch;                         {!!.08}

      {$ENDIF}

        {!!.06 end}



        {!!.07 begin}

        pAssignText, pAssignFile :

          with SpecialPatch do begin

            Instr[0] := $31; Instr[1] := $D2; {-XOR DX, DX}

            Code := $EA;          {-JMP FAR}

            case Which of

              pAssignText : Addr := @AssignText;

              pAssignFile : Addr := @AssignFile;

            end;

          end;

        {!!.07 end}



        pDummy : Exit;                                                 {!!.06}

      else

        WriteLn('Uuups.');

        Halt;

      end;



    {!!.06 begin}

  {$IFDEF Windows}

    Save := PatchAddr[Which];

    {-Datensegment-Alias fuer Codesegment holen}

    with OS(PatchAddr[Which]) do

      S := AllocCStoDSalias(S);

  {$ENDIF}

    {!!.06 end}



    case Which of                                                      {!!.07}

      pAssignText, pAssignFile :                                       {!!.07}

        Move(SpecialPatch, PatchAddr[Which]^,                          {!!.07}

             SizeOf(SpecialPatchRec));                                 {!!.07}

    else

      Move(Patch, PatchAddr[Which]^, SizeOf(PatchRec));

    end;



    {!!.06 begin}

  {$IFDEF Windows}

    {-Selector freigeben}

    if FreeSelector(OS(PatchAddr[Which]).S) = 0 then {nothing} ;

    PatchAddr[Which] := Save;

  {$ENDIF}

    {!!.06 end}

  end;



  procedure DisableLFNFunc(Which : PatchType);

    {-Deaktiviert die gewnschte Funktion dieser Unit}

  var

    Save : Pointer;

  begin

    {!!.06 begin}

  {$IFDEF Windows}

    Save := PatchAddr[Which];

    {-Datensegment-Alias fuer Codesegment holen}

    with OS(PatchAddr[Which]) do

      S := AllocCStoDSalias(S);

  {$ENDIF}

    {!!.06 end}



    case Which of                                                      {!!.07}

      pAssignText, pAssignFile :                                       {!!.07}

        Move(SpecialSavePatch[Which], PatchAddr[Which]^,               {!!.07}

             SizeOf(SpecialPatchRec));                                 {!!.07}

    else

      Move(SavePatch[Which], PatchAddr[Which]^, SizeOf(PatchRec));

    end;



    {!!.06 begin}

  {$IFDEF Windows}

    {-Selector freigeben}

    if FreeSelector(OS(PatchAddr[Which]).S) = 0 then ;

    PatchAddr[Which] := Save;

  {$ENDIF}

    {!!.06 end}

  end;



  procedure EnableLFN;

    {-Aktiviert die Untersttzung fr lange Dateinamen}

  var

    P : PatchType;

  begin

    LFN_Proc := LFN_AllProcs;

    for P := LowPatchType to Pred(HighPatchType) do

      EnableLFNFunc(P);                                                {!!.04}

  end;



  procedure DisableLFN;

    {-Deaktiviert die Untersttzung fr lange Dateinamen}

  var

    P : PatchType;

  begin

    LFN_Proc := 0;

    for P := LowPatchType to Pred(HighPatchType) do

      DisableLFNFunc(P);                                               {!!.04}

  end;



  function Win95_Aktiv : Boolean; Assembler;                 {!!.04 rewritten}

    {-Ermittelt ob Win95 aktiv ist}

  asm

    mov     ax, 160Ah

    int     2Fh

    or      ax, ax

    je      @@Supported

    {-Aufruf wird nicht untersttzt}

    mov     al, False

    jmp     @@Done

@@Supported:

    cmp     bx, 0395h             {-Ist es Win95a oder lter?}

    jl      @@Done

    mov     al, True

@@Done:

  end;

