|< 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 whetherCopyFile() 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 toMAX_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 toMAX_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 bylpNewFileName 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, callGetLastError().

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 toMAX_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, callGetLastError().

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 thelpReplacementFileName file. This file is opened with theGENERIC_READ,DELETE, and SYNCHRONIZE access rights.  The sharing mode isFILE_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 thelpReplacedFileName 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 theSYNCHRONIZE,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, callGetLastError().

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. IfuUnique 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 beMAX_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, callGetLastError().

The header file

<windows.h>

 

Table 4:  GetTempFileName() information.

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

Component

Meaning

<path>

Path specified by thelpPathName parameter.

<pre>

First three letters of thelpPrefixString string.

<uuuu>

Hexadecimal value ofuUnique.

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 bylpBuffer, 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 tolpBuffer, not including the terminating null character.  If the return value is greater thannBufferLength, 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, callGetLastError().

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 theGENERIC_READ access right. For asynchronous read operations,hFile can be any handle opened with theFILE_FLAG_OVERLAPPED flag by the CreateFile() function, or a socket handle returned by thesocket() 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 whenReadFile() returns TRUE on a named pipe, the other end of the message-mode pipe called theWriteFile() function with nNumberOfBytesToWrite set to zero.  IflpOverlapped is NULL, lpNumberOfBytesRead cannot be NULL.  IflpOverlapped is not NULL, lpNumberOfBytesRead can be NULL.  If this is an overlapped read operation, you can get the number of bytes read by callingGetOverlappedResult().  If hFile is associated with an I/O completion port, you can get the number of bytes read by callingGetQueuedCompletionStatus(). If I/O completion ports are used and you are using a callback routine to free the memory allocated to theOVERLAPPED structure pointed to by thelpOverlapped 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 anOVERLAPPED structure. This structure is required ifhFile was created with FILE_FLAG_OVERLAPPED. IfhFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL.  It must point to a validOVERLAPPED structure.  IfhFile was created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the read operation is complete. IfhFile 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 theGetLastError() function returnsERROR_IO_PENDING.  This allows the calling process to continue while the read operation finishes.  The event specified in theOVERLAPPED 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.

IfhFile was not opened withFILE_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. IfhFile is not opened withFILE_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

TheReadFile() 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, callGetLastError(). 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 theGENERIC_WRITE access right.  For asynchronous write operations,hFile can be any handle opened with theFILE_FLAG_OVERLAPPED flag by the CreateFile() function, or a socket handle returned by thesocket() 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 theSetEndOfFile() 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. IflpOverlapped is NULL, lpNumberOfBytesWritten cannot be NULL.  IflpOverlapped is not NULL, lpNumberOfBytesWritten can be NULL.  If this is an overlapped write operation, you can get the number of bytes written by callingGetOverlappedResult().  If hFile is associated with an I/O completion port, you can get the number of bytes written by callingGetQueuedCompletionStatus(). If I/O completion ports are used and you are using a callback routine to free the memory allocated to theOVERLAPPED structure pointed to by thelpOverlapped 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 anOVERLAPPED structure.  This structure is required ifhFile was opened with FILE_FLAG_OVERLAPPED. IfhFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL.  It must point to a validOVERLAPPED structure.  IfhFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the write operation is complete. IfhFile 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 theGetLastError() function returnsERROR_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. IfhFile was not opened withFILE_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 thehEvent 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.  IfhFile was not opened withFILE_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, callGetLastError().

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. ReactOS - Windows binary compatible OS - C/C++ source code repository, Doxygen.

  4. For Multi-bytes, Unicode characters and Localization please refer to Locale, wide characters & Unicode (Story) and Windows users & groups programming tutorials (Implementation).

  5. Structure, enum, union and typedef story can be foundC/C++ struct, enum, union & typedef.

  6. Windows data type information is inData types used in Windows programming.

  7. Notation used in MSDN is Hungarian Notation instead of CamelCase and is discussedVC++ programming notations.

 

 

 

 

 

 

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


C & C++ Programming Tutorial |C Programming Practice