Program Development using Unix Win32 File API

Contents

CreateFile
DeleteFile
CloseHandle
ReadFile
WriteFile
File Information
Use of these functions
The Win32 API provides a set of functions to perform the general operations available on files. The functions include
HANDLE CreateFile(...);	
BOOL DeleteFile(LPCWSTR lpFileName);
BOOL MoveFile(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName);
BOOL CloseHandle(HANDLE hObject);
BOOL ReadFile(...);
BOOL WriteFile(...);
DWORD SetFilePointer(...);
DWORD GetFileAttributes(LPCTSTR lpFileName);
BOOL GetFileInformationByHandle(HANDLE hFile,
     LPBY_HANDLE_FILE_INFORMATION lpFileInformation);
BOOL SetFileAttributes(ileAttributesW(LPCWSTR lpFileName,
    DWORD dwFileAttributes);

CreateFile

HANDLE CreateFile(
    LPCTSTR lpFileName,	// pointer to name of the file 
    DWORD dwDesiredAccess,	// access (read-write) mode 
    DWORD dwShareMode,	// share mode 
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,	// pointer to security descriptor 
    DWORD dwCreationDistribution,	// how to create 
    DWORD dwFlagsAndAttributes,	// file attributes 
    HANDLE hTemplateFile 	// handle to file with attributes to copy  
   );	
The CreateFile function creates, opens, or truncates a file, pipe, mailslot, communications resource, disk device, or console. It returns a handle that can be used to access the object. It can also open and return a handle to a directory.

The lpFileName can be set to an absolute or relative path, and has a maximum length of MAX_PATH.

The dwDesiredAccess can be set to GENERIC_READ and/or GENERIC_WRITE.

The dwShareMode can be set to allow no other proces to gain access while the file is open, or to grant read-share or write-share access.

The dwCreationDistribution specifies behaviour to take on files that exist or do not exist, with values

The dwFlagsAndAttributes specifies file attributes as a combination of

FILE_ATTRIBUTE_ARCHIVE
FILE_ATTRIBUTE_COMPRESSED
FILE_ATTRIBUTE_HIDDEN
FILE_ATTRIBUTE_NORMAL
FILE_ATTRIBUTE_OFFLINE
FILE_ATTRIBUTE_READONLY
FILE_ATTRIBUTE_SYSTEM
FILE_ATTRIBUTE_TEMPORARY
FILE_FLAG_WRITE_THROUGH	
FILE_FLAG_OVERLAPPED
FILE_FLAG_NO_BUFFERING
FILE_FLAG_RANDOM_ACCESS
FILE_FLAG_SEQUENTIAL_SCA
FILE_FLAG_DELETE_ON_CLOSE
FILE_FLAG_BACKUP_SEMANTICS
FILE_FLAG_POSIX_SEMANTICS
This gets worse: if the file is a pipe, there may also be ``quality of service'' flags specified! Security permissions may also be set over and above those of the DOS file system.

If CreateFile succeeds, it will return a handle to the open file. There are many circumstances in which it might fail (such as creating an existing file with CREATE_NEW specified). On failure INVALID_HANDLE_VALUE is returned. More information on errors is available by the GetLastError() call.

DeleteFile

The DeleteFile function deletes an existing file.
BOOL DeleteFile(
    LPCTSTR lpFileName 	// pointer to name of file to delete  
   );	

CloseHandle

This closes the handle to any object, including file handles:
BOOL CloseHandle(
    HANDLE hObject 	// handle to object to close  
   );
closes any open object.

ReadFile

BOOL ReadFile(
    HANDLE hFile,	// handle of file to read 
    LPVOID lpBuffer,	// address of buffer that receives data  
    DWORD nNumberOfBytesToRead,	// number of bytes to read 
    LPDWORD lpNumberOfBytesRead,	// address of number of bytes read 
    LPOVERLAPPED lpOverlapped 	// address of structure for data 
   );	
The function attepts to read a number of bytes into a buffer, setting the actual number read into lpNumberOfBytesRead. If the function succeeds, the return value is TRUE. If the return value is TRUE and the number of bytes read is zero, the file pointer was beyond the current end of the file at the time of the read operation.

WriteFile

BOOL WriteFile(
    HANDLE hFile,	// handle to file to write to 
    LPCVOID lpBuffer,	// pointer to data to write to file 
    DWORD nNumberOfBytesToWrite,	// number of bytes to write 
    LPDWORD lpNumberOfBytesWritten,	// pointer to number of bytes written 
    LPOVERLAPPED lpOverlapped 	// pointer to structure needed for overlapped I/O
   );	
Here is a file copy:
#include <iostream.h>
#include <windows.h>

const int BUF_SIZE = 1024;

int main(int argc, char *argv[])
{
    HANDLE fileIn, fileOut;
    char buf[BUF_SIZE];
    char inName[MAX_PATH],
         outName[MAX_PATH];
    DWORD nread,nwrote;

    cout << "Source file name:";
    cin >> inName;
    cout << "Destination file name:";
    cin >> outName;

    if ((fileIn = CreateFile(inName, GENERIC_READ,
                    0, 0, OPEN_EXISTING, 0, 0)) ==
                 INVALID_HANDLE_VALUE) {
        cerr << "Error opening source: " <<
                 GetLastError() << endl;
        exit(1);
    }

    if ((fileOut = CreateFile(outName, GENERIC_WRITE,
                    0, 0, CREATE_NEW, 0, 0)) ==
                    INVALID_HANDLE_VALUE) {
        cerr << "Error opening destination: " <<
                GetLastError() << endl;
        exit(2);
    }

    while (ReadFile(fileIn, buf, BUF_SIZE,
                    &nread, NULL) && nread > 0) {
        if ( ! WriteFile(fileOut, buf, nread,
                    &nwrote, NULL)) {
            cerr << "Error writing" <<
                GetLastError() << endl;
        }
    }
    CloseHandle(fileIn);
    CloseHandle(fileOut);

    exit(0);
    return 0; // never reached
}

File Information

The GetFileInformationByHandle function retrieves information about a specified file.
BOOL GetFileInformationByHandle(
    HANDLE hFile,     // handle of file 
    LPBY_HANDLE_FILE_INFORMATION lpFileInformation     // address of structure 
   );    
where
typedef struct _BY_HANDLE_FILE_INFORMATION { // bhfi  
    DWORD    dwFileAttributes; 
    FILETIME ftCreationTime; 
    FILETIME ftLastAccessTime; 
    FILETIME ftLastWriteTime; 
    DWORD    dwVolumeSerialNumber; 
    DWORD    nFileSizeHigh; 
    DWORD    nFileSizeLow; 
    DWORD    nNumberOfLinks; 
    DWORD    nFileIndexHigh; 
    DWORD    nFileIndexLow; 
} BY_HANDLE_FILE_INFORMATION; 
The following program extracts some of this:
#include <iostream.h>
#include <windows.h>

const int BUF_SIZE = 1024;

int main(int argc, char *argv[])
{
    char inName[BUF_SIZE];
    HANDLE fileIn;
    BY_HANDLE_FILE_INFORMATION bhfi;

    cout << "Source file name:";
    cin >> inName;

    if ((fileIn = CreateFile(inName, GENERIC_READ,
                    0, 0, OPEN_EXISTING, 0, 0)) ==
                 INVALID_HANDLE_VALUE) {
        cerr << "Error opening source: " <<
                 GetLastError() << endl;
        exit(1);
    }

    if (GetFileInformationByHandle(fileIn,
                &bhfi)) {
        cout << "Created: " << 
                 bhfi.ftCreationTime.dwLowDateTime << 
                 endl;
    }
    CloseHandle(fileIn);
    exit(0);
    return 0; // never reached
}

Use of these functions

When should you use these low-level functions? Only when you have to. In general use the high-level functions. There will be many times when you need finer control.

Note that these functions are specific to the Win32 API, and are not in Unix C, for example. So code written using these functions will only be portable across Windows platforms, not to other Operating Systems.

CreateFile

This function is a multi-purpose function that can be used to control all sorts of situations
  • It can set DOS and higher level access to files
  • It can be used on pipes and other non-file devices
  • It can be used on existing or new files
  • It can open directories
  • It can set sharing attributes
  • It can set buffering attributes

Jan Newmarch (http://jan.newmarch.name)
jan@newmarch.name
Last modified: Wed Nov 19 18:08:49 EST 1997
Copyright ©Jan Newmarch