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

hello all...
i am trying to get all .exe files of a given drive ...
i have used this .

Quote

mycmd 'cmd /c dir "H:\*.exe"  /s/w/b/a-d >C:\file.txt'
invoke wshell,addr mycmd


it will not work if there is no write permission in others mechine.
i have used FIND_FIRST_FILE in C
is there any approach in masm32 ??

i just want get all .exe file path one by one in runtime and print .
my previous apporoach store all file path in a .txt file first ...which i dont like at all  :'(

what is the solution ??
Thanks in advance ..

clive

FindFirstFile/FindNextFile/WIN32_FIND_DATA is one way to walk the file tree, and descend into directories. You build the path as you descend and start finding files in the new directory.

All the methods you would use in C, are the same as the ones which would work in ASM.

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

hutch--

The technique that Clive suggested is the one that will do the job, you basically need a recursive function that will climb up a directory structure on each directory listingt the files until it finds another directory or run out of files in that directory. Sounds a bit messy but its simple enough code once you get the swing of FindFirst/Nextfile API pair and the flags you need to pick between files and directories.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

maruf10

how can i implement this ??
any example.....??
i have written a C code which can do the same thing using recursion .
as i am not good in masm32 programming i am unable to convert that .
need an example badly which will print all file name of a given directory  using findfirstfile and findnextfile ... :'(

here is the code portion . it generate all file paths and do some extra work

Quote

void Find(char *Path)

{
   
 
   char tmpPath[MAX_PATH];  //maximum length of full path
   char subPath[MAX_PATH];   
   
   strcpy(tmpPath, Path);
   strcat(tmpPath, "*.*");
   
   WIN32_FIND_DATA FindData;   //describes a file by FindFirstFile,FindNextFile
                               //declares a structur named FindData
   HANDLE hFind = FindFirstFile(tmpPath,&FindData);

   if(hFind == INVALID_HANDLE_VALUE)
      return;
   
   do{
      if(FindData.cFileName[0]=='.')
         continue;
      
   
   if(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )//Specifies the file attributes of the file found
   {                                                        //identify a directory
                                                            //FILE_ATTRIBUTE_DIRECTORY is a mwmber of
                                                          //FindData.dwFileAttributes
                      strcpy(subPath, Path);
                      strcat(subPath, FindData.cFileName);
                  strcpy(holdPath,FindData.cFileName);
                  strcat(subPath, "\\");
                 
                 
                  Find(subPath);
         
      }
      
        else
          iLen=strlen(subPath);
      
      if(subPath[iLen-1]=='*')                 //hidden file
      {
         subPath[iLen-1]='\0';
         
      }
        

       iLen=strlen(holdPath);
      if(holdPath[iLen-1]=='*')
   
   holdPath[iLen-1]='\0';                      //holding current folder name

   total_file++;

     
     
      strcpy(subPath, Path);
       strcat(subPath, FindData.cFileName);   //current file path
     
       
       
   
   
      ttl=0;
   
      fp = fopen("virusname.txt","r");
      
   
        while(fscanf(fp,"%s",name[ttl])==1)
      {
   
       if(strcmp(FindData.cFileName,name[ttl]) == 0)
      {
                  
                    
                  strcpy(subPath, Path);
                    strcat(subPath, FindData.cFileName);
                strcpy(storePath[m],subPath);
               
                   
               
                flagArray[m]=1     ;    //name from file
                file_flag[m]=1;
                m++;
                infected_file++;
               



               
      }
      ttl++;
      }
      fclose(fp);
       

       strcpy(tempPath,holdPath);
      strcat(tempPath,".exe");
   
      if(strcmp(FindData.cFileName,tempPath)==0)
      {
                 
                        
                  strcpy(subPath, Path);
                    strcat(subPath, FindData.cFileName);
                strcpy(storePath[m],subPath);    
               
         

               
                flagArray[m]=2;   //menu will be printed
                file_flag[m]=1;
                m++;
                infected_file++;
      }
      
   
   
   }while( FindNextFile( hFind,&FindData ));

      
   
   
   FindClose(hFind);

     
}


my target is to delete those .exe files which name is same as their folder
e.g :
C:\myfolder\myfolder.exe

in this case i want to delete myfolder.exe

for this reasone i need the full file path to get .exe file name and its corresponding folder

thanks in advance

hutch--

If you understand the logic OK which seems so from your C code, don't convert it, write it from scratch, its faster than the other way.

Start with listing the files in the start directory and when that works OK, then you branch on a directory and change up to it and do the same.

With both FindFirstFile and FindNextFile they work the same as in C but with MASM you use "invoke" instead.

Just atsrt simple and add to it as you get the simpler bits to work.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

clive

I'm not sure if doing this in ASM as opposed to C is going to produce a dramatic improvement in performance. Your C code shows a reasonable grasp of how to attack this.

Algorithmically, I think I'd be caching the path fragment (ie the parent directory name) and passing it down, rather than try to separate if from the full path. You have the sub directory name at hand.

For example

c:\foo\FunnyFolder\FunnyFolder.exe
c:\foo\bar\OddFile\OddFile.exe

Find("c:\foo\FunnyFolder\","FunnyFolder"); // ie Find(subPath, FindData.cFileName);
Find("c:\foo\bar\OddFile\","OddFile");

or even adding the .EXE, passing that down, and doing a case insensitive comparison.

Find("c:\foo\FunnyFolder\","FunnyFolder.exe");

Once you have the efficiency issues modelled in C, doing it once in ASM will be easier. The task is pretty much IO bound.

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

maruf10

what is the equivalent code in masm of this code portion ??
:red
Quote

if(FindData.cFileName[0]=='.')
         continue;


qWord

if this snipped is placed inside an .while or .repeat loop it is similarly to c:
.continue .if FindData.cFileName[0]=='.'
FPU in a trice: SmplMath
It's that simple!

maruf10

 :(... how can i make recursive call like this ??

Quote

int main()
{
     find(pch);
}

void find(char pch)
{
    //some code
     find(pch);
}

clive

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

maruf10

Thanks ....
got it ...
i need little more help ....
what is the equivalen masm code for this??

Quote
iLen=strlen(subPath);
if(subPath[iLen-1]=='*')                 //hidden file
   subPath[iLen-1]='\0';
         

for 1st line have used

Quote

mov iLen,lengthof subPath
dec iLen



what will be the 2nd and 3rd line ??

clive

This doesn't work well if the string is NULL (zero length), does FindFirstFile return a '*'? There is a bit field attribute for hidden.


lea eax,subPath
push eax
call _strlen
add  esp,4

or eax,eax
jz @F
dec eax

cmp byte ptr subPath[eax],'*'
jnz @F
mov byte ptr subPath[eax],0
@@:

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

clive

If you want to understand how the C compiler does it, I would suggest you have it generate a .COD file. This will provide an assembler listing of the code.

cl  -c  -FAcs  foo.c

If you are just linking to C library functions code density and speed aren't going to improved markedly.

-Clive

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

maruf10

at last i have changed the C code

Quote
.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  db "D:\",0
   FindData  WIN32_FIND_DATA <>
   nofile  db 'Error: Invalid path specified.',0
   myTitle  db 'Folder Test',0
   hFind HANDLE ?
   newline db 10,13,0
   
   subPath db ?
   tmpPath db ?
   
   
   holdPath db ?
   ilen dd ?
   Extension db "*.*",0
   done db "here",0
   zero db "0",0
   pBuf dd ?
   Slash db "\",0
   buffer db ?
   
   
   
.code


Find proc Path:dword

   
   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
       invoke MessageBoxA,NULL,addr nofile,addr myTitle,MB_ICONERROR
      invoke ExitProcess,0
   .ENDIF
   
   
   
   
   .repeat
      
      .continue .if FindData.cFileName[0]=='.'
      
      
      
      .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
         
         invoke lstrcpy,addr subPath, Path
         invoke lstrcat,addr subPath,addr FindData.cFileName
         invoke lstrcat,addr subPath,addr Slash
         invoke lstrcpy , addr buffer,addr subPath
             invoke lstrcpy,addr holdPath,addr FindData.cFileName
         invoke lstrcpy , addr subPath,addr buffer
         
         invoke StdOut , addr done
   ;******************************************************      
                        invoke Find , addr subPath           ;this code is crashed here
        ;*****************************************************

         invoke StdOut , addr done
      
      .else
         mov ilen,lengthof subPath
      
      .endif
      
      
         
      mov eax,ilen
      dec eax
      
      .if subPath[eax]=='*'
         mov byte ptr subPath[eax],0
      .endif
      
      mov ilen,lengthof holdPath
      dec eax
      
      .if holdPath[eax]=='*'
         mov byte ptr holdPath[eax],0
      .endif
      
      
      invoke lstrcpy , addr subPath, addr Path
      invoke lstrcat , addr subPath , FindData.cFileName
      invoke StdOut , addr subPath
      
      
      
       invoke FindNextFile,hFind,addr FindData
       mov edx,eax
      
   .until edx!=0
Find endp

start:

   
   invoke Find,addr myPath
   invoke ExitProcess,0
   
END start




it should print all file paths of "D:"
but the code crashes at the time of first recursive call ....
i think i am not handling it properly.

another problem:
there is a file named ".bash_history" in C:
if i want to search file in "C:" at first it find the file .bash_history and starts an infinite loop
but it should be skipped using :
.continue .if FindData.cFileName[0]=='.'
but it works fine in do_while loop in C

what is the solution ??

clive

You need to be using local variables within the subroutine, and it needs to return not drop out the bottom.

ilen is only computed in one branch. Pretty sure lengthof doesn't perform a strlen() operation.

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