Part - 3

Retrieve file information
Before proceed to create the merge data file, it is important to know how to get the respective file information. If we fail to archieve this, no point for us to proceed further from here. But to arhieve this simple, which the WIN32 SDK does provide us the FindFirstFile or GetFileAttributesEx API. These API will return all the information we need.

But, becuase this project was scanning the specified folder without know the filename at the first place. So, GetFileAttributesEx will returning duplicate file information. As the FindFirstFile does return those information which return by GetFileAttributesEx. Below is the code snippet.

PHP Code:
HANDLE hFile               NULL;
WIN32_FIND_DATA    wfs     = {NULL};

// Get the specified file information by using the FindFirstFile instead of GetFileAttributesEx
hFile FindFirstFile("C:\\SelfExtract.exe", &wfs);

// Varify the reutn find file handle
if (NULL != hFile || INVALID_HANDLE_VALUE != hFile)
{
    
// Copy those file information you need into your define local/global variable here.
}

// Close the search file handle
if (NULL != hFile) {FindClose(hFile);}
hFile NULL
Thw way I scan files
Since the current GUI of the SelfExtract.exe module is only support user to specified the folder (fullpath) whereby those source files was saved. Hence, there is a need that the SelfExtract.exe module able to scan through the specified folder and retrieving each available file information as well as it content before the merge data file can be successfully build.

The code I use to scan a folder is extactly the same as the code I use to retrieve the file information. The only different is now, it require a do...while... loop instead of just calling the API once and the code snippet is show below.

PHP Code:
HANDLE hFile               NULL;
WIN32_FIND_DATA    wfs     = {NULL};

// Start scaning the directory
hFile FindFirstFile("C:\\*.*", &wfs);

// Check the return handle value
do
{
    
// Check is the current found file is directory?
    
if (!(FILE_ATTRIBUTE_DIRECTORY wfs.dwFileAttributes))
    {
        
// Put your code to read the current file information here.
    
}

    
// Scan the next match item in the directory
    
if (!FindNextFile(hFile, &wfs))
    {
        if (
ERROR_NO_MORE_FILES == GetLastError()) {break;}
    }

} while (
NULL != hFile || INVALID_HANDLE_VALUE != hFile);

// Close the search file handle
if (NULL != hFile) {FindClose(hFile);}
hFile NULL

Basic file access
Now, you have no problem in scanning any specficied folder. You still need to know how to open the file and read it content into a local variable. Without this, this project will not be complete. As it fail to create the merge data file. But, life is easy. Since the WIN32 SDK does provide us the necessary file I/O API. All you need to understand and remember the following fews APIs:



PHP Code:
// Create new file and write data into it.

HANDLE    hFile1        NULL;
DWORD    dwByteWrite    0;

// Create a new text file
hFile1 CreateFile("C:\\sample.txt",
                    
GENERIC_WRITE,
                    
FILE_SHARE_WRITE,
                    
NULL,
                    
CREATE_ALWAYS,
                    
FILE_ATTRIBUTE_NORMAL,
                    
NULL);

// Check the return handle value
if (NULL != hFile1 && INVALID_HANDLE_VALUE != hFile1)
{
    
// Move the file pointer to the begin of the file
    
SetFilePointer(hFile100FILE_BEGIN);
    
// Write the data into newly create file
    
WriteFile(hFile1,
              
"Hello world",
              
strlen("Hello world"),
              &
dwByteWrite,
              
NULL);
}
else
{
    
// Notify user about the error
    
MessageBox(hWnd"Fail to create file!"APP_TITLEMB_OK MB_ICONSTOP);
}

// Close the current open data file
if (NULL != hFile1) {CloseHandle(hFile1);}
hFile1 NULL

PHP Code:
// Open existing file and read the contents.

HANDLE    hFile         NULL;
DWORD     dwByteRead    0;
DWORD     dwFileSize    0;
LPBYTE    lpData        NULL;

// Open the existing file
hFile CreateFile("C:\\sample.txt",
                   
GENERIC_READ,
                   
FILE_SHARE_READ,
                   
NULL,
                   
OPEN_EXISTING,
                   
FILE_ATTRIBUTE_NORMAL,
                   
NULL);

// Check the return handle value
if (NULL != hFile && INVALID_HANDLE_VALUE != hFile)
{
    
// Get the current file size
    
dwFileSize GetFileSize(hFileNULL);

    
// Allocate local data buffer
    
lpData = (LPBYTE)LocalAlloc(LPTRdwFileSize);
    
// Reset local data buffer
    
ZeroMemory(lpDatadwFileSize);
    
    
// Move the file pointer to the begining
    
SetFilePointer(hFile00FILE_BEGIN);
    
// Read the data from the current open file
    
ReadFile(hFilelpDatadwFileSize, &dwByteReadNULL);
}
else
{
    
// Notify user about the error
    
MessageBox(hWnd"Fail to open file!"APP_TITLEMB_OK MB_ICONSTOP);
}

// Close the open file handle
if (NULL != hFile) {CloseHandle(hFile);}
hFile NULL