Creating File Handles in C using the Windows API

Before reading and writing to a file, we must first create a handle to the file. We create a file handle using the CreateFile() function, which returns a Win32 HANDLE. The CreateFile() function’s name is something of a misnomer, as it is used both to create new files as well as open existing files. 

Note that in the Win32 API, the maximum length of a file’s path should not exceed 260 characters.

An access mask defines how a process can interact with an object. In the case of a file handle, we will work with the generic access rights GENERIC_READ and GENERIC_WRITE, or a combination of the two. 

#include <stdio.h>
#include <Windows.h>

int main(void){

//260
printf("%d is the maximum length of a path.\n\r", MAX_PATH);

printf("0x%x generic read.\n\r", GENERIC_READ);
printf("0x%x generic write.\n\r", GENERIC_WRITE);
printf("0x%x generic read & write.\n\r", GENERIC_READ | GENERIC_WRITE);


return 0;

}

The file share mode specifies how the file can be shared. We can either allow other processes to read the file while we are accessing it, or we can specify that the file is locked to other processes. Putting NULL defaults to the later. To allow other processes to read the file, we put FILE_SHARE_READ

When creating a file handle, we should set its disposition. There are five possible dispositions, we will focus on four: CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING, and OPEN_ALWAYS.

#include <stdio.h>
#include <Windows.h>

int main(void){

printf("0x%x FILE_SHARE_READ\n\r", FILE_SHARE_READ);
printf("0x%x CREATE_NEW\n\r", CREATE_NEW);
printf("0x%x CREATE_ALWAYS\n\r", CREATE_ALWAYS);
printf("0x%x OPEN_EXISTING\n\r", OPEN_EXISTING);
printf("0x%x OPEN_ALWAYS\n\r", OPEN_ALWAYS);

return 0;

}

Alright, now let’s actually create the file handle. Note that that if the CreateFile() function fails, it returns the INVALID_HANDLE_VALUE. For more detailed information regarding the error, we can use the GetLastError() function, which is included in the Windows.h header file. 

#include <stdio.h>
#include <Windows.h>

int main(void){

int returnValue;
LPCWSTR filename = TEXT("somefile.txt");

HANDLE fileHandle = CreateFile(
filename, //file name
GENERIC_WRITE, //file access type (read, write, read & write)
0, //do we allow sharing? no. NULL also works
NULL, //default security
CREATE_ALWAYS, //create a new file only if an old one doesn't exist
FILE_ATTRIBUTE_NORMAL, //just a normal file, not an archive or hidden file, etc.
NULL
);

if(fileHandle != INVALID_HANDLE_VALUE){
printf("file handle created successfully.\n\r");
} else{
printf("There was a problem creating the file.\n\r");
}

returnValue = CloseHandle(fileHandle);

if(returnValue!=0){
printf("file handle successfully closed.\n\r");
}

return 0;

}

Note the use of the TEXT() macro to convert char * to LPCWSTR. LPCWSTR stands for long pointer to constant wide string; by wide they mean Unicode (16 bit) rather than ANSI (8 bit) characters. Basically, we use TEXT() to convert between Unicode and ANSI. 

 

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s