Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

Assembly, Directory Handling - The Current Directory (Win32, NASM)

assembly

  • Please log in to reply
No replies to this topic

#1 RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1307 posts
  • Location:C:\Countries\US
  • Programming Language:C, Java, C++, PHP, Python, JavaScript

Posted 27 August 2011 - 03:51 PM

When a program is started, its current directory is usually set to whatever the current directory is of its starter (such as the current working directory of the command prompt window you typed the program's name in, to start it).

In this tutorial, we would go over how to change and retrieve the current directory of the program.

Overview
  • Changing/Getting The Current Directory
  • Example Program








Changing/Getting The Current Directory
Even though changing or retrieving the current directory is not that much of a hard thing to do, it's still a good thing to know how to do.

SetCurrentDirectory
SetCurrentDirectory is the Win32 API function we'll use for changing the current directory.

Parameters:
  • The name of the directory to change to; this can be a relative path or a full path.

Return:
BOOL
If the function succeeds, the return value is non-zero (TRUE). The return value is zero (FALSE), otherwise.

For more reference to this function, go to SetCurrentDirectory Function (Windows).

To get the current directory, use GetCurrentDirectory().

GetCurrentDirectory

Parameters:
  • The size of the buffer that would receive the current directory name.
  • The pointer to that buffer.

Return:
The length of the current directory name. If the function fails, returns 0.

For more reference to this function, go to GetCurrentDirectory Function (Windows).









Example Program
We'll base this example program on last time's example program, except:
  • We'll change the directory to ".." after displaying the message box.
  • We would get another directory listing of the current directory (that we just changed) and display a message box with that.
  • Then we'll get the current directory and display a message box with it.

The changes from last tutorial's example program are outlined in orange.

The Code:
;; Define the externs. 
extern FindFirstFileA 
extern FindNextFileA 
extern FindClose 
extern GetLastError 
extern MessageBoxA 
extern ExitProcess            ;[COLOR=#FF8C00]
extern GetCurrentDirectoryA 
extern SetCurrentDirectoryA   ;[/COLOR]

;; Construct our symbol import table. 
import FindFirstFileA kernel32.dll 
import FindNextFileA kernel32.dll 
import FindClose kernel32.dll 
import GetLastError kernel32.dll 
import MessageBoxA user32.dll 
import ExitProcess kernel32.dll              ;[COLOR=#FF8C00]
import GetCurrentDirectoryA kernel32.dll 
import SetCurrentDirectoryA kernel32.dll     ;[/COLOR]

;; The following goes into the code section of the program; use 32-bit code. 
section .text use32 
;; Start program execution at this point. 
..start: 

;; Call the main() function. 
call main 

;; Exit, returning whatever main() returned. 
push eax 
call [ExitProcess] 

main: 
	;; [ebp-4096]= start of a string 
	enter 4096, 0 
	
	;; Initialize the string to "" (blank). 
	mov byte [ebp-4096], 0 
	
	;; Call the function that would scan through the directory listing. 
	lea eax, [ebp-4096] 
	push eax                                ;; This is the optional parameter for the callback function. 
	;; We use the address of our new string for this parameter. 
	push dword our_callback_function        ;; This is the address of the callback function; the callback 
	;; function is called for each item in the directory scan. 
	push dword file_search_string           ;; This is the path/string that is used for the search. 
	call dir_scan 
	
	;; Now we display a message box with our new string. 
	push dword 0 
	push dword the_title 
		lea eax, [ebp-4096] 
	push eax 
	push dword 0 
	call [MessageBoxA] 
	
	;[COLOR=#FF8C00]; Reset the string to "" (blank again). 
	mov byte [ebp-4096], 0 
	
	;; Change the current directory to the parent directory. 
	push dword new_directory                ;; The new directory to use. 
	call [SetCurrentDirectoryA] 
	
	;; We get the listing of this directory, now. 
	lea eax, [ebp-4096] 
	push eax 
	push dword our_callback_function 
	push dword file_search_string 
	call dir_scan 
	
	;; Now display the message box. 
	push dword 0 
	push dword the_title 
		lea eax, [ebp-4096] 
	push eax 
	push dword 0 
	call [MessageBoxA] 
	
	;; Get the current directory and save it to our string. 
	lea eax, [ebp-4096] 
	push eax                                ;; The pointer to the buffer that would receive the name of the current directory. 
	push dword 4096                         ;; The size of the buffer. 
	call [GetCurrentDirectoryA] 
	
	;; Now display the message box. 
	push dword 0 
	push dword the_title 
		lea eax, [ebp-4096] 
	push eax 
	push dword 0 
	call [MessageBoxA]                      ;[/COLOR]
	
	;; Return 0. 
	xor eax, eax 
	leave 
ret 

;; The callback function has to be in the dir_scan callback format. 
;; dir_scan format: 
;;  	parameters: 
;;  		pFindData	A pointer to a WIN32_FIND_DATA (ANSI version) structure that contains the information about the item (ie file). 
;;  		optParam	The optional parameter that was passed to dir_scan() as the third argument. 
;;  	calling convention: standard 
our_callback_function: 
	enter 4, 0 
	
	mov eax, dword [ebp+08]                 ;; The pointer to the WIN32_FIND_DATA structure. 
	add eax, 44                             ;; The offset of the filename part of the structure. 
	push eax                                ;; The address of the filename (or directory name) string. 
	push dword [ebp+12]                     ;; The optional parameter. 
	call strcat                             ;; The job, here, is to append the filename to the string that's passed to us 
	;; with the optional parameter. 
	
	;; Set [ebp-4] to the "\r\n" string. 
	mov byte [ebp-4], 13 
	mov byte [ebp-3], 10 
	mov word [ebp-2], 0 
	
	;; Append that string to our other string that's passed by the optional parameter. 
	lea eax, [ebp-4] 
	push eax 
	push dword [ebp+12] 
	call strcat 
	
	leave 
ret 8 

;; dir_scan() - Directory scan. 
;;  parameters: 
;;  	pFileSearchString	The directory or path, and the file name (wildcards are allowed). 
;;  	pCallbackFunction	The address of the (dir_scan) callback function. 
;;  	optCallbackParam	An optional parameter to pass to the callback function. 
dir_scan: 
	;; [ebp-318] = start of (ANSI version) WIN32_FIND_DATA structure. 
	;; [ebp-322] = hFindFile - find file handle. 
	enter 318 + 4, 0 
	pusha 
	
	lea eax, [ebp-318] 
	push eax                                ;; The pointer to the WIN32_FIND_DATA structure. 
	push dword [ebp+08]                     ;; The file search string. 
	call [FindFirstFileA] 
	mov dword [ebp-322], eax                ;; Save the handle to the file search. 
	
	.lp1: 
		;; Call the callback function. 
		push dword [ebp+16]                 ;; The second argument is the optional parameter, passed to us earlier. 
			lea eax, [ebp-318] 
		push eax                            ;; The first argument is the pointer to the WIN32_FIND_DATA structure. 
		call [ebp+12]                       ;; This function's second parameter is the address of the callback function. 
		
		lea eax, [ebp-318] 
		push eax                            ;; The address of the WIN32_FIND_DATA structure. 
		push dword [ebp-322]                ;; The handle to the file search. 
		call [FindNextFileA] 
		
		cmp eax, 0                          ;; Error? 
		jnz .lp1                            ;; If no, continue the loop. 
		
		call [GetLastError]                 ;; This function takes no parameters and returns the system error code of the last error. 
		cmp eax, 18                         ;; ERROR_NO_MORE_FILES = 18; means that there aren't any more files to scan. 
		jz .lp1s                            ;; If no more files, break from the loop. 
		
		;; Otherwise, well, let's just close the hFindFile handle and return -1. 
		push dword [ebp-322] 
		call [FindClose] 
		
		popa 
		mov eax, -1 
		leave 
		ret 12 
	.lp1s: 
	
	;; Close the find file handle. 
	push dword [ebp-322] 
	call [FindClose] 
	
	popa 
	xor eax, eax 
	leave 
ret 12 

%include "../inc/str.asm"                   ;; Include the file with the string function definitions. 

;; The following is for the data section. 
section .data 
;; The data definitions. 
the_title                                   db "LS", 0 
file_search_string                          db "*", 0                ;[COLOR=#FF8C00]
new_directory                               db "..", 0               ;[/COLOR]

The Output
Posted Image

(Fullsize Screenshot)








References:
GetCurrentDirectory Function (Windows)
SetCurrentDirectory Function (Windows)








First Tutorial:
Intro To Win32 Assembly, Using NASM

Previous Tutorial:
Directory Handling - Directory Listing

Next Tutorial:
Directory Handling - Removing Directories and Files
  • 0





Also tagged with one or more of these keywords: assembly