int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { int argc; TCHAR szMsg[RC_STRING_MAX_SIZE]; LPTSTR *argv; LPTSTR lptCmdLine,lptDllName,lptFuncName,lptMsgBuffer; LPSTR lpFuncName,lpaCmdLine; LPWSTR lpwCmdLine; HMODULE hDll; DllWinMainW fnDllWinMainW; DllWinMainA fnDllWinMainA; HWND hWindow; int i; size_t nStrLen; // Get command-line in argc-argv format argv = CommandLineToArgv(GetCommandLine(),&argc); // Skip all beginning arguments starting with a slash (/) for (i = 1; i < argc; i++) if (*argv[i] != _T('/')) break; // If no dll was specified, there is nothing to do if (i >= argc) { if (argv) free(argv); return 0; } lptDllName = argv[i++]; // The next argument, which specifies the name of the dll function, // can either have a comma between it and the dll filename or a space. // Using a comma here is the preferred method if (i < argc) lptFuncName = argv[i++]; else lptFuncName = _T(""); // If no function name was specified, nothing needs to be done if (!*lptFuncName) { if (argv) free(argv); return 0; } // The rest of the arguments will be passed to dll function if (i < argc) lptCmdLine = argv[i]; else lptCmdLine = _T(""); // Everything is all setup, so load the dll now hDll = LoadLibrary(lptDllName); if (hDll) { nStrLen = _tcslen(lptFuncName); // Make a non-unicode version of the function name, // since that is all GetProcAddress accepts lpFuncName = DuplicateToMultiByte(lptFuncName,nStrLen + 2); #ifdef UNICODE lpFuncName[nStrLen] = 'W'; lpFuncName[nStrLen+1] = 0; // Get address of unicode version of the dll function if it exists fnDllWinMainW = (DllWinMainW)GetProcAddress(hDll,lpFuncName); fnDllWinMainA = 0; if (!fnDllWinMainW) { // If no unicode function was found, get the address of the non-unicode function lpFuncName[nStrLen] = 'A'; fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName); if (!fnDllWinMainA) { // If first non-unicode function was not found, get the address // of the other non-unicode function lpFuncName[nStrLen] = 0; fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName); } } #else // Get address of non-unicode version of the dll function if it exists fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName); fnDllWinMainW = 0; if (!fnDllWinMainA) { // If first non-unicode function was not found, get the address // of the other non-unicode function lpFuncName[nStrLen] = 'A'; lpFuncName[nStrLen+1] = 0; fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName); if (!fnDllWinMainA) { // If non-unicode function was not found, get the address of the unicode function lpFuncName[nStrLen] = 'W'; fnDllWinMainW = (DllWinMainW)GetProcAddress(hDll,lpFuncName); } } #endif free(lpFuncName); if (!RegisterBlankClass(hInstance, hPrevInstance)) { return 0; } // Create a window so we can pass a window handle to // the dll function; this is required hWindow = CreateWindowEx(0,rundll32_wclass,rundll32_wtitle,0,CW_USEDEFAULT,0,CW_USEDEFAULT,0,0,0,hInstance,0); if (fnDllWinMainW) { // Convert the command-line string to unicode and call the dll function lpwCmdLine = ConvertToWideChar(lptCmdLine); fnDllWinMainW(hWindow,hInstance,lpwCmdLine,nCmdShow); FreeConvertedWideChar(lpwCmdLine); } else if (fnDllWinMainA) { // Convert the command-line string to ansi and call the dll function lpaCmdLine = ConvertToMultiByte(lptCmdLine); fnDllWinMainA(hWindow,hInstance,lpaCmdLine,nCmdShow); FreeConvertedMultiByte(lpaCmdLine); } else { // The specified dll function was not found; display an error message GetModuleTitle(); LoadString( GetModuleHandle(NULL), IDS_MissingEntry, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); lptMsgBuffer = (LPTSTR)malloc((_tcslen(szMsg) - 4 + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer,szMsg,lptFuncName,lptDllName); MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONERROR); free(lptMsgBuffer); } DestroyWindow(hWindow); UnregisterClass(rundll32_wclass,hInstance); // The dll function has finished executing, so unload it FreeLibrary(hDll); } else { // The dll could not be loaded; display an error message GetModuleTitle(); LoadString( GetModuleHandle(NULL), IDS_DllNotLoaded, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); lptMsgBuffer = (LPTSTR)malloc((_tcslen(szMsg) - 2 + _tcslen(lptDllName) + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer,szMsg,lptDllName); MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONERROR); free(lptMsgBuffer); } if (argv) free(argv); return 0; /* rundll32 always returns 0! */ }
int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { int argc; LPTSTR *argv; LPTSTR lptDllName,lptDllCmdLine,lptMsgBuffer; LPCTSTR lptFuncName; LPCSTR lpFuncName; LPWSTR lpwDllCmdLine; BOOL bUnregister,bSilent,bConsole,bInstall,bNoRegister; UINT nDllCount; HMODULE hDll; DLLREGISTER fnDllRegister; DLLINSTALL fnDllInstall; HRESULT hResult; DWORD dwErr; int nRetValue,i; // Get Langues msg LoadString( GetModuleHandle(NULL), IDS_UsageMessage, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE); LoadString( GetModuleHandle(NULL), IDS_NoDllSpecified, (LPTSTR) NoDllSpecified,RC_STRING_MAX_SIZE); LoadString( GetModuleHandle(NULL), IDS_InvalidFlag, (LPTSTR) InvalidFlag,RC_STRING_MAX_SIZE); LoadString( GetModuleHandle(NULL), IDS_SwitchN_NoI, (LPTSTR) SwitchN_NoI,RC_STRING_MAX_SIZE); LoadString( GetModuleHandle(NULL), IDS_DllNotLoaded, (LPTSTR) DllNotLoaded,RC_STRING_MAX_SIZE); LoadString( GetModuleHandle(NULL), IDS_MissingEntry, (LPTSTR) MissingEntry,RC_STRING_MAX_SIZE); LoadString( GetModuleHandle(NULL), IDS_FailureMessage, (LPTSTR) FailureMessage,RC_STRING_MAX_SIZE); LoadString( GetModuleHandle(NULL), IDS_SuccessMessage, (LPTSTR) SuccessMessage,RC_STRING_MAX_SIZE); // Get command-line in argc-argv format argv = CommandLineToArgv(GetCommandLine(),&argc); // Initialize variables lptFuncName = 0; lptDllCmdLine = 0; nDllCount = 0; bUnregister = FALSE; bSilent = FALSE; bConsole = FALSE; bInstall = FALSE; bNoRegister = FALSE; // Find all arguments starting with a slash (/) for (i = 1; i < argc; i++) { if (*argv[i] == _T('/')) { switch (argv[i][1]) { case _T('u'): case _T('U'): bUnregister = TRUE; break; case _T('s'): case _T('S'): bSilent = TRUE; break; case _T('c'): case _T('C'): bConsole = TRUE; break; case _T('i'): case _T('I'): bInstall = TRUE; lptDllCmdLine = argv[i]; while (*lptDllCmdLine != 0 && *lptDllCmdLine != _T(':')) lptDllCmdLine++; if (*lptDllCmdLine == _T(':')) lptDllCmdLine++; break; case _T('n'): case _T('N'): bNoRegister = TRUE; break; default: if (!lptFuncName) lptFuncName = argv[i]; } } else { nDllCount++; } } // An unrecognized flag was used, display a message and show available options if (lptFuncName) { lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(InvalidFlag) - 2 + _tcslen(lptFuncName) + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer + (_tcslen(UsageMessage) - 2),InvalidFlag,lptFuncName); _stprintf(lptMsgBuffer,UsageMessage,lptMsgBuffer + (_tcslen(UsageMessage) - 2)); DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION); free(lptMsgBuffer); GlobalFree(argv); return EXITCODE_PARAMERROR; } // /n was used without /i, display a message and show available options if (bNoRegister && (!bInstall)) { lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(SwitchN_NoI) + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer,UsageMessage,SwitchN_NoI); DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION); free(lptMsgBuffer); GlobalFree(argv); return EXITCODE_PARAMERROR; } // No dll was specified, display a message and show available options if (nDllCount == 0) { lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(NoDllSpecified) + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer,UsageMessage,NoDllSpecified); DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION); free(lptMsgBuffer); GlobalFree(argv); return EXITCODE_PARAMERROR; } nRetValue = EXITCODE_SUCCESS; if (!bUnregister) { lpFuncName = szDllRegister; lptFuncName = tszDllRegister; } else { lpFuncName = szDllUnregister; lptFuncName = tszDllUnregister; } if (lptDllCmdLine) lpwDllCmdLine = ConvertToWideChar(lptDllCmdLine); else lpwDllCmdLine = 0; // Initialize OLE32 before attempting to register the // dll. Some dll's require this to register properly OleInitialize(0); // (Un)register every dll whose filename was passed in the command-line string for (i = 1; i < argc && nRetValue == EXITCODE_SUCCESS; i++) { // Arguments that do not start with a slash (/) are filenames if (*argv[i] != _T('/')) { lptDllName = argv[i]; // Everything is all setup, so load the dll now hDll = LoadLibraryEx(lptDllName,0,LOAD_WITH_ALTERED_SEARCH_PATH); if (hDll) { if (!bNoRegister) { // Get the address of DllRegisterServer or DllUnregisterServer fnDllRegister = (DLLREGISTER)GetProcAddress(hDll,lpFuncName); if (fnDllRegister) { // If the function exists, call it hResult = fnDllRegister(); if (hResult == S_OK) { // (Un)register succeeded, display a message lptMsgBuffer = (LPTSTR)malloc((_tcslen(SuccessMessage) - 4 + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer,SuccessMessage,lptFuncName,lptDllName); DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONINFORMATION); } else { // (Un)register failed, display a message lptMsgBuffer = (LPTSTR)malloc((_tcslen(FailureMessage) + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer,FailureMessage,lptFuncName,lptDllName,hResult); DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION); } free(lptMsgBuffer); if (hResult != S_OK) nRetValue = EXITCODE_FAILURE; } else { FreeLibrary(hDll); // Dll(Un)register was not found, display an error message lptMsgBuffer = (LPTSTR)malloc((_tcslen(MissingEntry) - 8 + _tcslen(lptFuncName) * 2 + _tcslen(lptDllName) * 2 + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer,MissingEntry,lptDllName,lptFuncName,lptFuncName,lptDllName); DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION); free(lptMsgBuffer); nRetValue = EXITCODE_NOENTRY; } } if (bInstall && nRetValue == EXITCODE_SUCCESS) { // Get the address of DllInstall fnDllInstall = (DLLINSTALL)GetProcAddress(hDll,szDllInstall); if (fnDllInstall) { // If the function exists, call it if (!bUnregister) hResult = fnDllInstall(1,lpwDllCmdLine); else hResult = fnDllInstall(0,lpwDllCmdLine); if (hResult == S_OK) { // (Un)install succeeded, display a message lptMsgBuffer = (LPTSTR)malloc((_tcslen(SuccessMessage) - 4 + _tcslen(tszDllInstall) + _tcslen(lptDllName) + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer,SuccessMessage,tszDllInstall,lptDllName); DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONINFORMATION); } else { // (Un)install failed, display a message lptMsgBuffer = (LPTSTR)malloc((_tcslen(FailureMessage) + _tcslen(tszDllInstall) + _tcslen(lptDllName) + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer,FailureMessage,tszDllInstall,lptDllName,hResult); DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION); } free(lptMsgBuffer); if (hResult != S_OK) nRetValue = EXITCODE_FAILURE; } else { FreeLibrary(hDll); // DllInstall was not found, display an error message lptMsgBuffer = (LPTSTR)malloc((_tcslen(MissingEntry) - 8 + _tcslen(tszDllInstall) * 2 + _tcslen(lptDllName) * 2 + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer,MissingEntry,lptDllName,tszDllInstall,tszDllInstall,lptDllName); DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION); free(lptMsgBuffer); nRetValue = EXITCODE_NOENTRY; } } // The dll function has finished executing, so unload it FreeLibrary(hDll); } else { // The dll could not be loaded; display an error message dwErr = GetLastError(); lptMsgBuffer = (LPTSTR)malloc((_tcslen(DllNotLoaded) + 2 + _tcslen(lptDllName) + 1) * sizeof(TCHAR)); _stprintf(lptMsgBuffer,DllNotLoaded,lptDllName,dwErr); DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION); free(lptMsgBuffer); nRetValue = EXITCODE_LOADERROR; } } } if (lpwDllCmdLine) FreeConvertedWideChar(lpwDllCmdLine); GlobalFree(argv); OleUninitialize(); return nRetValue; }