advapi32: Reimplemented QueryServiceConfig2W in services.exe.
This commit is contained in:
parent
8e16e78710
commit
b608a43df7
|
@ -292,6 +292,7 @@ static DWORD map_exception_code(DWORD exception_code)
|
||||||
switch (exception_code)
|
switch (exception_code)
|
||||||
{
|
{
|
||||||
case RPC_X_NULL_REF_POINTER:
|
case RPC_X_NULL_REF_POINTER:
|
||||||
|
return ERROR_INVALID_ADDRESS;
|
||||||
case RPC_X_ENUM_VALUE_OUT_OF_RANGE:
|
case RPC_X_ENUM_VALUE_OUT_OF_RANGE:
|
||||||
case RPC_X_BYTE_COUNT_TOO_SMALL:
|
case RPC_X_BYTE_COUNT_TOO_SMALL:
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
@ -1654,9 +1655,7 @@ cleanup:
|
||||||
BOOL WINAPI QueryServiceConfig2W(SC_HANDLE hService, DWORD dwLevel, LPBYTE buffer,
|
BOOL WINAPI QueryServiceConfig2W(SC_HANDLE hService, DWORD dwLevel, LPBYTE buffer,
|
||||||
DWORD size, LPDWORD needed)
|
DWORD size, LPDWORD needed)
|
||||||
{
|
{
|
||||||
DWORD sz, type;
|
DWORD err;
|
||||||
HKEY hKey;
|
|
||||||
LONG r;
|
|
||||||
struct sc_service *hsvc;
|
struct sc_service *hsvc;
|
||||||
|
|
||||||
if(dwLevel != SERVICE_CONFIG_DESCRIPTION) {
|
if(dwLevel != SERVICE_CONFIG_DESCRIPTION) {
|
||||||
|
@ -1670,7 +1669,8 @@ BOOL WINAPI QueryServiceConfig2W(SC_HANDLE hService, DWORD dwLevel, LPBYTE buffe
|
||||||
SetLastError(ERROR_INVALID_LEVEL);
|
SetLastError(ERROR_INVALID_LEVEL);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(!needed || (!buffer && size)) {
|
|
||||||
|
if(!buffer && size) {
|
||||||
SetLastError(ERROR_INVALID_ADDRESS);
|
SetLastError(ERROR_INVALID_ADDRESS);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1683,36 +1683,36 @@ BOOL WINAPI QueryServiceConfig2W(SC_HANDLE hService, DWORD dwLevel, LPBYTE buffe
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
hKey = hsvc->hkey;
|
|
||||||
|
|
||||||
switch(dwLevel) {
|
__TRY
|
||||||
case SERVICE_CONFIG_DESCRIPTION: {
|
{
|
||||||
static const WCHAR szDescription[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
|
err = svcctl_QueryServiceConfig2W(hsvc->hdr.server_handle, dwLevel, buffer, size, needed);
|
||||||
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)
|
__EXCEPT(rpc_filter)
|
||||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
{
|
||||||
|
err = map_exception_code(GetExceptionCode());
|
||||||
|
}
|
||||||
|
__ENDTRY
|
||||||
|
|
||||||
return (*needed <= size);
|
if (err != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError( err );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (dwLevel)
|
||||||
|
{
|
||||||
|
case SERVICE_CONFIG_DESCRIPTION:
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
SERVICE_DESCRIPTIONW *descr = (SERVICE_DESCRIPTIONW *)buffer;
|
||||||
|
if (descr->lpDescription) /* make it an absolute pointer */
|
||||||
|
descr->lpDescription = (WCHAR *)(buffer + (ULONG_PTR)descr->lpDescription);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
|
@ -296,8 +296,14 @@ typedef [switch_type(DWORD)] union
|
||||||
/* Not compatible with Windows function 0x26 */
|
/* Not compatible with Windows function 0x26 */
|
||||||
DWORD svcctl_QueryServiceConfig2A(/* FIXME */);
|
DWORD svcctl_QueryServiceConfig2A(/* FIXME */);
|
||||||
|
|
||||||
/* Not compatible with Windows function 0x27 */
|
/* Untested with Windows function 0x27 */
|
||||||
DWORD svcctl_QueryServiceConfig2W(/* FIXME */);
|
DWORD svcctl_QueryServiceConfig2W(
|
||||||
|
[in] SC_RPC_HANDLE hService,
|
||||||
|
[in] DWORD InfoLevel,
|
||||||
|
[out,size_is(cbBufSize)] BYTE lpBuffer[],
|
||||||
|
[in] DWORD cbBufSize,
|
||||||
|
[out] LPDWORD pcbBytesNeeded
|
||||||
|
);
|
||||||
|
|
||||||
/* Untested with Windows function 0x28 */
|
/* Untested with Windows function 0x28 */
|
||||||
DWORD svcctl_QueryServiceStatusEx(
|
DWORD svcctl_QueryServiceStatusEx(
|
||||||
|
|
|
@ -646,6 +646,48 @@ DWORD svcctl_ChangeServiceConfig2W( SC_RPC_HANDLE hService, DWORD level, SERVICE
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD svcctl_QueryServiceConfig2W( SC_RPC_HANDLE hService, DWORD level,
|
||||||
|
BYTE *buffer, DWORD size, LPDWORD needed )
|
||||||
|
{
|
||||||
|
struct sc_service_handle *service;
|
||||||
|
DWORD err;
|
||||||
|
|
||||||
|
if ((err = validate_service_handle(hService, SERVICE_QUERY_STATUS, &service)) != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case SERVICE_CONFIG_DESCRIPTION:
|
||||||
|
{
|
||||||
|
SERVICE_DESCRIPTIONW *descr = (SERVICE_DESCRIPTIONW *)buffer;
|
||||||
|
|
||||||
|
service_lock_shared(service->service_entry);
|
||||||
|
*needed = sizeof(*descr);
|
||||||
|
if (service->service_entry->description)
|
||||||
|
*needed += (strlenW(service->service_entry->description) + 1) * sizeof(WCHAR);
|
||||||
|
if (size >= *needed)
|
||||||
|
{
|
||||||
|
if (service->service_entry->description)
|
||||||
|
{
|
||||||
|
/* store a buffer offset instead of a pointer */
|
||||||
|
descr->lpDescription = (WCHAR *)((BYTE *)(descr + 1) - buffer);
|
||||||
|
strcpyW( (WCHAR *)(descr + 1), service->service_entry->description );
|
||||||
|
}
|
||||||
|
else descr->lpDescription = NULL;
|
||||||
|
}
|
||||||
|
else err = ERROR_INSUFFICIENT_BUFFER;
|
||||||
|
service_unlock(service->service_entry);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WINE_FIXME("level %u not implemented\n", level);
|
||||||
|
err = ERROR_INVALID_LEVEL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD svcctl_QueryServiceStatusEx(
|
DWORD svcctl_QueryServiceStatusEx(
|
||||||
SC_RPC_HANDLE hService,
|
SC_RPC_HANDLE hService,
|
||||||
SC_STATUS_TYPE InfoLevel,
|
SC_STATUS_TYPE InfoLevel,
|
||||||
|
@ -1141,13 +1183,6 @@ DWORD svcctl_QueryServiceConfig2A(
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD svcctl_QueryServiceConfig2W(
|
|
||||||
void)
|
|
||||||
{
|
|
||||||
WINE_FIXME("\n");
|
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DWORD RPC_Init(void)
|
DWORD RPC_Init(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue