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 - Making A New 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:48 PM

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
  • 0





Also tagged with one or more of these keywords: assembly