Commit ad4c995c authored by Alexandre Julliard's avatar Alexandre Julliard

advapi32: Always pass valid buffers in the EnumServicesStatus requests.

parent 519fbf62
...@@ -1486,13 +1486,14 @@ EnumServicesStatusA( SC_HANDLE hmngr, DWORD type, DWORD state, LPENUM_SERVICE_ST ...@@ -1486,13 +1486,14 @@ EnumServicesStatusA( SC_HANDLE hmngr, DWORD type, DWORD state, LPENUM_SERVICE_ST
TRACE("%p 0x%x 0x%x %p %u %p %p %p\n", hmngr, type, state, services, size, needed, TRACE("%p 0x%x 0x%x %p %u %p %p %p\n", hmngr, type, state, services, size, needed,
returned, resume_handle); returned, resume_handle);
if (size && !(servicesW = HeapAlloc( GetProcessHeap(), 0, 2 * size ))) sz = max( 2 * size, sizeof(*servicesW) );
if (!(servicesW = HeapAlloc( GetProcessHeap(), 0, sz )))
{ {
SetLastError( ERROR_NOT_ENOUGH_MEMORY ); SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE; return FALSE;
} }
ret = EnumServicesStatusW( hmngr, type, state, servicesW, 2 * size, needed, returned, resume_handle ); ret = EnumServicesStatusW( hmngr, type, state, servicesW, sz, needed, returned, resume_handle );
if (!ret) goto done; if (!ret) goto done;
p = (char *)services + *returned * sizeof(ENUM_SERVICE_STATUSA); p = (char *)services + *returned * sizeof(ENUM_SERVICE_STATUSA);
...@@ -1532,6 +1533,7 @@ EnumServicesStatusW( SC_HANDLE hmngr, DWORD type, DWORD state, LPENUM_SERVICE_ST ...@@ -1532,6 +1533,7 @@ EnumServicesStatusW( SC_HANDLE hmngr, DWORD type, DWORD state, LPENUM_SERVICE_ST
LPDWORD resume_handle ) LPDWORD resume_handle )
{ {
DWORD err, i; DWORD err, i;
ENUM_SERVICE_STATUSW dummy_status;
TRACE("%p 0x%x 0x%x %p %u %p %p %p\n", hmngr, type, state, services, size, needed, TRACE("%p 0x%x 0x%x %p %u %p %p %p\n", hmngr, type, state, services, size, needed,
returned, resume_handle); returned, resume_handle);
...@@ -1545,6 +1547,13 @@ EnumServicesStatusW( SC_HANDLE hmngr, DWORD type, DWORD state, LPENUM_SERVICE_ST ...@@ -1545,6 +1547,13 @@ EnumServicesStatusW( SC_HANDLE hmngr, DWORD type, DWORD state, LPENUM_SERVICE_ST
return FALSE; return FALSE;
} }
/* make sure we pass a valid pointer */
if (!services || size < sizeof(*services))
{
services = &dummy_status;
size = sizeof(dummy_status);
}
__TRY __TRY
{ {
err = svcctl_EnumServicesStatusW( hmngr, type, state, (BYTE *)services, size, needed, returned ); err = svcctl_EnumServicesStatusW( hmngr, type, state, (BYTE *)services, size, needed, returned );
...@@ -1591,7 +1600,8 @@ EnumServicesStatusExA( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st ...@@ -1591,7 +1600,8 @@ EnumServicesStatusExA( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st
TRACE("%p %u 0x%x 0x%x %p %u %p %p %p %s\n", hmngr, level, type, state, buffer, TRACE("%p %u 0x%x 0x%x %p %u %p %p %p %s\n", hmngr, level, type, state, buffer,
size, needed, returned, resume_handle, debugstr_a(group)); size, needed, returned, resume_handle, debugstr_a(group));
if (size && !(servicesW = HeapAlloc( GetProcessHeap(), 0, 2 * size ))) sz = max( 2 * size, sizeof(*servicesW) );
if (!(servicesW = HeapAlloc( GetProcessHeap(), 0, sz )))
{ {
SetLastError( ERROR_NOT_ENOUGH_MEMORY ); SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE; return FALSE;
...@@ -1608,7 +1618,7 @@ EnumServicesStatusExA( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st ...@@ -1608,7 +1618,7 @@ EnumServicesStatusExA( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st
MultiByteToWideChar( CP_ACP, 0, group, -1, groupW, len * sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, group, -1, groupW, len * sizeof(WCHAR) );
} }
ret = EnumServicesStatusExW( hmngr, level, type, state, (BYTE *)servicesW, 2 * size, ret = EnumServicesStatusExW( hmngr, level, type, state, (BYTE *)servicesW, sz,
needed, returned, resume_handle, groupW ); needed, returned, resume_handle, groupW );
if (!ret) goto done; if (!ret) goto done;
...@@ -1650,6 +1660,7 @@ EnumServicesStatusExW( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st ...@@ -1650,6 +1660,7 @@ EnumServicesStatusExW( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st
LPDWORD resume_handle, LPCWSTR group ) LPDWORD resume_handle, LPCWSTR group )
{ {
DWORD err, i; DWORD err, i;
ENUM_SERVICE_STATUS_PROCESSW dummy_status;
ENUM_SERVICE_STATUS_PROCESSW *services = (ENUM_SERVICE_STATUS_PROCESSW *)buffer; ENUM_SERVICE_STATUS_PROCESSW *services = (ENUM_SERVICE_STATUS_PROCESSW *)buffer;
TRACE("%p %u 0x%x 0x%x %p %u %p %p %p %s\n", hmngr, level, type, state, buffer, TRACE("%p %u 0x%x 0x%x %p %u %p %p %p %s\n", hmngr, level, type, state, buffer,
...@@ -1669,6 +1680,13 @@ EnumServicesStatusExW( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st ...@@ -1669,6 +1680,13 @@ EnumServicesStatusExW( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st
return FALSE; return FALSE;
} }
/* make sure we pass a valid buffer pointer */
if (!services || size < sizeof(*services))
{
buffer = (BYTE *)&dummy_status;
size = sizeof(dummy_status);
}
__TRY __TRY
{ {
err = svcctl_EnumServicesStatusExW( hmngr, type, state, buffer, size, needed, err = svcctl_EnumServicesStatusExW( hmngr, type, state, buffer, size, needed,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment