Author: ShadowFlare

Arty's note:
Added ShadowFlare's regsvr32.  The one in rosapps doesn't seem to build,
so I think it should be eventually removed.
I'm putting this one here instead of rosapps because it goes with some
of the other apps in this directory (like rundll32)

svn path=/trunk/; revision=8183
This commit is contained in:
Art Yerkes
2004-02-15 05:51:20 +00:00
parent 904bf32b2a
commit b1fc9ebb02
4 changed files with 552 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
*.o
*.d
*.exe
*.coff
*.sym
*.map
+21
View File
@@ -0,0 +1,21 @@
PATH_TO_TOP = ../../..
TARGET_TYPE = program
TARGET_APPTYPE = windows
TARGET_NAME = regsvr32
TARGET_INSTALLDIR = system32
TARGET_SDKLIBS = kernel32.a user32.a ole32.a
TARGET_OBJECTS = regsvr32.o
TARGET_CFLAGS += -DUNICODE -Wall -Werror -D__USE_W32API
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
# EOF
+487
View File
@@ -0,0 +1,487 @@
/*
* ReactOS regsvr32
* Copyright (C) 2004 ReactOS Team
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS regsvr32.exe
* FILE: apps/utils/regsvr32/regsvr32.c
* PURPOSE: Register a COM component in the registry
* PROGRAMMER: ShadowFlare ([email protected])
*/
#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 <windows.h>
#include <ole2.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <tchar.h>
typedef HRESULT (WINAPI *DLLREGISTER)(void);
typedef HRESULT (WINAPI *DLLINSTALL)(BOOL bInstall, LPWSTR lpwCmdLine);
#define EXITCODE_SUCCESS 0
#define EXITCODE_PARAMERROR 1
#define EXITCODE_LOADERROR 3
#define EXITCODE_NOENTRY 4
#define EXITCODE_FAILURE 5
LPCSTR szDllRegister = "DllRegisterServer";
LPCSTR szDllUnregister = "DllUnregisterServer";
LPCSTR szDllInstall = "DllInstall";
#ifdef UNICODE
LPCWSTR tszDllRegister = L"DllRegisterServer";
LPCWSTR tszDllUnregister = L"DllUnregisterServer";
LPCWSTR tszDllInstall = L"DllInstall";
#else
#define tszDllRegister szDllRegister
#define tszDllUnregister szDllUnregister
#define tszDllInstall szDllInstall
#endif
LPCTSTR ModuleTitle = _T("RegSvr32");
LPCTSTR UsageMessage =
_T("%s\n\n")
_T("Usage: regsvr32 [/u] [/s] [/c] [/n] [/i[:cmdline]] dllname\n")
_T("/u - Unregister server\n")
_T("/s - Silent; display no message boxes\n")
_T("/c - Console output\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");
LPCTSTR NoDllSpecified = _T("No DLL name specified.");
LPCTSTR InvalidFlag = _T("Unrecognized flag: %s");
LPCTSTR SwitchN_NoI = _T("Unrecognized flag: /n must be used with the /i switch");
LPCTSTR DllNotLoaded =
_T("LoadLibrary(\"%s\") failed.\n")
_T("GetLastError returns 0x%08x.");
LPCTSTR MissingEntry =
_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.");
LPCTSTR FailureMessage =
_T("%s in %s failed.\n")
_T("Return code was: 0x%08x");
LPCTSTR SuccessMessage = _T("%s in %s succeeded.");
// The macro CommandLineToArgv maps to a function that converts
// a command-line string to argc and argv similar to the ones
// in the standard main function. If this code is compiled for
// unicode, the build-in Windows API function is used, otherwise
// a non-unicode non-API version is used for compatibility with
// Windows versions that have no unicode support.
#ifdef UNICODE
#define CommandLineToArgv CommandLineToArgvW
#include <shellapi.h>
#else
#define CommandLineToArgv CommandLineToArgvT
LPTSTR *WINAPI CommandLineToArgvT(LPCTSTR lpCmdLine, int *lpArgc)
{
HGLOBAL hargv;
LPTSTR *argv, lpSrc, lpDest, lpArg;
int argc, nBSlash;
BOOL bInQuotes;
// If null was passed in for lpCmdLine, there are no arguments
if (!lpCmdLine) {
if (lpArgc)
*lpArgc = 0;
return 0;
}
lpSrc = (LPTSTR)lpCmdLine;
// Skip spaces at beginning
while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
lpSrc++;
// If command-line starts with null, there are no arguments
if (*lpSrc == 0) {
if (lpArgc)
*lpArgc = 0;
return 0;
}
lpArg = lpSrc;
argc = 0;
nBSlash = 0;
bInQuotes = FALSE;
// Count the number of arguments
while (1) {
if (*lpSrc == 0 || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
// Whitespace not enclosed in quotes signals the start of another argument
argc++;
// Skip whitespace between arguments
while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
lpSrc++;
if (*lpSrc == 0)
break;
nBSlash = 0;
continue;
}
else if (*lpSrc == _T('\\')) {
// Count consecutive backslashes
nBSlash++;
}
else if (*lpSrc == _T('\"') && !(nBSlash & 1)) {
// Open or close quotes
bInQuotes = !bInQuotes;
nBSlash = 0;
}
else {
// Some other character
nBSlash = 0;
}
lpSrc++;
}
// Allocate space the same way as CommandLineToArgvW for compatibility
hargv = GlobalAlloc(0, argc * sizeof(LPTSTR) + (_tcslen(lpArg) + 1) * sizeof(TCHAR));
argv = (LPTSTR *)GlobalLock(hargv);
if (!argv) {
// Memory allocation failed
if (lpArgc)
*lpArgc = 0;
return 0;
}
lpSrc = lpArg;
lpDest = lpArg = (LPTSTR)(argv + argc);
argc = 0;
nBSlash = 0;
bInQuotes = FALSE;
// Fill the argument array
while (1) {
if (*lpSrc == 0 || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
// Whitespace not enclosed in quotes signals the start of another argument
// Null-terminate argument
*lpDest++ = 0;
argv[argc++] = lpArg;
// Skip whitespace between arguments
while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
lpSrc++;
if (*lpSrc == 0)
break;
lpArg = lpDest;
nBSlash = 0;
continue;
}
else if (*lpSrc == _T('\\')) {
*lpDest++ = _T('\\');
lpSrc++;
// Count consecutive backslashes
nBSlash++;
}
else if (*lpSrc == _T('\"')) {
if (!(nBSlash & 1)) {
// If an even number of backslashes are before the quotes,
// the quotes don't go in the output
lpDest -= nBSlash / 2;
bInQuotes = !bInQuotes;
}
else {
// If an odd number of backslashes are before the quotes,
// output a quote
lpDest -= (nBSlash + 1) / 2;
*lpDest++ = _T('\"');
}
lpSrc++;
nBSlash = 0;
}
else {
// Copy other characters
*lpDest++ = *lpSrc++;
nBSlash = 0;
}
}
if (lpArgc)
*lpArgc = argc;
return argv;
}
#endif
// The macro ConvertToWideChar takes a tstring parameter and returns
// a pointer to a unicode string. A conversion is performed if
// neccessary. FreeConvertedWideChar string should be used on the
// return value of ConvertToWideChar when the string is no longer
// needed. The original string or the string that is returned
// should not be modified until FreeConvertedWideChar has been called.
#ifdef UNICODE
#define ConvertToWideChar(lptString) (lptString)
#define FreeConvertedWideChar(lpwString)
#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(lpwString) free(lpwString)
#endif
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLineA,
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 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;
if (argv[i][2] == _T(':'))
lptDllCmdLine = argv[i]+3;
else
lptDllCmdLine = _T("");
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) {
if (!bSilent) {
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));
MessageBox(0,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)) {
if (!bSilent) {
lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(SwitchN_NoI) + 1) * sizeof(TCHAR));
_stprintf(lptMsgBuffer,UsageMessage,SwitchN_NoI);
MessageBox(0,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) {
if (!bSilent) {
lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(NoDllSpecified) + 1) * sizeof(TCHAR));
_stprintf(lptMsgBuffer,UsageMessage,NoDllSpecified);
MessageBox(0,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; 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 = LoadLibrary(lptDllName);
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 (!bSilent) {
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);
MessageBox(0,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);
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
}
free(lptMsgBuffer);
}
if (hResult != S_OK)
nRetValue = EXITCODE_FAILURE;
}
else {
FreeLibrary(hDll);
if (!bSilent) {
// 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);
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
free(lptMsgBuffer);
}
nRetValue = EXITCODE_NOENTRY;
}
}
if (bInstall) {
// 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 (!bSilent) {
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);
MessageBox(0,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);
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
}
free(lptMsgBuffer);
}
if (hResult != S_OK)
nRetValue = EXITCODE_FAILURE;
}
else {
FreeLibrary(hDll);
if (!bSilent) {
// 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);
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
free(lptMsgBuffer);
}
nRetValue = EXITCODE_NOENTRY;
}
}
// The dll function has finished executing, so unload it
FreeLibrary(hDll);
}
else {
if (!bSilent) {
// 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);
MessageBox(0,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
free(lptMsgBuffer);
}
nRetValue = EXITCODE_LOADERROR;
}
}
}
if (lpwDllCmdLine)
FreeConvertedWideChar(lpwDllCmdLine);
GlobalFree(argv);
OleUninitialize();
return nRetValue;
}
+38
View File
@@ -0,0 +1,38 @@
#include <defines.h>
#include <reactos/resource.h>
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", "Register a COM component in the registry\0"
VALUE "FileVersion", RES_STR_FILE_VERSION
VALUE "InternalName", "regsvr32\0"
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
VALUE "OriginalFilename", "regsvr32.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