diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index 09ab0deb4ee..c7bb0c70dc8 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -240,6 +240,8 @@ static const WCHAR szDependOnService[] = { 'D','e','p','e','n','d','O','n','S','e','r','v','i','c','e',0}; static const WCHAR szObjectName[] = { 'O','b','j','e','c','t','N','a','m','e',0}; +static const WCHAR szTag[] = { + 'T','a','g',0}; struct reg_value { DWORD type; @@ -1849,6 +1851,11 @@ QueryServiceConfigW( SC_HANDLE hService, } hKey = hsvc->hkey; + /* TODO: Check which members are mandatory and what the registry types + * should be. This should of course also be tested when a service is + * created. + */ + /* calculate the size required first */ total = sizeof (QUERY_SERVICE_CONFIGW); @@ -1871,6 +1878,8 @@ QueryServiceConfigW( SC_HANDLE hService, r = RegQueryValueExW( hKey, szGroup, 0, &type, NULL, &sz ); if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) ) total += sz; + else + total += sizeof(WCHAR); sz = 0; r = RegQueryValueExW( hKey, szDependencies, 0, &type, NULL, &sz ); @@ -1883,11 +1892,15 @@ QueryServiceConfigW( SC_HANDLE hService, r = RegQueryValueExW( hKey, szObjectName, 0, &type, NULL, &sz ); if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) ) total += sz; + else + total += sizeof(WCHAR); sz = 0; r = RegQueryValueExW( hKey, szDisplayName, 0, &type, NULL, &sz ); if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) ) total += sz; + else + total += sizeof(WCHAR); *pcbBytesNeeded = total; @@ -1915,6 +1928,11 @@ QueryServiceConfigW( SC_HANDLE hService, if( ( r == ERROR_SUCCESS ) || ( type == REG_DWORD ) ) lpServiceConfig->dwErrorControl = val; + sz = sizeof val; + r = RegQueryValueExW( hKey, szTag, 0, &type, (LPBYTE)&val, &sz ); + if( ( r == ERROR_SUCCESS ) || ( type == REG_DWORD ) ) + lpServiceConfig->dwTagId = val; + /* now do the strings */ p = (LPBYTE) &lpServiceConfig[1]; n = total - sizeof (QUERY_SERVICE_CONFIGW); @@ -1939,12 +1957,18 @@ QueryServiceConfigW( SC_HANDLE hService, sz = n; r = RegQueryValueExW( hKey, szGroup, 0, &type, p, &sz ); + lpServiceConfig->lpLoadOrderGroup = (LPWSTR) p; if( ( r == ERROR_SUCCESS ) || ( type == REG_SZ ) ) { - lpServiceConfig->lpLoadOrderGroup = (LPWSTR) p; p += sz; n -= sz; } + else + { + *(WCHAR *) p = 0; + p += sizeof(WCHAR); + n -= sizeof(WCHAR); + } sz = n; r = RegQueryValueExW( hKey, szDependencies, 0, &type, p, &sz ); @@ -1961,11 +1985,44 @@ QueryServiceConfigW( SC_HANDLE hService, n -= sizeof(WCHAR); } + sz = n; + r = RegQueryValueExW( hKey, szObjectName, 0, &type, p, &sz ); + lpServiceConfig->lpServiceStartName = (LPWSTR) p; + if( ( r == ERROR_SUCCESS ) || ( type == REG_SZ ) ) + { + p += sz; + n -= sz; + } + else + { + *(WCHAR *) p = 0; + p += sizeof(WCHAR); + n -= sizeof(WCHAR); + } + + sz = n; + r = RegQueryValueExW( hKey, szDisplayName, 0, &type, p, &sz ); + lpServiceConfig->lpDisplayName = (LPWSTR) p; + if( ( r == ERROR_SUCCESS ) || ( type == REG_SZ ) ) + { + p += sz; + n -= sz; + } + else + { + *(WCHAR *) p = 0; + p += sizeof(WCHAR); + n -= sizeof(WCHAR); + } + if( n < 0 ) ERR("Buffer overflow!\n"); - TRACE("Image path = %s\n", debugstr_w(lpServiceConfig->lpBinaryPathName) ); - TRACE("Group = %s\n", debugstr_w(lpServiceConfig->lpLoadOrderGroup) ); + TRACE("Image path = %s\n", debugstr_w(lpServiceConfig->lpBinaryPathName) ); + TRACE("Group = %s\n", debugstr_w(lpServiceConfig->lpLoadOrderGroup) ); + TRACE("Dependencies = %s\n", debugstr_w(lpServiceConfig->lpDependencies) ); + TRACE("Service account name = %s\n", debugstr_w(lpServiceConfig->lpServiceStartName) ); + TRACE("Display name = %s\n", debugstr_w(lpServiceConfig->lpDisplayName) ); return TRUE; } diff --git a/dlls/advapi32/tests/service.c b/dlls/advapi32/tests/service.c index 7dde5f54036..206e4f05e62 100644 --- a/dlls/advapi32/tests/service.c +++ b/dlls/advapi32/tests/service.c @@ -116,6 +116,8 @@ static void test_sequence(void) "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError()); ok(given == needed, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given, needed); } + ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName && + config->lpDisplayName, "Expected all string struct members to be non-NULL\n"); ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS), "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType); ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType); @@ -125,11 +127,11 @@ static void test_sequence(void) ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId); /* TODO: Show the double 0 terminated string */ todo_wine + { ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n"); - if(config->lpServiceStartName) /* FIXME: Wine workaround, remove when fixed */ - ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName); - if(config->lpDisplayName) /* FIXME: Wine workaround, remove when fixed */ - ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName); + ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName); + } + ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName); SetLastError(0xdeadbeef); ret = DeleteService(svc_handle);