Finding Shared Directories in Assembly

  • Thread starter maple23
  • Start date
  • #1
15
0

Main Question or Discussion Point

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:
.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!
 

Answers and Replies

  • #3
15
0
Yes, but that is not my problem.
Code:
[ ... ]
	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?
 
  • #4
rcgldr
Homework Helper
8,668
504
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?
 
  • #5
15
0
What it the attribute of the "SHARE" entries in the directory?
"SHARE" is in the directory's name (WIN32_FIND_DATA.cFileName).
If "SHARE" shows up as a directory, your program could be trying to open up "SHARE" as a sub-directory.
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.
Also, how are you handing the directory entries "." and "..", which should be ignored?
With the following code:
Code:
	[ ... ]
	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.
 
  • #6
rcgldr
Homework Helper
8,668
504
I don't understand this sequence in your code:

Code:
	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.
 
  • #7
15
0
The idea in that code was to save the hFind handle, then jump to the findFirstFile label.

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.
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.

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.
Are you saying you create 64 different "win32FindData" structures? If so, this does not sound logical...

The alternative is to place these variables on the stack and use recursive calls.
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:
 

Attachments

  • #8
rcgldr
Homework Helper
8,668
504
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.
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:
  • #9
rcgldr
Homework Helper
8,668
504
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.
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:
  • #10
15
0
Then why does the enumerate directory code work?
 
  • #11
rcgldr
Homework Helper
8,668
504
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:
  • #12
rcgldr
Homework Helper
8,668
504
No response for a while. Did the previous post help solve the problem (specifcally using "push [hfind]")?
 

Related Threads for: Finding Shared Directories in Assembly

Replies
9
Views
907
Replies
9
Views
368
  • Last Post
Replies
20
Views
3K
Replies
5
Views
2K
Replies
4
Views
3K
  • Last Post
Replies
4
Views
1K
Replies
5
Views
4K
Top