-
-
Save justaguywhocodes/430babdf6a1b4949e7e5a3f08d9c5715 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Here's the DLL code modified to work as C++ (.cpp file). The changes are minimal since the Windows API is C-based, but I'll add some C++ style and error handling: | |
```cpp | |
#include <windows.h> | |
BOOL APIENTRY DllMain(HMODULE hModule, | |
DWORD ul_reason_for_call, | |
LPVOID lpReserved) | |
{ | |
switch (ul_reason_for_call) | |
{ | |
case DLL_PROCESS_ATTACH: | |
{ | |
STARTUPINFOA si{}; | |
PROCESS_INFORMATION pi{}; | |
// Initialize startup info | |
si.cb = sizeof(si); | |
// Create the calculator process | |
BOOL success = CreateProcessA( | |
"C:\\Windows\\System32\\calc.exe", | |
nullptr, // No command line arguments | |
nullptr, // Process handle not inheritable | |
nullptr, // Thread handle not inheritable | |
FALSE, // Don't inherit handles | |
0, // No creation flags | |
nullptr, // Use parent's environment | |
nullptr, // Use parent's directory | |
&si, // Startup info | |
&pi // Process info | |
); | |
if (success) | |
{ | |
// Clean up handles using RAII-like approach | |
CloseHandle(pi.hProcess); | |
CloseHandle(pi.hThread); | |
} | |
else | |
{ | |
// In a real application, you might want to log this | |
// DWORD error = GetLastError(); | |
return FALSE; | |
} | |
break; | |
} | |
case DLL_THREAD_ATTACH: | |
case DLL_THREAD_DETACH: | |
case DLL_PROCESS_DETACH: | |
break; | |
} | |
return TRUE; | |
} | |
``` | |
Key C++-specific modifications: | |
1. Changed `NULL` to `nullptr` for modern C++ style | |
2. Used uniform initialization syntax with `{}` | |
3. Added scope blocks `{}` for better variable lifetime management | |
4. Added basic error handling with return value | |
To compile as a C++ DLL with g++ (MinGW): | |
``` | |
g++ -shared -o calc_dll.dll calc_dll.cpp | |
``` | |
If you want a more C++-style implementation with better error handling, here's an enhanced version: | |
```cpp | |
#include <windows.h> | |
#include <stdexcept> | |
class ProcessLauncher { | |
private: | |
static void CloseHandles(HANDLE hProcess, HANDLE hThread) { | |
if (hProcess != nullptr) CloseHandle(hProcess); | |
if (hThread != nullptr) CloseHandle(hThread); | |
} | |
public: | |
static void LaunchCalculator() { | |
STARTUPINFOA si{}; | |
PROCESS_INFORMATION pi{}; | |
si.cb = sizeof(si); | |
BOOL success = CreateProcessA( | |
"C:\\Windows\\System32\\calc.exe", | |
nullptr, | |
nullptr, | |
nullptr, | |
FALSE, | |
0, | |
nullptr, | |
nullptr, | |
&si, | |
&pi | |
); | |
if (!success) { | |
throw std::runtime_error("Failed to launch calculator"); | |
} | |
CloseHandles(pi.hProcess, pi.hThread); | |
} | |
}; | |
extern "C" BOOL APIENTRY DllMain(HMODULE hModule, | |
DWORD ul_reason_for_call, | |
LPVOID lpReserved) | |
{ | |
switch (ul_reason_for_call) | |
{ | |
case DLL_PROCESS_ATTACH: | |
try { | |
ProcessLauncher::LaunchCalculator(); | |
} | |
catch (const std::exception&) { | |
return FALSE; | |
} | |
break; | |
case DLL_THREAD_ATTACH: | |
case DLL_THREAD_DETACH: | |
case DLL_PROCESS_DETACH: | |
break; | |
} | |
return TRUE; | |
} | |
``` | |
This enhanced version: | |
1. Uses a class to encapsulate the launching logic | |
2. Implements proper C++ exception handling | |
3. Separates handle cleanup into a helper function | |
4. Uses `extern "C"` to ensure proper linkage for DllMain | |
Compile with: | |
``` | |
g++ -shared -o calc_dll.dll calc_dll.cpp -std=c++17 | |
``` | |
Both versions will work as a DLL in a C++ environment. The second version is more "C++-like" but might be overkill for this simple task. Choose based on your specific needs and whether you plan to expand the DLL's functionality later. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment