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

## Chris

*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.



```

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.



```

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:





```

// 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; 



```




```

// 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; 



```

----------

