Better handling of some service functions.
authorAric Stewart <aric@codeweavers.com>
Sat, 13 Dec 2003 03:25:37 +0000 (03:25 +0000)
committerAlexandre Julliard <julliard@winehq.org>
Sat, 13 Dec 2003 03:25:37 +0000 (03:25 +0000)
dlls/advapi32/service.c
include/winsvc.h

index f743d4b70eedd46a988656acf944d29b6c5528c4..70f7b5297a6ff6104618cfbca62d82005b533d1a 100644 (file)
@@ -40,6 +40,10 @@ static LPWSTR *start_lpServiceArgVectors;
 static const WCHAR _ServiceStartDataW[]  = {'A','D','V','A','P','I','_','S',
                                             'e','r','v','i','c','e','S','t',
                                             'a','r','t','D','a','t','a',0};
+static const WCHAR szServiceManagerKey[] = { 'S','y','s','t','e','m','\\',
+      'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+      'S','e','r','v','i','c','e','s','\\',0 };
+
 
 /******************************************************************************
  * EnumServicesStatusA [ADVAPI32.@]
@@ -273,9 +277,6 @@ SC_HANDLE WINAPI
 OpenSCManagerW( LPCWSTR lpMachineName, LPCWSTR lpDatabaseName,
                   DWORD dwDesiredAccess )
 {
-    const WCHAR szKey[] = { 'S','y','s','t','e','m','\\',
-      'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
-      'S','e','r','v','i','c','e','s','\\',0 };
     HKEY hReg, hKey = NULL;
     LONG r;
 
@@ -291,7 +292,7 @@ OpenSCManagerW( LPCWSTR lpMachineName, LPCWSTR lpDatabaseName,
     r = RegConnectRegistryW(lpMachineName,HKEY_LOCAL_MACHINE,&hReg);
     if (r==ERROR_SUCCESS)
     {
-        r = RegOpenKeyExW(hReg, szKey, 0, dwDesiredAccess, &hKey );
+        r = RegOpenKeyExW(hReg, szServiceManagerKey,0, dwDesiredAccess, &hKey );
         RegCloseKey( hReg );
     }
 
@@ -436,9 +437,10 @@ CreateServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
           debugstr_w(lpServiceName), debugstr_w(lpDisplayName));
 
     r = RegCreateKeyExW(hSCManager, lpServiceName, 0, NULL,
-                       REG_OPTION_NON_VOLATILE, dwDesiredAccess, NULL, &hKey, &dp);
+                       REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dp);
     if (r!=ERROR_SUCCESS)
         return 0;
+
     if (dp != REG_CREATED_NEW_KEY)
         return 0;
 
@@ -601,7 +603,64 @@ CreateServiceA( SC_HANDLE hSCManager, LPCSTR lpServiceName,
 BOOL WINAPI
 DeleteService( SC_HANDLE hService )
 {
+    WCHAR valname[MAX_PATH+1];
+    INT index = 0;
+    LONG rc;
+    DWORD value = 0x1;
+    DWORD size;
+    HKEY hKey;
+
+    static const WCHAR szDeleted[] = {'D','e','l','e','t','e','d',0};
+
     FIXME("(%p): stub\n",hService);
+   
+    size = MAX_PATH+1; 
+    /* Clean out the values */
+    rc = RegEnumValueW(hService, index, valname,&size,0,0,0,0);
+    while (rc == ERROR_SUCCESS)
+    {
+        RegDeleteValueW(hService,valname);
+        index++;
+        size = MAX_PATH+1; 
+        rc = RegEnumValueW(hService, index, valname, &size,0,0,0,0);
+    }
+
+    /* tag for deletion */
+    RegSetValueExW(hService, szDeleted, 0, REG_DWORD, (LPVOID)&value, 
+                    sizeof (DWORD) );
+
+    RegCloseKey(hService);
+
+    /* find and delete the key */
+    rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szServiceManagerKey,0,
+                        KEY_ALL_ACCESS, &hKey );
+    index = 0;
+    size = MAX_PATH+1; 
+    rc = RegEnumKeyExW(hKey,0, valname, &size, 0, 0, 0, 0);
+    while (rc == ERROR_SUCCESS)
+    {
+        HKEY checking;
+        rc = RegOpenKeyExW(hKey,valname,0,KEY_ALL_ACCESS,&checking);
+        if (rc == ERROR_SUCCESS)
+        {
+            DWORD deleted = 0;
+            DWORD size = sizeof(DWORD);
+            rc = RegQueryValueExW(checking, szDeleted , NULL, NULL,
+                                  (LPVOID)&deleted, &size);
+            if (deleted)
+            {
+                RegDeleteValueW(checking,szDeleted);
+                RegDeleteKeyW(hKey,valname);
+            }
+            else
+                index ++;
+            RegCloseKey(checking);
+        }
+        size = MAX_PATH+1; 
+        rc = RegEnumKeyExW(hKey, index, valname, &size, 0, 0, 0, 0);
+    }
+    RegCloseKey(hKey);
+
     return TRUE;
 }
 
@@ -978,3 +1037,39 @@ BOOL WINAPI ChangeServiceConfigA( SC_HANDLE hService, DWORD dwServiceType,
           debugstr_a(lpPassword), debugstr_a(lpDisplayName) );
     return TRUE;
 }
+
+/******************************************************************************
+ * ChangeServiceConfig2A  [ADVAPI32.@]
+ */
+BOOL WINAPI ChangeServiceConfig2A( SC_HANDLE hService, DWORD dwInfoLevel, 
+    LPVOID lpInfo)
+{
+    FIXME("STUB: %p %ld %p\n",hService, dwInfoLevel, lpInfo);
+    return TRUE;
+}
+
+/******************************************************************************
+ * ChangeServiceConfig2W  [ADVAPI32.@]
+ */
+BOOL WINAPI ChangeServiceConfig2W( SC_HANDLE hService, DWORD dwInfoLevel, 
+    LPVOID lpInfo)
+{
+    if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
+    {
+        static const WCHAR szDescription[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
+        LPSERVICE_DESCRIPTIONW sd = (LPSERVICE_DESCRIPTIONW)lpInfo;
+        if (sd->lpDescription)
+        {
+            TRACE("Setting Description to %s\n",debugstr_w(sd->lpDescription));
+            if (sd->lpDescription[0] == 0)
+                RegDeleteValueW(hService,szDescription);
+            else
+                RegSetValueExW(hService, szDescription, 0, REG_SZ,
+                                        (LPVOID)sd->lpDescription,
+                                 sizeof(WCHAR)*(strlenW(sd->lpDescription)+1));
+        }
+    }
+    else   
+        FIXME("STUB: %p %ld %p\n",hService, dwInfoLevel, lpInfo);
+    return TRUE;
+}
index fe37ead5354a3fc38f3ae70ba3deb66b7d3b8311..572a9582c0b0e803955a5ab3768e13c3d0478cac 100644 (file)
@@ -178,12 +178,64 @@ typedef struct _QUERY_SERVICE_CONFIGW {
     LPWSTR  lpDisplayName;
 } QUERY_SERVICE_CONFIGW, *LPQUERY_SERVICE_CONFIGW;
 
+/* defines and structures for ChangeServiceConfig2 */
+#define SERVICE_CONFIG_DESCRIPTION     1
+#define SERVICE_CONFIG_FAILURE_ACTIONS 2
+
+typedef struct _SERVICE_DESCRIPTIONA {
+   LPSTR lpDescription;
+} SERVICE_DESCRIPTIONA,*LPSERVICE_DESCRIPTIONA;
+
+typedef struct _SERVICE_DESCRIPTIONW {
+   LPWSTR lpDescription;
+} SERVICE_DESCRIPTIONW,*LPSERVICE_DESCRIPTIONW;
+
+DECL_WINELIB_TYPE_AW(SERVICE_DESCRIPTION)
+DECL_WINELIB_TYPE_AW(LPSERVICE_DESCRIPTION)
+
+typedef enum _SC_ACTION_TYPE {
+    SC_ACTION_NONE        = 0,
+    SC_ACTION_RESTART     = 1,
+    SC_ACTION_REBOOT      = 2,
+    SC_ACTION_RUN_COMMAND = 3
+} SC_ACTION_TYPE;
+
+typedef struct _SC_ACTION {
+   SC_ACTION_TYPE  Type;
+   DWORD       Delay;
+} SC_ACTION,*LPSC_ACTION;
+
+typedef struct _SERVICE_FAILURE_ACTIONSA {
+   DWORD   dwResetPeriod;
+   LPSTR   lpRebootMsg;
+   LPSTR   lpCommand;
+   DWORD   cActions;
+   SC_ACTION * lpsaActions;
+} SERVICE_FAILURE_ACTIONSA,*LPSERVICE_FAILURE_ACTIONSA;
+
+typedef struct _SERVICE_FAILURE_ACTIONSW {
+   DWORD   dwResetPeriod;
+   LPWSTR  lpRebootMsg;
+   LPWSTR  lpCommand;
+   DWORD   cActions;
+   SC_ACTION * lpsaActions;
+} SERVICE_FAILURE_ACTIONSW,*LPSERVICE_FAILURE_ACTIONSW;
+
+DECL_WINELIB_TYPE_AW(SERVICE_FAILURE_ACTIONS)
+DECL_WINELIB_TYPE_AW(LPSERVICE_FAILURE_ACTIONS)
+
 /* Service control handler function prototype */
 
 typedef VOID (WINAPI *LPHANDLER_FUNCTION)(DWORD);
 
 /* API function prototypes */
 
+BOOL        WINAPI ChangeServiceConfigA(SC_HANDLE,DWORD,DWORD,DWORD,LPCSTR,LPCSTR,LPDWORD,LPCSTR,LPCSTR,LPCSTR,LPCSTR);
+BOOL        WINAPI ChangeServiceConfigW(SC_HANDLE,DWORD,DWORD,DWORD,LPCWSTR,LPCWSTR,LPDWORD,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR);
+#define     ChangeServiceConfig WINELIB_NAME_AW(ChangeServiceConfig)
+BOOL        WINAPI ChangeServiceConfig2A(SC_HANDLE,DWORD,LPVOID);
+BOOL        WINAPI ChangeServiceConfig2W(SC_HANDLE,DWORD,LPVOID);
+#define     ChangeServiceConfig2 WINELIB_NAME_AW(ChangeServiceConfig2)
 BOOL        WINAPI CloseServiceHandle(SC_HANDLE);
 BOOL        WINAPI ControlService(SC_HANDLE,DWORD,LPSERVICE_STATUS);
 SC_HANDLE   WINAPI CreateServiceA(SC_HANDLE,LPCSTR,LPCSTR,DWORD,DWORD,DWORD,DWORD,LPCSTR,