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(hFile1, 0, 0, FILE_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_TITLE, MB_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(hFile, NULL);
// Allocate local data buffer
lpData = (LPBYTE)LocalAlloc(LPTR, dwFileSize);
// Reset local data buffer
ZeroMemory(lpData, dwFileSize);
// Move the file pointer to the begining
SetFilePointer(hFile, 0, 0, FILE_BEGIN);
// Read the data from the current open file
ReadFile(hFile, lpData, dwFileSize, &dwByteRead, NULL);
}
else
{
// Notify user about the error
MessageBox(hWnd, "Fail to open file!", APP_TITLE, MB_OK | MB_ICONSTOP);
}
// Close the open file handle
if (NULL != hFile) {CloseHandle(hFile);}
hFile = NULL;