|< C & Win32 programming 5 | Main | C & Win32 programming 7 >| Site Index | Download |


 

 

 

 

MODULE E1

WIN32 AND C PROGRAMMING 6

 

 

What are in this Module?

  1. Locking and Unlocking Byte Ranges in Files

  2. Flushing System-Buffered I/O Data to Disk

  3. Appending One File to Another File

  4. File Encryption

  5. File Compression and Decompression

  6. File Compression

  7. File Decompression

  8. Sparse Files

  9. File and Directory Linking

  10. Directory

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

 

The programming abilities:

  • Be familiar and play around with the Win32 programming.

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

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

Locking and Unlocking Byte Ranges in Files

  • Although the system allows more than one application to open a file and write to it, applications must not write over each other's work.  An application can prevent this problem by temporarily locking a region in a file.

  • The LockFile() and LockFileEx() functions lock a specified range of bytes in a file.  The range may extend beyond the current end of the file. Locking part of a file prevents all other processes from reading or writing anywhere in the specified area.

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

Information

Description

The function

LockFile().

The use

Locks the specified file for exclusive access by the calling process.

The prototype

BOOL LockFile( HANDLE hFile, DWORD  dwFileOffsetLow, DWORD  dwFileOffsetHigh, DWORD  nNumberOfBytesToLockLow, DWORD  nNumberOfBytesToLockHigh );

Example

HANDLE hAppend;

DWORD  dwBytesRead, dwPos;

 

hAppend = CreateFile(...);

LockFile(hAppend, dwPos, 0, dwBytesRead, 0);

The parameters

hFile - [in] Handle to the file with a region to be locked. The file handle must have been created with the GENERIC_READ or GENERIC_WRITE access right.

 dwFileOffsetLow - [in] Low-order word of the starting byte offset in the file where the lock should begin.

dwFileOffsetHigh - [in] High-order word of the starting byte offset in the file where the lock should begin.

nNumberOfBytesToLockLow - [in] Low-order word of the length of the byte range to be locked.

nNumberOfBytesToLockHigh - [in] High-order word of the length of the byte range to be locked.

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 6:  LockFile() information

 

Information

Description

The function

UnlockFile().

The use

Unlocks a region in an open file. Unlocking a region enables other processes to access the region.  For an alternate way to specify the region, use the UnlockFileEx() function.

The prototype

BOOL UnlockFile( HANDLE hFile, DWORD  dwFileOffsetLow, DWORD  dwFileOffsetHigh, DWORD  nNumberOfBytesToUnlockLow, DWORD  nNumberOfBytesToUnlockHigh );

Example

HANDLE hAppend;

DWORD  dwBytesRead, dwPos;

 

hAppend = CreateFile(...);

UnlockFile(hAppend, dwPos, 0, dwBytesRead, 0);

The parameters

hFile - [in] Handle to a file that contains a region locked with LockFile().  The file handle must have been created with either the GENERIC_READ or GENERIC_WRITE access right.

dwFileOffsetLow - [in] Low-order word of the starting byte offset in the file where the locked region begins.

dwFileOffsetHigh - [in] High-order word of the starting byte offset in the file where the locked region begins.

nNumberOfBytesToUnlockLow - [in] Low-order word of the length of the byte range to be unlocked.

nNumberOfBytesToUnlockHigh - [in] High-order word of the length of the byte range to be unlocked.

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:  UnlockFile() information.

 

Flushing System-Buffered I/O Data to Disk

Information

Description

The function

FlushFileBuffers().

The use

Flushes the buffers of the specified file and causes all buffered data to be written to the file.

The prototype

BOOL FlushFileBuffers(HANDLE hFile);

Example

HANDLE hFile;

 

hFile = CreateFile(...);

FlushFileBuffers(HANDLE hFile);

The parameters

hFile - [in] Handle to an open file. The file handle must have the GENERIC_WRITE access right. If hFile is a handle to a communications device, the function only flushes the transmit buffer. If hFile is a handle to the server end of a named pipe, the function does not return until the client has read all buffered data from the pipe.

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 function fails if hFile is a handle to console output. That is because console output is not buffered.  The function returns FALSE, and GetLastError() returns ERROR_INVALID_HANDLE.

The header file

<windows.h>

 

Table 8:  FlushFileBuffers() information.

Appending One File to Another File

#include <windows.h>

#include <stdio.h>

 

int main()

{

HANDLE hFile;

HANDLE hAppend;

DWORD  dwBytesRead, dwBytesWritten, dwPos;

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

char fname2[30] = "c:\\testfiletwo.txt";

char buff[4096];

 

// open the existing file.

hFile = CreateFile(fname,         //open testfile.txt

    GENERIC_READ,                 //open for reading

    0,                                            //do not share

    NULL,                                     //default security

    OPEN_EXISTING,                //existing file only

    FILE_ATTRIBUTE_NORMAL,    //normal file

    NULL);                                    //no attribute template

 

if(hFile == INVALID_HANDLE_VALUE)

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

else

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

// open the existing file, or if the file does not exist, create a new file.

hAppend = CreateFile(fname2,   //open testfiletwo.txt

    GENERIC_WRITE,             //open for writing

    0,                                          //do not share

    NULL,                                  //default security

    OPEN_ALWAYS,               //open or create

    FILE_ATTRIBUTE_NORMAL,     //normal file

    NULL);                                 //no attribute template

 

if(hAppend == INVALID_HANDLE_VALUE)

    printf("Could not open %s lol!.\n", fname2);

else

{

printf("%s opened/created successfully.\n", fname2);

printf("\nAppending %s\'s content to %s\'s content\n", fname, fname2);

printf("Check the %s content lol!\n\n", fname2);

}

 

// append the first file to the end of the second file. Lock the second file to prevent another process from

// accessing it while writing to it. Unlock the file when writing is finished.

do

{

    if(ReadFile(hFile, buff, 4096, &dwBytesRead, NULL))

    {

        dwPos = SetFilePointer(hAppend, 0, NULL, FILE_END);

        if(LockFile(hAppend, dwPos, 0, dwBytesRead, 0) != 0)

              printf("Locking %s...\n", fname2);

        WriteFile(hAppend, buff, dwBytesRead, &dwBytesWritten, NULL);

        if(UnlockFile(hAppend, dwPos, 0, dwBytesRead, 0) != 0)

              printf("Unlocking %s...\n", fname2);

    }

} while (dwBytesRead == 4096);

 

// close both files.

if(CloseHandle(hFile) != 0)

  printf("\nFile handle closed successfully!\n");

if(CloseHandle(hAppend) != 0)

  printf("File's append handle closed successfully!\n");

return 0;

}

 

The output:

 

c:\testfile.txt opened successfully.

c:\testfiletwo.txt opened/created successfully.

 

Appending c:\testfile.txt's content to c:\testfiletwo.txt's content

Check the c:\testfiletwo.txt content lol!

 

Locking c:\testfiletwo.txt...

Unlocking c:\testfiletwo.txt...

Locking c:\testfiletwo.txt...

Unlocking c:\testfiletwo.txt...

Locking c:\testfiletwo.txt...

Unlocking c:\testfiletwo.txt...

Locking c:\testfiletwo.txt...

Unlocking c:\testfiletwo.txt...

Locking c:\testfiletwo.txt...

Unlocking c:\testfiletwo.txt...

 

File handle closed successfully!

File's append handle closed successfully!

Press any key to continue

  • A sample output run on VC++ 2005.

File Encryption

  1. Compressed files.

  2. System files.

  3. System directories.

  4. Root directories.

File Compression and Decompression

File Compression

File Decompression

Sparse Files

File and Directory Linking

Directory

Information

Description

The function

CreateDirectory().

The use

Creates a new directory.  If the underlying file system supports security on files and directories, the function applies a specified security descriptor to the new directory.

The prototype

BOOL CreateDirectory( LPCTSTR  lpPathName, LPSECURITY_ATTRIBUTES  lpSecurityAttributes);

Example

char szDirPath[20] = "c:\\testdir";

CreateDirectory(szDirPath, NULL);

The parameters

lpPathName - [in] Pointer to a null-terminated string that specifies the path of the directory to be created.  There is a default string size limit for paths of 248 characters.  This limit is related to how the CreateDirectory() function parses paths.  To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.

lpSecurityAttributes - [in] Pointer to a SECURITY_ATTRIBUTES structure.  The lpSecurityDescriptor member of the structure specifies a security descriptor for the new directory.  If lpSecurityAttributes is NULL, the directory gets a default security descriptor.  The ACLs in the default security descriptor for a directory are inherited from its parent directory.  The target file system must support security on files and directories for this parameter to have an effect.

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().  Possible errors include the following:

  • ERROR_ALREADY_EXISTS - The specified directory already exists.

The header file

<windows.h>

 

Table 9:  CreateDirectory() information

Information

Description

The function

RemoveDirectory().

The use

Deletes an existing empty directory.

The prototype

BOOL RemoveDirectory(LPCTSTR  lpPathName);

Example

char szDirPath[20] = "c:\\testdir";

 

RemoveDirectory(szDirPath);

The parameters

lpPathName - [in] Pointer to a null-terminated string that specifies the path of the directory to be removed.  The path must specify an empty directory, and the calling process must have delete access to the 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.

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 10:  RemoveDirectory() information

#include <windows.h>

#include <stdio.h>

 

int main()

{

char szDirPath[20] = "c:\\testdir";

HANDLE hFile;

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

 

// create a new directory.

if(!CreateDirectory(szDirPath, NULL))

    printf("Couldn't create %s directory.\n", szDirPath);

else

printf("%s directory successfully created.\n", szDirPath);

 

// create a file

hFile = CreateFile(fname,           //file to be opened

                GENERIC_READ,       //open for writing

                FILE_SHARE_READ,    //share for writing

                NULL,               //default security

                CREATE_ALWAYS,      //create new file only

                FILE_ATTRIBUTE_ARCHIVE | SECURITY_IMPERSONATION, //archive and impersonate client

                NULL);              //no attribute template

 

// check the handle, then open...

if(hFile == INVALID_HANDLE_VALUE)

    printf("Could not open %s file (error %d)\n", fname, GetLastError());

else

{

    printf("%s file HANDLE is OK!\n", fname);

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

}

// close the handle...

if(CloseHandle(hFile) != 0)

    printf("CloseHandle() for %s file succeeded!\n", fname);

if(DeleteFile(fname) != 0)

    printf("%s file successfully deleted!\n", fname);

// delete the directory...

if(RemoveDirectory(szDirPath) != 0)

    printf("%s directory successfully deleted.\n", szDirPath);

 

return 0;

}

 

The output:

c:\testdir directory successfully created.

c:\testdir\testfile.txt file HANDLE is OK!

c:\testdir\testfile.txt opened successfully!

CloseHandle() for c:\testdir\testfile.txt file succeeded!

c:\testdir\testfile.txt file successfully deleted!

c:\testdir directory successfully deleted.

Press any key to continue

Information

Description

The function

GetCurrentDirectory().

The use

Retrieves the current directory for the current process.

The prototype

DWORD GetCurrentDirectory( DWORD  nBufferLength, LPTSTR lpBuffer);

Example

#define BUFFER_SIZE 200

TCHAR infoBuf[BUFFER_SIZE];

 

GetCurrentDirectory(BUFFER_SIZE, infoBuf);

The parameters

nBufferLength - [in] Length of the buffer for the current directory string, in TCHARs.  The buffer length must include room for a terminating null character.

lpBuffer - [out] Pointer to the buffer that receives the current directory string. This null-terminated string specifies the absolute path to the current directory.

The return value

If the function succeeds, the return value specifies the number of characters written to the buffer, not including the terminating null character. If the function fails, the return value is zero.  To get extended error information, call GetLastError(). If the buffer pointed to by lpBuffer is not large enough, the return value specifies the required size of the buffer, in characters, including the null- terminating character.

The header file

<windows.h>

 

Table 11:  GetCurrentDirectory() information.

Information

Description

The function

SetCurrentDirectory().

The use

Changes the current directory for the current process.  Each process has a single current directory made up of two parts:

  • A disk designator that is either a drive letter followed by a colon, or a server name and share name (\\servername\sharename).

  • A directory on the disk designator.

The prototype

BOOL SetCurrentDirectory(LPCTSTR  lpPathName);

Example

TCHAR lpPathName[200] = "D:\\Program Files\\Microsoft sql server";

SetCurrentDirectory(lpPathName);

The parameters

lpPathName - [in] Pointer to a null-terminated string that specifies the path to the new current directory.

This parameter may be a relative path or a full path. In either case, the full path of the specified directory is calculated and stored as the current directory. The string must not exceed MAX_PATH characters, including the terminating null character. The final character before the null character must be a backslash ('\').  If you do not specify the backslash, it will be added for you.  Therefore you can specify MAX_PATH-2 characters for the path or MAX_PATH-1 characters for the path if you include the trailing backslash.

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 12:  SetCurrentDirectory() information.

Information

Description

The function

GetSystemDirectory().

The use

Retrieves the path of the system directory.  The system directory contains system such files such as dynamic-link libraries, drivers, and font files.

The prototype

UINT GetSystemDirectory(LPTSTR  lpBuffer, UINT  uSize);

Example

#define BUFFER_SIZE 200

TCHAR infoBuf[BUFFER_SIZE];

 

GetSystemDirectory(infoBuf, BUFFER_SIZE);

The parameters

lpBuffer - [out] Pointer to the buffer to receive the null-terminated string containing the path.  This path does not end with a backslash unless the system directory is the root directory.  For example, if the system directory is named Windows\System on drive C, the path of the system directory retrieved by this function is C:\Windows\System.

uSize - [in] Maximum size of the buffer, in TCHARs.  This value should be set to MAX_PATH.

The return value

If the function succeeds, the return value is the length, in TCHARs, of the string copied to the buffer, not including the terminating null character.  If the length is greater than the size of the buffer, the return value is the size of the buffer required to hold the path, including the terminating null character. If the function fails, the return value is zero.

The header file

<windows.h>

 

Table 13:  GetSystemDirectory() information

Information

Description

The function

GetWindowsDirectory().

The use

Retrieves the path of the Windows directory.  The Windows directory contains such files as applications, initialization files, and help files.

The prototype

UINT GetWindowsDirectory(LPTSTR  lpBuffer, UINT  uSize);

Example

#define BUFFER_SIZE 200

TCHAR infoBuf[BUFFER_SIZE];

 

GetWindowsDirectory(infoBuf, BUFFER_SIZE);

The parameters

lpBuffer - [out] Pointer to the buffer to receive the null-terminated string containing the path.  This path does not end with a backslash unless the Windows directory is the root directory.  For example, if the Windows directory is named Windows on drive C, the path of the Windows directory retrieved by this function is C:\Windows.  If the system was installed in the root directory of drive C, the path retrieved is C:\.

uSize - [in] Maximum size of the buffer specified by the lpBuffer parameter, in TCHARs.  This value should be set to MAX_PATH.

The return value

If the function succeeds, the return value is the length of the string copied to the buffer, in TCHARs, not including the terminating null character. If the length is greater than the size of the buffer, the return value is the size 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 14:  GetWindowsDirectory() information.

#include <windows.h>

#include <stdio.h>

#define BUFFER_SIZE 200

 

int main()

{

  TCHAR infoBuf[BUFFER_SIZE];

  // Change accordingly to other path of your machine

  TCHAR lpPathName[200] = "D:\\mydvd\\Adobe Acrobat 3D 8.1";

  // get the current working directory

  if(!GetCurrentDirectory(BUFFER_SIZE, infoBuf))

    printf("GetCurrentDirectory() failed!\n");

  printf("Your current directory is: %s\n", infoBuf);

  printf("Changing directory...\n");

  // set to current working directory

  if(!SetCurrentDirectory(lpPathName))

    printf("SetCurrentDirectory() failed!\n");

  // do some verification...

  if(!GetCurrentDirectory(BUFFER_SIZE, infoBuf))

    printf("GetCurrentDirectory() failed!\n");

  printf("Your current directory is: %s\n", infoBuf);

  // get and display the Windows directory.

  if(!GetWindowsDirectory(infoBuf, BUFFER_SIZE))

    printf("GetWindowsDirectory() failed!\n");

  printf("Your Windows directory is: %s\n", infoBuf);

  // get and display the system directory.

  if(!GetSystemDirectory(infoBuf, BUFFER_SIZE))

    printf("GetSystemDirectory() failed!\n");

  printf("Your system directory is: %s\n", infoBuf);

 

  return 0;

}

 

The output:

 

Your current directory is: g:\vcnetprojek\win32prog

Changing directory...

Your current directory is: D:\Program Files\Microsoft sql server

Your Windows directory is: C:\WINDOWS

Your system directory is: C:\WINDOWS\system32

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. Notation used in MSDN is Hungarian Notation instead of CamelCase and is discussed VC++ programming notations.

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

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

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

 

 

 

 

 

 

|< C & Win32 programming 5 | Main | C & Win32 programming 7 >| Site Index | Download |


C & C++ Programming Tutorial | C Programming Practice