In this tutorial, we would go over how to change and retrieve the current directory of the program.
- 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 is the Win32 API function we'll use for changing the current directory.
- The name of the directory to change to; this can be a relative path or a full path.
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().
- The size of the buffer that would receive the current directory name.
- The pointer to that buffer.
The length of the current directory name. If the function fails, returns 0.
For more reference to this function, go to GetCurrentDirectory Function (Windows).
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.
;; 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]
GetCurrentDirectory Function (Windows)
SetCurrentDirectory Function (Windows)
Intro To Win32 Assembly, Using NASM
Directory Handling - Directory Listing
Directory Handling - Removing Directories and Files