http://bugs.winehq.org/show_bug.cgi?id=13958
Summary: Services: handle null display names properly when populating SCM db entries Product: Wine Version: 1.0-rc5 Platform: PC OS/Version: Linux Status: UNCONFIRMED Severity: normal Priority: P3 Component: programs AssignedTo: wine-bugs@winehq.org ReportedBy: focht@gmx.net
Hello,
there is a bug in services code when one or more services have no display name set (null). If CreateServiceW() is called, it checks for existing services using scmdatabase_find_service_by_displayname(). Unfortunately this internal helper doesn't handle the "null" service name properly while iterating, resulting in exception and messy side effects (although mapped to rpc exception it isn't propagated properly).
Following is service db dump with such cases:
--- snip --- 000d:trace:service:scmdatabase_load_services Loading service L"BITS" 000d:trace:service:load_service_config Image path = L"svchost.exe -k netsvcs" 000d:trace:service:load_service_config Group = (null) 000d:trace:service:load_service_config Service account name = L"LocalSystem" 000d:trace:service:load_service_config Display name = L"BITS" 000d:trace:service:load_service_config Service dependencies : (none) 000d:trace:service:load_service_config Group dependencies : (none) 000d:trace:service:scmdatabase_load_services Loading service L"MountMgr" 000d:trace:service:load_service_config Image path = L"C:\windows\system32\drivers\mountmgr.sys" 000d:trace:service:load_service_config Group = (null) 000d:trace:service:load_service_config Service account name = L"LocalSystem" 000d:trace:service:load_service_config Display name = L"Mount Manager" 000d:trace:service:load_service_config Service dependencies : (none) 000d:trace:service:load_service_config Group dependencies : (none) 000d:trace:service:scmdatabase_load_services Loading service L"MSIServer" 000d:trace:service:load_service_config Image path = L"C:\windows\system32\msiexec.exe /V" 000d:trace:service:load_service_config Group = (null) 000d:trace:service:load_service_config Service account name = L"LocalSystem" 000d:trace:service:load_service_config Display name = L"MSIServer" 000d:trace:service:load_service_config Service dependencies : (none) 000d:trace:service:load_service_config Group dependencies : (none) 000d:trace:service:scmdatabase_load_services Loading service L"PnkBstrA" 000d:trace:service:load_service_config Image path = L"C:\windows\system32\PnkBstrA.exe" 000d:trace:service:load_service_config Group = (null) 000d:trace:service:load_service_config Service account name = L"LocalSystem" 000d:trace:service:load_service_config Display name = L"PnkBstrA" 000d:trace:service:load_service_config Service dependencies : (none) 000d:trace:service:load_service_config Group dependencies : (none) 000d:trace:service:scmdatabase_load_services Loading service L"PnkBstrB" 000d:trace:service:load_service_config Image path = L"C:\windows\system32\PnkBstrB.exe" 000d:trace:service:load_service_config Group = (null) 000d:trace:service:load_service_config Service account name = L"LocalSystem" 000d:trace:service:load_service_config Display name = L"PnkBstrB" 000d:trace:service:load_service_config Service dependencies : (none) 000d:trace:service:load_service_config Group dependencies : (none) 000d:trace:service:scmdatabase_load_services Loading service L"PnkBstrK" 000d:trace:service:load_service_config Image path = L"C:\windows\system32\drivers\PnkBstrK.sys" 000d:trace:service:load_service_config Group = (null) 000d:trace:service:load_service_config Service account name = L"LocalSystem" 000d:trace:service:load_service_config Display name = L"PnkBstrK" 000d:trace:service:load_service_config Service dependencies : (none) 000d:trace:service:load_service_config Group dependencies : (none) 000d:trace:service:scmdatabase_load_services Loading service L"PROCMON13" 000d:trace:service:load_service_config Image path = L"\??\C:\windows\system32\Drivers\PROCMON13.SYS" 000d:trace:service:load_service_config Group = (null) 000d:trace:service:load_service_config Service account name = (null) 000d:trace:service:load_service_config Display name = (null) 000d:trace:service:load_service_config Service dependencies : (none) 000d:trace:service:load_service_config Group dependencies : (none) 000d:trace:service:scmdatabase_load_services Loading service L"SecDrv" 000d:trace:service:load_service_config Image path = L"C:\windows\system32\drivers\\SECDRV.SYS" 000d:trace:service:load_service_config Group = (null) 000d:trace:service:load_service_config Service account name = L"LocalSystem" 000d:trace:service:load_service_config Display name = L"SecDrv" 000d:trace:service:load_service_config Service dependencies : (none) 000d:trace:service:load_service_config Group dependencies : (none) 000d:trace:service:scmdatabase_load_services Loading service L"Spooler" 000d:trace:service:load_service_config Image path = L"C:\windows\system32\spoolsv.exe" 000d:trace:service:load_service_config Group = L"SpoolerGroup" 000d:trace:service:load_service_config Service account name = L"LocalSystem" 000d:trace:service:load_service_config Display name = L"Print Spooler" 000d:trace:service:load_service_config Service dependencies : (none) 000d:trace:service:load_service_config Group dependencies : (none) 000d:trace:service:scmdatabase_load_services Loading service L"VxD" 000d:trace:service:load_service_config Image path = (null) 000d:trace:service:load_service_config Group = (null) 000d:trace:service:load_service_config Service account name = (null) 000d:trace:service:load_service_config Display name = (null) 000d:trace:service:load_service_config Service dependencies : (none) 000d:trace:service:load_service_config Group dependencies : (none) --- snip ---
Quick fix:
--- snip ---
diff --git a/programs/services/services.c b/programs/services/services.c index 806fbb6..d48c985 100644 --- a/programs/services/services.c +++ b/programs/services/services.c @@ -341,7 +341,7 @@ struct service_entry *scmdatabase_find_service_by_displayname(struct scmdatabase
LIST_FOR_EACH_ENTRY(service, &db->services, struct service_entry, entry) { - if (strcmpiW(name, service->config.lpDisplayName) == 0) + if (service->config.lpDisplayName && strcmpiW(name, service->config.lpDisplayName) == 0) return service; }
--- snip ---
Hopefully it's not too late for 1.0 ;-|
Regards