Finding Shared Directories in Assembly

  • Thread starter maple23
  • Start date
  • Tags
    Assembly
In summary, the conversation involves a programmer seeking help with their code for a project that searches for shared directories on a computer. The code uses a function to convert directory names to uppercase and checks for the string "share" in the directory name. There are no errors when the code is compiled on its own, but when the directory-search function is introduced, errors occur. The conversation includes discussions about handling directory entries, using multiple instances of WIN32_FIND_DATA and handle structures, and the possibility of placing directory names on the stack.
  • #1
maple23
15
0
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!
 
Technology news on Phys.org
  • #3
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
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
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
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
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

  • enumerateDirectories.txt
    1.6 KB · Views: 294
  • #8
maple23 said:
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
Jeff Reid said:
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
Then why does the enumerate directory code work?
 
  • #11
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
No response for a while. Did the previous post help solve the problem (specifcally using "push [hfind]")?
 

1. How can I find shared directories in Assembly?

To find shared directories in Assembly, you can use the FindFirstFile and FindNextFile functions to search for files with the FILE_ATTRIBUTE_DIRECTORY flag set. Another option is to use the SHGetKnownFolderPath function and specify the FOLDERID_Public constant to retrieve the path of the Public folder, which is a shared directory in most systems.

2. Can I access shared directories on a network using Assembly?

Yes, you can access shared directories on a network using Assembly. You can use the WNetOpenEnum and WNetEnumResource functions to enumerate all network resources, including shared directories. Once you have the path of the shared directory, you can use the methods mentioned in the first question to access its contents.

3. How do I check if a directory is shared using Assembly?

To check if a directory is shared using Assembly, you can use the GetFileAttributes function and check if the FILE_ATTRIBUTE_DIRECTORY flag is set. If it is, then the directory is a shared directory. Alternatively, you can use the NetShareGetInfo function to retrieve information about a shared directory, including its path and permissions.

4. Is it possible to create a shared directory using Assembly?

Yes, it is possible to create a shared directory using Assembly. You can use the NetShareAdd function to create a new shared directory and specify its name, path, permissions, and other parameters. However, this function requires administrative privileges, so you may need to run your program with elevated privileges.

5. Can I access a shared directory from a different operating system using Assembly?

Yes, you can access a shared directory from a different operating system using Assembly. As long as the shared directory is visible on the network, you can use the methods mentioned in the second question to access its contents. However, the permissions and access may differ, so you may need to handle any errors or exceptions that may occur.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
20
Views
3K
  • Programming and Computer Science
Replies
4
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
2K
  • Programming and Computer Science
Replies
4
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
9
Views
3K
  • Programming and Computer Science
Replies
14
Views
8K
  • Engineering and Comp Sci Homework Help
Replies
12
Views
3K
Back
Top