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

## Chris

*Part - 7*

*Chances for inject data into different resource table*
*UpdateResource* API was used in this project for injecting the compressed merge data file into the spawned SetupEx.exe in order to
complete the self-extract executable file. 



```

if (FALSE == UpdateResource (hFile2,
                             "SETUP",
                             MAKEINTRESOURCE(IDR_SETUP1),
                             MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
                             lpBinData,
                             dwFileSize)) 



```

From this code snippet, the second, third and forth arguement will be the key value which will cause merge data file being injected into a wrong resource table. Hence, I will explain each of these scenario one-by-one.

For the first scenario, if the *"SETUP"* was change to something like *"ABC"* and the output will be like the 2 screens shot below. Which the differences can be clearly identifier (_there was an extra custom resource name "ABC"_). As a result, the spawned self-extacrt executable will remain locate and load the original dummy data stored inside the *"SETUP"* custom resource. Because the compressed merge data was injected into the *"ABC"* custom resource table instead of the pre-defined *"SETUP"*.

Basically, the *"SETUP"*  is represent the custom resource group name and it is very important when calling the *UpdateResource* API.



```

if (FALSE == UpdateResource (hFile2,
                             "ABC",
                             MAKEINTRESOURCE(IDR_SETUP1),
                             MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
                             lpBinData,
                             dwFileSize)) 



```

 

While second scenario, if the *MAKEINTRESOURCE(IDR_SETUP1)* was change to something like *2001* (_MAKEINTRESOURCE(IDR_SETUP1) will return the value of 2000, as the IDR_SETUP1 was defined as 2000 under the resource.h file_) and the output will be like the 2 screens shot below. As the differences can be clearly identifier (_there was an extra custom resource identifier 2001_). As a result, the spawned self-extacrt executable will remain locate and load the original dummy data stored inside the *2000* custom resource. Because the compressed merge data was injected into the *2001* custom resource instead of the pre-defined *2000*.

The *2001* is represent the custom resource identifier and it is also very important when calling the *UpdateResource* API. A wrong value will collapse the entire self-extract executable file.



```

if (FALSE == UpdateResource (hFile2,
                             "SETUP",
                             "2001",
                             MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
                             lpBinData,
                             dwFileSize)) 



```

 

For the last scenario, if the *MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)* was change to something like *MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK)* and the output will be like the 2 screens shot below. The differences can be clearly identifier (_there was an extra custom resource identifier 2000 with the value of 2057 on the right handside insetad of 1033_). As a result, the spawned self-extacrt executable will remain locate and load the original dummy data stored inside the *2000* custom resource with language id of 1033 and not the newly injected with same custom resource identifier but different language id (2057).

The *MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)*  is represent the language id for the respective custom resource. So, it is another key factor when calling the *UpdateResource* API. A wrong value will collapse the entire self-extract executable file as well.



```

if (FALSE == UpdateResource (hFile2,
                             "SETUP",
                             MAKEINTRESOURCE(IDR_SETUP1),
                             MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK),
                             lpBinData,
                             dwFileSize)) 



```

 

Besides the actual language identifier, you also can use the language neutral identifier to inject the compressed merge data into the spawned SetupEx.exe. Yet, it still work, although the compressed merge data was injected into the came group of custom resource table but under different language identifier *0* instead of *1033*.

For this, I am still searching for the answer about why it will work even the *LANG_NEUTRAL* and *SUBLANG_NEUTRAL* language identifier was used during the injection with *UpdateResource* API. Which does not match with the language identifier specified inside the SetupEx.exe.



```

if (FALSE == UpdateResource (hFile2,
                             "SETUP",
                             MAKEINTRESOURCE(IDR_SETUP1),
                             MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
                             lpBinData,
                             dwFileSize)) 



```

 

Please refer to the *MAKELANGID* API in MDSN library for the full list of _Primary Language Identifier_ and _Sub Language Identifier_.

----------

