diff --git a/reactos/apps/utils/Makefile b/reactos/apps/utils/Makefile index cf88d9fb194..cfad09395ee 100644 --- a/reactos/apps/utils/Makefile +++ b/reactos/apps/utils/Makefile @@ -9,7 +9,7 @@ include $(PATH_TO_TOP)/rules.mak # Console system utilities # cabman cat net objdir partinfo pice ps sc stats -UTIL_APPS = cat objdir partinfo pnpdump sc stats tickcount consw +UTIL_APPS = cat objdir partinfo pnpdump sc stats tickcount consw rundll32 UTIL_NET_APPS = diff --git a/reactos/apps/utils/rundll32/.cvsignore b/reactos/apps/utils/rundll32/.cvsignore new file mode 100644 index 00000000000..d63774a7353 --- /dev/null +++ b/reactos/apps/utils/rundll32/.cvsignore @@ -0,0 +1,6 @@ +*.o +*.d +*.exe +*.coff +*.sym +*.map diff --git a/reactos/apps/utils/rundll32/Makefile b/reactos/apps/utils/rundll32/Makefile new file mode 100644 index 00000000000..fb7399d48bb --- /dev/null +++ b/reactos/apps/utils/rundll32/Makefile @@ -0,0 +1,21 @@ +# $Id: Makefile,v 1.1 2003/11/07 09:12:44 gvg Exp $ + +PATH_TO_TOP = ../../.. + +TARGET_TYPE = program + +TARGET_APPTYPE = windows + +TARGET_NAME = rundll32 + +TARGET_SDKLIBS = kernel32.a user32.a + +TARGET_OBJECTS = rundll32.o + +TARGET_CFLAGS += -DUNICODE -Wall -Werror -D__USE_W32API + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/reactos/apps/utils/rundll32/rundll32.c b/reactos/apps/utils/rundll32/rundll32.c new file mode 100644 index 00000000000..9f57cbfc948 --- /dev/null +++ b/reactos/apps/utils/rundll32/rundll32.c @@ -0,0 +1,312 @@ +/* + * ReactOS rundll32 + * Copyright (C) 2003 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id: rundll32.c,v 1.1 2003/11/07 09:12:44 gvg Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS rundll32.exe + * FILE: rundll32/rundll32.c + * PURPOSE: Run a DLL as a program + * PROGRAMMER: ShadowFlare (blakflare@hotmail.com) + */ + +#define WIN32_LEAN_AND_MEAN + +// Both UNICODE and _UNICODE must be either defined or undefined +// because some headers use UNICODE and others use _UNICODE +#ifdef UNICODE +#ifndef _UNICODE +#define _UNICODE +#endif +#else +#ifdef _UNICODE +#define UNICODE +#endif +#endif + +#include +#include +#include +#include +#include + +typedef int (WINAPI *DllWinMainW)( + HWND hWnd, + HINSTANCE hInstance, + LPWSTR lpwCmdLine, + int nCmdShow +); +typedef int (WINAPI *DllWinMainA)( + HWND hWnd, + HINSTANCE hInstance, + LPSTR lpCmdLine, + int nCmdShow +); + +LPCTSTR DllNotLoaded = _T("LoadLibrary failed to load \"%ls\""); +LPCTSTR MissingEntry = _T("Missing entry point:%ls\nIn %ls"); +LPCTSTR rundll32_wtitle = _T("rundll32"); +LPCTSTR rundll32_wclass = _T("rundll32_window"); +TCHAR ModuleFileName[MAX_PATH+1]; +LPTSTR ModuleTitle; + +LPTSTR FindArgStart(LPTSTR lpStr) +{ + while (*lpStr) { + switch (*lpStr) { + case _T(' '): + case _T('\t'): + case _T('\r'): + case _T('\n'): + break; + default: + return lpStr; + } + lpStr++; + } + return lpStr; +} + +LPTSTR FindArgEnd(LPTSTR lpStr) +{ + if (*lpStr != _T('\"')) { + while (*lpStr) { + switch (*lpStr) { + case _T(' '): + case _T('\t'): + case _T('\r'): + case _T('\n'): + *(lpStr++) = 0; + return lpStr; + } + lpStr++; + } + } + else { + for (++lpStr;*lpStr && *lpStr != _T('\"');++lpStr) {} + if (*lpStr == _T('\"')) { + *(lpStr++) = 0; + } + } + + return lpStr; +} + +void GetModuleTitle(void) +{ + LPTSTR lpStr; + + GetModuleFileName(0,ModuleFileName,MAX_PATH); + ModuleTitle = ModuleFileName; + + for (lpStr = ModuleFileName;*lpStr;lpStr++) { + if (*lpStr == _T('\\')) + ModuleTitle = lpStr+1; + } + + for (lpStr = ModuleTitle;*lpStr;lpStr++) { + if (_tcsicmp(lpStr,_T(".exe"))==0) + break; + } + + *lpStr = 0; +} + +#ifdef UNICODE +#define ConvertToWideChar(lptString) (lptString) +#define FreeConvertedWideChar(lptString) +#else + +LPWSTR ConvertToWideChar(LPCSTR lpString) +{ + LPWSTR lpwString; + size_t nStrLen; + + nStrLen = strlen(lpString) + 1; + + lpwString = (LPWSTR)malloc(nStrLen * sizeof(WCHAR)); + MultiByteToWideChar(0,0,lpString,nStrLen,lpwString,nStrLen); + + return lpwString; +} + +#define FreeConvertedWideChar(lptString) free(lptString) +#endif + +#ifdef UNICODE +#define ConvertToMultiByte(lptString) DuplicateToMultiByte(lptString,0) +#define FreeConvertedMultiByte(lptString) free(lptString) +#else +#define ConvertToMultiByte(lptString) (lptString) +#define FreeConvertedMultiByte(lptString) +#endif + +LPSTR DuplicateToMultiByte(LPCTSTR lptString, size_t nBufferSize) +{ + LPSTR lpString; + size_t nStrLen; + + nStrLen = _tcslen(lptString) + 1; + if (nBufferSize == 0) nBufferSize = nStrLen; + + lpString = (LPSTR)malloc(nBufferSize); +#ifdef UNICODE + WideCharToMultiByte(0,0,lptString,nStrLen,lpString,nBufferSize,0,0); +#else + strncpy(lpString,lptString,nBufferSize); +#endif + + return lpString; +} + +LRESULT CALLBACK EmptyWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +ATOM RegisterBlankClass(HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = 0; + wcex.lpfnWndProc = EmptyWindowProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = 0; + wcex.hCursor = 0; + wcex.hbrBackground = 0; + wcex.lpszMenuName = 0; + wcex.lpszClassName = rundll32_wclass; + wcex.hIconSm = 0; + + return RegisterClassEx(&wcex); +} + +int WINAPI WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLineA, + int nCmdShow +) +{ + LPTSTR lptCmdLineCopy,lptCmdLine,lptDllName,lptFuncName,lptMsgBuffer; + LPSTR lpFuncName,lpaCmdLine; + LPWSTR lpwCmdLine; + HMODULE hDll; + DllWinMainW fnDllWinMainW; + DllWinMainA fnDllWinMainA; + HWND hWindow; + int nRetVal; + size_t nStrLen; + + lptCmdLineCopy = _tcsdup(GetCommandLine()); + + lptCmdLine = FindArgStart(lptCmdLineCopy); + lptCmdLine = FindArgEnd(lptCmdLine); + lptDllName = FindArgStart(lptCmdLine); + while (*lptDllName == _T('/')) + lptDllName = FindArgStart(FindArgEnd(++lptDllName)); + lptCmdLine = FindArgEnd(lptDllName); + if (*lptDllName == _T('\"')) lptDllName++; + + if (!*lptDllName) { + free(lptCmdLineCopy); + return 0; + } + + for (lptFuncName = lptDllName;*lptFuncName && *lptFuncName != _T(',');lptFuncName++) {} + if (*lptFuncName == _T(',')) { + *(lptFuncName++) = 0; + } + else { + lptFuncName = FindArgStart(lptCmdLine); + lptCmdLine = FindArgEnd(lptFuncName); + if (*lptFuncName == _T('\"')) lptFuncName++; + } + + if (!*lptFuncName) { + free(lptCmdLineCopy); + return 0; + } + + if (*lptCmdLine) lptCmdLine = FindArgStart(lptCmdLine); + + nRetVal = 0; + + hDll = LoadLibrary(lptDllName); + if (hDll) { + nStrLen = _tcslen(lptFuncName); + lpFuncName = DuplicateToMultiByte(lptFuncName,nStrLen + 2); + + lpFuncName[nStrLen] = 'W'; + lpFuncName[nStrLen+1] = 0; + fnDllWinMainW = (DllWinMainW)GetProcAddress(hDll,lpFuncName); + fnDllWinMainA = 0; + if (!fnDllWinMainW) { + lpFuncName[nStrLen] = 'A'; + fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName); + if (!fnDllWinMainA) { + lpFuncName[nStrLen] = 0; + fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName); + } + } + + free(lpFuncName); + + RegisterBlankClass(hInstance); + // Create a window to pass the handle to the dll function + hWindow = CreateWindowEx(0,rundll32_wclass,rundll32_wtitle,0,CW_USEDEFAULT,0,CW_USEDEFAULT,0,0,0,hInstance,0); + + if (fnDllWinMainW) { + lpwCmdLine = ConvertToWideChar(lptCmdLine); + nRetVal = fnDllWinMainW(hWindow,hInstance,lpwCmdLine,nCmdShow); + FreeConvertedWideChar(lpwCmdLine); + } + else if (fnDllWinMainA) { + lpaCmdLine = ConvertToMultiByte(lptCmdLine); + nRetVal = fnDllWinMainA(hWindow,hInstance,lpaCmdLine,nCmdShow); + FreeConvertedMultiByte(lpaCmdLine); + } + else { + GetModuleTitle(); + lptMsgBuffer = (LPTSTR)malloc((_tcslen(MissingEntry) - 6 + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR)); + _stprintf(lptMsgBuffer,MissingEntry,lptFuncName,lptDllName); + MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONERROR); + free(lptMsgBuffer); + } + + DestroyWindow(hWindow); + UnregisterClass(rundll32_wclass,hInstance); + + FreeLibrary(hDll); + } + else { + GetModuleTitle(); + lptMsgBuffer = (LPTSTR)malloc((_tcslen(DllNotLoaded) - 3 + _tcslen(lptDllName) + 1) * sizeof(TCHAR)); + _stprintf(lptMsgBuffer,DllNotLoaded,lptDllName); + MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONERROR); + free(lptMsgBuffer); + } + + free(lptCmdLineCopy); + return nRetVal; +} + diff --git a/reactos/apps/utils/rundll32/rundll32.rc b/reactos/apps/utils/rundll32/rundll32.rc new file mode 100644 index 00000000000..00d5edf1acf --- /dev/null +++ b/reactos/apps/utils/rundll32/rundll32.rc @@ -0,0 +1,38 @@ +#include +#include + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "Run a DLL as an App\0" + VALUE "FileVersion", RES_STR_FILE_VERSION + VALUE "InternalName", "rundll32\0" + VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT + VALUE "OriginalFilename", "rundll32.exe\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + diff --git a/reactos/install-unix.sh b/reactos/install-unix.sh index b54fd02f0ff..a3c3bb26234 100755 --- a/reactos/install-unix.sh +++ b/reactos/install-unix.sh @@ -109,6 +109,7 @@ cp apps/utils/pice/module/pice.sys $ROS_INSTALL/system32/drivers cp apps/utils/pice/module/pice.sym $ROS_INSTALL/symbols cp apps/utils/pice/pice.cfg $ROS_INSTALL/symbols cp apps/utils/sc/sc.exe $ROS_INSTALL/bin +cp apps/utils/rundll32/rundll32.exe $ROS_INSTALL/bin cp apps/tests/hello/hello.exe $ROS_INSTALL/bin cp apps/tests/args/args.exe $ROS_INSTALL/bin cp apps/tests/apc/apc.exe $ROS_INSTALL/bin diff --git a/reactos/install.bat b/reactos/install.bat index d5e0a88cb5b..4b3264b21ca 100644 --- a/reactos/install.bat +++ b/reactos/install.bat @@ -158,6 +158,7 @@ copy apps\utils\partinfo\partinfo.exe %ROS_INSTALL%\bin copy apps\utils\objdir\objdir.exe %ROS_INSTALL%\bin copy apps\utils\pice\pice.cfg %ROS_INSTALL%\symbols copy apps\utils\sc\sc.exe %ROS_INSTALL%\bin +copy apps\utils\rundll32\rundll32.exe %ROS_INSTALL%\bin rem copy apps\utils\pice\module\pice.sys %ROS_INSTALL%\system32\drivers rem copy apps\utils\pice\module\pice.sym %ROS_INSTALL%\symbols