News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

how to get all .exe files name of a given drive ??

Started by maruf10, March 30, 2010, 11:30:22 AM

Previous topic - Next topic

maruf10


qWord

myproc proc param:DWORD
LOCAL i:DWORD         ; loacal varibales
LOCAL sz[16]:BYTE     ;
...
    invoke myproc,123 ; recursive call
...
    ret    ;<- return
myproc endp

lengthof is not a runtime operator. use len() macro or call any library function determining string length.
FPU in a trice: SmplMath
It's that simple!

maruf10

thnks ...
but why should i use local ??
and how can i initialize a local varible ??

clive

Quote from: maruf10
but why should i use local ??

Because you are doing recursion. As you walk down the directory tree you need to retain context, so that when you return and continue with the current directory you haven't trashed your workspace. The C example uses local variables, if you made them global it would break.

Recursion implies you need to traverse the tree, going down each branch, coming back up a level and moving to the next branch, and repeating until all the leaves on the tree have been visited. In all these cases you need to remember where you have been so you can get back there later as things unwind.

For example, each time you invoke Find() you need to have a unique hFind handle, and you also need to close the handle when you have finished with it.

-Clive
It could be a random act of randomness. Those happen a lot as well.

maruf10

Thanks ...
but need some help again ...
here is the modified code



.386
.model flat, stdcall
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 Path:DWORD

.data



myPath dd "K",0
nofile dd "E",0
myTitle dd "F",0
newline dd 10,13,0



holdPath dd ?
ilen dd ?
Extension dd "*.*",0
done dd "here",0
zero dd "0",0
pBuf dd ?
Slash dd "\",0
colon dd ":",0
FindData  WIN32_FIND_DATA <>


.code

start:

invoke lstrcat,addr myPath,addr colon
invoke lstrcat,addr myPath,addr Slash
invoke Find,addr myPath
invoke ExitProcess,0


Find proc Path:dword

local tmpPath  :dword
local subPath  :dword
local hFind : HANDLE



invoke lstrcpy,addr tmpPath,Path
invoke lstrcat,addr tmpPath,addr Extension


invoke FindFirstFile,addr tmpPath,addr FindData
mov hFind,eax



.If hFind==INVALID_HANDLE_VALUE
    ret
.endif


.repeat


.if FindData.cFileName[0]!='.'

.if(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
invoke lstrcpy , addr subPath,Path
invoke lstrcat , addr subPath, addr FindData.cFileName
invoke lstrcpy , addr holdPath , addr FindData.cFileName
invoke lstrcat , addr subPath, addr Slash

invoke Find,addr subPath

.else
invoke lstrlen , addr subPath
.endif


    .if subPath[eax-1]=='*'
mov byte ptr subPath[eax-1],0
.endif


invoke lstrlen , addr holdPath
.if holdPath[eax-1]=='*'
mov byte ptr holdPath[eax-1],0
.endif



invoke lstrcpy , addr subPath, Path
invoke lstrcat , addr subPath, addr FindData.cFileName

invoke StdOut , addr subPath
invoke StdOut , addr newline


.endif

invoke FindNextFile , hFind , addr FindData


.until eax==0

invoke FindClose,hFind

Find endp



END start



problems
1.it should print all file pats of dir K: . but it is accessing only one folder of K:
2.recursive call is not working well ... it should return to the next line of calling but it just breaks after printing file paths of one folder
3.output :

Quote
K:\_p\documentataion.doc
K:\_p\documentataion.docpentium.doc
K:\_p\documentataion.docpentium.docpentium.pdf
K:\_p\documentataion.docpentium.docpentium.pdfPentium.ppt
K:\_p\documentataion.docpentium.docpentium.pdfPentium.pptpentium2.pdf
K:\_p\documentataion.docpentium.docpentium.pdfPentium.pptpentium2.pdfpentium_.ppt

it's concating all output one by one  :'(
i need seperate file paths

this code is just the mirror of the previous C code , i think .
but its not working at all :|

any solution ??

i hv attached my original C code which prints all file pats of C:
trying to do the same

sinsi

Don't forget the '\' character between names.

edit: You also need the WIN32_FIND_DATA structure in your Find proc as a local.
Light travels faster than sound, that's why some people seem bright until you hear them.

maruf10

 :red
i dont know how to initialize "FindData  WIN32_FIND_DATA <>" locally ...
what do you mean by '\' char ??

oex

Find proc Path:dword

LOCAL FindData:WIN32_FIND_DATA

and

c:\windows\
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

clive


Find proc Path:dword

local tmpPath  :dword ; Not DWORDs
local subPath  :dword ; Not DWORDs
local hFind : HANDLE

...

.until eax==0

invoke FindClose,hFind

  RET ; Must Return

Find endp
It could be a random act of randomness. Those happen a lot as well.

clive

#24
Let's start by getting your C code to work properly, without the pointless ilen/strlen junk.

void Find(char *Path)
{
  char subPath[MAX_PATH];  //maximum length of full path, temporary storage

  WIN32_FIND_DATA FindData;   //describes a file by FindFirstFile,FindNextFile
                              //declares a structur named FindData
  HANDLE hFind;

  strcpy(subPath, Path); // Build wildcard version for search
  strcat(subPath, "*.*");

  hFind = FindFirstFile(subPath, &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 ((strcmp(FindData.cFileName, ".") != 0) && // Test for . and .. directories
          (strcmp(FindData.cFileName, "..") != 0))
      {
        strcpy(subPath, Path);
        strcat(subPath, FindData.cFileName);
        strcat(subPath, "\\");

        Find(subPath);
      }
    }
    else
    {
      strcpy(subPath, Path);
      strcat(subPath, FindData.cFileName);   //current file path

      printf("%s\n", subPath); // Print the file name
    }
  }
  while(FindNextFile(hFind, &FindData));

  FindClose(hFind);
}
It could be a random act of randomness. Those happen a lot as well.

clive

Here's a quick working assembler example.
-Clive


        .386
        .model flat, stdcall
        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 Path:PTR BYTE

.data

MAXPATH equ 512

myPath db MAXPATH dup (?)

newline db 10,13,0

Extension db "*.*", 0

Drive   db "C", 0
Slash   db "\",0
Colon   db ":",0

.code

start:

        invoke  lstrcpy,addr myPath,addr Drive
        invoke  lstrcat,addr myPath,addr Colon
        invoke  lstrcat,addr myPath,addr Slash
        invoke  Find,addr myPath

        invoke  ExitProcess,0

Find proc Path:PTR BYTE

        local subPath[MAXPATH] : BYTE
        local hFind : HANDLE
        local FindData : WIN32_FIND_DATA

        invoke  lstrcpy,addr subPath, Path
        invoke  lstrcat,addr subPath,addr Extension

        invoke  FindFirstFile, addr subPath, addr FindData

        mov     hFind,eax

        .If (hFind == INVALID_HANDLE_VALUE)
                ret
        .endif

        .repeat

                .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)

                        .if FindData.cFileName[0]!='.' ; Poor test ".foobar" would fail

                        invoke lstrcpy , addr subPath, Path
                        invoke lstrcat , addr subPath, addr FindData.cFileName
                        invoke lstrcat , addr subPath, addr Slash

                        invoke Find,addr subPath

                        .endif

                .else

                        invoke lstrcpy , addr subPath, Path
                        invoke lstrcat , addr subPath, addr FindData.cFileName

                        invoke StdOut , addr subPath
                        invoke StdOut , addr newline

                .endif

                invoke FindNextFile , hFind , addr FindData

        .until eax==0

        invoke FindClose,hFind

        ret

Find endp

        END     start
It could be a random act of randomness. Those happen a lot as well.

clive

Ok, optimizing the algorithm in C because it's easier to demonstrate. This uses a single global path, is more stack friendly, and removes a lot of unnecessary string copies. It limits the work to the end of the path string so the strlen, strcat, and strcpy routines don't have to enumerate over a lot of static junk.

-Clive

#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
    {
      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:\\TEMP\\");

  Find(Path + strlen(Path));
}
It could be a random act of randomness. Those happen a lot as well.

clive

In assembler.

        .386
        .model flat, stdcall
        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:\TEMP\", 0

Slash   db      "\",0

Dot     db      ".",0

DotDot  db      "..",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_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
It could be a random act of randomness. Those happen a lot as well.

maruf10

thanks ...
its working now ...

i am using



invoke szCmp , addr FindData.cFileName , addr Dot
mov ebx,eax
invoke szCmp , addr FindData.cFileName , addr DDot
mov ecx,eax

.if (ebx==0 && ecx==0)
                 ;rest of the code



instead of


         
                if((strcmp(FindData.cFileName, ".") != 0)  && (strcmp(FindData.cFileName, "..") != 0)))
                //rest of the code



i think it ok now .

some Q:
how can i take the directory input from file chooser ??
it may b K:\ or K:\folder or some thing like that which i am passing now to myPath .

how can i write the output string to another .txt file ??

clive

Quote from: maruf10


invoke szCmp , addr FindData.cFileName , addr Dot
mov ebx,eax
invoke szCmp , addr FindData.cFileName , addr DDot
mov ecx,eax

.if (ebx==0 && ecx==0)
                                                ;rest of the code


That's not very efficient, it will always call szCmp twice.

Something like this would eliminate the strcmp from my code, and be much faster.


       mov    eax,dword ptr FindData.cFileName
        cmp    al,02Eh ; Cheap test
        jnz     Find_200 ; not a .XXXX file

        cmp   ax,0002Eh ; . <NUL>
        jz      Find_400 ; skip if .

        shr     eax,8
        cmp   ax,0002Eh ; .. <NUL> first character implicitly .
        jz      Find_400 ; skip if ..


I would take the directory information from the command line, or create a dialog box.

-Clive
It could be a random act of randomness. Those happen a lot as well.