[Bug 11420] New: service control manager API problem: name of named objects might differ (client vs. service process)

wine-bugs at winehq.org wine-bugs at winehq.org
Thu Jan 31 14:18:04 CST 2008


http://bugs.winehq.org/show_bug.cgi?id=11420

           Summary: service control manager API problem: name of named
                    objects might differ (client vs. service process)
           Product: Wine
           Version: 0.9.54.
          Platform: PC
        OS/Version: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: advapi32
        AssignedTo: wine-bugs at winehq.org
        ReportedBy: focht at gmx.net


Created an attachment (id=10552)
 --> (http://bugs.winehq.org/attachment.cgi?id=10552)
patch which fixes client vs. service SCM API when using named objects

Hello,

there seems to be a misconception in usage of names for named objects in
service control manager API.
Some people might have experienced such situation: wine hangs for several
seconds on startup (when starting services).
I usually disabled autostart type services (except for builtin ones) and the
problems went away.

Lately while fixing Microsoft Visual Studio .NET installers (2002/2003/2005)
this problem became more and more annoying because the installers and VS.NET
depend on some services, namely "debug manager" (service has to be running).

Consider the following snippet with "service_get_event_handle" trace message
added by me to highlight the problem:

0x9: client (net.exe)
0x11: service process (mdm.exe)
0x12: dispatcher thread

--- snip trace ---
..
0009:trace:advapi:OpenSCManagerW ((null),(null),0x000f003f)
0009:trace:advapi:sc_handle_alloc sc_handle type=0 -> 0x121450
0009:trace:advapi:OpenSCManagerW returning 0x121450 (access : 0x000f003f)
0009:trace:advapi:OpenServiceA 0x121450 "mdm" 983103
0009:trace:advapi:OpenServiceW 0x121450 L"mdm" 983103
0009:trace:advapi:sc_handle_alloc sc_handle type=1 -> 0x121488
0009:trace:advapi:OpenServiceW returning 0x121488
0009:trace:advapi:GetServiceDisplayNameA 0x121450 "mdm" 0x34ee48 0x34fe48
0009:trace:advapi:GetServiceDisplayNameW 0x121450 L"mdm" 0x1214b8 0x34ee08
The Machine Debug Manager service is starting.
0009:trace:advapi:StartServiceA (0x121488,0,(nil))
0009:trace:advapi:StartServiceW 0x121488 0 (nil)
0009:trace:advapi:LockServiceDatabase 0x121450
0009:trace:advapi:LockServiceDatabase returning 0x3c
0009:trace:advapi:service_start_process service_get_event_handle(L"mdm"): 0x40
0011:trace:advapi:LookupPrivilegeValueW L"",L"SeDebugPrivilege",0x34fc80
0011:trace:advapi:LookupPrivilegeValueW L"" -> 00000000-00000014
0011:trace:advapi:AdjustTokenPrivileges 
0011:trace:advapi:StartServiceCtrlDispatcherA 0x34fc9c
0011:trace:advapi:service_run_threads Starting 1 pipe listener threads.
Services running as process 16
0012:trace:advapi:service_control_dispatcher 0x121ea8 L"Machine Debug Manager"
0012:trace:advapi:service_control_dispatcher service_get_event_handle(L"Machine
Debug Manager"): 0x48
0009:trace:advapi:UnlockServiceDatabase 0x3c
0009:trace:advapi:StartServiceW returning 0
The Machine Debug Manager service failed to start.
0009:trace:advapi:CloseServiceHandle 0x121488
0009:trace:advapi:sc_handle_destroy_service destroying service 0x121488
0009:trace:advapi:CloseServiceHandle 0x121450
0009:trace:advapi:sc_handle_destroy_manager destroying SC Manager 0x121450
000d:trace:advapi:service_run_threads last user process exited, shutting down
0011:trace:advapi:service_run_threads last user process exited, shutting down
--- snip trace ---

When a service is started, named objects are created to internally communicate
data/events from the service process (dispatcher) to client side SCM API and
vice versa.
Unfortunately there exist service proccesses which pass service names to
dispatcher table (StartServiceCtrlDispatcher) not matching the service name on
the client side (registry "Services" key).

--- snip dlls/advapi32/service.c ---
static DWORD WINAPI service_control_dispatcher(LPVOID arg)
{
    service_data *service = arg;
    LPWSTR name;
    HANDLE pipe, event;

    TRACE("%p %s\n", service, debugstr_w(service->name));

    /* create a pipe to talk to the rest of the world with */
    name = service_get_pipe_name(service->name);       <--------- *problem*!
    pipe = CreateNamedPipeW(name, PIPE_ACCESS_DUPLEX,
                  PIPE_TYPE_BYTE|PIPE_WAIT, 1, 256, 256, 10000, NULL );

    if (pipe==INVALID_HANDLE_VALUE)
        ERR("failed to create pipe for %s, error = %d\n",
            debugstr_w(service->name), GetLastError());

    HeapFree(GetProcessHeap(), 0, name);

    /* let the process who started us know we've tried to create a pipe */
    event = service_get_event_handle(service->name);  <--------- *problem*!
    SetEvent(event);
    CloseHandle(event);
..
--- snip dlls/advapi32/service.c ---

As result, different named objects are created and signaled so the client side
can't communicate with the service side using named pipe and events.
This leads to infamous timeout problem (30 sec) and service startup failing.

In case of Microsoft Debug Manager the service is called "mdm" (registry).
The service process itself passes "Microsoft Debug Manager" as name to dispatch
table (see first trace).

Problem: how can both sides communicate a "common" name for named objects?
The service dispatcher part on the service side has only dispatch table data
available which doesn't help much.

I thought about this problem and found a feasible solution ... well call it
"hack" whatever.
If the client side API passes the service name in one of the process startup
parameter members before process creation, the service process' dispatcher
routine is able to access this data and create the named objects used for
communication.
I (ab)used startupinfo "title" member because only wine itself make exclusive
use of most service process startup parameters.
If not considered safe, use reserved/undoc fields...

With that patch applied the services in question start fine and can be
controlled using "net" commands.
No more hangs ;-)

Regards


-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list