Index: media/doc/README.WINE
===================================================================
--- media/doc/README.WINE	(Revision 31600)
+++ media/doc/README.WINE	(Arbeitskopie)
@@ -103,7 +103,7 @@
 reactos/base/applications/games/winemine  # Out of sync
 reactos/base/applications/regedit         # Out of sync
 reactos/base/system/expand                # Out of sync
-reactos/base/system/msiexec               # Synced to Wine-0_9_3
+reactos/base/system/msiexec               # Synced to Wine-20070105
 
 In addition the following libs, dlls and source files are mostly based on code ported
 from Winehq CVS. If you are looking to update something in these files
Index: base/system/msiexec/service.c
===================================================================
--- base/system/msiexec/service.c	(Revision 0)
+++ base/system/msiexec/service.c	(Revision 0)
@@ -0,0 +1,174 @@
+/*
+ * msiexec.exe implementation
+ *
+ * Copyright 2007 Google (James Hawkins)
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+#include <stdio.h>
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msiexec);
+
+static SERVICE_STATUS_HANDLE hstatus;
+
+static HANDLE thread;
+static HANDLE kill_event;
+
+void KillService(void)
+{
+    WINE_TRACE("Killing service\n");
+    SetEvent(kill_event);
+}
+
+static BOOL UpdateSCMStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
+                            DWORD dwServiceSpecificExitCode)
+{
+    SERVICE_STATUS status;
+
+    status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+    status.dwCurrentState = dwCurrentState;
+
+    if (dwCurrentState == SERVICE_START_PENDING)
+        status.dwControlsAccepted = 0;
+    else
+    {
+        status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
+                                    SERVICE_ACCEPT_PAUSE_CONTINUE |
+                                    SERVICE_ACCEPT_SHUTDOWN;
+    }
+
+    if (dwServiceSpecificExitCode == 0)
+    {
+        status.dwWin32ExitCode = dwWin32ExitCode;
+    }
+    else
+    {
+        status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
+    }
+
+    status.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
+    status.dwCheckPoint = 0;
+    status.dwWaitHint = 0;
+
+    if (!SetServiceStatus(hstatus, &status))
+    {
+        fprintf(stderr, "Failed to set service status\n");
+        KillService();
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void WINAPI ServiceCtrlHandler(DWORD code)
+{
+    WINE_TRACE("%d\n", code);
+
+    switch (code)
+    {
+        case SERVICE_CONTROL_SHUTDOWN:
+        case SERVICE_CONTROL_STOP:
+            UpdateSCMStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
+            KillService();
+            return;
+        default:
+            fprintf(stderr, "Unhandled service control code: %d\n", code);
+            break;
+    }
+
+    UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0);
+}
+
+static DWORD WINAPI ServiceExecutionThread(LPVOID param)
+{
+    while (TRUE)
+    {
+        /* do nothing */
+    }
+
+    return 0;
+}
+
+static BOOL StartServiceThread(void)
+{
+    DWORD id;
+
+    thread = CreateThread(0, 0, ServiceExecutionThread, 0, 0, &id);
+    if (!thread)
+    {
+        fprintf(stderr, "Failed to create thread\n");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void WINAPI ServiceMain(DWORD argc, LPSTR *argv)
+{
+    hstatus = RegisterServiceCtrlHandlerA("MSIServer", ServiceCtrlHandler);
+    if (!hstatus)
+    {
+        fprintf(stderr, "Failed to register service ctrl handler\n");
+        return;
+    }
+
+    UpdateSCMStatus(SERVICE_START_PENDING, NO_ERROR, 0);
+
+    kill_event = CreateEvent(0, TRUE, FALSE, 0);
+    if (!kill_event)
+    {
+        fprintf(stderr, "Failed to create event\n");
+        KillService();
+        return;
+    }
+
+    if (!StartServiceThread())
+    {
+        KillService();
+        return;
+    }
+
+    UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0);
+
+    WaitForSingleObject(kill_event, INFINITE);
+    KillService();
+}
+
+DWORD DoService(void)
+{
+    char service_name[] = "MSIServer";
+
+    const SERVICE_TABLE_ENTRY service[] =
+    {
+        {service_name, ServiceMain},
+        {NULL, NULL},
+    };
+
+    WINE_TRACE("Starting MSIServer service\n");
+
+    if (!StartServiceCtrlDispatcher(service))
+    {
+        fprintf(stderr, "Failed to start MSIServer service\n");
+        return 1;
+    }
+
+    return 0;
+}
Index: base/system/msiexec/msiexec.ico
===================================================================
Kann nicht anzeigen: Dateityp ist als binär angegeben.
svn:mime-type = application/octet-stream

Eigenschaftsänderungen: base/system/msiexec/msiexec.ico
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: base/system/msiexec/version.rc
===================================================================
--- base/system/msiexec/version.rc	(Revision 31600)
+++ base/system/msiexec/version.rc	(Arbeitskopie)
@@ -13,7 +13,7 @@
  *
  * 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
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
 #define WINE_FILEDESCRIPTION_STR "Wine Installer"
Index: base/system/msiexec/rsrc.rc
===================================================================
--- base/system/msiexec/rsrc.rc	(Revision 0)
+++ base/system/msiexec/rsrc.rc	(Revision 0)
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2006 Mike McCormack
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <windows.h>
+
+#include "version.rc"
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+/* @makedep: msiexec.ico */
+1 ICON DISCARDABLE msiexec.ico
Index: base/system/msiexec/msiexec.rbuild
===================================================================
--- base/system/msiexec/msiexec.rbuild	(Revision 31600)
+++ base/system/msiexec/msiexec.rbuild	(Arbeitskopie)
@@ -15,5 +15,7 @@
 	<library>ole32</library>
 	<library>msi</library>
 	<file>msiexec.c</file>
+	<file>rsrc.rc</file>
+	<file>service.c</file>
 	<file>version.rc</file>
 </module>
Index: base/system/msiexec/msiexec.c
===================================================================
--- base/system/msiexec/msiexec.c	(Revision 31600)
+++ base/system/msiexec/msiexec.c	(Arbeitskopie)
@@ -16,9 +16,11 @@
  *
  * 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
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define WIN32_LEAN_AND_MEAN
+
 #include <windows.h>
 #include <msi.h>
 #include <objbase.h>
@@ -32,6 +34,8 @@
 typedef HRESULT (WINAPI *DLLREGISTERSERVER)(void);
 typedef HRESULT (WINAPI *DLLUNREGISTERSERVER)(void);
 
+DWORD DoService(void);
+
 struct string_list
 {
 	struct string_list *next;
@@ -205,7 +209,7 @@
 		ret += (*str - '0');
 		str++;
 	}
-	return 0;
+	return ret;
 }
 
 static LPWSTR msi_strdup(LPCWSTR str)
@@ -224,34 +228,54 @@
 
 	len = MultiByteToWideChar( CP_ACP, 0, str2, -1, NULL, 0);
 	if( !len )
-		return TRUE;
+		return FALSE;
 	if( lstrlenW(str1) != (len-1) )
-		return TRUE;
+		return FALSE;
 	strW = (WCHAR*) HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
 	MultiByteToWideChar( CP_ACP, 0, str2, -1, strW, len);
 	ret = CompareStringW(GetThreadLocale(), NORM_IGNORECASE, str1, len, strW, len);
 	HeapFree(GetProcessHeap(), 0, strW);
-	return (ret != CSTR_EQUAL);
+	return (ret == CSTR_EQUAL);
 }
 
+/* prefix is hyphen or dash, and str1 is the same as str2, ignoring case */
+static BOOL msi_option_equal(LPCWSTR str1, LPCSTR str2)
+{
+    if (str1[0] != '/' && str1[0] != '-')
+        return FALSE;
+
+    /* skip over the hyphen or slash */
+    return msi_strequal(str1 + 1, str2);
+}
+
 /* str2 is at the beginning of str1, ignoring case */
 static BOOL msi_strprefix(LPCWSTR str1, LPCSTR str2)
 {
-	int len, ret;
+	DWORD len, ret;
 	LPWSTR strW;
 
 	len = MultiByteToWideChar( CP_ACP, 0, str2, -1, NULL, 0);
 	if( !len )
-		return TRUE;
+		return FALSE;
 	if( lstrlenW(str1) < (len-1) )
-		return TRUE;
+		return FALSE;
 	strW = (WCHAR*) HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
 	MultiByteToWideChar( CP_ACP, 0, str2, -1, strW, len);
 	ret = CompareStringW(GetThreadLocale(), NORM_IGNORECASE, str1, len-1, strW, len-1);
 	HeapFree(GetProcessHeap(), 0, strW);
-	return (ret != CSTR_EQUAL);
+	return (ret == CSTR_EQUAL);
 }
 
+/* prefix is hyphen or dash, and str2 is at the beginning of str1, ignoring case */
+static BOOL msi_option_prefix(LPCWSTR str1, LPCSTR str2)
+{
+    if (str1[0] != '/' && str1[0] != '-')
+        return FALSE;
+
+    /* skip over the hyphen or slash */
+    return msi_strprefix(str1 + 1, str2);
+}
+
 static VOID *LoadProc(LPCWSTR DllName, LPCSTR ProcName, HMODULE* DllHandle)
 {
 	VOID* (*proc)(void);
@@ -314,6 +338,43 @@
 	return 0;
 }
 
+static DWORD DoRegServer(void)
+{
+    SC_HANDLE scm, service;
+    CHAR path[MAX_PATH+12];
+    DWORD ret = 0;
+
+    scm = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE);
+    if (!scm)
+    {
+        fprintf(stderr, "Failed to open the service control manager.\n");
+        return 1;
+    }
+
+    GetSystemDirectory(path, MAX_PATH);
+    lstrcatA(path, "\\msiexec.exe /V");
+
+    service = CreateServiceA(scm, "MSIServer", "MSIServer", GENERIC_ALL,
+                             SERVICE_WIN32_SHARE_PROCESS, SERVICE_DEMAND_START,
+                             SERVICE_ERROR_NORMAL, path, NULL, NULL,
+                             NULL, NULL, NULL);
+
+    if (service) CloseServiceHandle(service);
+    else if (GetLastError() != ERROR_SERVICE_EXISTS)
+    {
+        fprintf(stderr, "Failed to create MSI service\n");
+        ret = 1;
+    }
+    CloseServiceHandle(scm);
+    return ret;
+}
+
+static INT DoEmbedding( LPWSTR key )
+{
+	printf("Remote custom actions are not supported yet\n");
+	return 1;
+}
+
 /*
  * state machine to break up the command line properly
  */
@@ -426,6 +487,7 @@
 			process_args(buf, pargc, pargv);
 			ret = TRUE;
 		}
+		HeapFree(GetProcessHeap(), 0, buf);
 	}
 	RegCloseKey(hkeyArgs);
 	return ret;
@@ -443,6 +505,7 @@
 	BOOL FunctionDllUnregisterServer = FALSE;
 	BOOL FunctionRegServer = FALSE;
 	BOOL FunctionUnregServer = FALSE;
+	BOOL FunctionServer = FALSE;
 	BOOL FunctionUnknown = FALSE;
 
 	LPWSTR PackageName = NULL;
@@ -451,7 +514,7 @@
 
 	DWORD RepairMode = 0;
 
-	DWORD AdvertiseMode = 0;
+	DWORD_PTR AdvertiseMode = 0;
 	struct string_list *transform_list = NULL;
 	LANGID Language = 0;
 
@@ -477,25 +540,28 @@
 	 *  We do that before starting to process the real commandline,
 	 * then overwrite the commandline again.
 	 */
-	if(!msi_strequal(argvW[1], "/@"))
+	if(argc>1 && msi_option_equal(argvW[1], "@"))
 	{
 		if(!process_args_from_reg( argvW[2], &argc, &argvW ))
 			return 1;
 	}
 
+	if (argc == 3 && msi_option_equal(argvW[1], "Embedding"))
+		return DoEmbedding( argvW[2] );
+
 	for(i = 1; i < argc; i++)
 	{
 		WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
 
-		if (!msi_strequal(argvW[i], "/regserver"))
+		if (msi_option_equal(argvW[i], "regserver"))
 		{
 			FunctionRegServer = TRUE;
 		}
-		else if (!msi_strequal(argvW[i], "/unregserver") || !msi_strequal(argvW[i], "/unregister"))
+		else if (msi_option_equal(argvW[i], "unregserver") || msi_option_equal(argvW[i], "unregister"))
 		{
 			FunctionUnregServer = TRUE;
 		}
-		else if(!msi_strprefix(argvW[i], "/i"))
+		else if(msi_option_prefix(argvW[i], "i"))
 		{
 			LPWSTR argvWi = argvW[i];
 			FunctionInstall = TRUE;
@@ -511,7 +577,7 @@
 			}
 			PackageName = argvWi;
 		}
-		else if(!msi_strequal(argvW[i], "/a"))
+		else if(msi_option_equal(argvW[i], "a"))
 		{
 			FunctionInstall = TRUE;
 			FunctionInstallAdmin = TRUE;
@@ -523,7 +589,7 @@
 			PackageName = argvW[i];
 			StringListAppend(&property_list, ActionAdmin);
 		}
-		else if(!msi_strprefix(argvW[i], "/f"))
+		else if(msi_option_prefix(argvW[i], "f"))
 		{
 			int j;
 			int len = lstrlenW(argvW[i]);
@@ -591,17 +657,21 @@
 			WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
 			PackageName = argvW[i];
 		}
-		else if(!msi_strequal(argvW[i], "/x"))
+		else if(msi_option_prefix(argvW[i], "x"))
 		{
 			FunctionInstall = TRUE;
+			PackageName = argvW[i]+2;
+			if (!PackageName[0])
+			{
 			i++;
 			if(i >= argc)
 				ShowUsage(1);
-			WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
 			PackageName = argvW[i];
+			}
+			WINE_TRACE("PackageName = %s\n", wine_dbgstr_w(PackageName));
 			StringListAppend(&property_list, RemoveAll);
 		}
-		else if(!msi_strprefix(argvW[i], "/j"))
+		else if(msi_option_prefix(argvW[i], "j"))
 		{
 			int j;
 			int len = lstrlenW(argvW[i]);
@@ -629,7 +699,7 @@
 			WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
 			PackageName = argvW[i];
 		}
-		else if(!msi_strequal(argvW[i], "u"))
+		else if(msi_strequal(argvW[i], "u"))
 		{
 			FunctionAdvertise = TRUE;
 			AdvertiseMode = ADVERTISEFLAGS_USERASSIGN;
@@ -639,7 +709,7 @@
 			WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
 			PackageName = argvW[i];
 		}
-		else if(!msi_strequal(argvW[i], "m"))
+		else if(msi_strequal(argvW[i], "m"))
 		{
 			FunctionAdvertise = TRUE;
 			AdvertiseMode = ADVERTISEFLAGS_MACHINEASSIGN;
@@ -649,7 +719,7 @@
 			WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
 			PackageName = argvW[i];
 		}
-		else if(!msi_strequal(argvW[i], "/t"))
+		else if(msi_option_equal(argvW[i], "t"))
 		{
 			i++;
 			if(i >= argc)
@@ -657,7 +727,7 @@
 			WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
 			StringListAppend(&transform_list, argvW[i]);
 		}
-		else if(!msi_strequal(argvW[i], "/g"))
+		else if(msi_option_equal(argvW[i], "g"))
 		{
 			i++;
 			if(i >= argc)
@@ -665,7 +735,7 @@
 			WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
 			Language = msi_atou(argvW[i]);
 		}
-		else if(!msi_strprefix(argvW[i], "/l"))
+		else if(msi_option_prefix(argvW[i], "l"))
 		{
 			int j;
 			int len = lstrlenW(argvW[i]);
@@ -756,7 +826,7 @@
 				ExitProcess(1);
 			}
 		}
-		else if(!msi_strequal(argvW[i], "/p"))
+		else if(msi_option_equal(argvW[i], "p"))
 		{
 			FunctionPatch = TRUE;
 			i++;
@@ -765,37 +835,38 @@
 			WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
 			PatchFileName = argvW[i];
 		}
-		else if(!msi_strprefix(argvW[i], "/q"))
+		else if(msi_option_prefix(argvW[i], "q"))
 		{
-			if(lstrlenW(argvW[i]) == 2 || !msi_strequal(argvW[i]+2, "n"))
+			if(lstrlenW(argvW[i]) == 2 || msi_strequal(argvW[i]+2, "n") ||
+			   msi_strequal(argvW[i] + 2, "uiet"))
 			{
 				InstallUILevel = INSTALLUILEVEL_NONE;
 			}
-			else if(!msi_strequal(argvW[i]+2, "b"))
+			else if(msi_strequal(argvW[i]+2, "b"))
 			{
 				InstallUILevel = INSTALLUILEVEL_BASIC;
 			}
-			else if(!msi_strequal(argvW[i]+2, "r"))
+			else if(msi_strequal(argvW[i]+2, "r"))
 			{
 				InstallUILevel = INSTALLUILEVEL_REDUCED;
 			}
-			else if(!msi_strequal(argvW[i]+2, "f"))
+			else if(msi_strequal(argvW[i]+2, "f"))
 			{
 				InstallUILevel = (INSTALLUILEVEL) (INSTALLUILEVEL_FULL|INSTALLUILEVEL_ENDDIALOG);
 			}
-			else if(!msi_strequal(argvW[i]+2, "n+"))
+			else if(msi_strequal(argvW[i]+2, "n+"))
 			{
 				InstallUILevel = (INSTALLUILEVEL) (INSTALLUILEVEL_NONE|INSTALLUILEVEL_ENDDIALOG);
 			}
-			else if(!msi_strequal(argvW[i]+2, "b+"))
+			else if(msi_strequal(argvW[i]+2, "b+"))
 			{
 				InstallUILevel = (INSTALLUILEVEL) (INSTALLUILEVEL_BASIC|INSTALLUILEVEL_ENDDIALOG);
 			}
-			else if(!msi_strequal(argvW[i]+2, "b-"))
+			else if(msi_strequal(argvW[i]+2, "b-"))
 			{
 				InstallUILevel = (INSTALLUILEVEL) (INSTALLUILEVEL_BASIC|INSTALLUILEVEL_PROGRESSONLY);
 			}
-			else if(!msi_strequal(argvW[i]+2, "b+!"))
+			else if(msi_strequal(argvW[i]+2, "b+!"))
 			{
 				InstallUILevel = (INSTALLUILEVEL) (INSTALLUILEVEL_BASIC|INSTALLUILEVEL_ENDDIALOG);
 				WINE_FIXME("Unknown modifier: !\n");
@@ -806,7 +877,7 @@
 					 wine_dbgstr_w(argvW[i]+2));
 			}
 		}
-		else if(!msi_strequal(argvW[i], "/y"))
+		else if(msi_option_equal(argvW[i], "y"))
 		{
 			FunctionDllRegisterServer = TRUE;
 			i++;
@@ -815,7 +886,7 @@
 			WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
 			DllName = argvW[i];
 		}
-		else if(!msi_strequal(argvW[i], "/z"))
+		else if(msi_option_equal(argvW[i], "z"))
 		{
 			FunctionDllUnregisterServer = TRUE;
 			i++;
@@ -824,29 +895,26 @@
 			WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
 			DllName = argvW[i];
 		}
-		else if(!msi_strequal(argvW[i], "/h") || !msi_strequal(argvW[i], "/?"))
+		else if(msi_option_equal(argvW[i], "h") || msi_option_equal(argvW[i], "?"))
 		{
 			ShowUsage(0);
 		}
-		else if(!msi_strequal(argvW[i], "/m"))
+		else if(msi_option_equal(argvW[i], "m"))
 		{
 			FunctionUnknown = TRUE;
 			WINE_FIXME("Unknown parameter /m\n");
 		}
-		else if(!msi_strequal(argvW[i], "/D"))
+		else if(msi_option_equal(argvW[i], "D"))
 		{
 			FunctionUnknown = TRUE;
 			WINE_FIXME("Unknown parameter /D\n");
 		}
-		else if(strchrW(argvW[i], '='))
+		else if (msi_option_equal(argvW[i], "V"))
 		{
-			StringListAppend(&property_list, argvW[i]);
+		    FunctionServer = TRUE;
 		}
 		else
-		{
-			FunctionInstall = TRUE;
-			PackageName = argvW[i];
-		}
+			StringListAppend(&property_list, argvW[i]);
 	}
 
 	/* start the GUI */
@@ -891,12 +959,16 @@
 	}
 	else if (FunctionRegServer)
 	{
-		WINE_FIXME( "/regserver not implemented yet, ignoring\n" );
+		ReturnCode = DoRegServer();
 	}
 	else if (FunctionUnregServer)
 	{
 		WINE_FIXME( "/unregserver not implemented yet, ignoring\n" );
 	}
+	else if (FunctionServer)
+	{
+	    ReturnCode = DoService();
+	}
 	else if (FunctionUnknown)
 	{
 		WINE_FIXME( "Unknown function, ignoring\n" );
