advapi32: Partly implemented QueryServiceConfig2A/W.
This commit is contained in:
parent
f14eecded8
commit
6cb602c6db
|
@ -448,8 +448,8 @@
|
|||
# @ stub QueryAllTracesA
|
||||
# @ stub QueryAllTracesW
|
||||
# @ stub QueryRecoveryAgentsOnEncryptedFile
|
||||
# @ stub QueryServiceConfig2A
|
||||
# @ stub QueryServiceConfig2W
|
||||
@ stdcall QueryServiceConfig2A(long long ptr long ptr)
|
||||
@ stdcall QueryServiceConfig2W(long long ptr long ptr)
|
||||
@ stdcall QueryServiceConfigA(long ptr long ptr)
|
||||
@ stdcall QueryServiceConfigW(long ptr long ptr)
|
||||
@ stdcall QueryServiceLockStatusA(long ptr long ptr)
|
||||
|
|
|
@ -2052,6 +2052,121 @@ QueryServiceConfigW( SC_HANDLE hService,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* QueryServiceConfig2A [ADVAPI32.@]
|
||||
*
|
||||
* Note
|
||||
* observed unter win2k:
|
||||
* The functions QueryServiceConfig2A and QueryServiceConfig2W return the same
|
||||
* required buffer size (in byte) at least for dwLevel SERVICE_CONFIG_DESCRIPTION
|
||||
*/
|
||||
BOOL WINAPI QueryServiceConfig2A(SC_HANDLE hService, DWORD dwLevel, LPBYTE buffer,
|
||||
DWORD size, LPDWORD needed)
|
||||
{
|
||||
BOOL ret;
|
||||
LPBYTE bufferW = NULL;
|
||||
|
||||
if(buffer && size)
|
||||
bufferW = HeapAlloc( GetProcessHeap(), 0, size);
|
||||
|
||||
ret = QueryServiceConfig2W(hService, dwLevel, bufferW, size, needed);
|
||||
if(!ret) goto cleanup;
|
||||
|
||||
switch(dwLevel) {
|
||||
case SERVICE_CONFIG_DESCRIPTION:
|
||||
{ LPSERVICE_DESCRIPTIONA configA = (LPSERVICE_DESCRIPTIONA) buffer;
|
||||
LPSERVICE_DESCRIPTIONW configW = (LPSERVICE_DESCRIPTIONW) bufferW;
|
||||
if (configW->lpDescription) {
|
||||
DWORD sz;
|
||||
configA->lpDescription = (LPSTR)(configA + 1);
|
||||
sz = WideCharToMultiByte( CP_ACP, 0, configW->lpDescription, -1,
|
||||
configA->lpDescription, size - sizeof(SERVICE_DESCRIPTIONA), NULL, NULL );
|
||||
if (!sz) {
|
||||
FIXME("WideCharToMultiByte failed for configW->lpDescription\n");
|
||||
ret = FALSE;
|
||||
configA->lpDescription = NULL;
|
||||
}
|
||||
}
|
||||
else configA->lpDescription = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("conversation W->A not implemented for level %d\n", dwLevel);
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
HeapFree( GetProcessHeap(), 0, bufferW);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* QueryServiceConfig2W [ADVAPI32.@]
|
||||
*/
|
||||
BOOL WINAPI QueryServiceConfig2W(SC_HANDLE hService, DWORD dwLevel, LPBYTE buffer,
|
||||
DWORD size, LPDWORD needed)
|
||||
{
|
||||
DWORD sz, type;
|
||||
HKEY hKey;
|
||||
LONG r;
|
||||
struct sc_service *hsvc;
|
||||
|
||||
if(dwLevel != SERVICE_CONFIG_DESCRIPTION) {
|
||||
if((dwLevel == SERVICE_CONFIG_DELAYED_AUTO_START_INFO) ||
|
||||
(dwLevel == SERVICE_CONFIG_FAILURE_ACTIONS) ||
|
||||
(dwLevel == SERVICE_CONFIG_FAILURE_ACTIONS_FLAG) ||
|
||||
(dwLevel == SERVICE_CONFIG_PRESHUTDOWN_INFO) ||
|
||||
(dwLevel == SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO) ||
|
||||
(dwLevel == SERVICE_CONFIG_SERVICE_SID_INFO))
|
||||
FIXME("Level %d not implemented\n", dwLevel);
|
||||
SetLastError(ERROR_INVALID_LEVEL);
|
||||
return FALSE;
|
||||
}
|
||||
if(!needed || (!buffer && size)) {
|
||||
SetLastError(ERROR_INVALID_ADDRESS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE("%p 0x%d %p 0x%d %p\n", hService, dwLevel, buffer, size, needed);
|
||||
|
||||
hsvc = sc_handle_get_handle_data(hService, SC_HTYPE_SERVICE);
|
||||
if (!hsvc)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
hKey = hsvc->hkey;
|
||||
|
||||
switch(dwLevel) {
|
||||
case SERVICE_CONFIG_DESCRIPTION: {
|
||||
static const WCHAR szDescription[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
|
||||
LPSERVICE_DESCRIPTIONW config = (LPSERVICE_DESCRIPTIONW) buffer;
|
||||
LPBYTE strbuf = NULL;
|
||||
*needed = sizeof (SERVICE_DESCRIPTIONW);
|
||||
sz = size - *needed;
|
||||
if(config && (*needed <= size))
|
||||
strbuf = (LPBYTE) (config + 1);
|
||||
r = RegQueryValueExW( hKey, szDescription, 0, &type, strbuf, &sz );
|
||||
if((r == ERROR_SUCCESS) && ( type != REG_SZ)) {
|
||||
FIXME("SERVICE_CONFIG_DESCRIPTION: don't know how to handle type %d\n", type);
|
||||
return FALSE;
|
||||
}
|
||||
*needed += sz;
|
||||
if(config) {
|
||||
if(r == ERROR_SUCCESS)
|
||||
config->lpDescription = (LPWSTR) (config + 1);
|
||||
else
|
||||
config->lpDescription = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(*needed > size)
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
|
||||
return (*needed <= size);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* EnumServicesStatusA [ADVAPI32.@]
|
||||
*/
|
||||
|
|
|
@ -946,6 +946,13 @@ static void test_queryconfig2(void)
|
|||
ok(!ret, "expected QueryServiceConfig2A to fail\n");
|
||||
ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
|
||||
|
||||
needed = 0;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
|
||||
ok(!ret, "expected QueryServiceConfig2A to fail\n");
|
||||
ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
|
||||
ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
|
||||
|
||||
needed = 0;
|
||||
pConfig->lpDescription = (LPSTR)0xdeadbeef;
|
||||
ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
|
||||
|
|
|
@ -243,8 +243,14 @@ typedef struct _QUERY_SERVICE_CONFIGW {
|
|||
} QUERY_SERVICE_CONFIGW, *LPQUERY_SERVICE_CONFIGW;
|
||||
|
||||
/* defines and structures for ChangeServiceConfig2 */
|
||||
#define SERVICE_CONFIG_DESCRIPTION 1
|
||||
#define SERVICE_CONFIG_FAILURE_ACTIONS 2
|
||||
#define SERVICE_CONFIG_DESCRIPTION 1
|
||||
#define SERVICE_CONFIG_FAILURE_ACTIONS 2
|
||||
#define SERVICE_CONFIG_DELAYED_AUTO_START_INFO 3
|
||||
#define SERVICE_CONFIG_FAILURE_ACTIONS_FLAG 4
|
||||
#define SERVICE_CONFIG_SERVICE_SID_INFO 5
|
||||
#define SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO 6
|
||||
#define SERVICE_CONFIG_PRESHUTDOWN_INFO 7
|
||||
|
||||
|
||||
typedef struct _SERVICE_DESCRIPTIONA {
|
||||
LPSTR lpDescription;
|
||||
|
@ -351,6 +357,9 @@ WINADVAPI BOOL WINAPI QueryServiceStatusEx(SC_HANDLE,SC_STATUS_TYPE,LPBYT
|
|||
WINADVAPI BOOL WINAPI QueryServiceConfigA(SC_HANDLE,LPQUERY_SERVICE_CONFIGA,DWORD,LPDWORD);
|
||||
WINADVAPI BOOL WINAPI QueryServiceConfigW(SC_HANDLE,LPQUERY_SERVICE_CONFIGW,DWORD,LPDWORD);
|
||||
#define QueryServiceConfig WINELIB_NAME_AW(QueryServiceConfig)
|
||||
WINADVAPI BOOL WINAPI QueryServiceConfig2A(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
|
||||
WINADVAPI BOOL WINAPI QueryServiceConfig2W(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
|
||||
#define QueryServiceConfig2 WINELIB_NAME_AW(QueryServiceConfig2)
|
||||
WINADVAPI BOOL WINAPI QueryServiceLockStatusA(SC_HANDLE,LPQUERY_SERVICE_LOCK_STATUSA,DWORD,LPDWORD);
|
||||
WINADVAPI BOOL WINAPI QueryServiceLockStatusW(SC_HANDLE,LPQUERY_SERVICE_LOCK_STATUSW,DWORD,LPDWORD);
|
||||
#define QueryServiceLockStatus WINELIB_NAME_AW(QueryServiceLockStatus)
|
||||
|
|
Loading…
Reference in New Issue