Alexandre Julliard : advapi32: Always pass valid buffers in the EnumServicesStatus requests.
Alexandre Julliard
julliard at winehq.org
Fri Jun 10 11:16:18 CDT 2011
Module: wine
Branch: master
Commit: ad4c995c3f9f844a35f3ee9cc9479bdb9b26e75c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ad4c995c3f9f844a35f3ee9cc9479bdb9b26e75c
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Jun 9 22:00:15 2011 +0200
advapi32: Always pass valid buffers in the EnumServicesStatus requests.
---
dlls/advapi32/service.c | 26 ++++++++++++++++++++++----
1 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c
index 1674c6f..88a15b9 100644
--- a/dlls/advapi32/service.c
+++ b/dlls/advapi32/service.c
@@ -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,
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 );
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;
p = (char *)services + *returned * sizeof(ENUM_SERVICE_STATUSA);
@@ -1532,6 +1533,7 @@ EnumServicesStatusW( SC_HANDLE hmngr, DWORD type, DWORD state, LPENUM_SERVICE_ST
LPDWORD resume_handle )
{
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,
returned, resume_handle);
@@ -1545,6 +1547,13 @@ EnumServicesStatusW( SC_HANDLE hmngr, DWORD type, DWORD state, LPENUM_SERVICE_ST
return FALSE;
}
+ /* make sure we pass a valid pointer */
+ if (!services || size < sizeof(*services))
+ {
+ services = &dummy_status;
+ size = sizeof(dummy_status);
+ }
+
__TRY
{
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
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));
- 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 );
return FALSE;
@@ -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) );
}
- ret = EnumServicesStatusExW( hmngr, level, type, state, (BYTE *)servicesW, 2 * size,
+ ret = EnumServicesStatusExW( hmngr, level, type, state, (BYTE *)servicesW, sz,
needed, returned, resume_handle, groupW );
if (!ret) goto done;
@@ -1650,6 +1660,7 @@ EnumServicesStatusExW( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st
LPDWORD resume_handle, LPCWSTR group )
{
DWORD err, i;
+ ENUM_SERVICE_STATUS_PROCESSW dummy_status;
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,
@@ -1669,6 +1680,13 @@ EnumServicesStatusExW( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st
return FALSE;
}
+ /* make sure we pass a valid buffer pointer */
+ if (!services || size < sizeof(*services))
+ {
+ buffer = (BYTE *)&dummy_status;
+ size = sizeof(dummy_status);
+ }
+
__TRY
{
err = svcctl_EnumServicesStatusExW( hmngr, type, state, buffer, size, needed,
More information about the wine-cvs
mailing list