Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Finding Shared Directories in Assembly

  1. May 6, 2008 #1
    Finding "Shared" Directories in Assembly

    For my next project, I am making a program which searches for all of the shared directories on a computer. My idea is if the directory contains the string "share", then it must be shared.

    For this, I wrote a function to convert the directory name to upper-case letters. After this, the program checks character-by-character for "SHARE". I have no errors in this code when compiled by itself. Once I introduce my directory-search function, I errors. Please look at my code and let me know what I have done wrong.
    Code (Text):
    .386
    .MODEL FLAT

    EXTRN   FindFirstFileA      :PROC
    EXTRN   MessageBoxA     :PROC
    EXTRN   FindNextFileA       :PROC
    EXTRN   FindClose       :PROC
    EXTRN   SetCurrentDirectoryA    :PROC
    EXTRN   lstrcpyA        :PROC

    MAX_PATH            equ 256
    FILE_ATTRIBUTE_DIRECTORY    equ 00000010h

    WIN32_FIND_DATA STRUC
        dwFileAttributes    dd ?
        ftCreationTime      dq ?
        ftLastAccessTime    dq ?
        ftLastWriteTime     dq ?
        nFileSizeHigh       dd ?
        nFileSizeLow        dd ?
        Reserved0       dd ?
        Reserved1       dd ?
        cFileName       db MAX_PATH dup(?)
        cAlternateFileName  db 14 dup(?)
    WIN32_FIND_DATA ENDS

    .DATA
        hFind       dd ?
        szMask      db "*.*", 0
        szBackDir   db "..", 0
        szDirectory db MAX_PATH dup(?)
        win32FindData   WIN32_FIND_DATA <?>
        szDrive     db "C:\", 0

    .CODE
    MAIN:
        push    offset szDrive
        call    SetCurrentDirectoryA

    findFirstFile:
        push    offset win32FindData
        push    offset szMask
        call    FindFirstFileA              ; find first file in C:\ drive
        mov [hFind], eax

    checkType:
        cmp eax, 0                  ; no files?
        je  downDirectory
        cmp byte ptr [win32FindData.cFileName], "."
        je  findNextFile
        cmp [win32FindData.dwFileAttributes], 10h
        je  upDirectory
        cmp [win32FindData.dwFileAttributes], 30h
        je  upDirectory

    findNextFile:
        push    offset win32FindData
        push    [hFind]
        call    FindNextFileA
        jmp checkType

    upDirectory:
        push    offset win32FindData.cFileName
        push    offset szDirectory
        call    lstrcpyA

        mov eax, offset szDirectory

        cmp byte ptr [eax], 90              ; already uppercase? (90 = Z)
        jle toUpperCase
        xor byte ptr [eax], 32              ; convert

    toUpperCase:
        inc eax
        cmp byte ptr [eax], 0               ; at end of string?
        je  endOfString
        cmp byte ptr [eax], 90              ; already uppercase?
        jle toUpperCase
        xor byte ptr [eax], 32              ; convert
        jmp toUpperCase

    endOfString:
        mov eax, 0
        mov eax, offset szDirectory

    searchShare:
        inc eax
        cmp byte ptr [eax], 0               ; end of string?
        jne noShare
        cmp byte ptr [eax], "S"             ; check for S
        jne searchShare
        cmp byte ptr [eax + 1], "H"             ; check for H
        jne searchShare
        cmp byte ptr [eax + 2], "A"             ;
        jne searchShare
        cmp byte ptr [eax + 3], "R"             ;
        jne searchShare
        cmp byte ptr [eax + 4], "E"             ;
        jne searchShare

        push    0
        push    offset szDirectory
        push    offset szDirectory
        push    0
        call    MessageBoxA                 ; display directory

    noShare:
        push    offset szDirectory
        call    SetCurrentDirectoryA
        cmp eax, 0
        je  findNextFile

        push    hFind
        jmp findFirstFile

    downDirectory:
        push    offset szBackDir
        call    SetCurrentDirectoryA
        push    [hFind]
        call    FindClose
        pop [hFind]
        cmp [hFind], 0
        jne findNextFile

    theEnd:
        ret
        END MAIN
    I am using TASM 5.0 and TLINK32 to compile.

    Thanks in advance!
     
  2. jcsd
  3. May 6, 2008 #2

    rcgldr

    User Avatar
    Homework Helper

  4. May 7, 2008 #3
    Yes, but that is not my problem.
    Code (Text):
    [ ... ]
        cmp eax, -1                 ; INVALID_HANDLE_VALUE
    [ ... ]
    Just has the code loop infinitely.

    The code sperately executes fine (the enumerate folders function works by itself; the convert-to-uppercase function works by itself; and the search for "SHARE" function works by itself). When put together, the program fails. It is not until it finds a directory which contains "SHARE" that I get an error.

    Any ideas?
     
  5. May 7, 2008 #4

    rcgldr

    User Avatar
    Homework Helper

    What it the attribute of the "SHARE" entries in the directory? If "SHARE" shows up as a directory, your program could be trying to open up "SHARE" as a sub-directory.

    Also, how are you handing the directory entries "." and "..", which should be ignored?
     
  6. May 8, 2008 #5
    "SHARE" is in the directory's name (WIN32_FIND_DATA.cFileName).
    I'm not sure I understand what you mean by this. However, the program would display a message box before trying to change directories, which it is not doing.
    With the following code:
    Code (Text):
        [ ... ]
        cmp byte ptr [win32FindData.cFileName], "."
        je  findNextFile
        [ ... ]
    The first line checks if the first byte in the string is a period ("."). If it is, the directory is skipped by jumping to the label findNextFile.
     
  7. May 8, 2008 #6

    rcgldr

    User Avatar
    Homework Helper

    I don't understand this sequence in your code:

    Code (Text):

        push    hFind
        jmp findFirstFile
     
    Note that SetCurrentDirectory has no effect on FindNextFile, since FindNextFile uses the data in the WIN32_FIND_DATA STRUC to keep track of where it is at.

    For each new directory you encounter, you need to use a new instance of WIN32_FIND_DATA STRUC (win32FindData), and a new instance of handle (hFind), to call FindFirstFile.

    My method for scanning a directory tree is to use an array of WIN32_FIND_DATA STRUC, and an array of handles (from FindFirstFile). The number of elements is the max level of nesting of directories you program will handle. 64 should be enough.

    The alternative is to place these variables on the stack and use recursive calls.
     
  8. May 8, 2008 #7
    The idea in that code was to save the hFind handle, then jump to the findFirstFile label.

    I disagree. The when the attached file is compiled, it works perfectly. It will display every directory on the C:\ drive without using multiple instances of WIN32_FIND_DATA and my hFind handle.

    Are you saying you create 64 different "win32FindData" structures? If so, this does not sound logical...

    Place the directory names on the stack? There will be hundreds of directory names per drive, so I do not think this would work either...

    Thank you very much for your response though, it's nice to know someone is willing to help me. :smile:
     

    Attached Files:

  9. May 8, 2008 #8

    rcgldr

    User Avatar
    Homework Helper

    I meant nested directories. For example, you can find c:\windows with a FindFirstFile of "c:\*.*", but to find c:\windows\system32, you'll need to use a FindFirstFile with "c:\windows\*.*". Each level of nesting requires a new instance of the handle, and I thought a new instance of the find structure, and a call to FindFirstFile. I'm not sure where windows saves it's current search progress, in the find data structure or in some internal structure related to the handle. Using a new instance of the find data structure for each level of nesting works, but I don't know if it's required.
     
    Last edited: May 8, 2008
  10. May 8, 2008 #9

    rcgldr

    User Avatar
    Homework Helper

    Mutiple instances of the find data structure are not required. The find data structure is described as only being used for output. This means that you just need a new instance of a handle and a call to findfirstfile for each directory you switch into.
     
    Last edited: May 8, 2008
  11. May 8, 2008 #10
    Then why does the enumerate directory code work?
     
  12. May 8, 2008 #11

    rcgldr

    User Avatar
    Homework Helper

    Looks like you should have a "push [hFind]" instead of a "push hFind" just before "downDirectory". I'm guessing this is the problem since you're pushing the offset to hFind instead of it's value, if I understand TASM syntax. It also seems that you should have a "push 0BAADF00Dh" before "FindFirstFile:".

    Shoudln't there be a check for EAX == -1 after the call to FindFirstFile?
     
    Last edited: May 8, 2008
  13. May 12, 2008 #12

    rcgldr

    User Avatar
    Homework Helper

    No response for a while. Did the previous post help solve the problem (specifcally using "push [hfind]")?
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?



Similar Discussions: Finding Shared Directories in Assembly
Loading...