6d8df8fec71ef60336ec9511e27c8d72e33bb614
[reactos.git] / reactos / subsys / system / winlogon / wlx.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/winlogon/winlogon.c
6 * PURPOSE: Logon
7 * PROGRAMMER: David Welch (welch@cwcom.net)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include "winlogon.h"
15
16 #define NDEBUG
17 #include <debug.h>
18
19 #define Unimplemented DbgPrint("WL: %S() at %S:%i unimplemented!\n", __FUNCTION__, __FILE__, __LINE__)
20
21 /*
22 * @implemented
23 */
24 VOID WINAPI
25 WlxUseCtrlAltDel(
26 HANDLE hWlx
27 )
28 {
29 WlxSetOption(hWlx, WLX_OPTION_USE_CTRL_ALT_DEL, TRUE, NULL);
30 }
31
32 /*
33 * @implemented
34 */
35 VOID WINAPI
36 WlxSetContextPointer(
37 HANDLE hWlx,
38 PVOID pWlxContext
39 )
40 {
41 WlxSetOption(hWlx, WLX_OPTION_CONTEXT_POINTER, (ULONG_PTR)pWlxContext, NULL);
42 }
43
44 /*
45 * @implemented
46 */
47 VOID WINAPI
48 WlxSasNotify(
49 HANDLE hWlx,
50 DWORD dwSasType
51 )
52 {
53 DispatchSAS((PWLSESSION)hWlx, dwSasType);
54 }
55
56 /*
57 * @unimplemented
58 */
59 BOOL WINAPI
60 WlxSetTimeout(
61 HANDLE hWlx,
62 DWORD Timeout
63 )
64 {
65 /* Unimplemented; */
66 return FALSE;
67 }
68
69 /*
70 * @unimplemented
71 */
72 int WINAPI
73 WlxAssignShellProtection(
74 HANDLE hWlx,
75 HANDLE hToken,
76 HANDLE hProcess,
77 HANDLE hThread
78 )
79 {
80 Unimplemented;
81 return 0;
82 }
83
84 /*
85 * @unimplemented
86 */
87 int WINAPI
88 WlxMessageBox(
89 HANDLE hWlx,
90 HWND hwndOwner,
91 LPWSTR lpszText,
92 LPWSTR lpszTitle,
93 UINT fuStyle
94 )
95 {
96 Unimplemented;
97 return 0;
98 }
99
100 /*
101 * @unimplemented
102 */
103 int WINAPI
104 WlxDialogBox(
105 HANDLE hWlx,
106 HANDLE hInst,
107 LPWSTR lpszTemplate,
108 HWND hwndOwner,
109 DLGPROC dlgprc
110 )
111 {
112 Unimplemented;
113 return 0;
114 }
115
116 /*
117 * @unimplemented
118 */
119 int WINAPI
120 WlxDialogBoxParam(
121 HANDLE hWlx,
122 HANDLE hInst,
123 LPWSTR lpszTemplate,
124 HWND hwndOwner,
125 DLGPROC dlgprc,
126 LPARAM dwInitParam
127 )
128 {
129 Unimplemented;
130 return 0;
131 }
132
133 /*
134 * @unimplemented
135 */
136 int WINAPI
137 WlxDialogBoxIndirect(
138 HANDLE hWlx,
139 HANDLE hInst,
140 LPCDLGTEMPLATE hDialogTemplate,
141 HWND hwndOwner,
142 DLGPROC dlgprc
143 )
144 {
145 Unimplemented;
146 return 0;
147 }
148
149 /*
150 * @unimplemented
151 */
152 int WINAPI
153 WlxDialogBoxIndirectParam(
154 HANDLE hWlx,
155 HANDLE hInst,
156 LPCDLGTEMPLATE hDialogTemplate,
157 HWND hwndOwner,
158 DLGPROC dlgprc,
159 LPARAM dwInitParam
160 )
161 {
162 Unimplemented;
163 return 0;
164 }
165
166 /*
167 * @unimplemented
168 */
169 int WINAPI
170 WlxSwitchDesktopToUser(
171 HANDLE hWlx
172 )
173 {
174 Unimplemented;
175 return 0;
176 }
177
178 /*
179 * @unimplemented
180 */
181 int WINAPI
182 WlxSwitchDesktopToWinlogon(
183 HANDLE hWlx
184 )
185 {
186 Unimplemented;
187 return 0;
188 }
189
190 /*
191 * @unimplemented
192 */
193 int WINAPI
194 WlxChangePasswordNotify(
195 HANDLE hWlx,
196 PWLX_MPR_NOTIFY_INFO pMprInfo,
197 DWORD dwChangeInfo
198 )
199 {
200 Unimplemented;
201 return 0;
202 }
203
204 /*
205 * @unimplemented
206 */
207 BOOL WINAPI
208 WlxGetSourceDesktop(
209 HANDLE hWlx,
210 PWLX_DESKTOP* ppDesktop
211 )
212 {
213 Unimplemented;
214 return FALSE;
215 }
216
217 /*
218 * @unimplemented
219 */
220 BOOL WINAPI
221 WlxSetReturnDesktop(
222 HANDLE hWlx,
223 PWLX_DESKTOP pDesktop
224 )
225 {
226 Unimplemented;
227 return FALSE;
228 }
229
230 /*
231 * @unimplemented
232 */
233 BOOL WINAPI
234 WlxCreateUserDesktop(
235 HANDLE hWlx,
236 HANDLE hToken,
237 DWORD Flags,
238 PWSTR pszDesktopName,
239 PWLX_DESKTOP* ppDesktop
240 )
241 {
242 Unimplemented;
243 return FALSE;
244 }
245
246 /*
247 * @unimplemented
248 */
249 int WINAPI
250 WlxChangePasswordNotifyEx(
251 HANDLE hWlx,
252 PWLX_MPR_NOTIFY_INFO pMprInfo,
253 DWORD dwChangeInfo,
254 PWSTR ProviderName,
255 PVOID Reserved
256 )
257 {
258 Unimplemented;
259 return 0;
260 }
261
262 /*
263 * @unimplemented
264 */
265 BOOL WINAPI
266 WlxCloseUserDesktop(
267 HANDLE hWlx,
268 PWLX_DESKTOP pDesktop,
269 HANDLE hToken
270 )
271 {
272 Unimplemented;
273 return FALSE;
274 }
275
276 /*
277 * @unimplemented
278 */
279 BOOL WINAPI
280 WlxSetOption(
281 HANDLE hWlx,
282 DWORD Option,
283 ULONG_PTR Value,
284 ULONG_PTR* OldValue
285 )
286 {
287 PWLSESSION Session = (PWLSESSION)hWlx;
288
289 if(Session || !Value)
290 {
291 switch(Option)
292 {
293 case WLX_OPTION_USE_CTRL_ALT_DEL:
294 return TRUE;
295 case WLX_OPTION_CONTEXT_POINTER:
296 {
297 *OldValue = (ULONG_PTR)Session->MsGina.Context;
298 Session->MsGina.Context = (PVOID)Value;
299 return TRUE;
300 }
301 case WLX_OPTION_USE_SMART_CARD:
302 return FALSE;
303 }
304 }
305
306 return FALSE;
307 }
308
309 /*
310 * @unimplemented
311 */
312 BOOL WINAPI
313 WlxGetOption(
314 HANDLE hWlx,
315 DWORD Option,
316 ULONG_PTR* Value
317 )
318 {
319 PMSGINAINSTANCE Instance = (PMSGINAINSTANCE)hWlx;
320 Unimplemented;
321 if(Instance || !Value)
322 {
323 switch(Option)
324 {
325 case WLX_OPTION_USE_CTRL_ALT_DEL:
326 return TRUE;
327 case WLX_OPTION_CONTEXT_POINTER:
328 {
329 *Value = (ULONG_PTR)Instance->Context;
330 return TRUE;
331 }
332 case WLX_OPTION_USE_SMART_CARD:
333 case WLX_OPTION_SMART_CARD_PRESENT:
334 case WLX_OPTION_SMART_CARD_INFO:
335 *Value = 0;
336 return FALSE;
337 case WLX_OPTION_DISPATCH_TABLE_SIZE:
338 {
339 switch(Instance->Version)
340 {
341 case WLX_VERSION_1_0:
342 *Value = sizeof(WLX_DISPATCH_VERSION_1_0);
343 break;
344 case WLX_VERSION_1_1:
345 *Value = sizeof(WLX_DISPATCH_VERSION_1_1);
346 break;
347 case WLX_VERSION_1_2:
348 *Value = sizeof(WLX_DISPATCH_VERSION_1_2);
349 break;
350 case WLX_VERSION_1_3:
351 *Value = sizeof(WLX_DISPATCH_VERSION_1_3);
352 break;
353 case WLX_VERSION_1_4:
354 *Value = sizeof(WLX_DISPATCH_VERSION_1_4);
355 break;
356 default:
357 return 0;
358 }
359 return TRUE;
360 }
361 }
362 }
363
364 return FALSE;
365 }
366
367 /*
368 * @unimplemented
369 */
370 VOID WINAPI
371 WlxWin31Migrate(
372 HANDLE hWlx
373 )
374 {
375 Unimplemented;
376 }
377
378 /*
379 * @unimplemented
380 */
381 BOOL WINAPI
382 WlxQueryClientCredentials(
383 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred
384 )
385 {
386 Unimplemented;
387 return FALSE;
388 }
389
390 /*
391 * @unimplemented
392 */
393 BOOL WINAPI
394 WlxQueryInetConnectorCredentials(
395 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred
396 )
397 {
398 Unimplemented;
399 return FALSE;
400 }
401
402 /*
403 * @unimplemented
404 */
405 DWORD WINAPI
406 WlxQueryConsoleSwitchCredentials(
407 PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred
408 )
409 {
410 Unimplemented;
411 return 0;
412 }
413
414 /*
415 * @unimplemented
416 */
417 BOOL WINAPI
418 WlxQueryTsLogonCredentials(
419 PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred
420 )
421 {
422 Unimplemented;
423 return FALSE;
424 }
425
426 /*
427 * @unimplemented
428 */
429 BOOL WINAPI
430 WlxDisconnect(void)
431 {
432 Unimplemented;
433 return FALSE;
434 }
435
436 /*
437 * @unimplemented
438 */
439 DWORD WINAPI
440 WlxQueryTerminalServicesData(
441 HANDLE hWlx,
442 PWLX_TERMINAL_SERVICES_DATA pTSData,
443 WCHAR* UserName,
444 WCHAR* Domain
445 )
446 {
447 Unimplemented;
448 return 0;
449 }
450
451 const
452 WLX_DISPATCH_VERSION_1_4 FunctionTable = {
453 WlxUseCtrlAltDel,
454 WlxSetContextPointer,
455 WlxSasNotify,
456 WlxSetTimeout,
457 WlxAssignShellProtection,
458 WlxMessageBox,
459 WlxDialogBox,
460 WlxDialogBoxParam,
461 WlxDialogBoxIndirect,
462 WlxDialogBoxIndirectParam,
463 WlxSwitchDesktopToUser,
464 WlxSwitchDesktopToWinlogon,
465 WlxChangePasswordNotify,
466 WlxGetSourceDesktop,
467 WlxSetReturnDesktop,
468 WlxCreateUserDesktop,
469 WlxChangePasswordNotifyEx,
470 WlxCloseUserDesktop,
471 WlxSetOption,
472 WlxGetOption,
473 WlxWin31Migrate,
474 WlxQueryClientCredentials,
475 WlxQueryInetConnectorCredentials,
476 WlxDisconnect,
477 WlxQueryTerminalServicesData,
478 WlxQueryConsoleSwitchCredentials,
479 WlxQueryTsLogonCredentials
480 };
481
482 /******************************************************************************/
483
484 static void
485 GetMsGinaPath(WCHAR *path)
486 {
487 DWORD Status, Type, Size;
488 HKEY hKey;
489
490 Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
491 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
492 0,
493 KEY_QUERY_VALUE,
494 &hKey);
495 if(Status != ERROR_SUCCESS)
496 {
497 wcscpy(path, L"msgina.dll");
498 return;
499 }
500
501 Size = MAX_PATH * sizeof(WCHAR);
502 Status = RegQueryValueEx(hKey,
503 L"GinaDLL",
504 NULL,
505 &Type,
506 (LPBYTE)path,
507 &Size);
508 if((Status != ERROR_SUCCESS) || (Size != REG_SZ) || (Size == 0))
509 {
510 wcscpy(path, L"msgina.dll");
511 }
512 RegCloseKey(hKey);
513 }
514
515 INT_PTR CALLBACK
516 GinaLoadFailedProc(
517 HWND hwndDlg,
518 UINT uMsg,
519 WPARAM wParam,
520 LPARAM lParam
521 )
522 {
523 switch(uMsg)
524 {
525 case WM_COMMAND:
526 {
527 switch(LOWORD(wParam))
528 {
529 case IDOK:
530 EndDialog(hwndDlg, IDOK);
531 break;
532 }
533 break;
534 }
535 case WM_INITDIALOG:
536 {
537 int len;
538 WCHAR str[MAX_PATH], str2[MAX_PATH];
539
540 if(lParam)
541 {
542 len = GetDlgItemText(hwndDlg, IDC_GINALOADFAILED, str, MAX_PATH);
543
544 if(len)
545 {
546 wsprintf(str2, str, (LPWSTR)lParam);
547 SetDlgItemText(hwndDlg, IDC_GINALOADFAILED, str2);
548 }
549 }
550 SetFocus(GetDlgItem(hwndDlg, IDOK));
551 break;
552 }
553 case WM_CLOSE:
554 {
555 EndDialog(hwndDlg, IDCANCEL);
556 return TRUE;
557 }
558 }
559 return FALSE;
560 }
561
562 BOOL
563 LoadGina(PMSGINAFUNCTIONS Functions, DWORD *DllVersion, HMODULE *GinaInstance)
564 {
565 HMODULE hGina;
566 WCHAR GinaDll[MAX_PATH + 1];
567
568 GetMsGinaPath(GinaDll);
569
570 if(!(hGina = LoadLibrary(GinaDll)))
571 {
572 DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), 0, GinaLoadFailedProc, (LPARAM)&GinaDll);
573 return FALSE;
574 }
575 *GinaInstance = hGina;
576
577 Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate");
578 Functions->WlxInitialize = (PFWLXINITIALIZE)GetProcAddress(hGina, "WlxInitialize");
579
580 if(Functions->WlxNegotiate)
581 {
582 if(!Functions->WlxNegotiate(WLX_VERSION_1_3, DllVersion))
583 {
584 return FALSE;
585 }
586
587 if(*DllVersion >= WLX_VERSION_1_0)
588 {
589 Functions->WlxActivateUserShell = (PFWLXACTIVATEUSERSHELL)GetProcAddress(hGina, "WlxActivateUserShell");
590 Functions->WlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hGina, "WlxDisplayLockedNotice");
591 Functions->WlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE)GetProcAddress(hGina, "WlxDisplaySASNotice");
592 Functions->WlxIsLockOk = (PFWLXISLOCKOK)GetProcAddress(hGina, "WlxIsLockOk");
593 Functions->WlxIsLogoffOk = (PFWLXISLOGOFFOK)GetProcAddress(hGina, "WlxIsLogoffOk");
594 Functions->WlxLoggedOnSAS = (PFWLXLOGGEDONSAS)GetProcAddress(hGina, "WlxLoggedOnSAS");
595 Functions->WlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS)GetProcAddress(hGina, "WlxLoggedOutSAS");
596 Functions->WlxLogoff = (PFWLXLOGOFF)GetProcAddress(hGina, "WlxLogoff");
597 Functions->WlxShutdown = (PFWLXSHUTDOWN)GetProcAddress(hGina, "WlxShutdown");
598 Functions->WlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS)GetProcAddress(hGina, "WlxWkstaLockedSAS");
599 }
600
601 if(*DllVersion >= WLX_VERSION_1_1)
602 {
603 Functions->WlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY)GetProcAddress(hGina, "WlxScreenSaverNotify");
604 Functions->WlxStartApplication = (PFWLXSTARTAPPLICATION)GetProcAddress(hGina, "WlxStartApplication");
605 }
606
607 if(*DllVersion >= WLX_VERSION_1_3)
608 {
609 Functions->WlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE)GetProcAddress(hGina, "WlxDisplayStatusMessage");
610 Functions->WlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE)GetProcAddress(hGina, "WlxGetStatusMessage");
611 Functions->WlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD)GetProcAddress(hGina, "WlxNetworkProviderLoad");
612 Functions->WlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE)GetProcAddress(hGina, "WlxRemoveStatusMessage");
613 }
614
615 if(*DllVersion >= WLX_VERSION_1_4)
616 {
617
618 }
619 }
620
621 return (Functions->WlxNegotiate != NULL) && (Functions->WlxInitialize != NULL);
622 }
623
624 PWLSESSION
625 MsGinaInit(void)
626 {
627 PWLSESSION WLSession;
628 DWORD GinaDllVersion;
629
630 WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLSESSION));
631 if(!WLSession)
632 {
633 return NULL;
634 }
635
636 if(!LoadGina(&WLSession->MsGina.Functions, &GinaDllVersion, &WLSession->MsGina.hDllInstance))
637 {
638 HeapFree(GetProcessHeap(), 0, WLSession);
639 return NULL;
640 }
641
642 WLSession->MsGina.Context = NULL;
643 WLSession->MsGina.Version = GinaDllVersion;
644 WLSession->SuppressStatus = FALSE;
645
646 if(!WLSession->MsGina.Functions.WlxInitialize(WLSession->InteractiveWindowStationName,
647 (HANDLE)WLSession,
648 NULL,
649 (PVOID)&FunctionTable,
650 &WLSession->MsGina.Context))
651 {
652 HeapFree(GetProcessHeap(), 0, WLSession);
653 return NULL;
654 }
655 return WLSession;
656 }
657
658 BOOL
659 WlxCreateWindowStationAndDesktops(PWLSESSION Session)
660 {
661 /*
662 * Create the interactive window station
663 */
664 Session->InteractiveWindowStationName = L"WinSta0";
665 Session->InteractiveWindowStation = CreateWindowStation(Session->InteractiveWindowStationName,
666 0, GENERIC_ALL, NULL);
667 if(!Session->InteractiveWindowStation)
668 {
669 DbgPrint("WL: Failed to create window station (0x%X)\n", GetLastError());
670 return FALSE;
671 }
672 SetProcessWindowStation(Session->InteractiveWindowStation);
673
674 /*
675 * Create the application desktop
676 */
677 Session->ApplicationDesktop = CreateDesktop(L"Default",
678 NULL,
679 NULL,
680 0, /* FIXME: Set some flags */
681 GENERIC_ALL,
682 NULL);
683 if(!Session->ApplicationDesktop)
684 {
685 DbgPrint("WL: Failed to create Default desktop (0x%X)\n", GetLastError());
686 return FALSE;
687 }
688
689 /*
690 * Create the winlogon desktop
691 */
692 Session->WinlogonDesktop = CreateDesktop(WINLOGON_DESKTOP,
693 NULL,
694 NULL,
695 0, /* FIXME: Set some flags */
696 GENERIC_ALL,
697 NULL);
698 if(!Session->WinlogonDesktop)
699 {
700 DbgPrint("WL: Failed to create Winlogon desktop (0x%X)\n", GetLastError());
701 return FALSE;
702 }
703
704 /*
705 * Create the screen saver desktop
706 */
707 Session->ScreenSaverDesktop = CreateDesktop(L"Screen-Saver",
708 NULL,
709 NULL,
710 0, /* FIXME: Set some flags */
711 GENERIC_ALL,
712 NULL);
713 if(!Session->ScreenSaverDesktop)
714 {
715 DbgPrint("WL: Failed to create Screen-Saver desktop (0x%X)\n", GetLastError());
716 return FALSE;
717 }
718
719 return TRUE;
720 }
721