Jump to content

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

- - - - -

  • Please log in to reply
No replies to this topic

#1
RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,251 posts
  • Location:C:\Countries\US
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




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users