| /* | |
| * PURPOSE: Register OLE components in the registry | |
| * | |
| * Copyright 2001 ReactOS project | |
| * Copyright 2001 Jurgen Van Gael [jurgen.vangael@student.kuleuven.ac.be] | |
| * Copyright 2002 Andriy Palamarchuk | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| * | |
| * This version deliberately differs in error handling compared to the | |
| * windows version. | |
| */ | |
| /* | |
| * | |
| * regsvr32 [/u] [/s] [/n] [/i[:cmdline]] dllname ... | |
| * [/u] unregister server | |
| * [/s] silent (no message boxes) | |
| * [/i] Call DllInstall passing it an optional [cmdline]; | |
| * when used with /u calls dll uninstall. | |
| * [/n] Do not call DllRegisterServer; this option must be used with [/i] | |
| * | |
| * Note the complication that this version may be passed unix format file names | |
| * which might be mistaken for flags. Conveniently the Windows version | |
| * requires each flag to be separate (e.g. no /su ) and so we will simply | |
| * assume that anything longer than /. is a filename. | |
| */ | |
| /** | |
| * FIXME - currently receives command-line parameters in ASCII only and later | |
| * converts to Unicode. Ideally the function should have wWinMain entry point | |
| * and then work in Unicode only, but it seems Wine does not have necessary | |
| * support. | |
| */ | |
| #include "config.h" | |
| #include "wine/port.h" | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <windows.h> | |
| typedef HRESULT (*DLLREGISTER) (void); | |
| typedef HRESULT (*DLLUNREGISTER) (void); | |
| typedef HRESULT (*DLLINSTALL) (BOOL,LPCWSTR); | |
| int Silent = 0; | |
| int Usage() | |
| { | |
| printf("regsvr32 [/u] [/s] [/n] [/i[:cmdline]] dllname ...\n"); | |
| printf("\t[/u] unregister server\n"); | |
| printf("\t[/s] silent (no message boxes)\n"); | |
| printf("\t[/i] Call DllInstall passing it an optional [cmdline];\n"); | |
| printf("\t when used with /u calls dll uninstall\n"); | |
| printf("\t[/n] Do not call DllRegisterServer; this option " | |
| "must be used with [/i]\n"); | |
| return 0; | |
| } | |
| /** | |
| * Loads procedure. | |
| * | |
| * Parameters: | |
| * strDll - name of the dll. | |
| * procName - name of the procedure to load from dll | |
| * pDllHanlde - output variable receives handle of the loaded dll. | |
| */ | |
| VOID *LoadProc(char* strDll, char* procName, HMODULE* DllHandle) | |
| { | |
| VOID* (*proc)(void); | |
| *DllHandle = LoadLibraryEx(strDll, 0, LOAD_WITH_ALTERED_SEARCH_PATH); | |
| if(!*DllHandle) | |
| { | |
| if(!Silent) | |
| printf("Dll %s not found\n", strDll); | |
| exit(-1); | |
| } | |
| proc = (VOID *) GetProcAddress(*DllHandle, procName); | |
| if(!proc) | |
| { | |
| if(!Silent) | |
| printf("%s not implemented in dll %s\n", procName, strDll); | |
| FreeLibrary(*DllHandle); | |
| exit(-1); | |
| } | |
| return proc; | |
| } | |
| int RegisterDll(char* strDll) | |
| { | |
| HRESULT hr; | |
| DLLREGISTER pfRegister; | |
| HMODULE DllHandle = NULL; | |
| pfRegister = LoadProc(strDll, "DllRegisterServer", &DllHandle); | |
| hr = pfRegister(); | |
| if(FAILED(hr)) | |
| { | |
| if(!Silent) | |
| printf("Failed to register dll %s\n", strDll); | |
| return -1; | |
| } | |
| if(!Silent) | |
| printf("Successfully registered dll %s\n", strDll); | |
| if(DllHandle) | |
| FreeLibrary(DllHandle); | |
| return 0; | |
| } | |
| int UnregisterDll(char* strDll) | |
| { | |
| HRESULT hr; | |
| DLLUNREGISTER pfUnregister; | |
| HMODULE DllHandle = NULL; | |
| pfUnregister = LoadProc(strDll, "DllUnregisterServer", &DllHandle); | |
| hr = pfUnregister(); | |
| if(FAILED(hr)) | |
| { | |
| if(!Silent) | |
| printf("Failed to unregister dll %s\n", strDll); | |
| return -1; | |
| } | |
| if(!Silent) | |
| printf("Successfully unregistered dll %s\n", strDll); | |
| if(DllHandle) | |
| FreeLibrary(DllHandle); | |
| return 0; | |
| } | |
| int InstallDll(BOOL install, char *strDll, WCHAR *command_line) | |
| { | |
| HRESULT hr; | |
| DLLINSTALL pfInstall; | |
| HMODULE DllHandle = NULL; | |
| pfInstall = LoadProc(strDll, "DllInstall", &DllHandle); | |
| hr = pfInstall(install, command_line); | |
| if(FAILED(hr)) | |
| { | |
| if(!Silent) | |
| printf("Failed to %s dll %s\n", install ? "install" : "uninstall", | |
| strDll); | |
| return -1; | |
| } | |
| if(!Silent) | |
| printf("Successfully %s dll %s\n", install ? "installed" : "uninstalled", | |
| strDll); | |
| if(DllHandle) | |
| FreeLibrary(DllHandle); | |
| return 0; | |
| } | |
| int main(int argc, char* argv[]) | |
| { | |
| int i; | |
| BOOL CallRegister = TRUE; | |
| BOOL CallInstall = FALSE; | |
| BOOL Unregister = FALSE; | |
| BOOL DllFound = FALSE; | |
| WCHAR* wsCommandLine = NULL; | |
| WCHAR EmptyLine[1] = {0}; | |
| /* Strictly, the Microsoft version processes all the flags before | |
| * the files (e.g. regsvr32 file1 /s file2 is silent even for file1. | |
| * For ease, we will not replicate that and will process the arguments | |
| * in order. | |
| */ | |
| for(i = 1; i < argc; i++) | |
| { | |
| if (!strcasecmp(argv[i], "/u")) | |
| Unregister = TRUE; | |
| else if (!strcasecmp(argv[i], "/s")) | |
| Silent = 1; | |
| else if (!strncasecmp(argv[i], "/i", strlen("/i"))) | |
| { | |
| CHAR* command_line = argv[i] + strlen("/i"); | |
| CallInstall = TRUE; | |
| if (command_line[0] == ':' && command_line[1]) | |
| { | |
| int len = strlen(command_line); | |
| command_line++; | |
| len--; | |
| /* remove double quotes */ | |
| if (command_line[0] == '"') | |
| { | |
| command_line++; | |
| len--; | |
| if (command_line[0]) | |
| { | |
| len--; | |
| command_line[len] = 0; | |
| } | |
| } | |
| if (command_line[0]) | |
| { | |
| len = MultiByteToWideChar(CP_ACP, 0, command_line, -1, | |
| NULL, 0); | |
| wsCommandLine = HeapAlloc(GetProcessHeap(), 0, | |
| len * sizeof(WCHAR)); | |
| if (wsCommandLine) | |
| MultiByteToWideChar(CP_ACP, 0, command_line, -1, | |
| wsCommandLine, len); | |
| } | |
| else | |
| { | |
| wsCommandLine = EmptyLine; | |
| } | |
| } | |
| else | |
| { | |
| wsCommandLine = EmptyLine; | |
| } | |
| } | |
| else if(!strcasecmp(argv[i], "/n")) | |
| CallRegister = FALSE; | |
| else if (argv[i][0] == '/' && (!argv[i][2] || argv[i][2] == ':')) | |
| printf("Unrecognized switch %s\n", argv[i]); | |
| else | |
| { | |
| char *DllName = argv[i]; | |
| int res = 0; | |
| DllFound = TRUE; | |
| if (!CallInstall || (CallInstall && CallRegister)) | |
| { | |
| if(Unregister) | |
| res = UnregisterDll(DllName); | |
| else | |
| res = RegisterDll(DllName); | |
| } | |
| if (res) | |
| return res; | |
| /* Confirmed. The windows version does stop on the first error.*/ | |
| if (CallInstall) | |
| { | |
| res = InstallDll(!Unregister, DllName, wsCommandLine); | |
| } | |
| if (res) | |
| return res; | |
| } | |
| } | |
| if (!DllFound) | |
| { | |
| if(!Silent) | |
| return Usage(); | |
| else | |
| return -1; | |
| } | |
| return 0; | |
| } |