No announcement yet.

API Call For File Search?

  • Filter
  • Time
  • Show
Clear All
new posts

  • API Call For File Search?

    Does anybody know of a Windows API function that will search
    a whole specified partition for a specified file name? I looked
    in the WIN32API Help File, and couldn't find anything. If you
    don't know of an actual API that will do this, please don't post
    the code to do it manually, as I can write it myself.

  • #2
    but you have to ask humbly...

    mailto:[email protected][email protected]</A>

    mailto:[email protected][email protected]</A>


    • #3
      OK, I found, in the WIN32API Hlp File, a function called:
      "SearchTreeForFile". By the description of it, it's just what
      I'm looking for. HOWEVER, there is no DECLARE for it in the
      WIN32API.INC file. So, does anybody know the proper DECLARE
      statement for it, so I can add it to the aforementioned .INC?
      I tried adding it under the "KERNEL32.DLL" section, using a
      couple of different settings, but, when I tried to run the test
      program, in both cases I got the Windows error message:
      Program 'TEST.EXE' linked to missing export in KERNEL32.DLL:
      SearchTreeForFile (or something to that effect)

      Any help would be GREATLY appreciated!

      Thanks in advance!


      • #4
        BOOL SearchTreeForFile(
          PSTR RootPath,       
          PSTR InputPathName,  
          PSTR OutputPathBuffer  
        Try DbgHelp.DLL
        This DLL is included with Windows® 2000. 
        To use this DLL on earlier systems, such as Windows NT® 4.0 
        or Windows 98, you can distribute the DLL with your application. 
        Declare Function SearchTreeForFile Lib "DBGHELP.DLL" _
                Alias "SearchTreeForFile"(RootPath as Asciiz, _
                                         InputPathName as Asciiz, _
                                         OutPutPathBuffer as Asciiz) as Long

        mailto:[email protected][email protected]</A>

        [This message has been edited by Fred Oxenby (edited April 03, 2001).]
        mailto:[email protected][email protected]</A>


        • #5
          This API is peculiar in that it's a string function without the usual "A" suffix,
          and the support DLL only comes with Win2K, but it takes ASCIIZ strings (not Unicode).
          I'm not clear that I fully trust it... seems like a last-minute hack that wasn't
          intended for distribution.

          Note that OutputPathBuffer needs to be preallocated to %MAX_PATH characters before
          calling SearchTreeForFile.

          Tom Hanlin
          PowerBASIC Staff


          • #6
            OK, thanks, Fred and Tom.

            I'll just write my own version. I've already created my own
            custom DLL with FUNCTION's that I use heavily in my main EXE's.
            I'll just add the routine to that DLL.

            Tom -

            Go ahead and close this thread if you want. I won't be needing
            to look for replies anymore to my original posting.

            - Clay

            Head SysOp/Owner
            Clear's Critters BBS
            Node 1: (218) 229-2593
            Node 3: (218) 229-3848
            Node 4: (218) 229-2353


            • #7
              Isn't the same call also available in IMAGEHLP.DLL? Never used
              it myself, but it's there alright, from Win98 and up, I think..



              • #8
                Okay - got curious and tested. It's there and works fine when it comes
                to finding specific files. Not very fast though - seems to be using a
                FindFirstFile loop and you have no control over things during a search.
                Same declare as in Fred's example, but for IMAGEHLP.DLL. For the records:
                ' Test of SearchTreeForFile - it returns 1 on succes, 0 on failure
                #COMPILE EXE
                #INCLUDE "WIN32API.INC"
                DECLARE FUNCTION SearchTreeForFile LIB "IMAGEHLP.DLL" _
                                            ALIAS "SearchTreeForFile"(RootPath AS ASCIIZ, _
                                                                     InputPathName AS ASCIIZ, _
                                                                     OutPutPathBuffer AS ASCIIZ) AS LONG
                ' Create dialog and controls, etc
                FUNCTION PBMAIN () AS LONG
                  LOCAL lRes AS LONG
                  LOCAL RootPath         AS ASCIIZ * %MAX_PATH
                  LOCAL InputPathName    AS ASCIIZ * %MAX_PATH
                  LOCAL OutPutPathBuffer AS ASCIIZ * %MAX_PATH
                  RootPath = "c:\"
                  InputPathName = "PBDLL.EXE"
                  MSGBOX "Start search for PBDLL.EXE"
                  lRes = SearchTreeForFile(RootPath, InputPathName, OutPutPathBuffer)
                  MSGBOX FORMAT$(lRes) & $CRLF & OutPutPathBuffer
                END FUNCTION



                • #9
                  Thanks, Borje! I'll try it immediately! I have Win98 SE for an
                  OS, so it should work fine by what you said.

                  Thanks, again!


                  Head SysOp/Owner
                  Clear's Critters BBS
                  Node 1: (218) 229-2593
                  Node 3: (218) 229-3848
                  Node 4: (218) 229-2353


                  • #10
                    OK, Borje was correct, the FUNCTION that is in IMAGEHLP.DLL
                    works fine, and is existent, in Win98 SE. However, unlike
                    Borje's observation, I didn't find it all that slow. I did a
                    search for a file that I knew were at the physical end of the
                    used portion of my HD, and it only took 4-5 seconds. Unless
                    that is considered "slow" by in-the-know PB/DLL programmers?
                    My system is a Pentium III 600EB, and my HD is 40GB, with appr.
                    13GB in use.

                    I found out by empirical testing that the FUNCTION will fail
                    (return FALSE) if wildcards are used in the InputPathName.

                    What would be REAL nice is if it had a corresponding
                    SearchTreeFindFileNext function.



                    Head SysOp/Owner
                    Clear's Critters BBS
                    Node 1: (218) 229-2593
                    Node 3: (218) 229-3848
                    Node 4: (218) 229-2353


                    • #11
                      This may help, TNGMP3 is also posted (CGI app) and may have the code you are looking for.

                      Dave Navarro posted a post a while back that searches the entire drive.
                      Search for WildCardMatch and hopefully it still comes up, if not I will send you the code...

                      Function GetDirList(CurrentDir As String,wFileSpec As String,LfnOrSfn As Long) Export As String
                      Local x        As Long
                      Local wCount   As Long
                      Local hDir     As Long
                      Local f        As String
                      Local sTmp     As String
                      Local St       As String
                      Local ShortName As Asciiz * 64
                      Local LongName As Asciiz * 64
                      Local l_FileSpec As String
                      Local FindData As WIN32_FIND_DATA
                      If Len(wFileSpec) = 0 Then
                          If Right$(CurrentDir,1) = "\" Then CurrentDir = Left$(CurrentDir,Len(CurrentDir) - 1) 'Remove rigt "\"
                          l_FileSpec = CurrentDir + "\*.*"
                         l_FileSpec = CurrentDir + "\" + wFileSpec
                      End If
                      FindData.dwFileAttributes = %FILE_ATTRIBUTE_DIRECTORY
                      hDir = FindFirstFile(ByVal StrPtr(CurrentDir), FindData)
                      If hDir = %INVALID_HANDLE_VALUE Then 'Directory did not exist
                          Function = "File or directory does not exist"
                          Exit Function
                          sTmp = "Directory of " + CurrentDir + "\" + $CRLF
                          hDir = FindFirstFile(ByVal StrPtr(l_FileSpec), FindData)
                          If IsFalse LfnOrSfn Then 'Use Long File Name otherwise use short name
                             LongName = FindData.cFileName
                             GetShortPathName LongName,ShortName, 63
                             FindData.cFileName = ShortName
                          End If
                          If hDir = %INVALID_HANDLE_VALUE Then
                             Function = "File not found"
                             Exit Function
                          End If
                             If FindData.cFileName = "." Or FindData.cFileName = ".." Then Iterate
                             Incr wCount
                             If FindData.dwFileAttributes = %FILE_ATTRIBUTE_DIRECTORY Then
                                     If IsFalse LfnOrSfn Then 'Use Long File Name
                                        LongName = FindData.cFileName
                                        If IsTrue GetShortPathName(LongName,ShortName, 63) Then FindData.cFileName = ShortName
                                     End If
                                     FindData.cFileName = "<" + FindData.cFileName + ">"
                                     sTmp = sTmp + PadString(Left$(FindData.cFilename,25),25,32) + " " + _
                                            PadString(Format$(FindData.nFileSizeLow,"###,###,###"),15,32) + " " + _
                                            padstring(FileDateTime(FindData),15,32) + $CRLF
                              End If
                          Loop While FindNextFile(hDir, FindData)
                      End If
                      FindClose hDir
                      Function = sTmp
                      End Function
                      Scott Turchin
                      MCSE, MCP+I
                      True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi


                      • #12
                        Total credit goes to Dave Navarro for this code, and it's been so long since I looked at it...

                        It has a bug in the display and some minor bugs in that area but it does do the search correctly, I integrated his code with my display (and that's the problem), otherwise works...

                        #Dim All
                        #Register None
                        #Include "WIN32API.INC"
                        #Resource "Where.pbr"
                        Type MyApp
                          title As String * 5
                          ver As String * 4
                          creator As String * 27
                          copyrite As String * 19
                          rights As String * 20
                        End Type
                        Global App As MyApp
                        Declare Function WildMatchFile(ByVal FileName As String, ByVal WildCard As String) As Integer
                        Declare Function FileDateTime(fd As WIN32_FIND_DATA) As String
                        Declare Function DrawCC() As Long
                        Declare Function AppError(ErrType As Long) As Long
                        Declare Function Xprint(St As String,Lf As Long) As Long
                        Declare Function HelpMe() As Long
                        Declare Function NewWindow() As String
                        Declare Function PadFileString(St As String) As String
                        Global RedirFl As Long
                        Global FileNum As Long
                        Global ErrType As Long
                        Function PbMain () As Long
                          Local ThisDir  As Long
                          Local SubDir   As Long
                          Local Found    As Long
                          Local f        As Asciiz * 256
                          Local d        As Asciiz * 256
                          Local hDir     As Long
                          Local FindData As WIN32_FIND_DATA
                          Local Temp     As String
                          Local Tmp      As Long
                          Local k        As Long
                          Local files    As Long
                          Local bytes    As Long
                          Local Period   As Long
                          Local Extention As String
                          Local Redir    As Asciiz * 2
                          Local DirFileName As Asciiz * 256
                          Dim cFileHeader(3) As String
                        Dim App As MyApp
                        app.creator = "Computer Creations Software"
                        app.ver = "v2.2"
                        app.title = "Where"
                        app.copyrite = "Copyright (c) 1998"
                        app.rights = "All rights reserved."
                          Dim dirs(1 To 500) As String
                          Dirs(1)  = Left$(CurDir$,3)
                          d        = Parse$(Command$,1)
                          Redir    = Parse$(Command$,2)
                          If Len(d)=0 Or  Instr(d,"?") Then
                             Exit Function
                          End If
                          If Left$(Redir,1) = ">" Then
                            RedirFl = 1
                            DirFileName = Parse$(Command$,3)
                          End If
                          cFileHeader(1) = App.Title + " " + App.copyrite + " " + App.creator
                          cFileHeader(2) = "Filename       Size     Date     Time     Drive:Path"
                          cFileHeader(3) = "-------------  ------   -------  -------  ---------------------"
                          If RedirFl = 1 Then
                             Filenum = FreeFile
                             Open DirFileName For Output As #Filenum
                          End If
                          For Filenum = 1 To 3
                              If FileNum = 1 Then
                                 Color 15,0
                              ElseIf FileNum = 2 Then
                                 Color 11,0
                              ElseIf FileNum = 3 Then
                                 Color 9,0
                              End If
                              Xprint cFileHeader(Filenum),1
                          Color 7,0
                            SubDir   = 1
                            Found    = 0
                            FindData.dwFileAttributes = %FILE_ATTRIBUTE_DIRECTORY
                            f = Dirs(1) + "*.*"
                            hDir = FindFirstFile(f, FindData)
                            If hDir = %INVALID_HANDLE_VALUE Then
                              Exit Do
                            End If
                              If WildMatchFile(FindData.cFilename, d) Then
                                If IsFalse(Found) Then Found = -1
                                Xprint PadFileString(Left$(FindData.cFilename,12)),0
                                Xprint Format$(FindData.nFileSizeLow,"###,###,###") + "kb " + FileDateTime(FindData) + " " + Dirs(1),1
                                Incr files
                                bytes = bytes + FindData.nFileSizeLow
                              End If
                              If (FindData.dwFileAttributes And %FILE_ATTRIBUTE_DIRECTORY) Then
                                If Asc(FindData.cFilename) <> 46 Then
                                  Incr SubDir
                                  Array Insert Dirs(SubDir), Dirs(1) + FindData.cFilename + "\"
                                End If
                              End If
                              k = Asc(InKey$)
                              If (k = 3) Or (k = 27) Then
                                GoTo Done
                              End If
                            Loop While FindNextFile(hDir, FindData)
                            FindClose hDir
                            Array Delete Dirs(1) For 498
                          Loop While Len(Dirs(1))
                          Xprint "",1
                          Xprint Format$(files,",")+" files found",1
                          Xprint Format$(bytes,",")+" total bytes",1
                          If RedirFl = 1 Then Close FileNum
                        End Function
                        Function WildMatchFile(ByVal FileName As String, ByVal WildCard As String) As Integer
                          Local FilePos  As Integer
                          Local WildPos  As Integer
                          Local FileByte As Integer
                          Local WildByte As Integer
                          '-- "*.*" matches everything --------
                          If WildCard = "*.*" Then
                            WildMatchFile = -1
                            Exit Function
                          End If
                          '-- Convert strings to upper case
                          FileName = UCase$(FileName)
                          WildCard = UCase$(WildCard)
                          FilePos = 1
                          WildPos = 1
                            '-- Get one byte from each string
                            FileByte = Asc(FileName, FilePos)
                            WildByte = Asc(WildCard, WildPos)
                            '-- End of wildcard?  See if we have a match
                            If WildPos > Len(WildCard) Then
                              WildMatchFile = (FilePos >= Len(FileName))
                              Exit Function
                            ' --- End of filename?  No match
                            ElseIf FilePos > Len(FileName) Then
                              WildMatchFile = 0
                              Exit Function
                            '-- Do bytes match?  Or is WildByte a question mark?
                            ElseIf (WildByte = FileByte) Or (WildByte = 63) Then
                              Incr WildPos
                              Incr FilePos
                            '-- Is WildByte an asterisk? (matches everything)
                            ElseIf (WildByte = 42) Then
                              '-- Skip to period or end of filename
                              While (FileByte<>32) And (FileByte<>46) And (FilePos < Len(FileName))
                                Incr FilePos
                                FileByte = Asc(FileName, FilePos)
                              Incr WildPos
                            '-- No match, so exit
                              WildMatchFile = 0
                              Exit Function
                            End If
                        End Function
                        Function FileDateTime(fd As WIN32_FIND_DATA) As String
                          Local fh    As Long
                          Local zText As Asciiz * 256
                          Local st    As SYSTEMTIME
                          Local Temp  As String
                          ' -- Convert the file time from UTC to local time
                          FileTimeToLocalFileTime fd.ftLastWriteTime, fd.ftLastWriteTime
                          ' -- Convert the file time into a compatible system time
                          FileTimeToSystemTime fd.ftLastWriteTime, st
                          ' -- Create a date string using the local settings
                          GetDateFormat %LOCALE_USER_DEFAULT, %NULL, st, "MM/dd/yy", zText, 256
                          Temp = zText
                          ' -- Create a time string using the local settings
                          GetTimeFormat %LOCALE_USER_DEFAULT, %TIME_NOSECONDS, st, "hh:mm tt", zText, 256
                          ' -- Return the file date and time
                          Function = Temp + "  " + zText
                        End Function
                        Function DrawCC() As Long
                        Page 1,2
                        Local X As Integer
                        Local Y As Integer
                        Color 9,0
                        '1st row of "C1"
                        Print String$(5,32)+Chr$(220)+ Chr$(219)+ Chr$(223)+ Chr$(220)+ Chr$(219)
                        '2nd row of "C1"
                        Print String$(4,32)+Chr$(222)+Chr$(219)+Chr$(221)+String$(2,32)+Chr$(219)
                        '3rd row of "C1"
                        Print String$(4,32)+String$(2,219)+String$(3,32);
                        Color 11,0
                        '1st row of "C2"
                        Print Chr$(220)+ Chr$(219)+ Chr$(223)+ Chr$(220)+ Chr$(219)
                        '4th row of "C1"
                        Color 9,0
                        Print String$(4,32)+Chr$(222)+Chr$(219)+Chr$(221)+Chr$(32);
                        Color 11,0
                        '2nd row of "C2"
                        Print Chr$(222)+Chr$(219)+Chr$(221)+String$(2,32)+Chr$(219)
                        '5th row of "C1"
                        Color 9,0
                        Print String$(5,32)+Chr$(223)+Chr$(219)+Chr$(220);
                        '3rd row of "C2"
                        Color 11,0
                        Print String$(2,219)+String$(3,32);
                        Color 9,0:Print 'Left$(App.Creator,8)
                        '4th row of "C2"
                        Color 11,0
                        Print String$(8,32)+Chr$(222)+Chr$(219)+Chr$(221)+String$(3,32);
                        Color 9,0
                        Print "  " + App.creator
                        Color 11,0
                        '5th row of "C2"
                        Print String$(9,32)+Chr$(223)+Chr$(219)+Chr$(220)+Chr$(220)+Chr$(223);
                        Color 14,0: Print"  " + App.title + " " + App.Ver + " 32 bit"
                        If Y < 25 Then Locate X,17 Else Print:Locate X,17
                        Color 11,0
                        Print app.copyrite;
                        Print " " + app.rights
                        If Y < 25 Then Locate X + 1,17 Else Print:Locate X + 1,17
                        Color 15,0:Print ""
                        Color 7,0
                        Page 1,1
                        End Function
                        Function Xprint(St As String,Lf As Long) As Long
                        On Error GoTo XprintErr
                        If RedirFl = 1 Then
                           Print #Filenum,St;
                           If Lf > 0 Then Print #FileNum, ""
                           stdout St;
                           If Lf > 0 Then StdOut ""
                        End If
                        Function = 1
                        Exit Function
                        ErrType = Err
                        AppError ErrType
                        Function = 0
                        End Function
                        Function AppError(ErrType As Long) As Long
                        Dim Er(100) As Asciiz * 50
                        Er(0)= "No Error
                        Er(5)= "Illegal Function Call
                        Er(7)= "Out of memory
                        Er(9)= "Subscript / Pointer Out of range
                        Er(51)= "Internal Error
                        Er(52)= "Bad file Name Or number
                        Er(53)= "File Not found
                        Er(54)= "Bad file mode
                        Er(55)= "File is already Open
                        Er(57)= "Device I/O Error
                        Er(58)= "File already exists
                        Er(61)= "Disk full
                        Er(62)= "Input past End
                        Er(63)= "Bad record number
                        Er(64)= "Bad file Name
                        Er(67)= "Too many files
                        Er(68)= "Device unavailable
                        Er(70)= "Permission denied
                        Er(71)= "Disk Not ready
                        Er(72)= "Disk media Error
                        Er(74)= "Rename across disks
                        Er(75)= "Path/file access Error
                        Er(76)= "Path Not found"
                        Print  "Error: " + Ltrim$(Str$(ErrType))
                        End Function
                        Function HelpMe() As Long
                        Local I As Asciiz * 2
                        Color 7,0
                        StdOut "Useage: Where <filename.ext> <options>"
                        StdOut " Where <filename.ext> can be any combination of wildcards"
                        StdOut "  Where *.*, Where *.txt Where Myfile.*"
                        StdOut "Options:"
                        StdOut " Where filename.ext > yourfile.ext   --> redirect to a file"
                        StdOut " Where filename.ext |more   --> pause after 24 lines"
                        StdOut ""
                        End Function
                        Function NewWindow() As String
                        Local hWnd As Long
                        Local TmpAsciiz As Asciiz * %Max_Path
                        Local y As Long
                        hWnd = GetForegroundWindow
                        If GetWindowThreadProcessId(hWnd, GetCurrentProcessId) <> GetCurrentThreadId Then
                           GetModuleFileName GetModuleHandle(ByVal 0), TmpAsciiz, SizeOf(TmpAsciiz) - 1
                           y = Shell (Chr$(34) + TmpAsciiz + Chr$(34, 32) + Command$, 1)
                           Exit Function
                        End If
                        'Console Screen , WindowY
                        Function =  Command$
                        End Function
                        Function PadFileString(St As String) As String
                        Local l_szSt As String * 14
                        Function = l_szSt
                        End Function
                        Scott Turchin
                        MCSE, MCP+I
                        True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi