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)
|
||||
{
|
||||
case RPC_X_NULL_REF_POINTER:
|
||||
return ERROR_INVALID_ADDRESS;
|
||||
case RPC_X_ENUM_VALUE_OUT_OF_RANGE:
|
||||
case RPC_X_BYTE_COUNT_TOO_SMALL:
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
@ -1654,9 +1655,7 @@ cleanup:
|
|||
BOOL WINAPI QueryServiceConfig2W(SC_HANDLE hService, DWORD dwLevel, LPBYTE buffer,
|
||||
DWORD size, LPDWORD needed)
|
||||
{
|
||||
DWORD sz, type;
|
||||
HKEY hKey;
|
||||
LONG r;
|
||||
DWORD err;
|
||||
struct sc_service *hsvc;
|
||||
|
||||
if(dwLevel != SERVICE_CONFIG_DESCRIPTION) {
|
||||
|
@ -1670,7 +1669,8 @@ BOOL WINAPI QueryServiceConfig2W(SC_HANDLE hService, DWORD dwLevel, LPBYTE buffe
|
|||
SetLastError(ERROR_INVALID_LEVEL);
|
||||
return FALSE;
|
||||
}
|
||||
if(!needed || (!buffer && size)) {
|
||||
|
||||
if(!buffer && size) {
|
||||
SetLastError(ERROR_INVALID_ADDRESS);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1683,36 +1683,36 @@ BOOL WINAPI QueryServiceConfig2W(SC_HANDLE hService, DWORD dwLevel, LPBYTE buffe
|
|||
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);
|
||||
__TRY
|
||||
{
|
||||
err = svcctl_QueryServiceConfig2W(hsvc->hdr.server_handle, dwLevel, buffer, size, needed);
|
||||
}
|
||||
__EXCEPT(rpc_filter)
|
||||
{
|
||||
err = map_exception_code(GetExceptionCode());
|
||||
}
|
||||
__ENDTRY
|
||||
|
||||
if (err != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError( err );
|
||||
return FALSE;
|
||||
}
|
||||
*needed += sz;
|
||||
if(config) {
|
||||
if(r == ERROR_SUCCESS)
|
||||
config->lpDescription = (LPWSTR) (config + 1);
|
||||
else
|
||||
config->lpDescription = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if(*needed > size)
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
return (*needed <= size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -296,8 +296,14 @@ typedef [switch_type(DWORD)] union
|
|||
/* Not compatible with Windows function 0x26 */
|
||||
DWORD svcctl_QueryServiceConfig2A(/* FIXME */);
|
||||
|
||||
/* Not compatible with Windows function 0x27 */
|
||||
DWORD svcctl_QueryServiceConfig2W(/* FIXME */);
|
||||
/* Untested with Windows function 0x27 */
|
||||
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 */
|
||||
DWORD svcctl_QueryServiceStatusEx(
|
||||
|
|
|
@ -646,6 +646,48 @@ DWORD svcctl_ChangeServiceConfig2W( SC_RPC_HANDLE hService, DWORD level, SERVICE
|
|||
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(
|
||||
SC_RPC_HANDLE hService,
|
||||
SC_STATUS_TYPE InfoLevel,
|
||||
|
@ -1141,13 +1183,6 @@ DWORD svcctl_QueryServiceConfig2A(
|
|||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
DWORD svcctl_QueryServiceConfig2W(
|
||||
void)
|
||||
{
|
||||
WINE_FIXME("\n");
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
DWORD RPC_Init(void)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue