The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: franlou on June 07, 2010, 01:11:56 PM

Title: find a file
Post by: franlou on June 07, 2010, 01:11:56 PM
Hello
where can I find an example to search a file named'wordpad.exe' on C:\
thanks
Title: Re: find a file
Post by: aker on June 07, 2010, 01:15:48 PM
Here's my example.
Title: Re: find a file
Post by: franlou on June 07, 2010, 03:04:35 PM
Quote from: aker on June 07, 2010, 01:15:48 PM
Here's my example.
Thank's I try it
Title: Re: find a file
Post by: frktons on June 07, 2010, 03:32:40 PM
Quote from: aker on June 07, 2010, 01:15:48 PM
Here's my example.

What did you put inside the source code?
example:

comment #
Microsoft Windows Vista Ultimate 32-bit english with Service Pack 1
  C:\ydctemp>dir c:\ /a-d/s/b>Result.txt
¹¦ÄÜ
  È«ÅÌÎļþËÑË÷³ÌÐò ¡ª¡ª Ö¸¶¨Ò»¸öÆðʼĿ¼£¬²éÕÒËùÓÐÎļþ£¨°üÀ¨×ÓĿ¼ÏµÄÎļþ£©
ʹÓà nmake »òÏÂÁÐÃüÁî½øÐбàÒëºÍÁ´½Ó
  ml.exe /c /coff FindFile.asm
  rc.exe FindFile.rc
  link.exe /subsystem:windows FindFile.obj FindFile.res
#
.386
.model flat,stdcall
option casemap:none
include windows.inc
;Include Îļþ¶¨Òå
include user32.inc


I can't understand what those characters mean  ::)
Title: Re: find a file
Post by: clive on June 07, 2010, 04:34:05 PM
Well it's hideous, this hopefully is a little clearer

FINDER.ASM
; ml -coff -Fl finder.asm -link /SUBSYSTEM:CONSOLE

        .386
        option casemap:none

        include \masm32\include\masm32rt.inc
        include \masm32\include\debug.inc

        includelib \masm32\lib\kernel32.lib
        includelib \masm32\lib\masm32.lib
        includelib \masm32\lib\debug.lib

        Find proto ThisPath:PTR BYTE

        .data

MAXPATH equ 512

Path    db      MAXPATH dup (?)

NewLine db      13,10,0

Extension db    "*.*", 0

Root    db      "C:\", 0

Slash   db      "\",0

Dot     db      ".",0

DotDot  db      "..",0

Match   db      "wordpad.exe",0

        .code

start:

        invoke  crt_strcpy, addr Path,addr Root

        invoke  crt_strlen, addr Path
        lea     eax,[Path + eax]
        invoke  Find, eax

        invoke  ExitProcess,0


; Now some real assembler, not some pansy ass stuff

Find    proc    ThisPath:PTR BYTE

        local FindData : WIN32_FIND_DATA

        push    esi ; ThisPath
        push    edi ; hFile HANDLE

        mov     esi, ThisPath

        invoke  crt_strcpy, esi, addr Extension

        invoke  FindFirstFile, addr Path, addr FindData

        mov     edi,eax ; hFile

        cmp     eax, INVALID_HANDLE_VALUE
        jz      Find_500

Find_100:

        test    [FindData.dwFileAttributes], FILE_ATTRIBUTE_DIRECTORY
        jz      Find_300

; Directory Branch

        cmp     byte ptr FindData.cFileName[0],'.' ; Cheap test
        jnz     Find_200 ; not a .XXXX file

        invoke  crt_strcmp, addr Dot, addr FindData.cFileName
        or      eax,eax
        jz      Find_400 ; skip if .

        invoke  crt_strcmp, addr DotDot, addr FindData.cFileName
        or      eax,eax
        jz      Find_400 ; skip if ..

Find_200:

        invoke  crt_strcpy, esi, addr FindData.cFileName
        invoke  crt_strcat, esi, addr Slash

        invoke  crt_strlen, esi ; ThisPath

        lea     eax,[esi + eax] ; ThisPath + strlen(ThisPath)

        invoke  Find, eax

        jmp     Find_400

; File Branch

Find_300:

        invoke  crt__stricmp, addr FindData.cFileName, addr Match ; Match to specific file
        or      eax,eax
        jnz     Find_400 ; Not matched

        invoke  crt_strcpy, esi, addr FindData.cFileName

        invoke  StdOut, addr Path
        invoke  StdOut, addr NewLine

; Next File/Directory

Find_400:

        invoke FindNextFile, edi, addr FindData

        or      eax,eax
        jnz     Find_100

        invoke  FindClose, edi

; Leave

Find_500:

        pop     edi
        pop     esi
        ret

Find    endp

        END     start
Title: Re: find a file
Post by: frktons on June 07, 2010, 05:13:09 PM
Quote from: clive on June 07, 2010, 04:34:05 PM
Well it's hideous, this hopefully is a little clearer

FINDER.ASM
; ml -coff -Fl finder.asm -link /SUBSYSTEM:CONSOLE

        .386
        option casemap:none

        include \masm32\include\masm32rt.inc
        include \masm32\include\debug.inc

        includelib \masm32\lib\kernel32.lib
        includelib \masm32\lib\masm32.lib
        includelib \masm32\lib\debug.lib

        Find proto ThisPath:PTR BYTE

        .data

MAXPATH equ 512

Path    db      MAXPATH dup (?)

NewLine db      13,10,0

Extension db    "*.*", 0

Root    db      "C:\", 0

Slash   db      "\",0

Dot     db      ".",0

DotDot  db      "..",0

Match   db      "wordpad.exe",0

        .code

start:

        invoke  crt_strcpy, addr Path,addr Root

        invoke  crt_strlen, addr Path
        lea     eax,[Path + eax]
        invoke  Find, eax

        invoke  ExitProcess,0


; Now some real assembler, not some pansy ass stuff

Find    proc    ThisPath:PTR BYTE

        local FindData : WIN32_FIND_DATA

        push    esi ; ThisPath
        push    edi ; hFile HANDLE

        mov     esi, ThisPath

        invoke  crt_strcpy, esi, addr Extension

        invoke  FindFirstFile, addr Path, addr FindData

        mov     edi,eax ; hFile

        cmp     eax, INVALID_HANDLE_VALUE
        jz      Find_500

Find_100:

        test    [FindData.dwFileAttributes], FILE_ATTRIBUTE_DIRECTORY
        jz      Find_300

; Directory Branch

        cmp     byte ptr FindData.cFileName[0],'.' ; Cheap test
        jnz     Find_200 ; not a .XXXX file

        invoke  crt_strcmp, addr Dot, addr FindData.cFileName
        or      eax,eax
        jz      Find_400 ; skip if .

        invoke  crt_strcmp, addr DotDot, addr FindData.cFileName
        or      eax,eax
        jz      Find_400 ; skip if ..

Find_200:

        invoke  crt_strcpy, esi, addr FindData.cFileName
        invoke  crt_strcat, esi, addr Slash

        invoke  crt_strlen, esi ; ThisPath

        lea     eax,[esi + eax] ; ThisPath + strlen(ThisPath)

        invoke  Find, eax

        jmp     Find_400

; File Branch

Find_300:

        invoke  crt__stricmp, addr FindData.cFileName, addr Match ; Match to specific file
        or      eax,eax
        jnz     Find_400 ; Not matched

        invoke  crt_strcpy, esi, addr FindData.cFileName

        invoke  StdOut, addr Path
        invoke  StdOut, addr NewLine

; Next File/Directory

Find_400:

        invoke FindNextFile, edi, addr FindData

        or      eax,eax
        jnz     Find_100

        invoke  FindClose, edi

; Leave

Find_500:

        pop     edi
        pop     esi
        ret

Find    endp

        END     start


Quote
this hopefully is a little clearer

That definitely is clearer  :bg

Thanks Clive, you're always very helpful indeed.  :U

It would be nice to have the GUI hideous version  in clear for the sake
of studying it.
I hope aker is going to post the readable version soon or later.  ::)
Title: Re: find a file
Post by: franlou on June 07, 2010, 06:08:09 PM
Quote from: frktons on June 07, 2010, 05:13:09 PM
Quote from: clive on June 07, 2010, 04:34:05 PM
Well it's hideous, this hopefully is a little clearer

FINDER.ASM
; ml -coff -Fl finder.asm -link /SUBSYSTEM:CONSOLE

        .386
        option casemap:none

        include \masm32\include\masm32rt.inc
        include \masm32\include\debug.inc

        includelib \masm32\lib\kernel32.lib
        includelib \masm32\lib\masm32.lib
        includelib \masm32\lib\debug.lib

        Find proto ThisPath:PTR BYTE

        .data

MAXPATH equ 512

Path    db      MAXPATH dup (?)

NewLine db      13,10,0

Extension db    "*.*", 0

Root    db      "C:\", 0

Slash   db      "\",0

Dot     db      ".",0

DotDot  db      "..",0

Match   db      "wordpad.exe",0

        .code

start:

        invoke  crt_strcpy, addr Path,addr Root

        invoke  crt_strlen, addr Path
        lea     eax,[Path + eax]
        invoke  Find, eax

        invoke  ExitProcess,0


; Now some real assembler, not some pansy ass stuff

Find    proc    ThisPath:PTR BYTE

        local FindData : WIN32_FIND_DATA

        push    esi ; ThisPath
        push    edi ; hFile HANDLE

        mov     esi, ThisPath

        invoke  crt_strcpy, esi, addr Extension

        invoke  FindFirstFile, addr Path, addr FindData

        mov     edi,eax ; hFile

        cmp     eax, INVALID_HANDLE_VALUE
        jz      Find_500

Find_100:

        test    [FindData.dwFileAttributes], FILE_ATTRIBUTE_DIRECTORY
        jz      Find_300

; Directory Branch

        cmp     byte ptr FindData.cFileName[0],'.' ; Cheap test
        jnz     Find_200 ; not a .XXXX file

        invoke  crt_strcmp, addr Dot, addr FindData.cFileName
        or      eax,eax
        jz      Find_400 ; skip if .

        invoke  crt_strcmp, addr DotDot, addr FindData.cFileName
        or      eax,eax
        jz      Find_400 ; skip if ..

Find_200:

        invoke  crt_strcpy, esi, addr FindData.cFileName
        invoke  crt_strcat, esi, addr Slash

        invoke  crt_strlen, esi ; ThisPath

        lea     eax,[esi + eax] ; ThisPath + strlen(ThisPath)

        invoke  Find, eax

        jmp     Find_400

; File Branch

Find_300:

        invoke  crt__stricmp, addr FindData.cFileName, addr Match ; Match to specific file
        or      eax,eax
        jnz     Find_400 ; Not matched

        invoke  crt_strcpy, esi, addr FindData.cFileName

        invoke  StdOut, addr Path
        invoke  StdOut, addr NewLine

; Next File/Directory

Find_400:

        invoke FindNextFile, edi, addr FindData

        or      eax,eax
        jnz     Find_100

        invoke  FindClose, edi

; Leave

Find_500:

        pop     edi
        pop     esi
        ret

Find    endp

        END     start


Quote
this hopefully is a little clearer

That definitely is clearer  :bg

Thanks Clive, you're always very helpful indeed.  :U

It would be nice to have the GUI hideous version  in clear for the sake
of studying it.
I hope aker is going to post the readable version soon or later.  ::)

splendid :U :clap:
Title: Re: find a file
Post by: aker on June 08, 2010, 12:30:48 AM
 :lol
Those characters are comments.
Title: Re: find a file
Post by: franlou on June 08, 2010, 04:58:18 PM
ok
I'm sorry but there is a long time ago that I don't practice MASM
and I don't know where are this subroutines: :red

"invoke  crt_strcpy, addr Path,addr Root
invoke  crt_strlen, addr Path
crt_strcmp
crt_strcpy, esi, addr FindData.cFileName
crt_strcat, esi, addr Slash
StdOut..."
are there the some that  'lstrcmpi ,lstrcmp, lstrcat, lstrcpy ..' thay I found  in Win32 Programmer's Reference in the chapter '  the functions used with string manipulation' ?  :dazzled:
thank's
Title: Re: find a file
Post by: jj2007 on June 08, 2010, 05:05:18 PM
crt_ stands for C RunTime. Google for strcpy instead of crt_strcpy.
Title: Re: find a file
Post by: frktons on June 08, 2010, 05:36:56 PM
Quote from: aker on June 08, 2010, 12:30:48 AM
:lol
Those characters are comments.

So if I delete them, the rest is the actual MASM program?

Well it is supposed comments help to highlight chunks of code, don't them?  :P
Title: Re: find a file
Post by: clive on June 08, 2010, 05:38:18 PM
strcmp - String Compare (0 if equivalent)
stricmp - String Compare - Case Insensitive
strcpy - String Copy
strcat - String Concatenate
strlen - String Length

They pull from MSVCRT.DLL

Equivalent code in C
// cl -Ox finder.c

#include <windows.h>

#include <stdio.h>
#include <stdlib.h>

char Path[MAX_PATH];  //maximum length of full path

void Find(char *EndPath) // End of Path passed down
{
  HANDLE hFind; // Local context, required unique for each descent

  WIN32_FIND_DATA FindData;   // describes a file by FindFirstFile,FindNextFile
                              //  declares a structure named FindData

  strcpy(EndPath, "*.*"); // Build wildcard version for search

  hFind = FindFirstFile(Path, &FindData);

  if (hFind == INVALID_HANDLE_VALUE)
    return;

  do
  {
    if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //Specifies the file attributes of the file found
    {                                                         //identify a directory
                                                              //FILE_ATTRIBUTE_DIRECTORY is a member of
                                                              //FindData.dwFileAttributes

      if ((FindData.cFileName[0] != '.') ||           // Cheap test for most cases
          ((strcmp(FindData.cFileName, ".") != 0) &&  // More expensive test for . and .. directories
           (strcmp(FindData.cFileName, "..") != 0)))
      {
        strcpy(EndPath, FindData.cFileName); // append current directory to the path
        strcat(EndPath, "\\");

        Find(EndPath + strlen(EndPath)); // Recurse, passing new end of path to optimize concatenation
      }
    }
    else
    {
      // Use a case insensitive compare to produce a list of files

      if (stricmp(FindData.cFileName, "wordpad.exe") == 0) // File wordpad.exe
      {
        strcpy(EndPath, FindData.cFileName);   // append current file to path

        puts(Path); // Print the file name, with the whole path
      }
    }
  }
  while(FindNextFile(hFind, &FindData));

  FindClose(hFind);
}

int main(int argc, char **argv)
{
  strcpy(Path, "C:\\");

  Find(Path + strlen(Path));
}
Title: Re: find a file
Post by: franlou on June 09, 2010, 06:02:05 AM
Hi
When I was programming I used the String Manipulation Functions from "Microsoft® Win32® Programmer's Reference " where I found :
lstrcat
lstrcmp
lstrcmpi
lstrcpy
lstrcpyn
lstrlen

What is the difference with the functions which are in  MSVCRT.DLL?
is there an advanvantage?
thank's
Title: Re: find a file
Post by: clive on June 09, 2010, 01:18:51 PM
From the DLL they take very little space in the application. It would get bigger if I statically linked against a LIB file which would link the functions directly into the EXE.

The lstrxxx functions from Win32 might also be usable (they also live in a DLL), I used the crt_strxxx versions in MASM32's include file because it was convenient.
Title: Re: find a file
Post by: franlou on June 16, 2010, 05:02:28 PM
Hi
I try the code of clive
But I am worried
I got ALL paths where there is "wordpad.exe"

but in fact It is only the first occurence which is interesting for me:
"C:\ProgramFiles\WindowsNT\Accessories\wordpad.exe"

It is the path of the application;
The others are not intresting for me , then I wish ended the subroutine

How to end properly the routine in this case?
thank you
Title: Re: find a file
Post by: clive on June 16, 2010, 05:35:04 PM
Yes, it is searching "C:" for occurrences of the file. Do you know the first occurrence is the correct one, as there is no guarantee that is the case? It will basically find any/ALL files which have this name. One would normally search directories in the PATH (environment variable), SYSTEMROOT, or PROGRAMFILES for standard applications.

To find the first match and then stop, you will have to write code to exit the loop and unwind/terminate the recursion. Would an example in C be instructive?
Title: Re: find a file
Post by: dedndave on June 16, 2010, 05:36:26 PM
one approach would be to read the default registry value for [HKEY_CLASSES_ROOT\Applications\wordpad.exe\shell\open\command]
that way, you don't have to search at all   :bg
the WordPad.exe file is sometimes not located in the Windows\System32 folder, or in any of the PATH'ed folders
Title: Re: find a file
Post by: clive on June 16, 2010, 05:55:15 PM
I guess I would be interested in more details of the actual purpose for this code. And why more classical approaches might not work. For example there are forms of spawn() that will search for executables.

As Dave indicates there are many ways to narrow the search, and then expand it when the more "usual" locations have been eliminated, and finally doing a whole drive search. I will note that the search order for directories/files provided by FindFirstFile/FindNextFile is some what arbitrary, based on the order they were created in the file system. A more complicated solution is to sort the names during gathering, and then descend the directories in alphabetic order, or go with the file system optimized order and either queue the directories for descent, or sort the whole tree laters.

I would also worry about some clown calling their file WORDPAD.EXE to catch people/applications that spider the drive in this fashion.
Title: Re: find a file
Post by: franlou on June 17, 2010, 08:30:52 AM
In fact my problem is this:
in 2000, I made an application which could have need (only sometimes ) of 'Wordpad.exe' and I needed to locate it .
So I stored the path of this application in registry, in a record user-specific data under the HKEY_CURRENT_USER key

with the old versions of windows I looked for 'wordpad.exe', and I stored the path ; It was nice with Windows9x, but not later...

So the routine that clive display ALL 'wordpad.exe'; I did not know that they had  several;

I wish get ONLY   the path of application  : here (Windows vista)   "C:\ProgramFiles\WindowsNT\Accessories\wordpad.exe" to store it in registry

is it always the  same path in diffent version of Windows? if yes my problem is resolved.

thank's




Title: Re: find a file
Post by: dedndave on June 17, 2010, 10:03:36 AM
it may be in different places for different versions of windows
you should have a look at the registry value:

[HKEY_CLASSES_ROOT\Applications\wordpad.exe\shell\open\command]

the information you want is already stored in the registry for you
it is unicode text, so each character is followed by a null (0 byte)
under XP, the value is:

"%ProgramFiles%\Windows NT\Accessories\WORDPAD.EXE" "%1"

you can strip off the "%1" and expand the environment variable %ProgramFiles% and have a complete path

otherwise, you could look in that specific folder first
then, look in %SystemRoot%\System32, then %SystemRoot%

but, it is probably "the proper way" to look at the registry value