예제 #1
0
파일: rundll32.c 프로젝트: RareHare/reactos
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! */
}
예제 #2
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;
}