Jump to content

Assembly, Directory Handling - Making A New 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
We have been looking at algorithms for some time, now; let's take a break from those and look at some Win32 API functions for directory handling.

In this tutorial, we'll look at how to create a directory.

Overview
  • Directory Handling
  • CreateDirectory Windows Function
  • Example Program








Directory Handling
In the next few tutorials, we'll make programs that would do some basic things in managing directories. In this tutorial, we would make a new directory, if one does not already exist, and display an okay message; otherwise, if the directory already exists, we would display a message box with an error message.

The third parameter of the MessageBox() function is the title for the message box; if that parameter is NULL, a default value of "Error" is used.

Besides this, in the next few tutorials, we would go over handling every item in a directory, changing the current directory, removing a directory, and deleting a file.

So first of all, to make a directory, we would need to use the CreateDirectory() Win32 API function; let's take a look at that.








CreateDirectory Windows Function
The CreateDirectory() Win32 API function makes a directory at the path specified by the first parameter. All the intermediate directories in the path have to already exist, by the time you call this function.

Parameters:
  • The path to the new directory.
  • An optional pointer to a SECURITY_ATTRIBUTES structure.

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

This function has ANSI and Unicode versions (CreateDirectoryA and CreateDirectoryW; just CreateDirectory won't work).

We would be using the CreateDirectoryA() version of the function.

This function is part of the kernel32.dll DLL. The kernel32.dll DLL contains a lot of the functions that are needed for a program to survive (ie memory allocation, file I/O, etc.).

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






Example Program
Okay, now let's use the CreateDirectory() function.

The Plan
Use the CreateDirectoryA() Win32 API function to make a new directory, named our_dir.
If successful, display a message box that says so; display an error message box, otherwise.

To display a success message, we would need to compile a string from parts. We would need to copy part 1 of the message to a string, then append the name of the directory to that string, and then append part 2 of the message to the string.

Similar with the error message, except that we use part 1 and part 2 of the error message, for the copying and appending, instead of using the regular message's part 1 and part 2.

The Code
;; Define the externs. 

extern CreateDirectoryA 

extern MessageBoxA 

extern ExitProcess 


;; Construct our symbol import table. 

import CreateDirectoryA kernel32.dll 

import MessageBoxA user32.dll 

import ExitProcess kernel32.dll 


;; The following goes into the code section; use 32-bit code. 

section .text use32 

;; Start program execution here. 

..start: 


;; Call the main() function. 

call main 


;; Exit, returning whatever main() returned. 

push eax 

call [ExitProcess] 


main: 

	enter 0, 0 

	

	push dword 0                            ;; The second argument is an optional pointer to a SECURITY_ATTRIBUTES structure. 

	;; Just as with the CreateFile(), the second parameter is optional, and can be NULL. 

	push dword directory_name               ;; The first argument is the pointer to a string that contains the name of the new directory. 

	;; This string doesn't have to be a plain name, it can also be a path to the new directory to make, but 

	;; if it's a path, all the parent directories of the new directory have to already exist by the time we 

	;; call this function. 

	call [CreateDirectoryA]                 ;; And we call the function. 

	

	cmp eax, 0                              ;; CreateDirectoryA() returns 0 if it fails. 

	jz .error 

	

	;; Set string1 to part1. 

	push dword part1 

	push dword string1 

	call strcpy 

	

	;; Append directory_name to string1. 

	push dword directory_name 

	push dword string1 

	call strcat 

	

	;; Append part2 to string1. 

	push dword part2 

	push dword string1 

	call strcat 

	

	;; Display a message box with the prepared message. 

	push dword 0 

	push dword the_title 

	push dword string1 

	push dword 0 

	call [MessageBoxA] 

	

	;; Clear the return value and go to .finish 

	xor eax, eax 

	jmp .finish 

	

	.error: 

	

	;; Set string1 to err_p1 

	push dword err_p1 

	push dword string1 

	call strcpy 

	

	;; Append directory_name to string1 

	push dword directory_name 

	push dword string1 

	call strcat 

	

	;; Append err_p2 to string1 

	push dword err_p2 

	push dword string1 

	call strcat 

	

	;; Display a message box with the prepared message. 

	push dword 0 

	push dword 0                            ;; If this parameter is NULL, MessageBoxA uses "Error" as a title. 

	push dword string1 

	push dword 0 

	call [MessageBoxA] 

	

	;; Load the return value with 1 and go to .finish 

	mov eax, 1 

	jmp .finish 

	

	;; There's no point of the 'jmp .finish' instruction, since it would go to .finish anyway (because .finish is 

	;; the label for the next instruction), but I put it there just for fun; the other reason I put it there is 

	;; in case I add another label between here and .finish, it would still go to .finish; it's kind of like 

	;; using a 'break' keyword, in JavaScript/C/C++/etc., at the end of a switch statement. 

	

	.finish: 

	

	leave 

ret 


%include "../inc/str.asm"                   ;; In order to use the string functions (strcpy, strcat, etc.), we need to 

;; include the file that defines them. 


;; The following goes into the data section. 

section .data 

;; We define the string with the name of the directory we want to make. 

directory_name                              db "our_dir", 0 

;; The title for our message box. 

the_title                                   db "Success!", 0 

;; And parts of the message we'll display in the message box. 

part1                                       db "The directory ", 0 

part2                                       db " has been successfully made. ", 0 

;; Well, we might need an error message, in case CreateDirectoryA() fails. 

err_p1                                      db "Error. Could not make the directory ", 0 

err_p2                                      db " . ", 0 


;; The following is for the bss section. 

section .bss 

;; string1 is a blank string, to start out with. 

string1                                     resb 512 

The Output
If the directory does not already exist, the output should be something like this:
Posted Image

(Fullsize Screenshot)

If the directory does exist, an error message should come up. You can remove the directory and try again, in that case.









References:
CreateDirectory Function (Windows)






First Tutorial:
Intro To Win32 Assembly, Using NASM

Previous Tutorial:
More About Arrays

Next Tutorial:
Directory Handling - Directory Listing




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users