ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

regsvr32.c
Go to the documentation of this file.
00001 /*
00002  * ReactOS regsvr32
00003  * Copyright (C) 2004-2006 ReactOS Team
00004  *
00005  * COPYRIGHT:       See COPYING in the top level directory
00006  * PROJECT:         ReactOS regsvr32.exe
00007  * FILE:            base/system/regsvr32/regsvr32.c
00008  * PURPOSE:         Register a COM component in the registry
00009  * PROGRAMMER:      ShadowFlare (blakflare@hotmail.com)
00010  */
00011 
00012 #define WIN32_LEAN_AND_MEAN
00013 
00014 // Both UNICODE and _UNICODE must be either defined or undefined
00015 // because some headers use UNICODE and others use _UNICODE
00016 #ifdef UNICODE
00017 #ifndef _UNICODE
00018 #define _UNICODE
00019 #endif
00020 #else
00021 #ifdef _UNICODE
00022 #define UNICODE
00023 #endif
00024 #endif
00025 
00026 #include <windows.h>
00027 #include <ole2.h>
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <malloc.h>
00031 #include <tchar.h>
00032 
00033 typedef HRESULT (WINAPI *DLLREGISTER)(void);
00034 typedef HRESULT (WINAPI *DLLINSTALL)(BOOL bInstall, LPWSTR lpwCmdLine);
00035 
00036 #define EXITCODE_SUCCESS 0
00037 #define EXITCODE_PARAMERROR 1
00038 #define EXITCODE_LOADERROR 3
00039 #define EXITCODE_NOENTRY 4
00040 #define EXITCODE_FAILURE 5
00041 
00042 LPCSTR szDllRegister = "DllRegisterServer";
00043 LPCSTR szDllUnregister = "DllUnregisterServer";
00044 LPCSTR szDllInstall = "DllInstall";
00045 #ifdef UNICODE
00046 LPCWSTR tszDllRegister = L"DllRegisterServer";
00047 LPCWSTR tszDllUnregister = L"DllUnregisterServer";
00048 LPCWSTR tszDllInstall = L"DllInstall";
00049 #else
00050 #define tszDllRegister szDllRegister
00051 #define tszDllUnregister szDllUnregister
00052 #define tszDllInstall szDllInstall
00053 #endif
00054 
00055 
00056 
00057 #include "resource.h"
00058 
00059 LPCTSTR ModuleTitle = _T("RegSvr32");
00060 
00061 TCHAR UsageMessage[RC_STRING_MAX_SIZE];
00062 TCHAR NoDllSpecified[RC_STRING_MAX_SIZE];
00063 TCHAR InvalidFlag[RC_STRING_MAX_SIZE];
00064 TCHAR SwitchN_NoI[RC_STRING_MAX_SIZE];
00065 TCHAR DllNotLoaded[RC_STRING_MAX_SIZE];
00066 TCHAR MissingEntry[RC_STRING_MAX_SIZE];
00067 TCHAR FailureMessage[RC_STRING_MAX_SIZE];
00068 TCHAR SuccessMessage[RC_STRING_MAX_SIZE];
00069 
00070 
00071 // The macro CommandLineToArgv maps to a function that converts
00072 // a command-line string to argc and argv similar to the ones
00073 // in the standard main function.  If this code is compiled for
00074 // unicode, the build-in Windows API function is used, otherwise
00075 // a non-unicode non-API version is used for compatibility with
00076 // Windows versions that have no unicode support.
00077 #ifdef UNICODE
00078 #define CommandLineToArgv CommandLineToArgvW
00079 #include <shellapi.h>
00080 #else
00081 #define CommandLineToArgv CommandLineToArgvT
00082 
00083 LPTSTR *WINAPI CommandLineToArgvT(LPCTSTR lpCmdLine, int *lpArgc)
00084 {
00085     HGLOBAL hargv;
00086     LPTSTR *argv, lpSrc, lpDest, lpArg;
00087     int argc, nBSlash;
00088     BOOL bInQuotes;
00089 
00090     // If null was passed in for lpCmdLine, there are no arguments
00091     if (!lpCmdLine) {
00092         if (lpArgc)
00093             *lpArgc = 0;
00094         return 0;
00095     }
00096 
00097     lpSrc = (LPTSTR)lpCmdLine;
00098     // Skip spaces at beginning
00099     while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
00100         lpSrc++;
00101 
00102     // If command-line starts with null, there are no arguments
00103     if (*lpSrc == 0) {
00104         if (lpArgc)
00105             *lpArgc = 0;
00106         return 0;
00107     }
00108 
00109     lpArg = lpSrc;
00110     argc = 0;
00111     nBSlash = 0;
00112     bInQuotes = FALSE;
00113 
00114     // Count the number of arguments
00115     while (1) {
00116         if (*lpSrc == 0 || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
00117             // Whitespace not enclosed in quotes signals the start of another argument
00118             argc++;
00119 
00120             // Skip whitespace between arguments
00121             while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
00122                 lpSrc++;
00123             if (*lpSrc == 0)
00124                 break;
00125             nBSlash = 0;
00126             continue;
00127         }
00128         else if (*lpSrc == _T('\\')) {
00129             // Count consecutive backslashes
00130             nBSlash++;
00131         }
00132         else if (*lpSrc == _T('\"') && !(nBSlash & 1)) {
00133             // Open or close quotes
00134             bInQuotes = !bInQuotes;
00135             nBSlash = 0;
00136         }
00137         else {
00138             // Some other character
00139             nBSlash = 0;
00140         }
00141         lpSrc++;
00142     }
00143 
00144     // Allocate space the same way as CommandLineToArgvW for compatibility
00145     hargv = GlobalAlloc(0, argc * sizeof(LPTSTR) + (_tcslen(lpArg) + 1) * sizeof(TCHAR));
00146     argv = (LPTSTR *)GlobalLock(hargv);
00147 
00148     if (!argv) {
00149         // Memory allocation failed
00150         if (lpArgc)
00151             *lpArgc = 0;
00152         return 0;
00153     }
00154 
00155     lpSrc = lpArg;
00156     lpDest = lpArg = (LPTSTR)(argv + argc);
00157     argc = 0;
00158     nBSlash = 0;
00159     bInQuotes = FALSE;
00160 
00161     // Fill the argument array
00162     while (1) {
00163         if (*lpSrc == 0 || ((*lpSrc == _T(' ') || *lpSrc == _T('\t')) && !bInQuotes)) {
00164             // Whitespace not enclosed in quotes signals the start of another argument
00165             // Null-terminate argument
00166             *lpDest++ = 0;
00167             argv[argc++] = lpArg;
00168 
00169             // Skip whitespace between arguments
00170             while (*lpSrc == _T(' ') || *lpSrc == _T('\t'))
00171                 lpSrc++;
00172             if (*lpSrc == 0)
00173                 break;
00174             lpArg = lpDest;
00175             nBSlash = 0;
00176             continue;
00177         }
00178         else if (*lpSrc == _T('\\')) {
00179             *lpDest++ = _T('\\');
00180             lpSrc++;
00181 
00182             // Count consecutive backslashes
00183             nBSlash++;
00184         }
00185         else if (*lpSrc == _T('\"')) {
00186             if (!(nBSlash & 1)) {
00187                 // If an even number of backslashes are before the quotes,
00188                 // the quotes don't go in the output
00189                 lpDest -= nBSlash / 2;
00190                 bInQuotes = !bInQuotes;
00191             }
00192             else {
00193                 // If an odd number of backslashes are before the quotes,
00194                 // output a quote
00195                 lpDest -= (nBSlash + 1) / 2;
00196                 *lpDest++ = _T('\"');
00197             }
00198             lpSrc++;
00199             nBSlash = 0;
00200         }
00201         else {
00202             // Copy other characters
00203             *lpDest++ = *lpSrc++;
00204             nBSlash = 0;
00205         }
00206     }
00207 
00208     if (lpArgc)
00209         *lpArgc = argc;
00210     return argv;
00211 }
00212 
00213 #endif
00214 
00215 // The macro ConvertToWideChar takes a tstring parameter and returns
00216 // a pointer to a unicode string.  A conversion is performed if
00217 // neccessary.  FreeConvertedWideChar string should be used on the
00218 // return value of ConvertToWideChar when the string is no longer
00219 // needed.  The original string or the string that is returned
00220 // should not be modified until FreeConvertedWideChar has been called.
00221 #ifdef UNICODE
00222 #define ConvertToWideChar(lptString) (lptString)
00223 #define FreeConvertedWideChar(lpwString) ((void) 0)
00224 #else
00225 
00226 LPWSTR ConvertToWideChar(LPCSTR lpString)
00227 {
00228     LPWSTR lpwString;
00229     size_t nStrLen;
00230 
00231     nStrLen = strlen(lpString) + 1;
00232 
00233     lpwString = (LPWSTR)malloc(nStrLen * sizeof(WCHAR));
00234     MultiByteToWideChar(0,0,lpString,nStrLen,lpwString,nStrLen);
00235 
00236     return lpwString;
00237 }
00238 
00239 #define FreeConvertedWideChar(lpwString) free(lpwString)
00240 #endif
00241 
00242 void DisplayMessage(BOOL bConsole, BOOL bSilent, LPCTSTR lpMessage, LPCTSTR lpTitle, UINT uType)
00243 {
00244     if (!bSilent)
00245         MessageBox(0,lpMessage,lpTitle,uType);
00246     if (bConsole)
00247         _tprintf(_T("%s: %s\n\n"),lpTitle,lpMessage);
00248 }
00249 
00250 int WINAPI _tWinMain(
00251   HINSTANCE hInstance,
00252   HINSTANCE hPrevInstance,
00253   LPTSTR lpCmdLine,
00254   int nCmdShow
00255 )
00256 {
00257     int argc;
00258     LPTSTR *argv;
00259     LPTSTR lptDllName,lptDllCmdLine,lptMsgBuffer;
00260     LPCTSTR lptFuncName;
00261     LPCSTR lpFuncName;
00262     LPWSTR lpwDllCmdLine;
00263     BOOL bUnregister,bSilent,bConsole,bInstall,bNoRegister;
00264     UINT nDllCount;
00265     HMODULE hDll;
00266     DLLREGISTER fnDllRegister;
00267     DLLINSTALL fnDllInstall;
00268     HRESULT hResult;
00269     DWORD dwErr;
00270     int nRetValue,i;
00271 
00272     // Get Langues msg
00273     LoadString( GetModuleHandle(NULL), IDS_UsageMessage, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
00274     LoadString( GetModuleHandle(NULL), IDS_NoDllSpecified, (LPTSTR) NoDllSpecified,RC_STRING_MAX_SIZE);
00275     LoadString( GetModuleHandle(NULL), IDS_InvalidFlag, (LPTSTR) InvalidFlag,RC_STRING_MAX_SIZE);
00276     LoadString( GetModuleHandle(NULL), IDS_SwitchN_NoI, (LPTSTR) SwitchN_NoI,RC_STRING_MAX_SIZE);
00277 
00278     LoadString( GetModuleHandle(NULL), IDS_DllNotLoaded, (LPTSTR)   DllNotLoaded,RC_STRING_MAX_SIZE);
00279     LoadString( GetModuleHandle(NULL), IDS_MissingEntry, (LPTSTR)   MissingEntry,RC_STRING_MAX_SIZE);
00280     LoadString( GetModuleHandle(NULL), IDS_FailureMessage, (LPTSTR) FailureMessage,RC_STRING_MAX_SIZE);
00281     LoadString( GetModuleHandle(NULL), IDS_SuccessMessage, (LPTSTR) SuccessMessage,RC_STRING_MAX_SIZE);
00282 
00283     // Get command-line in argc-argv format
00284     argv = CommandLineToArgv(GetCommandLine(),&argc);
00285 
00286     // Initialize variables
00287     lptFuncName = 0;
00288     lptDllCmdLine = 0;
00289     nDllCount = 0;
00290     bUnregister = FALSE;
00291     bSilent = FALSE;
00292     bConsole = FALSE;
00293     bInstall = FALSE;
00294     bNoRegister = FALSE;
00295 
00296     // Find all arguments starting with a slash (/)
00297     for (i = 1; i < argc; i++) {
00298         if (*argv[i] == _T('/')) {
00299             switch (argv[i][1]) {
00300             case _T('u'):
00301             case _T('U'):
00302                 bUnregister = TRUE;
00303                 break;
00304             case _T('s'):
00305             case _T('S'):
00306                 bSilent = TRUE;
00307                 break;
00308             case _T('c'):
00309             case _T('C'):
00310                 bConsole = TRUE;
00311                 break;
00312             case _T('i'):
00313             case _T('I'):
00314                 bInstall = TRUE;
00315                 lptDllCmdLine = argv[i];
00316                 while (*lptDllCmdLine != 0 && *lptDllCmdLine != _T(':'))
00317                     lptDllCmdLine++;
00318                 if (*lptDllCmdLine == _T(':'))
00319                     lptDllCmdLine++;
00320                 break;
00321             case _T('n'):
00322             case _T('N'):
00323                 bNoRegister = TRUE;
00324                 break;
00325             default:
00326                 if (!lptFuncName)
00327                     lptFuncName = argv[i];
00328             }
00329         }
00330         else {
00331             nDllCount++;
00332         }
00333     }
00334 
00335     // An unrecognized flag was used, display a message and show available options
00336 
00337     if (lptFuncName) {
00338         lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(InvalidFlag) - 2 + _tcslen(lptFuncName) + 1) * sizeof(TCHAR));
00339         _stprintf(lptMsgBuffer + (_tcslen(UsageMessage) - 2),InvalidFlag,lptFuncName);
00340         _stprintf(lptMsgBuffer,UsageMessage,lptMsgBuffer + (_tcslen(UsageMessage) - 2));
00341         DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
00342         free(lptMsgBuffer);
00343         GlobalFree(argv);
00344         return EXITCODE_PARAMERROR;
00345     }
00346 
00347     // /n was used without /i, display a message and show available options
00348     if (bNoRegister && (!bInstall)) {
00349         lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(SwitchN_NoI) + 1) * sizeof(TCHAR));
00350         _stprintf(lptMsgBuffer,UsageMessage,SwitchN_NoI);
00351         DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
00352         free(lptMsgBuffer);
00353         GlobalFree(argv);
00354         return EXITCODE_PARAMERROR;
00355     }
00356 
00357     // No dll was specified, display a message and show available options
00358     if (nDllCount == 0) {
00359         lptMsgBuffer = (LPTSTR)malloc((_tcslen(UsageMessage) - 2 + _tcslen(NoDllSpecified) + 1) * sizeof(TCHAR));
00360         _stprintf(lptMsgBuffer,UsageMessage,NoDllSpecified);
00361         DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
00362         free(lptMsgBuffer);
00363         GlobalFree(argv);
00364         return EXITCODE_PARAMERROR;
00365     }
00366 
00367     nRetValue = EXITCODE_SUCCESS;
00368     if (!bUnregister) {
00369         lpFuncName = szDllRegister;
00370         lptFuncName = tszDllRegister;
00371     }
00372     else {
00373         lpFuncName = szDllUnregister;
00374         lptFuncName = tszDllUnregister;
00375     }
00376 
00377     if (lptDllCmdLine)
00378         lpwDllCmdLine = ConvertToWideChar(lptDllCmdLine);
00379     else
00380         lpwDllCmdLine = 0;
00381 
00382     // Initialize OLE32 before attempting to register the
00383     // dll.  Some dll's require this to register properly
00384     OleInitialize(0);
00385 
00386     // (Un)register every dll whose filename was passed in the command-line string
00387     for (i = 1; i < argc && nRetValue == EXITCODE_SUCCESS; i++) {
00388         // Arguments that do not start with a slash (/) are filenames
00389         if (*argv[i] != _T('/')) {
00390             lptDllName = argv[i];
00391 
00392             // Everything is all setup, so load the dll now
00393             hDll = LoadLibraryEx(lptDllName,0,LOAD_WITH_ALTERED_SEARCH_PATH);
00394             if (hDll) {
00395                 if (!bNoRegister) {
00396                     // Get the address of DllRegisterServer or DllUnregisterServer
00397                     fnDllRegister = (DLLREGISTER)GetProcAddress(hDll,lpFuncName);
00398                     if (fnDllRegister) {
00399                         // If the function exists, call it
00400                         hResult = fnDllRegister();
00401                         if (hResult == S_OK) {
00402                             // (Un)register succeeded, display a message
00403                             lptMsgBuffer = (LPTSTR)malloc((_tcslen(SuccessMessage) - 4 + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
00404                             _stprintf(lptMsgBuffer,SuccessMessage,lptFuncName,lptDllName);
00405                             DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONINFORMATION);
00406                         }
00407                         else {
00408                             // (Un)register failed, display a message
00409                             lptMsgBuffer = (LPTSTR)malloc((_tcslen(FailureMessage) + _tcslen(lptFuncName) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
00410                             _stprintf(lptMsgBuffer,FailureMessage,lptFuncName,lptDllName,hResult);
00411                             DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
00412                         }
00413                         free(lptMsgBuffer);
00414                         if (hResult != S_OK)
00415                             nRetValue = EXITCODE_FAILURE;
00416                     }
00417                     else {
00418                         FreeLibrary(hDll);
00419                         // Dll(Un)register was not found, display an error message
00420                         lptMsgBuffer = (LPTSTR)malloc((_tcslen(MissingEntry) - 8 + _tcslen(lptFuncName) * 2 + _tcslen(lptDllName) * 2 + 1) * sizeof(TCHAR));
00421                         _stprintf(lptMsgBuffer,MissingEntry,lptDllName,lptFuncName,lptFuncName,lptDllName);
00422                         DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
00423                         free(lptMsgBuffer);
00424                         nRetValue = EXITCODE_NOENTRY;
00425                     }
00426                 }
00427 
00428                 if (bInstall && nRetValue == EXITCODE_SUCCESS) {
00429                     // Get the address of DllInstall
00430                     fnDllInstall = (DLLINSTALL)GetProcAddress(hDll,szDllInstall);
00431                     if (fnDllInstall) {
00432                         // If the function exists, call it
00433                         if (!bUnregister)
00434                             hResult = fnDllInstall(1,lpwDllCmdLine);
00435                         else
00436                             hResult = fnDllInstall(0,lpwDllCmdLine);
00437                         if (hResult == S_OK) {
00438                             // (Un)install succeeded, display a message
00439                             lptMsgBuffer = (LPTSTR)malloc((_tcslen(SuccessMessage) - 4 + _tcslen(tszDllInstall) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
00440                             _stprintf(lptMsgBuffer,SuccessMessage,tszDllInstall,lptDllName);
00441                             DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONINFORMATION);
00442                         }
00443                         else {
00444                             // (Un)install failed, display a message
00445                             lptMsgBuffer = (LPTSTR)malloc((_tcslen(FailureMessage) + _tcslen(tszDllInstall) + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
00446                             _stprintf(lptMsgBuffer,FailureMessage,tszDllInstall,lptDllName,hResult);
00447                             DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
00448                         }
00449                         free(lptMsgBuffer);
00450                         if (hResult != S_OK)
00451                             nRetValue = EXITCODE_FAILURE;
00452                     }
00453                     else {
00454                         FreeLibrary(hDll);
00455                         // DllInstall was not found, display an error message
00456                         lptMsgBuffer = (LPTSTR)malloc((_tcslen(MissingEntry) - 8 + _tcslen(tszDllInstall) * 2 + _tcslen(lptDllName) * 2 + 1) * sizeof(TCHAR));
00457                         _stprintf(lptMsgBuffer,MissingEntry,lptDllName,tszDllInstall,tszDllInstall,lptDllName);
00458                         DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
00459                         free(lptMsgBuffer);
00460                         nRetValue = EXITCODE_NOENTRY;
00461                     }
00462                 }
00463 
00464                 // The dll function has finished executing, so unload it
00465                 FreeLibrary(hDll);
00466             }
00467             else {
00468                 // The dll could not be loaded; display an error message
00469                 dwErr = GetLastError();
00470                 lptMsgBuffer = (LPTSTR)malloc((_tcslen(DllNotLoaded) + 2 + _tcslen(lptDllName) + 1) * sizeof(TCHAR));
00471                 _stprintf(lptMsgBuffer,DllNotLoaded,lptDllName,dwErr);
00472                 DisplayMessage(bConsole,bSilent,lptMsgBuffer,ModuleTitle,MB_ICONEXCLAMATION);
00473                 free(lptMsgBuffer);
00474                 nRetValue = EXITCODE_LOADERROR;
00475             }
00476         }
00477     }
00478 
00479     if (lpwDllCmdLine)
00480         FreeConvertedWideChar(lpwDllCmdLine);
00481     GlobalFree(argv);
00482     OleUninitialize();
00483     return nRetValue;
00484 }
00485 

Generated on Sun May 27 2012 04:18:48 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.