advapi32: Partly implemented QueryServiceConfig2A/W.
This commit is contained in:
parent
f14eecded8
commit
6cb602c6db
|
@ -448,8 +448,8 @@
|
||||||
# @ stub QueryAllTracesA
|
# @ stub QueryAllTracesA
|
||||||
# @ stub QueryAllTracesW
|
# @ stub QueryAllTracesW
|
||||||
# @ stub QueryRecoveryAgentsOnEncryptedFile
|
# @ stub QueryRecoveryAgentsOnEncryptedFile
|
||||||
# @ stub QueryServiceConfig2A
|
@ stdcall QueryServiceConfig2A(long long ptr long ptr)
|
||||||
# @ stub QueryServiceConfig2W
|
@ stdcall QueryServiceConfig2W(long long ptr long ptr)
|
||||||
@ stdcall QueryServiceConfigA(long ptr long ptr)
|
@ stdcall QueryServiceConfigA(long ptr long ptr)
|
||||||
@ stdcall QueryServiceConfigW(long ptr long ptr)
|
@ stdcall QueryServiceConfigW(long ptr long ptr)
|
||||||
@ stdcall QueryServiceLockStatusA(long ptr long ptr)
|
@ stdcall QueryServiceLockStatusA(long ptr long ptr)
|
||||||
|
|
|
@ -2052,6 +2052,121 @@ QueryServiceConfigW( SC_HANDLE hService,
|
||||||
return TRUE;
|
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.@]
|
* EnumServicesStatusA [ADVAPI32.@]
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -946,6 +946,13 @@ static void test_queryconfig2(void)
|
||||||
ok(!ret, "expected QueryServiceConfig2A to fail\n");
|
ok(!ret, "expected QueryServiceConfig2A to fail\n");
|
||||||
ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
|
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;
|
needed = 0;
|
||||||
pConfig->lpDescription = (LPSTR)0xdeadbeef;
|
pConfig->lpDescription = (LPSTR)0xdeadbeef;
|
||||||
ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
|
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;
|
} QUERY_SERVICE_CONFIGW, *LPQUERY_SERVICE_CONFIGW;
|
||||||
|
|
||||||
/* defines and structures for ChangeServiceConfig2 */
|
/* defines and structures for ChangeServiceConfig2 */
|
||||||
#define SERVICE_CONFIG_DESCRIPTION 1
|
#define SERVICE_CONFIG_DESCRIPTION 1
|
||||||
#define SERVICE_CONFIG_FAILURE_ACTIONS 2
|
#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 {
|
typedef struct _SERVICE_DESCRIPTIONA {
|
||||||
LPSTR lpDescription;
|
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 QueryServiceConfigA(SC_HANDLE,LPQUERY_SERVICE_CONFIGA,DWORD,LPDWORD);
|
||||||
WINADVAPI BOOL WINAPI QueryServiceConfigW(SC_HANDLE,LPQUERY_SERVICE_CONFIGW,DWORD,LPDWORD);
|
WINADVAPI BOOL WINAPI QueryServiceConfigW(SC_HANDLE,LPQUERY_SERVICE_CONFIGW,DWORD,LPDWORD);
|
||||||
#define QueryServiceConfig WINELIB_NAME_AW(QueryServiceConfig)
|
#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 QueryServiceLockStatusA(SC_HANDLE,LPQUERY_SERVICE_LOCK_STATUSA,DWORD,LPDWORD);
|
||||||
WINADVAPI BOOL WINAPI QueryServiceLockStatusW(SC_HANDLE,LPQUERY_SERVICE_LOCK_STATUSW,DWORD,LPDWORD);
|
WINADVAPI BOOL WINAPI QueryServiceLockStatusW(SC_HANDLE,LPQUERY_SERVICE_LOCK_STATUSW,DWORD,LPDWORD);
|
||||||
#define QueryServiceLockStatus WINELIB_NAME_AW(QueryServiceLockStatus)
|
#define QueryServiceLockStatus WINELIB_NAME_AW(QueryServiceLockStatus)
|
||||||
|
|
Loading…
Reference in New Issue