-
May 16th, 2004, 09:01 AM
#1
Thread Starter
PowerPoster
C++ - Pure WIN32 Self-Extract EXE Builder (Part - 4)
Part - 4
How to build the merge data file
At this stage, you have gain all the minimum knowledge on accessing the file I/O. Also, you get the idea how the final merge data file being structure. So, it is the big time for the core task of the entire project... building the merge data file. Before I start explain the most interesting part (program code) step by step, let recap some of the important step to build the merge data file.
NOTE:
In the following code snippet, I was filter out those code related to GUI update. These GUI update is mainly to keep the user inform about the status of the entire building self-extract executable file process. If you wish to get more about this GUI update code, you can always refer to the full source code enclosed together with this article.
Basically, the following code snippet will cover from step #1 and #4. Which is a do... while... loop to scan through the folder.
PHP Code:
// Get the current user define source folder
GetDlgItemText(hWnd, IDC_EDIT1, szBuffer1, sizeof(szBuffer1));
// Format the full path for the source folder
sprintf(szBuffer2,
"%s\\*.*",
szBuffer1);
// Start scaning the directory
hFile = FindFirstFile(szBuffer2, &wfs);
// Check the return handle value
do
{
// Check is the current found file is directory?
if (!(FILE_ATTRIBUTE_DIRECTORY & wfs.dwFileAttributes))
{
// Save the information into data file
WriteSelfExtractHeader (hWnd, &wfs);
// Save the information into data file
WriteSelfExtractBinData (hWnd, &wfs);
}
// 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 handle
if (NULL != hFile) {FindClose(hFile);}
hFile = NULL;
Next block of code snippet will cover the reading & writing the file information into the header block. As well as the code for reading & writing the content of the current file.
NOTE:
The file size informatin is very important in the (SetupEx.exe) module, because this will be the key information that instruct the SetupEx.exe how much it should move the file pointer in order to get back to the original staring point of the each individual distributed file.
PHP Code:
void WriteSelfExtractHeader (HWND hWnd, LPWIN32_FIND_DATA lpFindFileData)
{
EXTRACTFILEINFO efi = {NULL};
HANDLE hFile = NULL;
DWORD dwByteWrite = 0;
__try
{
// Open the existing temporary data file
hFile = CreateFile(szTmpBinFile1,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
// Check the return handle value
if (NULL == hFile || INVALID_HANDLE_VALUE == hFile)
{
// Open the existing temporary data file
hFile = CreateFile(szTmpBinFile1,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
}
// Check the return handle value
if (NULL != hFile && INVALID_HANDLE_VALUE != hFile)
{
// Reset the local EXTRACTFILEINFO structure
ZeroMemory(&efi, sizeof(EXTRACTFILEINFO));
// Initialize the EXTRACTFILEINFO structure
efi.dwIndex = dwFileCount;
CopyMemory(&efi.CreateTime, &lpFindFileData->ftCreationTime, sizeof(FILETIME));
CopyMemory(&efi.LastAcessTime, &lpFindFileData->ftLastAccessTime, sizeof(FILETIME));
CopyMemory(&efi.LastWriteTime, &lpFindFileData->ftLastWriteTime, sizeof(FILETIME));
CopyMemory(&efi.dwFileSizeHigh, &lpFindFileData->nFileSizeHigh , sizeof(DWORD));
CopyMemory(&efi.dwFileSizeLow, &lpFindFileData->nFileSizeLow, sizeof(DWORD));
CopyMemory(&efi.szBinFileName, &lpFindFileData->cFileName, strlen(lpFindFileData->cFileName));
// Check current file count & move the file pointer
if (0 == dwFileCount)
SetFilePointer(hFile, sizeof(UPDATEINFO), 0, FILE_BEGIN);
else
SetFilePointer(hFile, 0, 0, FILE_END);
// Write the data into setup list file
WriteFile(hFile,
&efi,
sizeof(EXTRACTFILEINFO),
&dwByteWrite,
NULL);
// Increate the counter
dwFileCount++;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
// PUT YOUR ERROR HANDLING CODE HERE
}
// Close the open file handle
if (NULL != hFile) {CloseHandle(hFile);}
hFile = NULL;
}
void WriteSelfExtractBinData (HWND hWnd, LPWIN32_FIND_DATA lpFindFileData)
{
HANDLE hFile = NULL;
LPBYTE lpData = NULL;
DWORD dwSize = 0;
DWORD dwByteRead = 0;
DWORD dwByteWrite = 0;
char szBuffer1[MAX_PATH] = {NULL};
char szBuffer2[MAX_PATH] = {NULL};
__try
{
// Get the user define source folder
GetDlgItemText(hWnd, IDC_EDIT1, szBuffer1, sizeof(szBuffer1));
// Format the full file path
sprintf(szBuffer2,
"%s\\%s",
szBuffer1, lpFindFileData->cFileName);
// STAGE #1
// Read the current binary file data
hFile = CreateFile(szBuffer2,
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
dwSize = (lpFindFileData->nFileSizeHigh*(MAXDWORD+1)) +
lpFindFileData->nFileSizeLow;
// Allocate local data buffer
lpData = (LPBYTE)LocalAlloc(LPTR, dwSize);
// Reset local data buffer
ZeroMemory(lpData, dwSize);
// Move the file pointer to the begining
SetFilePointer(hFile, 0, 0, FILE_BEGIN);
// Read the binary data
ReadFile(hFile, lpData, dwSize, &dwByteRead, NULL);
}
// Close the open file handle
if (NULL != hFile) {CloseHandle(hFile);}
hFile = NULL;
// STAGE #2
// WRITE THE READ BINDARY DATA INTO THE TEMPORARY FILE
// Open the existing setup data file (szTmpBinFile2)
hFile = CreateFile(szTmpBinFile2,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
// Check the return handle value
if (NULL == hFile || INVALID_HANDLE_VALUE == hFile)
{
// Open the existing setup.lst data file
hFile = CreateFile(szTmpBinFile2,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
}
// Check the return handle value
if (NULL != hFile && INVALID_HANDLE_VALUE != hFile)
{
// Move the file pointer
SetFilePointer(hFile, 0, 0, FILE_END);
// Write the data into setup list file
WriteFile(hFile,
lpData,
dwSize,
&dwByteWrite,
NULL);
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
// PUT YOUR ERROR HANDLING CODE HERE
}
// Release the allocated data buffer
if (NULL != lpData){LocalFree((LPBYTE)lpData);}
lpData = NULL;
// Close the open file handle
if (NULL != hFile) {CloseHandle(hFile);}
hFile = NULL;
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|