mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:33:10 +00:00
- Fixed line endings
- Updated regsvr32 to latest version by ShadowFlare. svn path=/trunk/; revision=8265
This commit is contained in:
parent
bb25722258
commit
e4340278d7
2 changed files with 947 additions and 954 deletions
|
@ -1,487 +1,480 @@
|
||||||
/*
|
/*
|
||||||
* ReactOS regsvr32
|
* ReactOS regsvr32
|
||||||
* Copyright (C) 2004 ReactOS Team
|
* Copyright (C) 2004 ReactOS Team
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS regsvr32.exe
|
* PROJECT: ReactOS regsvr32.exe
|
||||||
* FILE: apps/utils/regsvr32/regsvr32.c
|
* FILE: apps/utils/regsvr32/regsvr32.c
|
||||||
* PURPOSE: Register a COM component in the registry
|
* PURPOSE: Register a COM component in the registry
|
||||||
* PROGRAMMER: ShadowFlare (blakflare@hotmail.com)
|
* PROGRAMMER: ShadowFlare (blakflare@hotmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
// Both UNICODE and _UNICODE must be either defined or undefined
|
// Both UNICODE and _UNICODE must be either defined or undefined
|
||||||
// because some headers use UNICODE and others use _UNICODE
|
// because some headers use UNICODE and others use _UNICODE
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
#ifndef _UNICODE
|
#ifndef _UNICODE
|
||||||
#define _UNICODE
|
#define _UNICODE
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
#define UNICODE
|
#define UNICODE
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ole2.h>
|
#include <ole2.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
typedef HRESULT (WINAPI *DLLREGISTER)(void);
|
typedef HRESULT (WINAPI *DLLREGISTER)(void);
|
||||||
typedef HRESULT (WINAPI *DLLINSTALL)(BOOL bInstall, LPWSTR lpwCmdLine);
|
typedef HRESULT (WINAPI *DLLINSTALL)(BOOL bInstall, LPWSTR lpwCmdLine);
|
||||||
|
|
||||||
#define EXITCODE_SUCCESS 0
|
#define EXITCODE_SUCCESS 0
|
||||||
#define EXITCODE_PARAMERROR 1
|
#define EXITCODE_PARAMERROR 1
|
||||||
#define EXITCODE_LOADERROR 3
|
#define EXITCODE_LOADERROR 3
|
||||||
#define EXITCODE_NOENTRY 4
|
#define EXITCODE_NOENTRY 4
|
||||||
#define EXITCODE_FAILURE 5
|
#define EXITCODE_FAILURE 5
|
||||||
|
|
||||||
LPCSTR szDllRegister = "DllRegisterServer";
|
LPCSTR szDllRegister = "DllRegisterServer";
|
||||||
LPCSTR szDllUnregister = "DllUnregisterServer";
|
LPCSTR szDllUnregister = "DllUnregisterServer";
|
||||||
LPCSTR szDllInstall = "DllInstall";
|
LPCSTR szDllInstall = "DllInstall";
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
LPCWSTR tszDllRegister = L"DllRegisterServer";
|
LPCWSTR tszDllRegister = L"DllRegisterServer";
|
||||||
LPCWSTR tszDllUnregister = L"DllUnregisterServer";
|
LPCWSTR tszDllUnregister = L"DllUnregisterServer";
|
||||||
LPCWSTR tszDllInstall = L"DllInstall";
|
LPCWSTR tszDllInstall = L"DllInstall";
|
||||||
#else
|
#else
|
||||||
#define tszDllRegister szDllRegister
|
#define tszDllRegister szDllRegister
|
||||||
#define tszDllUnregister szDllUnregister
|
#define tszDllUnregister szDllUnregister
|
||||||
#define tszDllInstall szDllInstall
|
#define tszDllInstall szDllInstall
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LPCTSTR ModuleTitle = _T("RegSvr32");
|
LPCTSTR ModuleTitle = _T("RegSvr32");
|
||||||
LPCTSTR UsageMessage =
|
LPCTSTR UsageMessage =
|
||||||
_T("%s\n\n")
|
_T("%s\n\n")
|
||||||
_T("Usage: regsvr32 [/u] [/s] [/c] [/n] [/i[:cmdline]] dllname\n")
|
_T("Usage: regsvr32 [/u] [/s] [/c] [/n] [/i[:cmdline]] dllname\n")
|
||||||
_T("/u - Unregister server\n")
|
_T("/u - Unregister server\n")
|
||||||
_T("/s - Silent; display no message boxes\n")
|
_T("/s - Silent; display no message boxes\n")
|
||||||
_T("/c - Console output\n")
|
_T("/c - Console output\n")
|
||||||
_T("/i - Call DllInstall passing it an optional [cmdline]; when used with /u calls dll uninstall\n")
|
_T("/i - Call DllInstall passing it an optional [cmdline]; when used with /u calls dll uninstall\n")
|
||||||
_T("/n - Do not call DllRegisterServer; this option must be used with /i");
|
_T("/n - Do not call DllRegisterServer; this option must be used with /i");
|
||||||
LPCTSTR NoDllSpecified = _T("No DLL name specified.");
|
LPCTSTR NoDllSpecified = _T("No DLL name specified.");
|
||||||
LPCTSTR InvalidFlag = _T("Unrecognized flag: %s");
|
LPCTSTR InvalidFlag = _T("Unrecognized flag: %s");
|
||||||
LPCTSTR SwitchN_NoI = _T("Unrecognized flag: /n must be used with the /i switch");
|
LPCTSTR SwitchN_NoI = _T("Unrecognized flag: /n must be used with the /i switch");
|
||||||
LPCTSTR DllNotLoaded =
|
LPCTSTR DllNotLoaded =
|
||||||
_T("LoadLibrary(\"%s\") failed.\n")
|
_T("LoadLibrary(\"%s\") failed.\n")
|
||||||
_T("GetLastError returns 0x%08x.");
|
_T("GetLastError returns 0x%08x.");
|
||||||
LPCTSTR MissingEntry =
|
LPCTSTR MissingEntry =
|
||||||
_T("%s was loaded, but the %s entry point was not found.\n\n")
|
_T("%s was loaded, but the %s entry point was not found.\n\n")
|
||||||
_T("%s may not be exported, or a corrupt version of %s may be in memory. Consider using PView to detect and remove it.");
|
_T("%s may not be exported, or a corrupt version of %s may be in memory. Consider using PView to detect and remove it.");
|
||||||
LPCTSTR FailureMessage =
|
LPCTSTR FailureMessage =
|
||||||
_T("%s in %s failed.\n")
|
_T("%s in %s failed.\n")
|
||||||
_T("Return code was: 0x%08x");
|
_T("Return code was: 0x%08x");
|
||||||
LPCTSTR SuccessMessage = _T("%s in %s succeeded.");
|
LPCTSTR SuccessMessage = _T("%s in %s succeeded.");
|
||||||
|
|
||||||
// The macro CommandLineToArgv maps to a function that converts
|
// The macro CommandLineToArgv maps to a function that converts
|
||||||
// a command-line string to argc and argv similar to the ones
|
// a command-line string to argc and argv similar to the ones
|
||||||
// in the standard main function. If this code is compiled for
|
// in the standard main function. If this code is compiled for
|
||||||
// unicode, the build-in Windows API function is used, otherwise
|
// unicode, the build-in Windows API function is used, otherwise
|
||||||
// a non-unicode non-API version is used for compatibility with
|
// a non-unicode non-API version is used for compatibility with
|
||||||
// Windows versions that have no unicode support.
|
// Windows versions that have no unicode support.
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
#define CommandLineToArgv CommandLineToArgvW
|
#define CommandLineToArgv CommandLineToArgvW
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#else
|
#else
|
||||||
#define CommandLineToArgv CommandLineToArgvT
|
#define CommandLineToArgv CommandLineToArgvT
|
||||||
|
|
||||||
LPTSTR *WINAPI CommandLineToArgvT(LPCTSTR lpCmdLine, int *lpArgc)
|
LPTSTR *WINAPI CommandLineToArgvT(LPCTSTR lpCmdLine, int *lpArgc)
|
||||||
{
|
{
|
||||||
HGLOBAL hargv;
|
HGLOBAL hargv;
|
||||||
LPTSTR *argv, lpSrc, lpDest, lpArg;
|
LPTSTR *argv, lpSrc, lpDest, lpArg;
|
||||||
int argc, nBSlash;
|
int argc, nBSlash;
|
||||||
BOOL bInQuotes;
|
BOOL bInQuotes;
|
||||||
|
|
||||||
// If null was passed in for lpCmdLine, there are no arguments
|
// If null was passed in for lpCmdLine, there are no arguments
|
||||||
if (!lpCmdLine) {
|
if (!lpCmdLine) {
|
||||||
if (lpArgc)
|
if (lpArgc)
|
||||||
*lpArgc = 0;
|
*lpArgc = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpSrc = (LPTSTR)lpCmdLine;
|
lpSrc = (LPTSTR)lpCmdLine;
|
||||||
// Skip spaces at beginning
|
// Skip spaces at beginning
|
||||||
while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
|
while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
|
|
||||||
// If command-line starts with null, there are no arguments
|
// If command-line starts with null, there are no arguments
|
||||||
if (*lpSrc == 0) {
|
if (*lpSrc == 0) {
|
||||||
if (lpArgc)
|
if (lpArgc)
|
||||||
*lpArgc = 0;
|
*lpArgc = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpArg = lpSrc;
|
lpArg = lpSrc;
|
||||||
argc = 0;
|
argc = 0;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
bInQuotes = FALSE;
|
bInQuotes = FALSE;
|
||||||
|
|
||||||
// Count the number of arguments
|
// Count the number of arguments
|
||||||
while (1) {
|
while (1) {
|
||||||
if (*lpSrc == 0 || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
|
if (*lpSrc == 0 || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
|
||||||
// Whitespace not enclosed in quotes signals the start of another argument
|
// Whitespace not enclosed in quotes signals the start of another argument
|
||||||
argc++;
|
argc++;
|
||||||
|
|
||||||
// Skip whitespace between arguments
|
// Skip whitespace between arguments
|
||||||
while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
|
while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
if (*lpSrc == 0)
|
if (*lpSrc == 0)
|
||||||
break;
|
break;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (*lpSrc == _T('\\')) {
|
else if (*lpSrc == _T('\\')) {
|
||||||
// Count consecutive backslashes
|
// Count consecutive backslashes
|
||||||
nBSlash++;
|
nBSlash++;
|
||||||
}
|
}
|
||||||
else if (*lpSrc == _T('\"') && !(nBSlash & 1)) {
|
else if (*lpSrc == _T('\"') && !(nBSlash & 1)) {
|
||||||
// Open or close quotes
|
// Open or close quotes
|
||||||
bInQuotes = !bInQuotes;
|
bInQuotes = !bInQuotes;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Some other character
|
// Some other character
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
}
|
}
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate space the same way as CommandLineToArgvW for compatibility
|
// Allocate space the same way as CommandLineToArgvW for compatibility
|
||||||
hargv = GlobalAlloc(0, argc * sizeof(LPTSTR) + (_tcslen(lpArg) + 1) * sizeof(TCHAR));
|
hargv = GlobalAlloc(0, argc * sizeof(LPTSTR) + (_tcslen(lpArg) + 1) * sizeof(TCHAR));
|
||||||
argv = (LPTSTR *)GlobalLock(hargv);
|
argv = (LPTSTR *)GlobalLock(hargv);
|
||||||
|
|
||||||
if (!argv) {
|
if (!argv) {
|
||||||
// Memory allocation failed
|
// Memory allocation failed
|
||||||
if (lpArgc)
|
if (lpArgc)
|
||||||
*lpArgc = 0;
|
*lpArgc = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpSrc = lpArg;
|
lpSrc = lpArg;
|
||||||
lpDest = lpArg = (LPTSTR)(argv + argc);
|
lpDest = lpArg = (LPTSTR)(argv + argc);
|
||||||
argc = 0;
|
argc = 0;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
bInQuotes = FALSE;
|
bInQuotes = FALSE;
|
||||||
|
|
||||||
// Fill the argument array
|
// Fill the argument array
|
||||||
while (1) {
|
while (1) {
|
||||||
if (*lpSrc == 0 || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
|
if (*lpSrc == 0 || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
|
||||||
// Whitespace not enclosed in quotes signals the start of another argument
|
// Whitespace not enclosed in quotes signals the start of another argument
|
||||||
// Null-terminate argument
|
// Null-terminate argument
|
||||||
*lpDest++ = 0;
|
*lpDest++ = 0;
|
||||||
argv[argc++] = lpArg;
|
argv[argc++] = lpArg;
|
||||||
|
|
||||||
// Skip whitespace between arguments
|
// Skip whitespace between arguments
|
||||||
while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
|
while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
if (*lpSrc == 0)
|
if (*lpSrc == 0)
|
||||||
break;
|
break;
|
||||||
lpArg = lpDest;
|
lpArg = lpDest;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (*lpSrc == _T('\\')) {
|
else if (*lpSrc == _T('\\')) {
|
||||||
*lpDest++ = _T('\\');
|
*lpDest++ = _T('\\');
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
|
|
||||||
// Count consecutive backslashes
|
// Count consecutive backslashes
|
||||||
nBSlash++;
|
nBSlash++;
|
||||||
}
|
}
|
||||||
else if (*lpSrc == _T('\"')) {
|
else if (*lpSrc == _T('\"')) {
|
||||||
if (!(nBSlash & 1)) {
|
if (!(nBSlash & 1)) {
|
||||||
// If an even number of backslashes are before the quotes,
|
// If an even number of backslashes are before the quotes,
|
||||||
// the quotes don't go in the output
|
// the quotes don't go in the output
|
||||||
lpDest -= nBSlash / 2;
|
lpDest -= nBSlash / 2;
|
||||||
bInQuotes = !bInQuotes;
|
bInQuotes = !bInQuotes;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If an odd number of backslashes are before the quotes,
|
// If an odd number of backslashes are before the quotes,
|
||||||
// output a quote
|
// output a quote
|
||||||
lpDest -= (nBSlash + 1) / 2;
|
lpDest -= (nBSlash + 1) / 2;
|
||||||
*lpDest++ = _T('\"');
|
*lpDest++ = _T('\"');
|
||||||
}
|
}
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Copy other characters
|
// Copy other characters
|
||||||
*lpDest++ = *lpSrc++;
|
*lpDest++ = *lpSrc++;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpArgc)
|
if (lpArgc)
|
||||||
*lpArgc = argc;
|
*lpArgc = argc;
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The macro ConvertToWideChar takes a tstring parameter and returns
|
// The macro ConvertToWideChar takes a tstring parameter and returns
|
||||||
// a pointer to a unicode string. A conversion is performed if
|
// a pointer to a unicode string. A conversion is performed if
|
||||||
// neccessary. FreeConvertedWideChar string should be used on the
|
// neccessary. FreeConvertedWideChar string should be used on the
|
||||||
// return value of ConvertToWideChar when the string is no longer
|
// return value of ConvertToWideChar when the string is no longer
|
||||||
// needed. The original string or the string that is returned
|
// needed. The original string or the string that is returned
|
||||||
// should not be modified until FreeConvertedWideChar has been called.
|
// should not be modified until FreeConvertedWideChar has been called.
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
#define ConvertToWideChar(lptString) (lptString)
|
#define ConvertToWideChar(lptString) (lptString)
|
||||||
#define FreeConvertedWideChar(lpwString)
|
#define FreeConvertedWideChar(lpwString)
|
||||||
#else
|
#else
|
||||||
|
|
||||||
LPWSTR ConvertToWideChar(LPCSTR lpString)
|
LPWSTR ConvertToWideChar(LPCSTR lpString)
|
||||||
{
|
{
|
||||||
LPWSTR lpwString;
|
LPWSTR lpwString;
|
||||||
size_t nStrLen;
|
size_t nStrLen;
|
||||||
|
|
||||||
nStrLen = strlen(lpString) + 1;
|
nStrLen = strlen(lpString) + 1;
|
||||||
|
|
||||||
lpwString = (LPWSTR)malloc(nStrLen * sizeof(WCHAR));
|
lpwString = (LPWSTR)malloc(nStrLen * sizeof(WCHAR));
|
||||||
MultiByteToWideChar(0,0,lpString,nStrLen,lpwString,nStrLen);
|
MultiByteToWideChar(0,0,lpString,nStrLen,lpwString,nStrLen);
|
||||||
|
|
||||||
return lpwString;
|
return lpwString;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FreeConvertedWideChar(lpwString) free(lpwString)
|
#define FreeConvertedWideChar(lpwString) free(lpwString)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int WINAPI WinMain(
|
void DisplayMessage(BOOL bConsole, BOOL bSilent, LPCTSTR lpMessage, LPCTSTR lpTitle, UINT uType)
|
||||||
HINSTANCE hInstance,
|
{
|
||||||
HINSTANCE hPrevInstance,
|
if (!bSilent)
|
||||||
LPSTR lpCmdLineA,
|
MessageBox(0,lpMessage,lpTitle,uType);
|
||||||
int nCmdShow
|
if (bConsole)
|
||||||
)
|
_tprintf(_T("%s: %s\n\n"),lpTitle,lpMessage);
|
||||||
{
|
}
|
||||||
int argc;
|
|
||||||
LPTSTR *argv;
|
int WINAPI WinMain(
|
||||||
LPTSTR lptDllName,lptDllCmdLine,lptMsgBuffer;
|
HINSTANCE hInstance,
|
||||||
LPCTSTR lptFuncName;
|
HINSTANCE hPrevInstance,
|
||||||
LPCSTR lpFuncName;
|
LPSTR lpCmdLineA,
|
||||||
LPWSTR lpwDllCmdLine;
|
int nCmdShow
|
||||||
BOOL bUnregister,bSilent,bConsole,bInstall,bNoRegister;
|
)
|
||||||
UINT nDllCount;
|
{
|
||||||
HMODULE hDll;
|
int argc;
|
||||||
DLLREGISTER fnDllRegister;
|
LPTSTR *argv;
|
||||||
DLLINSTALL fnDllInstall;
|
LPTSTR lptDllName,lptDllCmdLine,lptMsgBuffer;
|
||||||
HRESULT hResult;
|
LPCTSTR lptFuncName;
|
||||||
DWORD dwErr;
|
LPCSTR lpFuncName;
|
||||||
int nRetValue,i;
|
LPWSTR lpwDllCmdLine;
|
||||||
|
BOOL bUnregister,bSilent,bConsole,bInstall,bNoRegister;
|
||||||
// Get command-line in argc-argv format
|
UINT nDllCount;
|
||||||
argv = CommandLineToArgv(GetCommandLine(),&argc);
|
HMODULE hDll;
|
||||||
|
DLLREGISTER fnDllRegister;
|
||||||
// Initialize variables
|
DLLINSTALL fnDllInstall;
|
||||||
lptFuncName = 0;
|
HRESULT hResult;
|
||||||
lptDllCmdLine = 0;
|
DWORD dwErr;
|
||||||
nDllCount = 0;
|
int nRetValue,i;
|
||||||
bUnregister = FALSE;
|
|
||||||
bSilent = FALSE;
|
// Get command-line in argc-argv format
|
||||||
bConsole = FALSE;
|
argv = CommandLineToArgv(GetCommandLine(),&argc);
|
||||||
bInstall = FALSE;
|
|
||||||
bNoRegister = FALSE;
|
// Initialize variables
|
||||||
|
lptFuncName = 0;
|
||||||
// Find all arguments starting with a slash (/)
|
lptDllCmdLine = 0;
|
||||||
for (i = 1; i < argc; i++) {
|
nDllCount = 0;
|
||||||
if (*argv[i] == _T('/')) {
|
bUnregister = FALSE;
|
||||||
switch (argv[i][1]) {
|
bSilent = FALSE;
|
||||||
case _T('u'):
|
bConsole = FALSE;
|
||||||
case _T('U'):
|
bInstall = FALSE;
|
||||||
bUnregister = TRUE;
|
bNoRegister = FALSE;
|
||||||
break;
|
|
||||||
case _T('s'):
|
// Find all arguments starting with a slash (/)
|
||||||
case _T('S'):
|
for (i = 1; i < argc; i++) {
|
||||||
bSilent = TRUE;
|
if (*argv[i] == _T('/')) {
|
||||||
break;
|
switch (argv[i][1]) {
|
||||||
case _T('c'):
|
case _T('u'):
|
||||||
case _T('C'):
|
case _T('U'):
|
||||||
bConsole = TRUE;
|
bUnregister = TRUE;
|
||||||
break;
|
break;
|
||||||
case _T('i'):
|
case _T('s'):
|
||||||
case _T('I'):
|
case _T('S'):
|
||||||
bInstall = TRUE;
|
bSilent = TRUE;
|
||||||
if (argv[i][2] == _T(':'))
|
break;
|
||||||
lptDllCmdLine = argv[i]+3;
|
case _T('c'):
|
||||||
else
|
case _T('C'):
|
||||||
lptDllCmdLine = _T("");
|
bConsole = TRUE;
|
||||||
break;
|
break;
|
||||||
case _T('n'):
|
case _T('i'):
|
||||||
case _T('N'):
|
case _T('I'):
|
||||||
bNoRegister = TRUE;
|
bInstall = TRUE;
|
||||||
break;
|
lptDllCmdLine = argv[i];
|
||||||
default:
|
while (*lptDllCmdLine != 0 && *lptDllCmdLine != _T(':'))
|
||||||
if (!lptFuncName)
|
lptDllCmdLine++;
|
||||||
lptFuncName = argv[i];
|
if (*lptDllCmdLine == _T(':'))
|
||||||
}
|
lptDllCmdLine++;
|
||||||
}
|
break;
|
||||||
else {
|
case _T('n'):
|
||||||
nDllCount++;
|
case _T('N'):
|
||||||
}
|
bNoRegister = TRUE;
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
// An unrecognized flag was used, display a message and show available options
|
if (!lptFuncName)
|
||||||
if (lptFuncName) {
|
lptFuncName = argv[i];
|
||||||
if (!bSilent) {
|
}
|
||||||
lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(InvalidFlag) - 2 + _tcslen(lptFuncName) + 1) * sizeof(TCHAR));
|
}
|
||||||
_stprintf(lptMsgBuffer + (_tcslen(UsageMessage) - 2),InvalidFlag,lptFuncName);
|
else {
|
||||||
_stprintf(lptMsgBuffer,UsageMessage,lptMsgBuffer + (_tcslen(UsageMessage) - 2));
|
nDllCount++;
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
}
|
||||||
free(lptMsgBuffer);
|
}
|
||||||
}
|
|
||||||
GlobalFree(argv);
|
// An unrecognized flag was used, display a message and show available options
|
||||||
return EXITCODE_PARAMERROR;
|
if (lptFuncName) {
|
||||||
}
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(InvalidFlag) - 2 + _tcslen(lptFuncName) + 1) * sizeof(TCHAR));
|
||||||
|
_stprintf(lptMsgBuffer + (_tcslen(UsageMessage) - 2),InvalidFlag,lptFuncName);
|
||||||
// /n was used without /i, display a message and show available options
|
_stprintf(lptMsgBuffer,UsageMessage,lptMsgBuffer + (_tcslen(UsageMessage) - 2));
|
||||||
if (bNoRegister && (!bInstall)) {
|
DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
||||||
if (!bSilent) {
|
free(lptMsgBuffer);
|
||||||
lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(SwitchN_NoI) + 1) * sizeof(TCHAR));
|
GlobalFree(argv);
|
||||||
_stprintf(lptMsgBuffer,UsageMessage,SwitchN_NoI);
|
return EXITCODE_PARAMERROR;
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
}
|
||||||
free(lptMsgBuffer);
|
|
||||||
}
|
// /n was used without /i, display a message and show available options
|
||||||
GlobalFree(argv);
|
if (bNoRegister && (!bInstall)) {
|
||||||
return EXITCODE_PARAMERROR;
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(SwitchN_NoI) + 1) * sizeof(TCHAR));
|
||||||
}
|
_stprintf(lptMsgBuffer,UsageMessage,SwitchN_NoI);
|
||||||
|
DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
||||||
// No dll was specified, display a message and show available options
|
free(lptMsgBuffer);
|
||||||
if (nDllCount == 0) {
|
GlobalFree(argv);
|
||||||
if (!bSilent) {
|
return EXITCODE_PARAMERROR;
|
||||||
lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(NoDllSpecified) + 1) * sizeof(TCHAR));
|
}
|
||||||
_stprintf(lptMsgBuffer,UsageMessage,NoDllSpecified);
|
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
// No dll was specified, display a message and show available options
|
||||||
free(lptMsgBuffer);
|
if (nDllCount == 0) {
|
||||||
}
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(NoDllSpecified) + 1) * sizeof(TCHAR));
|
||||||
GlobalFree(argv);
|
_stprintf(lptMsgBuffer,UsageMessage,NoDllSpecified);
|
||||||
return EXITCODE_PARAMERROR;
|
DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
||||||
}
|
free(lptMsgBuffer);
|
||||||
|
GlobalFree(argv);
|
||||||
nRetValue = EXITCODE_SUCCESS;
|
return EXITCODE_PARAMERROR;
|
||||||
if (!bUnregister) {
|
}
|
||||||
lpFuncName = szDllRegister;
|
|
||||||
lptFuncName = tszDllRegister;
|
nRetValue = EXITCODE_SUCCESS;
|
||||||
}
|
if (!bUnregister) {
|
||||||
else {
|
lpFuncName = szDllRegister;
|
||||||
lpFuncName = szDllUnregister;
|
lptFuncName = tszDllRegister;
|
||||||
lptFuncName = tszDllUnregister;
|
}
|
||||||
}
|
else {
|
||||||
|
lpFuncName = szDllUnregister;
|
||||||
if (lptDllCmdLine)
|
lptFuncName = tszDllUnregister;
|
||||||
lpwDllCmdLine = ConvertToWideChar(lptDllCmdLine);
|
}
|
||||||
else
|
|
||||||
lpwDllCmdLine = 0;
|
if (lptDllCmdLine)
|
||||||
|
lpwDllCmdLine = ConvertToWideChar(lptDllCmdLine);
|
||||||
// Initialize OLE32 before attempting to register the
|
else
|
||||||
// dll. Some dll's require this to register properly
|
lpwDllCmdLine = 0;
|
||||||
OleInitialize(0);
|
|
||||||
|
// Initialize OLE32 before attempting to register the
|
||||||
// (Un)register every dll whose filename was passed in the command-line string
|
// dll. Some dll's require this to register properly
|
||||||
for (i = 1; i < argc; i++) {
|
OleInitialize(0);
|
||||||
// Arguments that do not start with a slash (/) are filenames
|
|
||||||
if (*argv[i] != _T('/')) {
|
// (Un)register every dll whose filename was passed in the command-line string
|
||||||
lptDllName = argv[i];
|
for (i = 1; i < argc; i++) {
|
||||||
|
// Arguments that do not start with a slash (/) are filenames
|
||||||
// Everything is all setup, so load the dll now
|
if (*argv[i] != _T('/')) {
|
||||||
hDll = LoadLibrary(lptDllName);
|
lptDllName = argv[i];
|
||||||
if (hDll) {
|
|
||||||
if (!bNoRegister) {
|
// Everything is all setup, so load the dll now
|
||||||
// Get the address of DllRegisterServer or DllUnregisterServer
|
hDll = LoadLibraryEx(lptDllName,0,LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||||
fnDllRegister = (DLLREGISTER)GetProcAddress(hDll,lpFuncName);
|
if (hDll) {
|
||||||
if (fnDllRegister) {
|
if (!bNoRegister) {
|
||||||
// If the function exists, call it
|
// Get the address of DllRegisterServer or DllUnregisterServer
|
||||||
hResult = fnDllRegister();
|
fnDllRegister = (DLLREGISTER)GetProcAddress(hDll,lpFuncName);
|
||||||
if (!bSilent) {
|
if (fnDllRegister) {
|
||||||
if (hResult == S_OK) {
|
// If the function exists, call it
|
||||||
// (Un)register succeeded, display a message
|
hResult = fnDllRegister();
|
||||||
lptMsgBuffer = (LPTSTR)malloc((_tcslen(SuccessMessage) - 4 + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
if (hResult == S_OK) {
|
||||||
_stprintf(lptMsgBuffer,SuccessMessage,lptFuncName,lptDllName);
|
// (Un)register succeeded, display a message
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONINFORMATION);
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(SuccessMessage) - 4 + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
||||||
}
|
_stprintf(lptMsgBuffer,SuccessMessage,lptFuncName,lptDllName);
|
||||||
else {
|
DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONINFORMATION);
|
||||||
// (Un)register failed, display a message
|
}
|
||||||
lptMsgBuffer = (LPTSTR)malloc((_tcslen(FailureMessage) + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
else {
|
||||||
_stprintf(lptMsgBuffer,FailureMessage,lptFuncName,lptDllName,hResult);
|
// (Un)register failed, display a message
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(FailureMessage) + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
||||||
}
|
_stprintf(lptMsgBuffer,FailureMessage,lptFuncName,lptDllName,hResult);
|
||||||
free(lptMsgBuffer);
|
DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
||||||
}
|
}
|
||||||
if (hResult != S_OK)
|
free(lptMsgBuffer);
|
||||||
nRetValue = EXITCODE_FAILURE;
|
if (hResult != S_OK)
|
||||||
}
|
nRetValue = EXITCODE_FAILURE;
|
||||||
else {
|
}
|
||||||
FreeLibrary(hDll);
|
else {
|
||||||
if (!bSilent) {
|
FreeLibrary(hDll);
|
||||||
// Dll(Un)register was not found, display an error message
|
// 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));
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(MissingEntry) - 8 + _tcslen(lptFuncName) * 2 + _tcslen(lptDllName) * 2 + 1) * sizeof(TCHAR));
|
||||||
_stprintf(lptMsgBuffer,MissingEntry,lptDllName,lptFuncName,lptFuncName,lptDllName);
|
_stprintf(lptMsgBuffer,MissingEntry,lptDllName,lptFuncName,lptFuncName,lptDllName);
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
||||||
free(lptMsgBuffer);
|
free(lptMsgBuffer);
|
||||||
}
|
nRetValue = EXITCODE_NOENTRY;
|
||||||
nRetValue = EXITCODE_NOENTRY;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (bInstall) {
|
||||||
if (bInstall) {
|
// Get the address of DllInstall
|
||||||
// Get the address of DllInstall
|
fnDllInstall = (DLLINSTALL)GetProcAddress(hDll,szDllInstall);
|
||||||
fnDllInstall = (DLLINSTALL)GetProcAddress(hDll,szDllInstall);
|
if (fnDllInstall) {
|
||||||
if (fnDllInstall) {
|
// If the function exists, call it
|
||||||
// If the function exists, call it
|
if (!bUnregister)
|
||||||
if (!bUnregister)
|
hResult = fnDllInstall(1,lpwDllCmdLine);
|
||||||
hResult = fnDllInstall(1,lpwDllCmdLine);
|
else
|
||||||
else
|
hResult = fnDllInstall(0,lpwDllCmdLine);
|
||||||
hResult = fnDllInstall(0,lpwDllCmdLine);
|
if (hResult == S_OK) {
|
||||||
if (!bSilent) {
|
// (Un)install succeeded, display a message
|
||||||
if (hResult == S_OK) {
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(SuccessMessage) - 4 + _tcslen(tszDllInstall) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
||||||
// (Un)install succeeded, display a message
|
_stprintf(lptMsgBuffer,SuccessMessage,tszDllInstall,lptDllName);
|
||||||
lptMsgBuffer = (LPTSTR)malloc((_tcslen(SuccessMessage) - 4 + _tcslen(tszDllInstall) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONINFORMATION);
|
||||||
_stprintf(lptMsgBuffer,SuccessMessage,tszDllInstall,lptDllName);
|
}
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONINFORMATION);
|
else {
|
||||||
}
|
// (Un)install failed, display a message
|
||||||
else {
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(FailureMessage) + _tcslen(tszDllInstall) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
||||||
// (Un)install failed, display a message
|
_stprintf(lptMsgBuffer,FailureMessage,tszDllInstall,lptDllName,hResult);
|
||||||
lptMsgBuffer = (LPTSTR)malloc((_tcslen(FailureMessage) + _tcslen(tszDllInstall) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
||||||
_stprintf(lptMsgBuffer,FailureMessage,tszDllInstall,lptDllName,hResult);
|
}
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
free(lptMsgBuffer);
|
||||||
}
|
if (hResult != S_OK)
|
||||||
free(lptMsgBuffer);
|
nRetValue = EXITCODE_FAILURE;
|
||||||
}
|
}
|
||||||
if (hResult != S_OK)
|
else {
|
||||||
nRetValue = EXITCODE_FAILURE;
|
FreeLibrary(hDll);
|
||||||
}
|
// DllInstall was not found, display an error message
|
||||||
else {
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(MissingEntry) - 8 + _tcslen(tszDllInstall) * 2 + _tcslen(lptDllName) * 2 + 1) * sizeof(TCHAR));
|
||||||
FreeLibrary(hDll);
|
_stprintf(lptMsgBuffer,MissingEntry,lptDllName,tszDllInstall,tszDllInstall,lptDllName);
|
||||||
if (!bSilent) {
|
DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
||||||
// DllInstall was not found, display an error message
|
free(lptMsgBuffer);
|
||||||
lptMsgBuffer = (LPTSTR)malloc((_tcslen(MissingEntry) - 8 + _tcslen(tszDllInstall) * 2 + _tcslen(lptDllName) * 2 + 1) * sizeof(TCHAR));
|
nRetValue = EXITCODE_NOENTRY;
|
||||||
_stprintf(lptMsgBuffer,MissingEntry,lptDllName,tszDllInstall,tszDllInstall,lptDllName);
|
}
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
}
|
||||||
free(lptMsgBuffer);
|
|
||||||
}
|
// The dll function has finished executing, so unload it
|
||||||
nRetValue = EXITCODE_NOENTRY;
|
FreeLibrary(hDll);
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
// The dll could not be loaded; display an error message
|
||||||
// The dll function has finished executing, so unload it
|
dwErr = GetLastError();
|
||||||
FreeLibrary(hDll);
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(DllNotLoaded) + 2 + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
||||||
}
|
_stprintf(lptMsgBuffer,DllNotLoaded,lptDllName,dwErr);
|
||||||
else {
|
DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
||||||
if (!bSilent) {
|
free(lptMsgBuffer);
|
||||||
// The dll could not be loaded; display an error message
|
nRetValue = EXITCODE_LOADERROR;
|
||||||
dwErr = GetLastError();
|
}
|
||||||
lptMsgBuffer = (LPTSTR)malloc((_tcslen(DllNotLoaded) + 2 + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
}
|
||||||
_stprintf(lptMsgBuffer,DllNotLoaded,lptDllName,dwErr);
|
}
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
|
|
||||||
free(lptMsgBuffer);
|
if (lpwDllCmdLine)
|
||||||
}
|
FreeConvertedWideChar(lpwDllCmdLine);
|
||||||
nRetValue = EXITCODE_LOADERROR;
|
GlobalFree(argv);
|
||||||
}
|
OleUninitialize();
|
||||||
}
|
return nRetValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpwDllCmdLine)
|
|
||||||
FreeConvertedWideChar(lpwDllCmdLine);
|
|
||||||
GlobalFree(argv);
|
|
||||||
OleUninitialize();
|
|
||||||
return nRetValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,467 +1,467 @@
|
||||||
/*
|
/*
|
||||||
* ReactOS rundll32
|
* ReactOS rundll32
|
||||||
* Copyright (C) 2003-2004 ReactOS Team
|
* Copyright (C) 2003-2004 ReactOS Team
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS rundll32.exe
|
* PROJECT: ReactOS rundll32.exe
|
||||||
* FILE: apps/utils/rundll32/rundll32.c
|
* FILE: apps/utils/rundll32/rundll32.c
|
||||||
* PURPOSE: Run a DLL as a program
|
* PURPOSE: Run a DLL as a program
|
||||||
* PROGRAMMER: ShadowFlare (blakflare@hotmail.com)
|
* PROGRAMMER: ShadowFlare (blakflare@hotmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
// Both UNICODE and _UNICODE must be either defined or undefined
|
// Both UNICODE and _UNICODE must be either defined or undefined
|
||||||
// because some headers use UNICODE and others use _UNICODE
|
// because some headers use UNICODE and others use _UNICODE
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
#ifndef _UNICODE
|
#ifndef _UNICODE
|
||||||
#define _UNICODE
|
#define _UNICODE
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
#define UNICODE
|
#define UNICODE
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
typedef int (WINAPI *DllWinMainW)(
|
typedef int (WINAPI *DllWinMainW)(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
HINSTANCE hInstance,
|
HINSTANCE hInstance,
|
||||||
LPWSTR lpwCmdLine,
|
LPWSTR lpwCmdLine,
|
||||||
int nCmdShow
|
int nCmdShow
|
||||||
);
|
);
|
||||||
typedef int (WINAPI *DllWinMainA)(
|
typedef int (WINAPI *DllWinMainA)(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
HINSTANCE hInstance,
|
HINSTANCE hInstance,
|
||||||
LPSTR lpCmdLine,
|
LPSTR lpCmdLine,
|
||||||
int nCmdShow
|
int nCmdShow
|
||||||
);
|
);
|
||||||
|
|
||||||
LPCTSTR DllNotLoaded = _T("LoadLibrary failed to load \"%s\"");
|
LPCTSTR DllNotLoaded = _T("LoadLibrary failed to load \"%s\"");
|
||||||
LPCTSTR MissingEntry = _T("Missing entry point:%s\nIn %s");
|
LPCTSTR MissingEntry = _T("Missing entry point:%s\nIn %s");
|
||||||
LPCTSTR rundll32_wtitle = _T("rundll32");
|
LPCTSTR rundll32_wtitle = _T("rundll32");
|
||||||
LPCTSTR rundll32_wclass = _T("rundll32_window");
|
LPCTSTR rundll32_wclass = _T("rundll32_window");
|
||||||
TCHAR ModuleFileName[MAX_PATH+1];
|
TCHAR ModuleFileName[MAX_PATH+1];
|
||||||
LPTSTR ModuleTitle;
|
LPTSTR ModuleTitle;
|
||||||
|
|
||||||
// CommandLineToArgv converts a command-line string to argc and
|
// CommandLineToArgv converts a command-line string to argc and
|
||||||
// argv similar to the ones in the standard main function.
|
// argv similar to the ones in the standard main function.
|
||||||
// This is a specialized version coded specifically for rundll32
|
// This is a specialized version coded specifically for rundll32
|
||||||
// and is not intended to be used in any other program.
|
// and is not intended to be used in any other program.
|
||||||
LPTSTR *WINAPI CommandLineToArgv(LPCTSTR lpCmdLine, int *lpArgc)
|
LPTSTR *WINAPI CommandLineToArgv(LPCTSTR lpCmdLine, int *lpArgc)
|
||||||
{
|
{
|
||||||
LPTSTR *argv, lpSrc, lpDest, lpArg;
|
LPTSTR *argv, lpSrc, lpDest, lpArg;
|
||||||
int argc, nBSlash, nNames;
|
int argc, nBSlash, nNames;
|
||||||
BOOL bInQuotes, bFirstChar;
|
BOOL bInQuotes, bFirstChar;
|
||||||
|
|
||||||
// If null was passed in for lpCmdLine, there are no arguments
|
// If null was passed in for lpCmdLine, there are no arguments
|
||||||
if (!lpCmdLine) {
|
if (!lpCmdLine) {
|
||||||
if (lpArgc)
|
if (lpArgc)
|
||||||
*lpArgc = 0;
|
*lpArgc = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpSrc = (LPTSTR)lpCmdLine;
|
lpSrc = (LPTSTR)lpCmdLine;
|
||||||
// Skip spaces at beginning
|
// Skip spaces at beginning
|
||||||
while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
|
while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
|
|
||||||
// If command-line starts with null, there are no arguments
|
// If command-line starts with null, there are no arguments
|
||||||
if (*lpSrc == 0) {
|
if (*lpSrc == 0) {
|
||||||
if (lpArgc)
|
if (lpArgc)
|
||||||
*lpArgc = 0;
|
*lpArgc = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpArg = lpSrc;
|
lpArg = lpSrc;
|
||||||
argc = 0;
|
argc = 0;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
bInQuotes = FALSE;
|
bInQuotes = FALSE;
|
||||||
bFirstChar = TRUE;
|
bFirstChar = TRUE;
|
||||||
nNames = 0;
|
nNames = 0;
|
||||||
|
|
||||||
// Count the number of arguments
|
// Count the number of arguments
|
||||||
while (nNames < 4) {
|
while (nNames < 4) {
|
||||||
if (*lpSrc == 0 || (*lpSrc == _T(',') && nNames == 2) || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
|
if (*lpSrc == 0 || (*lpSrc == _T(',') && nNames == 2) || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
|
||||||
// Whitespace not enclosed in quotes signals the start of another argument
|
// Whitespace not enclosed in quotes signals the start of another argument
|
||||||
argc++;
|
argc++;
|
||||||
|
|
||||||
// Skip whitespace between arguments
|
// Skip whitespace between arguments
|
||||||
while (*lpSrc == _T(' ') || *lpSrc == _T('\t') || (*lpSrc == _T(',') && nNames == 2))
|
while (*lpSrc == _T(' ') || *lpSrc == _T('\t') || (*lpSrc == _T(',') && nNames == 2))
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
if (*lpSrc == 0)
|
if (*lpSrc == 0)
|
||||||
break;
|
break;
|
||||||
if (nNames >= 3) {
|
if (nNames >= 3) {
|
||||||
// Increment the count for the last argument
|
// Increment the count for the last argument
|
||||||
argc++;
|
argc++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
bFirstChar = TRUE;
|
bFirstChar = TRUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (*lpSrc == _T('\\')) {
|
else if (*lpSrc == _T('\\')) {
|
||||||
// Count consecutive backslashes
|
// Count consecutive backslashes
|
||||||
nBSlash++;
|
nBSlash++;
|
||||||
bFirstChar = FALSE;
|
bFirstChar = FALSE;
|
||||||
}
|
}
|
||||||
else if (*lpSrc == _T('\"') && !(nBSlash & 1)) {
|
else if (*lpSrc == _T('\"') && !(nBSlash & 1)) {
|
||||||
// Open or close quotes
|
// Open or close quotes
|
||||||
bInQuotes = !bInQuotes;
|
bInQuotes = !bInQuotes;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Some other character
|
// Some other character
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
if (bFirstChar && ((*lpSrc != _T('/') && nNames <= 1) || nNames > 1))
|
if (bFirstChar && ((*lpSrc != _T('/') && nNames <= 1) || nNames > 1))
|
||||||
nNames++;
|
nNames++;
|
||||||
bFirstChar = FALSE;
|
bFirstChar = FALSE;
|
||||||
}
|
}
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate space for the pointers in argv and the strings in one block
|
// Allocate space for the pointers in argv and the strings in one block
|
||||||
argv = (LPTSTR *)malloc(argc * sizeof(LPTSTR) + (_tcslen(lpArg) + 1) * sizeof(TCHAR));
|
argv = (LPTSTR *)malloc(argc * sizeof(LPTSTR) + (_tcslen(lpArg) + 1) * sizeof(TCHAR));
|
||||||
|
|
||||||
if (!argv) {
|
if (!argv) {
|
||||||
// Memory allocation failed
|
// Memory allocation failed
|
||||||
if (lpArgc)
|
if (lpArgc)
|
||||||
*lpArgc = 0;
|
*lpArgc = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpSrc = lpArg;
|
lpSrc = lpArg;
|
||||||
lpDest = lpArg = (LPTSTR)(argv + argc);
|
lpDest = lpArg = (LPTSTR)(argv + argc);
|
||||||
argc = 0;
|
argc = 0;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
bInQuotes = FALSE;
|
bInQuotes = FALSE;
|
||||||
bFirstChar = TRUE;
|
bFirstChar = TRUE;
|
||||||
nNames = 0;
|
nNames = 0;
|
||||||
|
|
||||||
// Fill the argument array
|
// Fill the argument array
|
||||||
while (nNames < 4) {
|
while (nNames < 4) {
|
||||||
if (*lpSrc == 0 || (*lpSrc == _T(',') && nNames == 2) || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
|
if (*lpSrc == 0 || (*lpSrc == _T(',') && nNames == 2) || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
|
||||||
// Whitespace not enclosed in quotes signals the start of another argument
|
// Whitespace not enclosed in quotes signals the start of another argument
|
||||||
// Null-terminate argument
|
// Null-terminate argument
|
||||||
*lpDest++ = 0;
|
*lpDest++ = 0;
|
||||||
argv[argc++] = lpArg;
|
argv[argc++] = lpArg;
|
||||||
|
|
||||||
// Skip whitespace between arguments
|
// Skip whitespace between arguments
|
||||||
while (*lpSrc == _T(' ') || *lpSrc == _T('\t') || (*lpSrc == _T(',') && nNames == 2))
|
while (*lpSrc == _T(' ') || *lpSrc == _T('\t') || (*lpSrc == _T(',') && nNames == 2))
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
if (*lpSrc == 0)
|
if (*lpSrc == 0)
|
||||||
break;
|
break;
|
||||||
lpArg = lpDest;
|
lpArg = lpDest;
|
||||||
if (nNames >= 3) {
|
if (nNames >= 3) {
|
||||||
// Copy the rest of the command-line to the last argument
|
// Copy the rest of the command-line to the last argument
|
||||||
argv[argc++] = lpArg;
|
argv[argc++] = lpArg;
|
||||||
_tcscpy(lpArg,lpSrc);
|
_tcscpy(lpArg,lpSrc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
bFirstChar = TRUE;
|
bFirstChar = TRUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (*lpSrc == _T('\\')) {
|
else if (*lpSrc == _T('\\')) {
|
||||||
*lpDest++ = _T('\\');
|
*lpDest++ = _T('\\');
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
|
|
||||||
// Count consecutive backslashes
|
// Count consecutive backslashes
|
||||||
nBSlash++;
|
nBSlash++;
|
||||||
bFirstChar = FALSE;
|
bFirstChar = FALSE;
|
||||||
}
|
}
|
||||||
else if (*lpSrc == _T('\"')) {
|
else if (*lpSrc == _T('\"')) {
|
||||||
if (!(nBSlash & 1)) {
|
if (!(nBSlash & 1)) {
|
||||||
// If an even number of backslashes are before the quotes,
|
// If an even number of backslashes are before the quotes,
|
||||||
// the quotes don't go in the output
|
// the quotes don't go in the output
|
||||||
lpDest -= nBSlash / 2;
|
lpDest -= nBSlash / 2;
|
||||||
bInQuotes = !bInQuotes;
|
bInQuotes = !bInQuotes;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If an odd number of backslashes are before the quotes,
|
// If an odd number of backslashes are before the quotes,
|
||||||
// output a quote
|
// output a quote
|
||||||
lpDest -= (nBSlash + 1) / 2;
|
lpDest -= (nBSlash + 1) / 2;
|
||||||
*lpDest++ = _T('\"');
|
*lpDest++ = _T('\"');
|
||||||
bFirstChar = FALSE;
|
bFirstChar = FALSE;
|
||||||
}
|
}
|
||||||
lpSrc++;
|
lpSrc++;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Copy other characters
|
// Copy other characters
|
||||||
if (bFirstChar && ((*lpSrc != _T('/') && nNames <= 1) || nNames > 1))
|
if (bFirstChar && ((*lpSrc != _T('/') && nNames <= 1) || nNames > 1))
|
||||||
nNames++;
|
nNames++;
|
||||||
*lpDest++ = *lpSrc++;
|
*lpDest++ = *lpSrc++;
|
||||||
nBSlash = 0;
|
nBSlash = 0;
|
||||||
bFirstChar = FALSE;
|
bFirstChar = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpArgc)
|
if (lpArgc)
|
||||||
*lpArgc = argc;
|
*lpArgc = argc;
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetModuleTitle(void)
|
void GetModuleTitle(void)
|
||||||
{
|
{
|
||||||
LPTSTR lpStr;
|
LPTSTR lpStr;
|
||||||
|
|
||||||
GetModuleFileName(0,ModuleFileName,MAX_PATH);
|
GetModuleFileName(0,ModuleFileName,MAX_PATH);
|
||||||
ModuleTitle = ModuleFileName;
|
ModuleTitle = ModuleFileName;
|
||||||
|
|
||||||
for (lpStr = ModuleFileName;*lpStr;lpStr++) {
|
for (lpStr = ModuleFileName;*lpStr;lpStr++) {
|
||||||
if (*lpStr == _T('\\'))
|
if (*lpStr == _T('\\'))
|
||||||
ModuleTitle = lpStr+1;
|
ModuleTitle = lpStr+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (lpStr = ModuleTitle;*lpStr;lpStr++) {
|
for (lpStr = ModuleTitle;*lpStr;lpStr++) {
|
||||||
if (_tcsicmp(lpStr,_T(".exe"))==0)
|
if (_tcsicmp(lpStr,_T(".exe"))==0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*lpStr = 0;
|
*lpStr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The macro ConvertToWideChar takes a tstring parameter and returns
|
// The macro ConvertToWideChar takes a tstring parameter and returns
|
||||||
// a pointer to a unicode string. A conversion is performed if
|
// a pointer to a unicode string. A conversion is performed if
|
||||||
// neccessary. FreeConvertedWideChar string should be used on the
|
// neccessary. FreeConvertedWideChar string should be used on the
|
||||||
// return value of ConvertToWideChar when the string is no longer
|
// return value of ConvertToWideChar when the string is no longer
|
||||||
// needed. The original string or the string that is returned
|
// needed. The original string or the string that is returned
|
||||||
// should not be modified until FreeConvertedWideChar has been called.
|
// should not be modified until FreeConvertedWideChar has been called.
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
#define ConvertToWideChar(lptString) (lptString)
|
#define ConvertToWideChar(lptString) (lptString)
|
||||||
#define FreeConvertedWideChar(lpwString)
|
#define FreeConvertedWideChar(lpwString)
|
||||||
#else
|
#else
|
||||||
|
|
||||||
LPWSTR ConvertToWideChar(LPCSTR lpString)
|
LPWSTR ConvertToWideChar(LPCSTR lpString)
|
||||||
{
|
{
|
||||||
LPWSTR lpwString;
|
LPWSTR lpwString;
|
||||||
size_t nStrLen;
|
size_t nStrLen;
|
||||||
|
|
||||||
nStrLen = strlen(lpString) + 1;
|
nStrLen = strlen(lpString) + 1;
|
||||||
|
|
||||||
lpwString = (LPWSTR)malloc(nStrLen * sizeof(WCHAR));
|
lpwString = (LPWSTR)malloc(nStrLen * sizeof(WCHAR));
|
||||||
MultiByteToWideChar(0,0,lpString,nStrLen,lpwString,nStrLen);
|
MultiByteToWideChar(0,0,lpString,nStrLen,lpwString,nStrLen);
|
||||||
|
|
||||||
return lpwString;
|
return lpwString;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FreeConvertedWideChar(lpwString) free(lpwString)
|
#define FreeConvertedWideChar(lpwString) free(lpwString)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The macro ConvertToMultiByte takes a tstring parameter and returns
|
// The macro ConvertToMultiByte takes a tstring parameter and returns
|
||||||
// a pointer to an ansi string. A conversion is performed if
|
// a pointer to an ansi string. A conversion is performed if
|
||||||
// neccessary. FreeConvertedMultiByte string should be used on the
|
// neccessary. FreeConvertedMultiByte string should be used on the
|
||||||
// return value of ConvertToMultiByte when the string is no longer
|
// return value of ConvertToMultiByte when the string is no longer
|
||||||
// needed. The original string or the string that is returned
|
// needed. The original string or the string that is returned
|
||||||
// should not be modified until FreeConvertedMultiByte has been called.
|
// should not be modified until FreeConvertedMultiByte has been called.
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
#define ConvertToMultiByte(lptString) DuplicateToMultiByte(lptString,0)
|
#define ConvertToMultiByte(lptString) DuplicateToMultiByte(lptString,0)
|
||||||
#define FreeConvertedMultiByte(lpaString) free(lpaString)
|
#define FreeConvertedMultiByte(lpaString) free(lpaString)
|
||||||
#else
|
#else
|
||||||
#define ConvertToMultiByte(lptString) (lptString)
|
#define ConvertToMultiByte(lptString) (lptString)
|
||||||
#define FreeConvertedMultiByte(lpaString)
|
#define FreeConvertedMultiByte(lpaString)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// DuplicateToMultiByte takes a tstring parameter and always returns
|
// DuplicateToMultiByte takes a tstring parameter and always returns
|
||||||
// a pointer to a duplicate ansi string. If nBufferSize is zero,
|
// a pointer to a duplicate ansi string. If nBufferSize is zero,
|
||||||
// the buffer length is the exact size of the string plus the
|
// the buffer length is the exact size of the string plus the
|
||||||
// terminating null. If nBufferSize is nonzero, the buffer length
|
// terminating null. If nBufferSize is nonzero, the buffer length
|
||||||
// is equal to nBufferSize. As with strdup, free should be called
|
// is equal to nBufferSize. As with strdup, free should be called
|
||||||
// for the returned string when it is no longer needed.
|
// for the returned string when it is no longer needed.
|
||||||
LPSTR DuplicateToMultiByte(LPCTSTR lptString, size_t nBufferSize)
|
LPSTR DuplicateToMultiByte(LPCTSTR lptString, size_t nBufferSize)
|
||||||
{
|
{
|
||||||
LPSTR lpString;
|
LPSTR lpString;
|
||||||
size_t nStrLen;
|
size_t nStrLen;
|
||||||
|
|
||||||
nStrLen = _tcslen(lptString) + 1;
|
nStrLen = _tcslen(lptString) + 1;
|
||||||
if (nBufferSize == 0) nBufferSize = nStrLen;
|
if (nBufferSize == 0) nBufferSize = nStrLen;
|
||||||
|
|
||||||
lpString = (LPSTR)malloc(nBufferSize);
|
lpString = (LPSTR)malloc(nBufferSize);
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
WideCharToMultiByte(0,0,lptString,nStrLen,lpString,nBufferSize,0,0);
|
WideCharToMultiByte(0,0,lptString,nStrLen,lpString,nBufferSize,0,0);
|
||||||
#else
|
#else
|
||||||
strncpy(lpString,lptString,nBufferSize);
|
strncpy(lpString,lptString,nBufferSize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return lpString;
|
return lpString;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK EmptyWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK EmptyWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registers a minimal window class for passing to the dll function
|
// Registers a minimal window class for passing to the dll function
|
||||||
ATOM RegisterBlankClass(HINSTANCE hInstance)
|
ATOM RegisterBlankClass(HINSTANCE hInstance)
|
||||||
{
|
{
|
||||||
WNDCLASSEX wcex;
|
WNDCLASSEX wcex;
|
||||||
|
|
||||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
|
||||||
wcex.style = 0;
|
wcex.style = 0;
|
||||||
wcex.lpfnWndProc = EmptyWindowProc;
|
wcex.lpfnWndProc = EmptyWindowProc;
|
||||||
wcex.cbClsExtra = 0;
|
wcex.cbClsExtra = 0;
|
||||||
wcex.cbWndExtra = 0;
|
wcex.cbWndExtra = 0;
|
||||||
wcex.hInstance = hInstance;
|
wcex.hInstance = hInstance;
|
||||||
wcex.hIcon = 0;
|
wcex.hIcon = 0;
|
||||||
wcex.hCursor = 0;
|
wcex.hCursor = 0;
|
||||||
wcex.hbrBackground = 0;
|
wcex.hbrBackground = 0;
|
||||||
wcex.lpszMenuName = 0;
|
wcex.lpszMenuName = 0;
|
||||||
wcex.lpszClassName = rundll32_wclass;
|
wcex.lpszClassName = rundll32_wclass;
|
||||||
wcex.hIconSm = 0;
|
wcex.hIconSm = 0;
|
||||||
|
|
||||||
return RegisterClassEx(&wcex);
|
return RegisterClassEx(&wcex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WINAPI WinMain(
|
int WINAPI WinMain(
|
||||||
HINSTANCE hInstance,
|
HINSTANCE hInstance,
|
||||||
HINSTANCE hPrevInstance,
|
HINSTANCE hPrevInstance,
|
||||||
LPSTR lpCmdLineA,
|
LPSTR lpCmdLineA,
|
||||||
int nCmdShow
|
int nCmdShow
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int argc;
|
int argc;
|
||||||
LPTSTR *argv;
|
LPTSTR *argv;
|
||||||
LPTSTR lptCmdLine,lptDllName,lptFuncName,lptMsgBuffer;
|
LPTSTR lptCmdLine,lptDllName,lptFuncName,lptMsgBuffer;
|
||||||
LPSTR lpFuncName,lpaCmdLine;
|
LPSTR lpFuncName,lpaCmdLine;
|
||||||
LPWSTR lpwCmdLine;
|
LPWSTR lpwCmdLine;
|
||||||
HMODULE hDll;
|
HMODULE hDll;
|
||||||
DllWinMainW fnDllWinMainW;
|
DllWinMainW fnDllWinMainW;
|
||||||
DllWinMainA fnDllWinMainA;
|
DllWinMainA fnDllWinMainA;
|
||||||
HWND hWindow;
|
HWND hWindow;
|
||||||
int nRetVal,i;
|
int nRetVal,i;
|
||||||
size_t nStrLen;
|
size_t nStrLen;
|
||||||
|
|
||||||
// Get command-line in argc-argv format
|
// Get command-line in argc-argv format
|
||||||
argv = CommandLineToArgv(GetCommandLine(),&argc);
|
argv = CommandLineToArgv(GetCommandLine(),&argc);
|
||||||
|
|
||||||
// Skip all beginning arguments starting with a slash (/)
|
// Skip all beginning arguments starting with a slash (/)
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
if (*argv[i] != _T('/')) break;
|
if (*argv[i] != _T('/')) break;
|
||||||
|
|
||||||
// If no dll was specified, there is nothing to do
|
// If no dll was specified, there is nothing to do
|
||||||
if (i >= argc) {
|
if (i >= argc) {
|
||||||
if (argv) free(argv);
|
if (argv) free(argv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lptDllName = argv[i++];
|
lptDllName = argv[i++];
|
||||||
|
|
||||||
// The next argument, which specifies the name of the dll function,
|
// 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.
|
// can either have a comma between it and the dll filename or a space.
|
||||||
// Using a comma here is the preferred method
|
// Using a comma here is the preferred method
|
||||||
if (i < argc)
|
if (i < argc)
|
||||||
lptFuncName = argv[i++];
|
lptFuncName = argv[i++];
|
||||||
else
|
else
|
||||||
lptFuncName = _T("");
|
lptFuncName = _T("");
|
||||||
|
|
||||||
// If no function name was specified, nothing needs to be done
|
// If no function name was specified, nothing needs to be done
|
||||||
if (!*lptFuncName) {
|
if (!*lptFuncName) {
|
||||||
if (argv) free(argv);
|
if (argv) free(argv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The rest of the arguments will be passed to dll function
|
// The rest of the arguments will be passed to dll function
|
||||||
if (i < argc)
|
if (i < argc)
|
||||||
lptCmdLine = argv[i];
|
lptCmdLine = argv[i];
|
||||||
else
|
else
|
||||||
lptCmdLine = _T("");
|
lptCmdLine = _T("");
|
||||||
|
|
||||||
nRetVal = 0;
|
nRetVal = 0;
|
||||||
|
|
||||||
// Everything is all setup, so load the dll now
|
// Everything is all setup, so load the dll now
|
||||||
hDll = LoadLibrary(lptDllName);
|
hDll = LoadLibrary(lptDllName);
|
||||||
if (hDll) {
|
if (hDll) {
|
||||||
nStrLen = _tcslen(lptFuncName);
|
nStrLen = _tcslen(lptFuncName);
|
||||||
// Make a non-unicode version of the function name,
|
// Make a non-unicode version of the function name,
|
||||||
// since that is all GetProcAddress accepts
|
// since that is all GetProcAddress accepts
|
||||||
lpFuncName = DuplicateToMultiByte(lptFuncName,nStrLen + 2);
|
lpFuncName = DuplicateToMultiByte(lptFuncName,nStrLen + 2);
|
||||||
|
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
lpFuncName[nStrLen] = 'W';
|
lpFuncName[nStrLen] = 'W';
|
||||||
lpFuncName[nStrLen+1] = 0;
|
lpFuncName[nStrLen+1] = 0;
|
||||||
// Get address of unicode version of the dll function if it exists
|
// Get address of unicode version of the dll function if it exists
|
||||||
fnDllWinMainW = (DllWinMainW)GetProcAddress(hDll,lpFuncName);
|
fnDllWinMainW = (DllWinMainW)GetProcAddress(hDll,lpFuncName);
|
||||||
fnDllWinMainA = 0;
|
fnDllWinMainA = 0;
|
||||||
if (!fnDllWinMainW) {
|
if (!fnDllWinMainW) {
|
||||||
// If no unicode function was found, get the address of the non-unicode function
|
// If no unicode function was found, get the address of the non-unicode function
|
||||||
lpFuncName[nStrLen] = 'A';
|
lpFuncName[nStrLen] = 'A';
|
||||||
fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName);
|
fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName);
|
||||||
if (!fnDllWinMainA) {
|
if (!fnDllWinMainA) {
|
||||||
// If first non-unicode function was not found, get the address
|
// If first non-unicode function was not found, get the address
|
||||||
// of the other non-unicode function
|
// of the other non-unicode function
|
||||||
lpFuncName[nStrLen] = 0;
|
lpFuncName[nStrLen] = 0;
|
||||||
fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName);
|
fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Get address of non-unicode version of the dll function if it exists
|
// Get address of non-unicode version of the dll function if it exists
|
||||||
fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName);
|
fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName);
|
||||||
fnDllWinMainW = 0;
|
fnDllWinMainW = 0;
|
||||||
if (!fnDllWinMainA) {
|
if (!fnDllWinMainA) {
|
||||||
// If first non-unicode function was not found, get the address
|
// If first non-unicode function was not found, get the address
|
||||||
// of the other non-unicode function
|
// of the other non-unicode function
|
||||||
lpFuncName[nStrLen] = 'A';
|
lpFuncName[nStrLen] = 'A';
|
||||||
lpFuncName[nStrLen+1] = 0;
|
lpFuncName[nStrLen+1] = 0;
|
||||||
fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName);
|
fnDllWinMainA = (DllWinMainA)GetProcAddress(hDll,lpFuncName);
|
||||||
if (!fnDllWinMainA) {
|
if (!fnDllWinMainA) {
|
||||||
// If non-unicode function was not found, get the address of the unicode function
|
// If non-unicode function was not found, get the address of the unicode function
|
||||||
lpFuncName[nStrLen] = 'W';
|
lpFuncName[nStrLen] = 'W';
|
||||||
fnDllWinMainW = (DllWinMainW)GetProcAddress(hDll,lpFuncName);
|
fnDllWinMainW = (DllWinMainW)GetProcAddress(hDll,lpFuncName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free(lpFuncName);
|
free(lpFuncName);
|
||||||
|
|
||||||
RegisterBlankClass(hInstance);
|
RegisterBlankClass(hInstance);
|
||||||
// Create a window so we can pass a window handle to
|
// Create a window so we can pass a window handle to
|
||||||
// the dll function; this is required
|
// the dll function; this is required
|
||||||
hWindow = CreateWindowEx(0,rundll32_wclass,rundll32_wtitle,0,CW_USEDEFAULT,0,CW_USEDEFAULT,0,0,0,hInstance,0);
|
hWindow = CreateWindowEx(0,rundll32_wclass,rundll32_wtitle,0,CW_USEDEFAULT,0,CW_USEDEFAULT,0,0,0,hInstance,0);
|
||||||
|
|
||||||
if (fnDllWinMainW) {
|
if (fnDllWinMainW) {
|
||||||
// Convert the command-line string to unicode and call the dll function
|
// Convert the command-line string to unicode and call the dll function
|
||||||
lpwCmdLine = ConvertToWideChar(lptCmdLine);
|
lpwCmdLine = ConvertToWideChar(lptCmdLine);
|
||||||
nRetVal = fnDllWinMainW(hWindow,hInstance,lpwCmdLine,nCmdShow);
|
nRetVal = fnDllWinMainW(hWindow,hInstance,lpwCmdLine,nCmdShow);
|
||||||
FreeConvertedWideChar(lpwCmdLine);
|
FreeConvertedWideChar(lpwCmdLine);
|
||||||
}
|
}
|
||||||
else if (fnDllWinMainA) {
|
else if (fnDllWinMainA) {
|
||||||
// Convert the command-line string to ansi and call the dll function
|
// Convert the command-line string to ansi and call the dll function
|
||||||
lpaCmdLine = ConvertToMultiByte(lptCmdLine);
|
lpaCmdLine = ConvertToMultiByte(lptCmdLine);
|
||||||
nRetVal = fnDllWinMainA(hWindow,hInstance,lpaCmdLine,nCmdShow);
|
nRetVal = fnDllWinMainA(hWindow,hInstance,lpaCmdLine,nCmdShow);
|
||||||
FreeConvertedMultiByte(lpaCmdLine);
|
FreeConvertedMultiByte(lpaCmdLine);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// The specified dll function was not found; display an error message
|
// The specified dll function was not found; display an error message
|
||||||
GetModuleTitle();
|
GetModuleTitle();
|
||||||
lptMsgBuffer = (LPTSTR)malloc((_tcslen(MissingEntry) - 4 + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(MissingEntry) - 4 + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
||||||
_stprintf(lptMsgBuffer,MissingEntry,lptFuncName,lptDllName);
|
_stprintf(lptMsgBuffer,MissingEntry,lptFuncName,lptDllName);
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONERROR);
|
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONERROR);
|
||||||
free(lptMsgBuffer);
|
free(lptMsgBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
DestroyWindow(hWindow);
|
DestroyWindow(hWindow);
|
||||||
UnregisterClass(rundll32_wclass,hInstance);
|
UnregisterClass(rundll32_wclass,hInstance);
|
||||||
|
|
||||||
// The dll function has finished executing, so unload it
|
// The dll function has finished executing, so unload it
|
||||||
FreeLibrary(hDll);
|
FreeLibrary(hDll);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// The dll could not be loaded; display an error message
|
// The dll could not be loaded; display an error message
|
||||||
GetModuleTitle();
|
GetModuleTitle();
|
||||||
lptMsgBuffer = (LPTSTR)malloc((_tcslen(DllNotLoaded) - 2 + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
lptMsgBuffer = (LPTSTR)malloc((_tcslen(DllNotLoaded) - 2 + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
|
||||||
_stprintf(lptMsgBuffer,DllNotLoaded,lptDllName);
|
_stprintf(lptMsgBuffer,DllNotLoaded,lptDllName);
|
||||||
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONERROR);
|
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONERROR);
|
||||||
free(lptMsgBuffer);
|
free(lptMsgBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv) free(argv);
|
if (argv) free(argv);
|
||||||
return nRetVal;
|
return nRetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue