home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / Verify.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  14.7 KB  |  837 lines

  1. /*
  2. **    Verify.c
  3. **
  4. **    Check if files/drawers/programs are where they should be
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. struct Path
  17. {
  18.     BPTR    path_Next,
  19.             path_Lock;
  20. };
  21.  
  22.     /* FindPath(struct Window *Parent,STRPTR Path,BOOL CanCreate,LONG *Error):
  23.      *
  24.      *    For the complete path of a file, this checks if the
  25.      *    path leading to the file actually exists. This is
  26.      *    primarily for files the program should create. Thus,
  27.      *    the file in question may not yet exist.
  28.      */
  29.  
  30. BOOL
  31. FindPath(struct Window *Parent,STRPTR Path,BOOL CanCreate,LONG *Error)
  32. {
  33.     UBYTE    LocalBuffer[MAX_FILENAME_LENGTH];
  34.     STRPTR    Index;
  35.  
  36.     strcpy(LocalBuffer,Path);
  37.  
  38.     Index = PathPart(LocalBuffer);
  39.  
  40.     *Index = 0;
  41.  
  42.     return(FindDrawer(Parent,LocalBuffer,CanCreate,Error));
  43. }
  44.  
  45.     /* FindDrawer(struct Window *Parent,STRPTR Drawer,BOOL CanCreate,LONG *Error):
  46.      *
  47.      *    Check if a given drawer exists and give
  48.      *    the user the choice to create it if necessary.
  49.      */
  50.  
  51. BOOL
  52. FindDrawer(struct Window *Parent,STRPTR Drawer,BOOL CanCreate,LONG *Error)
  53. {
  54.     APTR    OldPtr = ThisProcess -> pr_WindowPtr;
  55.     BPTR    FileLock;
  56.     BOOL    Result = FALSE;
  57.     LONG    LocalError;
  58.  
  59.     if(!Config -> MiscConfig -> ProtectiveMode)
  60.         return(TRUE);
  61.  
  62.     if(!Error)
  63.         Error = &LocalError;
  64.  
  65.         // Lock out DOS requesters
  66.  
  67.     ThisProcess -> pr_WindowPtr = (APTR)-1;
  68.  
  69.         // Does the drawer exist?
  70.  
  71.     if(FileLock = Lock(Drawer,ACCESS_READ))
  72.     {
  73.         struct FileInfoBlock __aligned FileInfo;
  74.  
  75.             // Take a closer look
  76.  
  77.         if(Examine(FileLock,&FileInfo))
  78.         {
  79.                 // Is this actually a file?
  80.  
  81.             if(FileInfo . fib_DirEntryType < 0)
  82.                 *Error = ERR_NOT_A_DRAWER;
  83.             else
  84.             {
  85.                 *Error = 0;
  86.  
  87.                 Result = TRUE;
  88.             }
  89.         }
  90.         else
  91.             *Error = IoErr();
  92.  
  93.         UnLock(FileLock);
  94.     }
  95.     else
  96.     {
  97.         LONG Result2 = IoErr();
  98.  
  99.             // If it doesn't exist, see if we should ask the user to create it
  100.  
  101.         if(Result2 == ERROR_OBJECT_NOT_FOUND && Parent && CanCreate)
  102.         {
  103.             UBYTE    LocalBuffer[MAX_FILENAME_LENGTH];
  104.             STRPTR    Index;
  105.             BOOL    CanCreate = FALSE;
  106.  
  107.                 // Chop off the last path part
  108.  
  109.             strcpy(LocalBuffer,Drawer);
  110.  
  111.             Index = PathPart(LocalBuffer);
  112.  
  113.             *Index = 0;
  114.  
  115.                 // Get a lock on the parent drawer
  116.  
  117.             if(FileLock = Lock(LocalBuffer,ACCESS_READ))
  118.             {
  119.                 struct InfoData __aligned InfoData;
  120.  
  121.                     // Inquire volume information
  122.  
  123.                 if(Info(FileLock,&InfoData))
  124.                 {
  125.                         // Can we write to this volume?
  126.  
  127.                     if(InfoData . id_DiskState == ID_VALIDATED)
  128.                         CanCreate = TRUE;
  129.                 }
  130.  
  131.                 UnLock(FileLock);
  132.             }
  133.  
  134.                 // Give it a try?
  135.  
  136.             if(CanCreate)
  137.             {
  138.                 LT_LockWindow(Parent);
  139.  
  140.                     // Ask if we should create it
  141.  
  142.                 if(ShowRequest(Parent,LocaleString(MSG_VERIFY_NO_DRAWER_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Drawer))
  143.                 {
  144.                     if(FileLock = CreateDir(Drawer))
  145.                     {
  146.                         Result2 = 0;
  147.  
  148.                         Result = TRUE;
  149.  
  150.                         UnLock(FileLock);
  151.                     }
  152.                     else
  153.                         Result2 = IoErr();
  154.                 }
  155.                 else
  156.                 {
  157.                     Result2 = 0;
  158.                     Result = TRUE;
  159.                 }
  160.  
  161.                 LT_UnlockWindow(Parent);
  162.             }
  163.         }
  164.  
  165.         *Error = Result2;
  166.     }
  167.  
  168.     ThisProcess -> pr_WindowPtr = OldPtr;
  169.  
  170.     if(Window && !Result && *Error)
  171.     {
  172.         LT_LockWindow(Parent);
  173.  
  174.         if(*Error == ERR_NOT_A_DRAWER)
  175.             ShowError(Parent,*Error,NULL,Drawer);
  176.         else
  177.             ShowError(Parent,ERR_DRAWER_NOT_FOUND,*Error,Drawer);
  178.  
  179.         LT_UnlockWindow(Parent);
  180.     }
  181.  
  182.     return(Result);
  183. }
  184.  
  185.     /* FindFile(struct Window *Parent,STRPTR File,LONG *Error):
  186.      *
  187.      *    Try to locate a file.
  188.      */
  189.  
  190. BOOL
  191. FindFile(struct Window *Parent,STRPTR File,LONG *Error)
  192. {
  193.     APTR    OldPtr = ThisProcess -> pr_WindowPtr;
  194.     BPTR    FileLock;
  195.     BOOL    Result = FALSE;
  196.     LONG    LocalError;
  197.  
  198.     if(!Config -> MiscConfig -> ProtectiveMode)
  199.         return(TRUE);
  200.  
  201.     if(!Error)
  202.         Error = &LocalError;
  203.  
  204.         // Lock out DOS requesters
  205.  
  206.     ThisProcess -> pr_WindowPtr = (APTR)-1;
  207.  
  208.         // Try to get a lock on the file
  209.  
  210.     if(FileLock = Lock(File,ACCESS_READ))
  211.     {
  212.         struct FileInfoBlock __aligned FileInfo;
  213.  
  214.             // Take a closer look
  215.  
  216.         if(Examine(FileLock,&FileInfo))
  217.         {
  218.                 // Is it actually a drawer?
  219.  
  220.             if(FileInfo . fib_DirEntryType > 0)
  221.                 *Error = ERR_NOT_A_FILE;
  222.             else
  223.             {
  224.                 *Error = 0;
  225.  
  226.                 Result = TRUE;
  227.             }
  228.         }
  229.         else
  230.             *Error = IoErr();
  231.  
  232.         UnLock(FileLock);
  233.     }
  234.     else
  235.         *Error = IoErr();
  236.  
  237.     ThisProcess -> pr_WindowPtr = OldPtr;
  238.  
  239.     if(Window && !Result && *Error)
  240.     {
  241.         LT_LockWindow(Parent);
  242.  
  243.         if(*Error == ERR_NOT_A_FILE)
  244.             ShowError(Parent,*Error,NULL,File);
  245.         else
  246.             ShowError(Parent,ERR_FILE_NOT_FOUND,*Error,File);
  247.  
  248.         LT_UnlockWindow(Parent);
  249.     }
  250.  
  251.     return(Result);
  252. }
  253.  
  254.     /* FindARexxComment(STRPTR LocalBuffer,LONG Len):
  255.      *
  256.      *    Check for a valid ARexx file comment.
  257.      */
  258.  
  259. STATIC BOOL
  260. FindARexxComment(STRPTR LocalBuffer,LONG Len)
  261. {
  262.     register LONG    i;
  263.     register LONG    c;
  264.  
  265.     for(i = 0 ; i < Len - 1 ; i++)
  266.     {
  267.         c = LocalBuffer[i];
  268.  
  269.             // Stop on invalid characters.
  270.  
  271.         if((c < ' ' && c != '\r' && c != '\n' && c != '\a') || (c >= 127 && c < 160))
  272.             break;
  273.         else
  274.         {
  275.                 // Looks like the typical
  276.                 // introductory comment line.
  277.  
  278.             if(c == '/' && LocalBuffer[i + 1] == '*')
  279.                 return(TRUE);
  280.         }
  281.     }
  282.  
  283.     return(FALSE);
  284. }
  285.  
  286.     /* FindProgram(struct Window *Parent,STRPTR Program,LONG *Error):
  287.      *
  288.      *    Try to find a program given by name. Firstly, try to access the
  289.      *    file by its name. If unsuccessful, search the Shell path list.
  290.      *    As a last resort, search the global AmigaDOS resident program
  291.      *    list. Note that while this routine may fail program execution
  292.      *    may still work. WShell for example maintains its own internal
  293.      *    resident list.
  294.      */
  295.  
  296. BOOL
  297. FindProgram(struct Window *Parent,STRPTR Program,LONG *Error)
  298. {
  299.     UBYTE    LocalBuffer[MAX_FILENAME_LENGTH];
  300.     APTR    OldPtr = ThisProcess -> pr_WindowPtr;
  301.     BPTR    FileLock;
  302.     LONG    i;
  303.     BOOL    Result        = FALSE,
  304.             CanExecute    = FALSE;
  305.     LONG    LocalError;
  306.  
  307.     if(!Config -> MiscConfig -> ProtectiveMode)
  308.         return(TRUE);
  309.  
  310.     if(!Error)
  311.         Error = &LocalError;
  312.  
  313.         // Chop off the program arguments
  314.  
  315.     while(*Program == ' ')
  316.         Program++;
  317.  
  318.     strcpy(LocalBuffer,Program);
  319.  
  320.     for(i = 0 ; i < strlen(LocalBuffer) ; i++)
  321.     {
  322.         if(LocalBuffer[i] == ' ')
  323.         {
  324.             LocalBuffer[i] = 0;
  325.  
  326.             break;
  327.         }
  328.     }
  329.  
  330.     Program = LocalBuffer;
  331.  
  332.         // Lock out DOS requesters
  333.  
  334.     ThisProcess -> pr_WindowPtr = (APTR)-1;
  335.  
  336.         // Try to lock the program
  337.  
  338.     if(FileLock = Lock(Program,ACCESS_READ))
  339.     {
  340.         struct FileInfoBlock __aligned FileInfo;
  341.  
  342.             // Take a closer look
  343.  
  344.         if(Examine(FileLock,&FileInfo))
  345.         {
  346.                 // Is it actually a drawer?
  347.  
  348.             if(FileInfo . fib_DirEntryType > 0)
  349.                 *Error = ERR_NOT_A_FILE;
  350.             else
  351.             {
  352.                 BOOL GotIt = FALSE;
  353.  
  354.                     // So far, so good
  355.  
  356.                 *Error = 0;
  357.  
  358.                 Result = TRUE;
  359.  
  360.                     // Is it marked as being executable?
  361.  
  362.                 if(!(FileInfo . fib_Protection & FIBF_EXECUTE))
  363.                 {
  364.                     BPTR    FileHandle;
  365.                     ULONG    Value;
  366.  
  367.                         // Look at the contents
  368.  
  369.                     if(FileHandle = Open(Program,MODE_OLDFILE))
  370.                     {
  371.                         if(Read(FileHandle,&Value,sizeof(ULONG)) == sizeof(ULONG))
  372.                         {
  373.                                 // Not a failproof check, but better than nothing
  374.  
  375.                             if(Value == HUNK_HEADER)
  376.                             {
  377.                                 CanExecute = TRUE;
  378.                                 GotIt = TRUE;
  379.                             }
  380.                         }
  381.  
  382.                         Close(FileHandle);
  383.                     }
  384.                 }
  385.  
  386.                 if(!GotIt)
  387.                 {
  388.                         // Does it have the script bit set? */
  389.  
  390.                     if(FileInfo . fib_Protection & FIBF_SCRIPT)
  391.                         CanExecute = TRUE;
  392.                     else
  393.                     {
  394.                         BPTR FileHandle;
  395.  
  396.                             // Now check if it's an ARexx script.
  397.  
  398.                         if(FileHandle = Open(Program,MODE_OLDFILE))
  399.                         {
  400.                             UBYTE    LocalBuffer[256];
  401.                             LONG    Len;
  402.  
  403.                             if((Len = Read(FileHandle,LocalBuffer,256)) > 0)
  404.                             {
  405.                                 if(CanExecute = FindARexxComment(LocalBuffer,Len))
  406.                                     Result = TRUE;
  407.                             }
  408.  
  409.                             Close(FileHandle);
  410.                         }
  411.                     }
  412.                 }
  413.             }
  414.         }
  415.  
  416.         UnLock(FileLock);
  417.     }
  418.     else
  419.     {
  420.         LONG Result2 = IoErr();
  421.  
  422.         if(Result2 == ERROR_DEVICE_NOT_MOUNTED)
  423.             *Error = ERROR_OBJECT_NOT_FOUND;
  424.         else
  425.             *Error = Result2;
  426.     }
  427.  
  428.         // Give it another try
  429.  
  430.     if(!Result || !CanExecute)
  431.     {
  432.             // Take care
  433.  
  434.         if(ThisProcess -> pr_CLI)
  435.         {
  436.             struct CommandLineInterface    *CLI = BADDR(ThisProcess -> pr_CLI);
  437.             BPTR                         StartCD,
  438.                                          Drawer;
  439.             struct Path                    *Path;
  440.             BOOL                         InitialCD    = TRUE,
  441.                                          GotIt        = FALSE;
  442.  
  443.                 // Run down the Shell path search list
  444.  
  445.             for(Path = BADDR(CLI -> cli_CommandDir) ; Path && !GotIt ; Path = BADDR(Path -> path_Next))
  446.             {
  447.                 Drawer = CurrentDir(Path -> path_Lock);
  448.  
  449.                 if(InitialCD)
  450.                 {
  451.                     StartCD        = Drawer;
  452.                     InitialCD    = FALSE;
  453.                 }
  454.  
  455.                     // Try to lock the program
  456.  
  457.                 if(FileLock = Lock(Program,ACCESS_READ))
  458.                 {
  459.                     struct FileInfoBlock __aligned FileInfo;
  460.  
  461.                         // Take a closer look
  462.  
  463.                     if(Examine(FileLock,&FileInfo))
  464.                     {
  465.                             // Is this a file marked as being executable?
  466.  
  467.                         if(FileInfo . fib_DirEntryType < 0)
  468.                         {
  469.                             if(!(FileInfo . fib_Protection & FIBF_EXECUTE))
  470.                             {
  471.                                 BPTR    FileHandle;
  472.                                 ULONG    Value;
  473.  
  474.                                     // Look at the contents
  475.  
  476.                                 if(FileHandle = Open(Program,MODE_OLDFILE))
  477.                                 {
  478.                                     if(Read(FileHandle,&Value,sizeof(ULONG)) == sizeof(ULONG))
  479.                                     {
  480.                                             // Not a failproof check, but better than nothing
  481.  
  482.                                         if(Value == HUNK_HEADER)
  483.                                             GotIt = TRUE;
  484.                                     }
  485.  
  486.                                     Close(FileHandle);
  487.                                 }
  488.                             }
  489.  
  490.                             if(!GotIt)
  491.                             {
  492.                                     // Does it look like a script?
  493.  
  494.                                 if(FileInfo . fib_Protection & FIBF_SCRIPT)
  495.                                     GotIt = TRUE;
  496.                                 else
  497.                                 {
  498.                                     BPTR FileHandle;
  499.  
  500.                                         // Now check if it's an ARexx script.
  501.  
  502.                                     if(FileHandle = Open(Program,MODE_OLDFILE))
  503.                                     {
  504.                                         UBYTE    LocalBuffer[256];
  505.                                         LONG    Len;
  506.  
  507.                                         if((Len = Read(FileHandle,LocalBuffer,256)) > 0)
  508.                                         {
  509.                                             if(CanExecute = FindARexxComment(LocalBuffer,Len))
  510.                                                 GotIt = TRUE;
  511.                                         }
  512.  
  513.                                         Close(FileHandle);
  514.                                     }
  515.                                 }
  516.                             }
  517.                         }
  518.                     }
  519.  
  520.                     UnLock(FileLock);
  521.                 }
  522.             }
  523.  
  524.             if(!GotIt)
  525.             {
  526.                 BPTR CommandDir = Lock("C:",ACCESS_READ);
  527.  
  528.                 Drawer = CurrentDir(CommandDir);
  529.  
  530.                 if(InitialCD)
  531.                 {
  532.                     StartCD        = Drawer;
  533.                     InitialCD    = FALSE;
  534.                 }
  535.  
  536.                     // Try to lock the program
  537.  
  538.                 if(FileLock = Lock(Program,ACCESS_READ))
  539.                 {
  540.                     struct FileInfoBlock __aligned FileInfo;
  541.  
  542.                         // Take a closer look
  543.  
  544.                     if(Examine(FileLock,&FileInfo))
  545.                     {
  546.                             // Is this a file marked as being executable?
  547.  
  548.                         if(FileInfo . fib_DirEntryType < 0)
  549.                         {
  550.                             if(!(FileInfo . fib_Protection & FIBF_EXECUTE))
  551.                             {
  552.                                 BPTR    FileHandle;
  553.                                 ULONG    Value;
  554.  
  555.                                     // Look at the contents
  556.  
  557.                                 if(FileHandle = Open(Program,MODE_OLDFILE))
  558.                                 {
  559.                                     if(Read(FileHandle,&Value,sizeof(ULONG)) == sizeof(ULONG))
  560.                                     {
  561.                                             // Not a failproof check, but better than nothing
  562.  
  563.                                         if(Value == HUNK_HEADER)
  564.                                             GotIt = TRUE;
  565.                                     }
  566.  
  567.                                     Close(FileHandle);
  568.                                 }
  569.                             }
  570.  
  571.                             if(!GotIt)
  572.                             {
  573.                                     // Does it look like a script?
  574.  
  575.                                 if(FileInfo . fib_Protection & FIBF_SCRIPT)
  576.                                     GotIt = TRUE;
  577.                                 else
  578.                                 {
  579.                                     BPTR FileHandle;
  580.  
  581.                                         // Now check if it's an ARexx script.
  582.  
  583.                                     if(FileHandle = Open(Program,MODE_OLDFILE))
  584.                                     {
  585.                                         UBYTE    LocalBuffer[256];
  586.                                         LONG    Len;
  587.  
  588.                                         if((Len = Read(FileHandle,LocalBuffer,256)) > 0)
  589.                                         {
  590.                                             if(CanExecute = FindARexxComment(LocalBuffer,Len))
  591.                                                 GotIt = TRUE;
  592.                                         }
  593.  
  594.                                         Close(FileHandle);
  595.                                     }
  596.                                 }
  597.                             }
  598.                         }
  599.                     }
  600.  
  601.                     UnLock(FileLock);
  602.                 }
  603.  
  604.                 UnLock(CommandDir);
  605.             }
  606.  
  607.             if(!InitialCD)
  608.                 CurrentDir(StartCD);
  609.  
  610.             if(GotIt)
  611.             {
  612.                 CanExecute = TRUE;
  613.  
  614.                 *Error = 0;
  615.  
  616.                 Result = TRUE;
  617.             }
  618.         }
  619.     }
  620.  
  621.         // As a last resort, scan the resident program list
  622.  
  623.     if(!Result)
  624.     {
  625.         Forbid();
  626.  
  627.         if(FindSegment(Program,NULL,DOSFALSE) || FindSegment(Program,NULL,DOSTRUE))
  628.         {
  629.             CanExecute = TRUE;
  630.  
  631.             *Error = 0;
  632.  
  633.             Result = TRUE;
  634.         }
  635.  
  636.         Permit();
  637.     }
  638.  
  639.         // Last check for ARexx script.
  640.  
  641.     if(!Result)
  642.     {
  643.         UBYTE RexxName[MAX_FILENAME_LENGTH];
  644.  
  645.         strcpy(RexxName,"REXX:");
  646.  
  647.         if(AddPart(RexxName,Program,MAX_FILENAME_LENGTH))
  648.         {
  649.             BPTR FileHandle;
  650.  
  651.                 // Now check if it's an ARexx script.
  652.  
  653.             if(FileHandle = Open(RexxName,MODE_OLDFILE))
  654.             {
  655.                 UBYTE    LocalBuffer[256];
  656.                 LONG    Len;
  657.  
  658.                 if((Len = Read(FileHandle,LocalBuffer,256)) > 0)
  659.                 {
  660.                     if(CanExecute = FindARexxComment(LocalBuffer,Len))
  661.                         Result = TRUE;
  662.                 }
  663.  
  664.                 Close(FileHandle);
  665.             }
  666.         }
  667.     }
  668.  
  669.         // Last check for AmigaDOS script
  670.  
  671.     if(!Result)
  672.     {
  673.         UBYTE ScriptName[MAX_FILENAME_LENGTH];
  674.  
  675.         strcpy(ScriptName,"S:");
  676.  
  677.         if(AddPart(ScriptName,Program,MAX_FILENAME_LENGTH))
  678.         {
  679.             BPTR FileLock;
  680.  
  681.             if(FileLock = Lock(ScriptName,ACCESS_READ))
  682.             {
  683.                 struct FileInfoBlock __aligned FileInfo;
  684.  
  685.                 if(Examine(FileLock,&FileInfo))
  686.                 {
  687.                     if(FileInfo . fib_DirEntryType < 0 && (FileInfo . fib_Protection & FIBF_SCRIPT) && FileInfo . fib_Size > 0)
  688.                         CanExecute = Result = TRUE;
  689.                 }
  690.  
  691.                 UnLock(FileLock);
  692.             }
  693.         }
  694.     }
  695.  
  696.     if(!CanExecute && Result)
  697.     {
  698.         *Error = ERROR_NOT_EXECUTABLE;
  699.  
  700.         Result = FALSE;
  701.     }
  702.  
  703.     ThisProcess -> pr_WindowPtr = OldPtr;
  704.  
  705.     if(Window && !Result && *Error)
  706.     {
  707.         LT_LockWindow(Parent);
  708.  
  709.         if(*Error == ERR_NOT_A_FILE)
  710.             ShowError(Parent,*Error,NULL,Program);
  711.         else
  712.             ShowError(Parent,ERR_PROGRAM_NOT_FOUND,*Error,Program);
  713.  
  714.         LT_UnlockWindow(Parent);
  715.     }
  716.  
  717.     return(Result);
  718. }
  719.  
  720.     /* FindLibDev(struct Window *Parent,STRPTR File,LONG Type,LONG *Error):
  721.      *
  722.      *    Try to locate a file.
  723.      */
  724.  
  725. BOOL
  726. FindLibDev(struct Window *Parent,STRPTR File,LONG Type,LONG *Error)
  727. {
  728.     UBYTE         LocalBuffer[MAX_FILENAME_LENGTH];
  729.     STRPTR         OriginalFile;
  730.     APTR         OldPtr = ThisProcess -> pr_WindowPtr;
  731.     BPTR         FileLock;
  732.     BOOL         Result        = FALSE,
  733.                  Replaced    = FALSE;
  734.     LONG         LocalError;
  735.     struct Node    *Node;
  736.  
  737.     if(!Config -> MiscConfig -> ProtectiveMode)
  738.         return(TRUE);
  739.  
  740.     if(!Error)
  741.         Error = &LocalError;
  742.  
  743.     Forbid();
  744.  
  745.     if(Type == NT_LIBRARY)
  746.         Node = FindName(&SysBase -> LibList,PathPart(File));
  747.     else
  748.         Node = FindName(&SysBase -> DeviceList,PathPart(File));
  749.  
  750.     Permit();
  751.  
  752.     if(Node)
  753.     {
  754.         *Error = 0;
  755.  
  756.         return(TRUE);
  757.     }
  758.  
  759.         // Lock out DOS requesters
  760.  
  761.     ThisProcess -> pr_WindowPtr = (APTR)-1;
  762.  
  763.         // Try to get a lock on the file
  764.  
  765. Look:
  766.  
  767.     if(FileLock = Lock(File,ACCESS_READ))
  768.     {
  769.         struct FileInfoBlock __aligned FileInfo;
  770.  
  771.             // Take a closer look
  772.  
  773.         if(Examine(FileLock,&FileInfo))
  774.         {
  775.                 // Is it actually a drawer?
  776.  
  777.             if(FileInfo . fib_DirEntryType > 0)
  778.                 *Error = ERR_NOT_A_FILE;
  779.             else
  780.             {
  781.                 if(ValidateFile(File,Type,NULL))
  782.                 {
  783.                     *Error = 0;
  784.  
  785.                     Result = TRUE;
  786.                 }
  787.                 else
  788.                     *Error = ERROR_OBJECT_WRONG_TYPE;
  789.             }
  790.         }
  791.         else
  792.             *Error = IoErr();
  793.  
  794.         UnLock(FileLock);
  795.     }
  796.     else
  797.         *Error = IoErr();
  798.  
  799.     if(!Result && !Replaced)
  800.     {
  801.         Replaced = TRUE;
  802.  
  803.         if(Type == NT_LIBRARY)
  804.             strcpy(LocalBuffer,"Libs:");
  805.         else
  806.             strcpy(LocalBuffer,"Devs:");
  807.  
  808.         OriginalFile = File;
  809.  
  810.         if(AddPart(LocalBuffer,File,MAX_FILENAME_LENGTH))
  811.         {
  812.             File = LocalBuffer;
  813.  
  814.             goto Look;
  815.         }
  816.     }
  817.  
  818.     if(Replaced)
  819.         File = OriginalFile;
  820.  
  821.     ThisProcess -> pr_WindowPtr = OldPtr;
  822.  
  823.     if(Window && !Result && *Error)
  824.     {
  825.         LT_LockWindow(Parent);
  826.  
  827.         if(*Error == ERR_NOT_A_FILE)
  828.             ShowError(Parent,*Error,NULL,File);
  829.         else
  830.             ShowError(Parent,ERR_FILE_NOT_FOUND,*Error,File);
  831.  
  832.         LT_UnlockWindow(Parent);
  833.     }
  834.  
  835.     return(Result);
  836. }
  837.