# VBForums CodeBank > CodeBank - C++ >  C++ - Pure WIN32 Self-Extract EXE Builder (Part - 4 (Continue))

## Chris

*Part - 4 (Continue)*

Now, we have both the header and content data file, and it is the time to merge this 2 files into a single file before proceed to compress it using the *Zlib** algorithm.



```

// Begin to merge the header and data file
if (TRUE == MergeSelfExtractData (hWnd))
{
    // Compress the current data file to the user define location & 
    // Notify user about the process is completed
    if (0 == Compress(szTmpBinFile1, szTmpBinFile3))
    {
        // Proceed to spawn the SetupEx.exe
        
        // Proceed to inject the merge data file into the spawned SetupEx.exe
    }
}
else
    // Notify user about the error
    MessageBox(hWnd, "Fail to compress the self-extract file!", APP_TITLE, MB_OK | MB_ICONSTOP); 



```



```

BOOL MergeSelfExtractData (HWND hWnd)
{
    UPDATEINFO    ui    = {NULL};

    BOOL       bResult        = FALSE;
    
    LPBYTE     lpData         = NULL;
    HANDLE     hFile          = NULL;
    DWORD      dwSize         = 0;
    DWORD      dwByteWrite    = 0;
    DWORD      dwByteRead     = 0;

    __try
    {
        // STAGE #1
        {
            // Read the current binary file data
            hFile = CreateFile(szTmpBinFile2,
                               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 = GetFileSize(hFile, 0);
                // 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
        // 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)
        {
            // Setup the UPDATEINFO structure
            ui.dwFileCount = dwFileCount;
            
            // Move the file pointer
            SetFilePointer(hFile, 0, 0, FILE_BEGIN);
            // Write the total binary data file being included
            WriteFile(hFile,
                      &ui,
                      sizeof(UPDATEINFO),
                      &dwByteWrite,
                      NULL);

            // Move the file pointer
            SetFilePointer(hFile, 0, 0, FILE_END);
            // Append the actual binary data from the temp file
            WriteFile(hFile,
                      lpData,
                      dwSize,
                      &dwByteWrite,
                      NULL);

            // Set return value
            bResult = TRUE;
        }
        else
            // Set return value
            bResult = FALSE;


    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        // PUT YOUR ERROR HANDLING CODE HERE

        // Set default return value
        bResult = FALSE;
    }

    // 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;
    
    // Return local result
    return bResult;
} 



```

----------

