Hello
where can I find an example to search a file named'wordpad.exe' on C:\
thanks
Here's my example.
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 ::)
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 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. ::)
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:
:lol
Those characters are comments.
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
crt_ stands for C RunTime. Google for strcpy instead of crt_strcpy.
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
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));
}
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
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.
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
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?
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
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.
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
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