Alexandre Julliard : advapi32:
Reimplement QueryServiceConfigA on top of QueryServiceConfigW.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Feb 28 14:40:07 CST 2007
Module: wine
Branch: master
Commit: ee1706035aea9764efd80eef6ef764396c450439
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ee1706035aea9764efd80eef6ef764396c450439
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Feb 28 20:47:51 2007 +0100
advapi32: Reimplement QueryServiceConfigA on top of QueryServiceConfigW.
---
dlls/advapi32/service.c | 186 +++++++++++++----------------------------------
1 files changed, 52 insertions(+), 134 deletions(-)
diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c
index 24b209e..9e482df 100644
--- a/dlls/advapi32/service.c
+++ b/dlls/advapi32/service.c
@@ -1644,146 +1644,64 @@ BOOL WINAPI QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel,
/******************************************************************************
* QueryServiceConfigA [ADVAPI32.@]
*/
-BOOL WINAPI
-QueryServiceConfigA( SC_HANDLE hService,
- LPQUERY_SERVICE_CONFIGA lpServiceConfig,
- DWORD cbBufSize, LPDWORD pcbBytesNeeded)
+BOOL WINAPI QueryServiceConfigA( SC_HANDLE hService, LPQUERY_SERVICE_CONFIGA config,
+ DWORD size, LPDWORD needed )
{
- static const CHAR szDisplayName[] = "DisplayName";
- static const CHAR szType[] = "Type";
- static const CHAR szStart[] = "Start";
- static const CHAR szError[] = "ErrorControl";
- static const CHAR szImagePath[] = "ImagePath";
- static const CHAR szGroup[] = "Group";
- static const CHAR szDependencies[] = "Dependencies";
- struct sc_service *hsvc;
- HKEY hKey;
- CHAR str_buffer[ MAX_PATH ];
- LONG r;
- DWORD type, val, sz, total, n;
- LPSTR p;
-
- TRACE("%p %p %d %p\n", hService, lpServiceConfig,
- cbBufSize, pcbBytesNeeded);
-
- hsvc = sc_handle_get_handle_data(hService, SC_HTYPE_SERVICE);
- if (!hsvc)
- {
- SetLastError( ERROR_INVALID_HANDLE );
- return FALSE;
- }
- hKey = hsvc->hkey;
+ DWORD n;
+ LPSTR p, buffer;
+ BOOL ret;
+ QUERY_SERVICE_CONFIGW *configW;
- /* calculate the size required first */
- total = sizeof (QUERY_SERVICE_CONFIGA);
+ TRACE("%p %p %d %p\n", hService, config, size, needed);
- sz = sizeof(str_buffer);
- r = RegQueryValueExA( hKey, szImagePath, 0, &type, (LPBYTE)str_buffer, &sz );
- if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ || type == REG_EXPAND_SZ ) )
- {
- sz = ExpandEnvironmentStringsA(str_buffer,NULL,0);
- if( 0 == sz ) return FALSE;
-
- total += sz;
- }
- else
+ if (!(buffer = HeapAlloc( GetProcessHeap(), 0, 2 * size )))
{
- /* FIXME: set last error */
- return FALSE;
- }
-
- sz = 0;
- r = RegQueryValueExA( hKey, szGroup, 0, &type, NULL, &sz );
- if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) )
- total += sz;
-
- sz = 0;
- r = RegQueryValueExA( hKey, szDependencies, 0, &type, NULL, &sz );
- if( ( r == ERROR_SUCCESS ) && ( type == REG_MULTI_SZ ) )
- total += sz;
-
- sz = 0;
- r = RegQueryValueExA( hKey, szStart, 0, &type, NULL, &sz );
- if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) )
- total += sz;
-
- sz = 0;
- r = RegQueryValueExA( hKey, szDisplayName, 0, &type, NULL, &sz );
- if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) )
- total += sz;
-
- *pcbBytesNeeded = total;
-
- /* if there's not enough memory, return an error */
- if( total > cbBufSize )
- {
- SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
-
- ZeroMemory( lpServiceConfig, total );
-
- sz = sizeof val;
- r = RegQueryValueExA( hKey, szType, 0, &type, (LPBYTE)&val, &sz );
- if( ( r == ERROR_SUCCESS ) || ( type == REG_DWORD ) )
- lpServiceConfig->dwServiceType = val;
-
- sz = sizeof val;
- r = RegQueryValueExA( hKey, szStart, 0, &type, (LPBYTE)&val, &sz );
- if( ( r == ERROR_SUCCESS ) || ( type == REG_DWORD ) )
- lpServiceConfig->dwStartType = val;
-
- sz = sizeof val;
- r = RegQueryValueExA( hKey, szError, 0, &type, (LPBYTE)&val, &sz );
- if( ( r == ERROR_SUCCESS ) || ( type == REG_DWORD ) )
- lpServiceConfig->dwErrorControl = val;
-
- /* now do the strings */
- p = (LPSTR) &lpServiceConfig[1];
- n = total - sizeof (QUERY_SERVICE_CONFIGA);
-
- sz = sizeof(str_buffer);
- r = RegQueryValueExA( hKey, szImagePath, 0, &type, (LPBYTE)str_buffer, &sz );
- if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ || type == REG_EXPAND_SZ ) )
- {
- sz = ExpandEnvironmentStringsA(str_buffer, p, n);
- if( 0 == sz || sz > n ) return FALSE;
-
- lpServiceConfig->lpBinaryPathName = p;
- p += sz;
- n -= sz;
- }
- else
- {
- /* FIXME: set last error */
- return FALSE;
- }
-
- sz = n;
- r = RegQueryValueExA( hKey, szGroup, 0, &type, (LPBYTE)p, &sz );
- if( ( r == ERROR_SUCCESS ) || ( type == REG_SZ ) )
- {
- lpServiceConfig->lpLoadOrderGroup = p;
- p += sz;
- n -= sz;
- }
-
- sz = n;
- r = RegQueryValueExA( hKey, szDependencies, 0, &type, (LPBYTE)p, &sz );
- if( ( r == ERROR_SUCCESS ) || ( type == REG_SZ ) )
- {
- lpServiceConfig->lpDependencies = p;
- p += sz;
- n -= sz;
- }
-
- if( n < 0 )
- ERR("Buffer overflow!\n");
-
- TRACE("Image path = %s\n", lpServiceConfig->lpBinaryPathName );
- TRACE("Group = %s\n", lpServiceConfig->lpLoadOrderGroup );
-
- return TRUE;
+ configW = (QUERY_SERVICE_CONFIGW *)buffer;
+ ret = QueryServiceConfigW( hService, configW, 2 * size, needed );
+ if (!ret) goto done;
+
+ config->dwServiceType = configW->dwServiceType;
+ config->dwStartType = configW->dwStartType;
+ config->dwErrorControl = configW->dwErrorControl;
+ config->lpBinaryPathName = NULL;
+ config->lpLoadOrderGroup = NULL;
+ config->dwTagId = configW->dwTagId;
+ config->lpDependencies = NULL;
+ config->lpServiceStartName = NULL;
+ config->lpDisplayName = NULL;
+
+ p = (LPSTR)(config + 1);
+ n = size - sizeof(*config);
+ ret = FALSE;
+
+#define MAP_STR(str) \
+ do { \
+ if (configW->str) \
+ { \
+ DWORD sz = WideCharToMultiByte( CP_ACP, 0, configW->str, -1, p, n, NULL, NULL ); \
+ if (!sz) goto done; \
+ config->str = p; \
+ p += sz; \
+ n -= sz; \
+ } \
+ } while (0)
+
+ MAP_STR( lpBinaryPathName );
+ MAP_STR( lpLoadOrderGroup );
+ MAP_STR( lpDependencies );
+ MAP_STR( lpServiceStartName );
+ MAP_STR( lpDisplayName );
+#undef MAP_STR
+
+ *needed = p - buffer;
+ ret = TRUE;
+
+done:
+ HeapFree( GetProcessHeap(), 0, buffer );
+ return ret;
}
/******************************************************************************
More information about the wine-cvs
mailing list