|< C & Win32 programming 2 | Main | C & Win32 programming 4 >| Site Index | Download |


 

 

 

 

MODULE D

WIN32 AND C PROGRAMMING 3

 

 

 

 

What are in this Module?

  1. Moving and Replacing Files

  2. Creating and Using a Temporary File

  3. Reading From and Writing to Files

 

 

 

My Training Period: bb hours. Before you begin, read some instruction here.

 

The skills that you suppose to acquire:

  • Be familiar and play around with the Win32 programming.

  • Able to understand the Windows file system (NTFS), directory and file.

  • Able to find and collect information about file management functions.

  • Able to understand and use the collected information about the functions in programs.

Moving and Replacing Files

  • Before a file can be copied, it must be closed or opened only for reading.  No thread can have the file opened for writing.

  • To copy an existing file to a new one, use the CopyFile() or CopyFileEx() function. Applications can specify whether CopyFile() and CopyFileEx() fail if the destination file already exists.

  • The following Table lists the needed information in order to use the CopyFile() function.

Information

Description

The function

CopyFile().

The use

Copies an existing file to a new file.

The prototype

BOOL CopyFile( LPCTSTR  lpExistingFileName, LPCTSTR  lpNewFileName, BOOL     bFailIfExists);

Example

WIN32_FIND_DATA FileData;

char szNewPath[MAX_PATH];

CopyFile(FileData.cFileName, szNewPath, FALSE);

The parameters

lpExistingFileName - [in] Pointer to a null-terminated string that specifies the name of an existing file. In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.

lpNewFileName - [in] Pointer to a null-terminated string that specifies the name of the new file.

In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.

bFailIfExists - [in] If this parameter is TRUE and the new file specified by lpNewFileName already exists, the function fails. If this parameter is FALSE and the new file already exists, the function overwrites the existing file and succeeds.

The return value

If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero. To get extended error information, call GetLastError().

The header file needed

<windows.h>

 

Table 1:  CopyFile() information.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Information

Description

The function

MoveFile().

The use

Moves an existing file or a directory, including its children.

The prototype

BOOL MoveFile( LPCTSTR  lpExistingFileName, LPCTSTR  lpNewFileName);

Example

char szTempName[MAX_PATH];

 

GetTempFileName("c:\\temp",  // directory for temp files

    "testmp",                                  // temp file name prefix

    0,                                              // create unique name

    szTempName);                       // buffer for name

 

MoveFile(szTempName, "c:\\newfile.txt")

The parameters

lpExistingFileName - [in] Pointer to a null-terminated string that names an existing file or directory.  In the ANSI version of this function, the name is limited to MAX_PATH characters.  To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.

lpNewFileName - [in] Pointer to a null-terminated string that specifies the new name of a file or directory.  The new name must not already exist. A new file may be on a different file system or drive.  A new directory must be on the same drive.

In the ANSI version of this function, the name is limited to MAX_PATH characters.  To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.

The return value

If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero.  To get extended error information, call GetLastError().

The header file

<windows.h>

 

Table 2:  MoveFile() information.

Information

Description

The function

ReplaceFile().

The use

Replaces one file with another file, with the option of creating a backup copy of the original file.  The replacement file assumes the name of the replaced file and its identity.

The prototype

BOOL ReplaceFile( LPCTSTR lpReplacedFileName, LPCTSTR lpReplacementFileName, LPCTSTR lpBackupFileName, DWORD   dwReplaceFlags, LPVOID  lpExclude, LPVOID  lpReserved);

Example

char *lpReplacedFileName = "C:\\module20.txt";

char *lpReplacementFileName = "C:\\testfile.txt";

LPVOID lpExclude;

LPVOID lpReserved;

 

ReplaceFile(

  lpReplacedFileName,

  lpReplacementFileName,

  "C:\\backup.txt",

  REPLACEFILE_IGNORE_MERGE_ERRORS,

  lpExclude,

  lpReserved

);

The parameters

lpReplacedFileName - [in] Pointer to a null-terminated string that specifies the name of the file that will be replaced by the lpReplacementFileName file. This file is opened with the GENERIC_READ, DELETE, and SYNCHRONIZE access rights.  The sharing mode is FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE. The caller must have write access to the file to be replaced.

lpReplacementFileName - [in] Pointer to a null-terminated string that specifies the name of the file that will replace the lpReplacedFileName file. The function attempts to open this file with the SYNCHRONIZE, GENERIC_READ, GENERIC_WRITE, DELETE, and WRITE_DAC access rights so that it can preserve all attributes and ACLs. If this fails, the function attempts to open the file with the SYNCHRONIZE, GENERIC_READ, DELETE, and WRITE_DAC access rights. No sharing mode is specified.

lpBackupFileName - [in] Pointer to a null-terminated string that specifies the name of the file that will serve as a backup copy of the lpReplacedFileName file.  If this parameter is NULL, no backup file is created.

dwReplaceFlags - [in] Replacement options.  This parameter can be one or more of the following values:

  1. REPLACEFILE_IGNORE_MERGE_ERRORS - Ignores errors that occur while merging information (such as attributes and ACLs) from the replaced file to the replacement file. Therefore, if you specify this flag and do not have WRITE_DAC access, the function succeeds but the ACLs are not preserved.

  2. REPLACEFILE_WRITE_THROUGH - Guarantees that information copied from the replaced file is flushed to disk before the function returns.

 

lpExclude - Reserved for future use.

lpReserved - Reserved for future use.

The return value

If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero.  To get extended error information, call GetLastError().

The header file

<windows.h>

 

Table 3:  ReplaceFile() information.

// for WinXp Pro

#define _WIN32_WINNT 0x0501

#include <windows.h>

#include <stdio.h>

 

char *lpReplacedFileName = "C:\\module20.txt";

char *lpReplacementFileName = "C:\\testfile.txt";

LPVOID lpExclude;

LPVOID lpReserved;

 

int main()

{

    BOOL test = ReplaceFile(

      lpReplacedFileName,

      lpReplacementFileName,

      "C:\\backup.txt",

      REPLACEFILE_IGNORE_MERGE_ERRORS,

      lpExclude,

      lpReserved

);

 

    printf("The original file   = %s\n", lpReplacedFileName);

    printf("The replacement file  = %s\n", lpReplacementFileName);

    printf("The return value = %d\n", test);

    return 0;

}

 

A sample output:

 

The original file   = C:\module20.txt

The replacement file  = C:\testfile.txt

The return value = 1

Press any key to continue

Creating and Using a Temporary File

Information

Description

The function

GetTempFileName().

The use

Creates a name for a temporary file.  If a unique file name is generated, an empty file is created and the handle to it is released; otherwise, only a file name is generated.

The prototype

UINT GetTempFileName( LPCTSTR lpPathName, LPCTSTR lpPrefixString, UINT    uUnique, LPTSTR  lpTempFileName);

Example

char szTempName[MAX_PATH];

 

GetTempFileName("c:\\temp",  // directory for temp files

    "testmp",                                  // temp file name prefix

    0,                                              // create unique name

    szTempName);                       // buffer for name

The parameters

lpPathName - [in] Pointer to a null-terminated string that specifies the directory path for the file name.  Applications typically specify a period (.) for the current directory or the result of the GetTempPath() function.  The string cannot be longer than MAX_PATH-14 characters.  If this parameter is NULL, the function fails.

lpPrefixString - [in] Pointer to a null-terminated prefix string.  The function uses up to the first three characters of this string as the prefix of the file name.  This string must consist of characters in the OEM-defined character set.

uUnique - [in] Unsigned integer to be used in creating the temporary file name. If uUnique is zero, the function attempts to form a unique file name using the current system time.  If the file already exists, the number is increased by one and the functions tests if this file already exists.  This continues until a unique filename is found; the function creates a file by that name and closes it.  Note that the function does not attempt to verify the uniqueness of the file name when uUnique is nonzero.

lpTempFileName - [out] Pointer to the buffer that receives the temporary file name.  This string must consist of characters in the OEM-defined character set.  This buffer should be MAX_PATH characters to accommodate the path plus the terminating null character.

The return value

If the function succeeds, the return value specifies the unique numeric value used in the temporary file name.  If the uUnique parameter is nonzero, the return value specifies that same number.  If the function fails, the return value is zero.  To get extended error information, call GetLastError().

The header file

<windows.h>

 

Table 4:  GetTempFileName() information.

<path>\<pre><uuuu>.TMP

Component

Meaning

<path>

Path specified by the lpPathName parameter.

<pre>

First three letters of the lpPrefixString string.

<uuuu>

Hexadecimal value of uUnique.

Information

Description

The function

GetTempPath().

The use

Retrieves the path of the directory designated for temporary files.

The prototype

DWORD GetTempPath(DWORD  nBufferLength, LPTSTR lpBuffer);

Example

DWORD nBufferLength = 100;

char lpBuffer[50];

 

GetTempPath(nBufferLength, lpBuffer);

The parameters

nBufferLength - [in] Size of the string buffer identified by lpBuffer, in TCHARs.

lpBuffer - [out] Pointer to a string buffer that receives the null-terminated string specifying the temporary file path.  The returned string ends with a backslash, for example, C:\TEMP\.

The return value

If the function succeeds, the return value is the length, in TCHARs, of the string copied to lpBuffer, not including the terminating null character.  If the return value is greater than nBufferLength, the return value is the length, in TCHARs, of the buffer required to hold the path.  If the function fails, the return value is zero. To get extended error information, call GetLastError().

The header file

<windows.h>

 

Table 5:  GetTempPath() information.

#include <windows.h>

#include <stdio.h>

 

int main()

{

    DWORD nBufferLength = 100;

    char lpBuffer[50];

 

    // get temp path

    DWORD temPathLength =

    GetTempPath( nBufferLength, lpBuffer );

 

    printf("Temp path = %s.\n", lpBuffer);

    printf("Temp path length = %d.\n", temPathLength);

    return 0;

}

 

A sample output:

 

Temp path = C:\DOCUME~1\mike\LOCALS~1\Temp\.

Temp path length = 31.

Press any key to continue

Reading From and Writing to Files

Information

Description

The function

ReadFile().

The use

Reads data from a file, starting at the position indicated by the file pointer.  This function is designed for both synchronous and asynchronous operation.

The prototype

BOOL ReadFile( HANDLE   hFile, LPVOID   lpBuffer, DWORD    nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED  lpOverlapped);

Example

HANDLE hFile;

DWORD  dwBytesRead;

char buffer[4096];

 

ReadFile(hFile, buffer, 2048, &dwBytesRead, NULL);

The parameters

hFile - [in] Handle to the file to be read.  The file handle must have been created with the GENERIC_READ access right. For asynchronous read operations, hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile() function, or a socket handle returned by the socket() or accept() function.

lpBuffer - [out] Pointer to the buffer that receives the data read from the file.

nNumberOfBytesToRead - [in] Number of bytes to be read from the file.

lpNumberOfBytesRead - [out] Pointer to the variable that receives the number of bytes read. ReadFile() sets this value to zero before doing any work or error checking. If this parameter is zero when ReadFile() returns TRUE on a named pipe, the other end of the message-mode pipe called the WriteFile() function with nNumberOfBytesToWrite set to zero.  If lpOverlapped is NULL, lpNumberOfBytesRead cannot be NULL.  If lpOverlapped is not NULL, lpNumberOfBytesRead can be NULL.  If this is an overlapped read operation, you can get the number of bytes read by calling GetOverlappedResult().  If hFile is associated with an I/O completion port, you can get the number of bytes read by calling GetQueuedCompletionStatus(). If I/O completion ports are used and you are using a callback routine to free the memory allocated to the OVERLAPPED structure pointed to by the lpOverlapped parameter, specify NULL as the value of this parameter to avoid a memory corruption problem during the de-allocation.  This memory corruption problem will cause an invalid number of bytes to be returned in this parameter.

lpOverlapped - [in] Pointer to an OVERLAPPED structure. This structure is required if hFile was created with FILE_FLAG_OVERLAPPED. If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL.  It must point to a valid OVERLAPPED structure.  If hFile was created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the read operation is complete. If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure and ReadFile() may return before the read operation has been completed. In this case, ReadFile() returns FALSE and the GetLastError() function returns ERROR_IO_PENDING.  This allows the calling process to continue while the read operation finishes.  The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the read operation.  The caller must adjust the position of the file pointer upon completion.

If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the read operation starts at the current file position and ReadFile() does not return until the operation has been completed.  The system updates the file pointer upon completion. If hFile is not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure.  ReadFile() does not return until the read operation has been completed.  The system updates the file pointer upon completion.

The return value

The ReadFile() function returns when one of the following conditions is met: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs. If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero.  To get extended error information, call GetLastError(). If the return value is nonzero 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.

The header file

<windows.h>

 

Table 6:  ReadFile() information.

Information

Description

The function

WriteFile().

The use

Writes data to a file at the position specified by the file pointer. This function is designed for both synchronous and asynchronous operation.

The prototype

BOOL WriteFile( HANDLE   hFile, LPCVOID  lpBuffer, DWORD    nNumberOfBytesToWrite, LPDWORD  lpNumberOfBytesWritten, LPOVERLAPPED  lpOverlapped);

Example

hTempFile = CreateFile(...);

char buffer[4096];

DWORD  dwBytesRead, dwBytesWritten;

 

WriteFile(hTempFile, buffer, dwBytesRead, &dwBytesWritten, NULL);

The parameters

hFile - [in] Handle to the file.  The file handle must have been created with the GENERIC_WRITE access right.  For asynchronous write operations, hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile() function, or a socket handle returned by the socket() or accept() function.

lpBuffer - [in] Pointer to the buffer containing the data to be written to the file.

nNumberOfBytesToWrite - [in] Number of bytes to be written to the file. A value of zero specifies a null write operation.  The behavior of a null write operation depends on the underlying file system.  To truncate or extend a file, use the SetEndOfFile() function. Named pipe write operations across a network are limited to 65,535 bytes.

lpNumberOfBytesWritten - [out] Pointer to the variable that receives the number of bytes written.  WriteFile() sets this value to zero before doing any work or error checking. If lpOverlapped is NULL, lpNumberOfBytesWritten cannot be NULL.  If lpOverlapped is not NULL, lpNumberOfBytesWritten can be NULL.  If this is an overlapped write operation, you can get the number of bytes written by calling GetOverlappedResult().  If hFile is associated with an I/O completion port, you can get the number of bytes written by calling GetQueuedCompletionStatus(). If I/O completion ports are used and you are using a callback routine to free the memory allocated to the OVERLAPPED structure pointed to by the lpOverlapped parameter, specify NULL as the value of this parameter to avoid a memory corruption problem during the de-allocation.  This memory corruption problem will cause an invalid number of bytes to be returned in this parameter.

lpOverlapped - [in] Pointer to an OVERLAPPED structure.  This structure is required if hFile was opened with FILE_FLAG_OVERLAPPED. If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL.  It must point to a valid OVERLAPPED structure.  If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the write operation is complete. If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile() may return before the write operation has been completed. In this case, WriteFile() returns FALSE and the GetLastError() function returns ERROR_IO_PENDING.  This allows the calling process to continue processing while the write operation is being completed.  The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the write operation.  The caller must adjust the position of the file pointer upon completion. If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the write operation starts at the current file position and WriteFile() does not return until the operation has been completed.  The system updates the file pointer upon completion. WriteFile() resets the event specified by the hEvent member of the OVERLAPPED structure to a non-signaled state when it begins the I/O operation.  Therefore, there is no need for the caller to do so.  If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile() does not return until the write operation has been completed.  The system updates the file pointer upon completion.

The return value

If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero.  To get extended error information, call GetLastError().

The header file

<windows.h>

 

Table 7:  WriteFile() information.

#include <windows.h>

#include <stdio.h>

 

int main()

{

HANDLE hFile;

HANDLE hTempFile;

DWORD  dwBytesRead, dwBytesWritten;

char szTempName[MAX_PATH];

char buffer[4096];

char fname[50] = "c:\\testfile.txt";

// open the existing file.

hFile = CreateFile(fname,                  // file name

    GENERIC_READ,                          // open for reading

    0,                                                       // do not share

    NULL,                                               // default security

    OPEN_EXISTING,                         // existing file only

    FILE_ATTRIBUTE_NORMAL,      // normal file

    NULL);                                             // no template

 

if(hFile == INVALID_HANDLE_VALUE)

{

    printf("Could not open %s file.\n", fname);

}

else

    printf("%s file opened successfully.\n", fname);

 

// create a temporary file.  Make sure is are c:\temp folder

GetTempFileName("c:\\temp",                                     // directory for temp files

    "testmp",                                                                     // temp file name prefix

    0,                                                                                 // create unique name

    szTempName);                                                          // buffer for name

 

hTempFile = CreateFile((LPTSTR) szTempName,  // file name

    GENERIC_READ | GENERIC_WRITE,                 // open for read/write

    0,                                                                                 // do not share

    NULL,                                                                         // default security

    CREATE_ALWAYS,                                                // overwrite existing file

    FILE_ATTRIBUTE_NORMAL,                                // normal file

    NULL);                                                                        // no attribute template

 

if(hTempFile == INVALID_HANDLE_VALUE)

    printf("Could not create %s temporary file.\n", szTempName);

else

    printf("%s temporary file created successfully.\n", szTempName);

 

// read 2K blocks of the content to the buffer.  Change all characters in the buffer to uppercase.

// Write the buffer to the temporary file.

printf("Reading the %s file, change to the uppercase and\n", fname);

printf("write to %s temporary file\n", szTempName);

do

{

    if(ReadFile(hFile, buffer, 2048, &dwBytesRead, NULL))

    {

        CharUpperBuff(buffer, dwBytesRead);

        WriteFile(hTempFile, buffer, dwBytesRead, &dwBytesWritten, NULL);

    }

} while (dwBytesRead == 2048);

 

// close both files' handles.

if(CloseHandle(hFile) != 0)

    printf("%s handle closed successfully.\n", fname);

if(CloseHandle(hTempFile) != 0)

    printf("%s handle closed successfully.\n", szTempName);

 

// move the temporary file to the new text file

if(!MoveFile(szTempName, "c:\\newfile.txt"))

    printf("Could not move %s temp file.\n", szTempName);

else

    printf("%s temp file moved successfully.\n", szTempName);

return 0;

}

 

A sample output:

 

c:\testfile.txt file opened successfully.

c:\temp\tes1A.tmp temporary file created successfully.

Reading the c:\testfile.txt file, change to the uppercase and

write to c:\temp\tes1A.tmp temporary file

c:\testfile.txt handle closed successfully.

c:\temp\tes1A.tmp handle closed successfully.

c:\temp\tes1A.tmp temp file moved successfully.

Press any key to continue

 

 

 

 

 

 

 

 

 

 

 

 

Further reading and digging:

 

  1. Check the best selling C, C++ and Windows books at Amazon.com.

  2. Microsoft Visual C++, online MSDN.

  3. For Multibytes, Unicode characters and Localization please refer to Locale, wide characters & Unicode (Story) and Windows users & groups programming tutorials (Implementation).

  4. Structure, enum, union and typedef story can be found C/C++ struct, enum, union & typedef.

  5. Windows data type information is in Data types used in Windows programming.

  6. Notation used in MSDN is Hungarian Notation instead of CamelCase and is discussed VC++ programming notations.

 

 

 

 

 

 

|< C & Win32 programming 2 | Main | C & Win32 programming 4 >| Site Index | Download |


 

C & C++ Programming Tutorial | C Programming Practice