merge ROS Shell without integrated explorer part into trunk
[reactos.git] / reactos / services / umpnpmgr / umpnpmgr.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2005 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: services/umpnpmgr/umpnpmgr.c
24 * PURPOSE: User-mode Plug and Play manager
25 * PROGRAMMER: Eric Kohl
26 */
27
28 /* INCLUDES *****************************************************************/
29
30 #define NTOS_MODE_USER
31 #include <ntos.h>
32 #include <ntos/ntpnp.h>
33 #include <ddk/wdmguid.h>
34 #include <windows.h>
35 #include <tchar.h>
36 #include <stdio.h>
37
38 #include <rpc.h>
39 #include <rpcdce.h>
40
41 #include "pnp.h"
42
43 #define DBG
44 #define NDEBUG
45 #include <debug.h>
46
47
48
49 /* GLOBALS ******************************************************************/
50
51 static VOID CALLBACK
52 ServiceMain(DWORD argc, LPTSTR *argv);
53
54 static SERVICE_TABLE_ENTRY ServiceTable[2] =
55 {
56 {_T("PlugPlay"), ServiceMain},
57 {NULL, NULL}
58 };
59
60
61 /* FUNCTIONS *****************************************************************/
62
63 static DWORD WINAPI
64 RpcServerThread(LPVOID lpParameter)
65 {
66 RPC_STATUS Status;
67
68 DPRINT("RpcServerThread() called\n");
69
70 Status = RpcServerUseProtseqEpW(L"ncacn_np",
71 20,
72 L"\\pipe\\umpnpmgr",
73 NULL); // Security descriptor
74 if (Status != RPC_S_OK)
75 {
76 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
77 return 0;
78 }
79
80 Status = RpcServerRegisterIf(pnp_v1_0_s_ifspec,
81 NULL,
82 NULL);
83 if (Status != RPC_S_OK)
84 {
85 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status);
86 return 0;
87 }
88
89 Status = RpcServerListen(1,
90 20,
91 FALSE);
92 if (Status != RPC_S_OK)
93 {
94 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status);
95 return 0;
96 }
97
98 DPRINT("RpcServerThread() done\n");
99
100 return 0;
101 }
102
103
104 void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
105 {
106 return GlobalAlloc(GPTR, len);
107 }
108
109
110 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
111 {
112 GlobalFree(ptr);
113 }
114
115
116 //WORD PNP_GetVersion(RPC_BINDING_HANDLE BindingHandle)
117 WORD PNP_GetVersion(handle_t BindingHandle)
118 {
119 return 0x0400;
120 }
121
122
123 static DWORD WINAPI
124 PnpEventThread(LPVOID lpParameter)
125 {
126 PPLUGPLAY_EVENT_BLOCK PnpEvent;
127 ULONG PnpEventSize;
128 NTSTATUS Status;
129 RPC_STATUS RpcStatus;
130
131 PnpEventSize = 0x1000;
132 PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize);
133 if (PnpEvent == NULL)
134 return ERROR_OUTOFMEMORY;
135
136 for (;;)
137 {
138 DPRINT("Calling NtGetPlugPlayEvent()\n");
139
140 /* Wait for the next pnp event */
141 Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize);
142 /* Resize the buffer for the PnP event if it's too small. */
143 if (Status == STATUS_BUFFER_TOO_SMALL)
144 {
145 PnpEventSize += 0x400;
146 PnpEvent = HeapReAlloc(GetProcessHeap(), 0, PnpEvent, PnpEventSize);
147 if (PnpEvent == NULL)
148 return ERROR_OUTOFMEMORY;
149 continue;
150 }
151 if (!NT_SUCCESS(Status))
152 {
153 DPRINT("NtPlugPlayEvent() failed (Status %lx)\n", Status);
154 break;
155 }
156
157 DPRINT("Received PnP Event\n");
158 if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
159 {
160 DPRINT1("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds);
161 }
162 else
163 {
164 DPRINT1("Unknown event\n");
165 }
166
167 /* FIXME: Process the pnp event */
168
169 /* Dequeue the current pnp event and signal the next one */
170 NtPlugPlayControl(PLUGPLAY_USER_RESPONSE, NULL, 0);
171 }
172
173 HeapFree(GetProcessHeap(), 0, PnpEvent);
174
175 return ERROR_SUCCESS;
176 }
177
178
179 static VOID CALLBACK
180 ServiceMain(DWORD argc, LPTSTR *argv)
181 {
182 HANDLE hThread;
183 DWORD dwThreadId;
184
185 DPRINT("ServiceMain() called\n");
186
187 hThread = CreateThread(NULL,
188 0,
189 PnpEventThread,
190 NULL,
191 0,
192 &dwThreadId);
193 if (hThread != NULL)
194 CloseHandle(hThread);
195
196 hThread = CreateThread(NULL,
197 0,
198 RpcServerThread,
199 NULL,
200 0,
201 &dwThreadId);
202 if (hThread != NULL)
203 CloseHandle(hThread);
204
205 DPRINT("ServiceMain() done\n");
206 }
207
208
209 int
210 main(int argc, char *argv[])
211 {
212 DPRINT("Umpnpmgr: main() started\n");
213
214 StartServiceCtrlDispatcher(ServiceTable);
215
216 DPRINT("Umpnpmgr: main() done\n");
217
218 ExitThread(0);
219
220 return 0;
221 }
222
223 /* EOF */