ReactOS 0.4.16-dev-1537-g4e425b5
wlx.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winlogon
4 * FILE: base/system/winlogon/wlx.c
5 * PURPOSE: Logon
6 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 * Ge van Geldorp (gvg@reactos.com)
8 * Herv� Poussineau (hpoussin@reactos.org)
9 */
10
11/* INCLUDES *****************************************************************/
12
13#include "winlogon.h"
14
15typedef struct _DIALOG_LIST_ENTRY
16{
22
23/* GLOBALS ******************************************************************/
24
25//static UINT_PTR IdTimer;
27
28/* FUNCTIONS ****************************************************************/
29
30VOID
32{
34}
35
36
37static
40{
41 PDIALOG_LIST_ENTRY ListEntry;
42
43 ListEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIALOG_LIST_ENTRY));
44 if (ListEntry == NULL)
45 return NULL;
46
47 TRACE("Add entry %p\n", ListEntry);
48
50 &ListEntry->Entry);
51
52 return ListEntry;
53}
54
55
56static
57VOID
59{
60 TRACE("Remove entry %p\n", ListEntry);
61
62 RemoveEntryList(&ListEntry->Entry);
63 RtlFreeHeap(RtlGetProcessHeap(), 0, ListEntry);
64}
65
66
67static
70{
71 PDIALOG_LIST_ENTRY Current;
72 PLIST_ENTRY ListEntry;
73
74 ListEntry = DialogListHead.Flink;
75 while (ListEntry != &DialogListHead)
76 {
77 Current = CONTAINING_RECORD(ListEntry,
79 Entry);
80 if (Current->hWnd == hwndDlg)
81 {
82 TRACE("Found entry: %p\n", Current);
83 return Current;
84 }
85
86 ListEntry = ListEntry->Flink;
87 }
88
89 TRACE("Found no entry!\n");
90 return NULL;
91}
92
93
94VOID
96{
97 PDIALOG_LIST_ENTRY Current;
98 PLIST_ENTRY ListEntry;
99
100 ListEntry = DialogListHead.Flink;
101 while (ListEntry != &DialogListHead)
102 {
103 Current = CONTAINING_RECORD(ListEntry,
105 Entry);
106
108
109 ListEntry = ListEntry->Flink;
110 }
111}
112
113
114static
118 IN HWND hwndDlg,
119 IN UINT uMsg,
122{
123 PDIALOG_LIST_ENTRY ListEntry;
124 INT_PTR ret;
125
126 if (uMsg == WM_INITDIALOG)
127 {
128 ListEntry = (PDIALOG_LIST_ENTRY)lParam;
129
130 TRACE("Set dialog handle: %p\n", hwndDlg);
131 ListEntry->hWnd = hwndDlg;
132 lParam = ListEntry->lParam;
133// SetTopTimeout(hWnd);
134 }
135 else
136 {
137 ListEntry = GetDialogListEntry(hwndDlg);
138 if (ListEntry == NULL)
139 return FALSE;
140 }
141
142 if (uMsg == WLX_WM_SAS)
143 {
144 /* Determine which result to return */
145 switch (wParam)
146 {
148 default:
150 break;
153 break;
156 break;
159 break;
160 }
161 EndDialog(hwndDlg, ret);
162 return TRUE;
163 }
164
165 ret = ListEntry->DlgProc(hwndDlg, uMsg, wParam, lParam);
166
167 return ret;
168
169/*
170 if (uMsg == WM_TIMER && (UINT_PTR)wParam == IdTimer)
171 {
172 EndDialog(hwndDlg, -1);
173 KillTimer(hwndDlg, IdTimer);
174 return TRUE;
175 }
176 else if (uMsg == WM_INITDIALOG)
177 {
178 IdTimer = SetTimer(hwndDlg, 0, WLSession->DialogTimeout * 1000, NULL);
179 return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
180 }
181 else if (uMsg == WM_NCDESTROY)
182 {
183 BOOL ret;
184 ret = PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
185 PreviousWindowProc = NULL;
186 return ret;
187 }
188 else
189 {
190 return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
191 }
192*/
193}
194
195/*
196 * @implemented
197 */
198VOID
199WINAPI
201 HANDLE hWlx)
202{
203 ULONG_PTR OldValue;
204
205 TRACE("WlxUseCtrlAltDel()\n");
206
208}
209
210/*
211 * @implemented
212 */
213VOID
214WINAPI
216 HANDLE hWlx,
217 PVOID pWlxContext)
218{
219 ULONG_PTR OldValue;
220
221 TRACE("WlxSetContextPointer(%p)\n", pWlxContext);
222
223 WlxSetOption(hWlx, WLX_OPTION_CONTEXT_POINTER, (ULONG_PTR)pWlxContext, &OldValue);
224}
225
226/*
227 * @implemented
228 */
229VOID
230WINAPI
232 HANDLE hWlx,
233 DWORD dwSasType)
234{
235 PWLSESSION Session = (PWLSESSION)hWlx;
236
237 TRACE("WlxSasNotify(0x%lx)\n", dwSasType);
238
239 if (dwSasType == WLX_SAS_TYPE_CTRL_ALT_DEL || dwSasType > WLX_SAS_TYPE_MAX_MSFT_VALUE)
240 PostMessageW(Session->SASWindow, WLX_WM_SAS, dwSasType, 0);
241}
242
243/*
244 * @implemented
245 */
246BOOL
247WINAPI
249 HANDLE hWlx,
251{
252 PWLSESSION Session = (PWLSESSION)hWlx;
253
254 TRACE("WlxSetTimeout(%lu)\n", Timeout);
255
256 Session->DialogTimeout = Timeout;
257 return TRUE;
258}
259
260/*
261 * @unimplemented
262 */
263int
264WINAPI
266 HANDLE hWlx,
267 HANDLE hToken,
270{
275
277 return 0;
278}
279
280/*
281 * @implemented
282 */
283int
284WINAPI
286 HANDLE hWlx,
287 HWND hwndOwner,
288 LPWSTR lpszText,
289 LPWSTR lpszTitle,
290 UINT fuStyle)
291{
293
294 TRACE("WlxMessageBox()\n");
295 /* FIXME: Provide a custom window proc to be able to handle timeout */
296 return MessageBoxW(hwndOwner, lpszText, lpszTitle, fuStyle);
297}
298
299/*
300 * @implemented
301 */
302int
303WINAPI
305 HANDLE hWlx,
307 LPWSTR lpszTemplate,
308 HWND hwndOwner,
309 DLGPROC dlgprc)
310{
312
313 TRACE("WlxDialogBox()\n");
314
315 return (int)WlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner, dlgprc, 0);
316}
317
318/*
319 * @implemented
320 */
321int
322WINAPI
324 HANDLE hWlx,
326 LPWSTR lpszTemplate,
327 HWND hwndOwner,
328 DLGPROC dlgprc,
329 LPARAM dwInitParam)
330{
331 PDIALOG_LIST_ENTRY ListEntry;
332 int ret;
333
335
336 TRACE("WlxDialogBoxParam()\n");
337
338 ListEntry = AddDialogListEntry();
339 if (ListEntry == NULL)
340 return -1;
341
342 ListEntry->DlgProc = dlgprc;
343 ListEntry->lParam = dwInitParam;
344
345 ret = (int)DialogBoxParamW(hInst, lpszTemplate, hwndOwner, DefaultWlxWindowProc, (LPARAM)ListEntry);
346
347 RemoveDialogListEntry(ListEntry);
348
349 return ret;
350}
351
352/*
353 * @implemented
354 */
355int
356WINAPI
358 HANDLE hWlx,
360 LPCDLGTEMPLATE hDialogTemplate,
361 HWND hwndOwner,
362 DLGPROC dlgprc)
363{
365
366 TRACE("WlxDialogBoxIndirect()\n");
367
368 return (int)WlxDialogBoxIndirectParam(hWlx, hInst, hDialogTemplate, hwndOwner, dlgprc, 0);
369}
370
371/*
372 * @implemented
373 */
374int
375WINAPI
377 HANDLE hWlx,
379 LPCDLGTEMPLATE hDialogTemplate,
380 HWND hwndOwner,
381 DLGPROC dlgprc,
382 LPARAM dwInitParam)
383{
384 PDIALOG_LIST_ENTRY ListEntry;
385 int ret;
386
388
389 TRACE("WlxDialogBoxIndirectParam()\n");
390
391 ListEntry = AddDialogListEntry();
392 if (ListEntry == NULL)
393 return -1;
394
395 ListEntry->DlgProc = dlgprc;
396 ListEntry->lParam = dwInitParam;
397
398 ret = (int)DialogBoxIndirectParamW(hInst, hDialogTemplate, hwndOwner, DefaultWlxWindowProc, (LPARAM)ListEntry);
399
400 RemoveDialogListEntry(ListEntry);
401
402 return ret;
403}
404
405/*
406 * @implemented
407 */
408int
409WINAPI
411 HANDLE hWlx)
412{
413 PWLSESSION Session = (PWLSESSION)hWlx;
414 BOOL bRet;
415
416 TRACE("WlxSwitchDesktopToUser()\n");
417
418 bRet = SwitchDesktop(Session->ApplicationDesktop);
419 if (bRet)
421 return (int)bRet;
422}
423
424/*
425 * @implemented
426 */
427int
428WINAPI
430 HANDLE hWlx)
431{
432 PWLSESSION Session = (PWLSESSION)hWlx;
433 BOOL bRet;
434
435 TRACE("WlxSwitchDesktopToWinlogon()\n");
436
437 bRet = SwitchDesktop(Session->WinlogonDesktop);
438 if (bRet)
440 return (int)bRet;
441}
442
443/*
444 * @unimplemented
445 */
446int
447WINAPI
449 HANDLE hWlx,
450 PWLX_MPR_NOTIFY_INFO pMprInfo,
451 DWORD dwChangeInfo)
452{
454 UNREFERENCED_PARAMETER(pMprInfo);
455 UNREFERENCED_PARAMETER(dwChangeInfo);
456
458 return 0;
459}
460
461/*
462 * @unimplemented
463 */
464BOOL
465WINAPI
467 HANDLE hWlx,
468 PWLX_DESKTOP* ppDesktop)
469{
471 UNREFERENCED_PARAMETER(ppDesktop);
472
474 return FALSE;
475}
476
477/*
478 * @unimplemented
479 */
480BOOL
481WINAPI
483 HANDLE hWlx,
484 PWLX_DESKTOP pDesktop)
485{
487 UNREFERENCED_PARAMETER(pDesktop);
488
490 return FALSE;
491}
492
493/*
494 * @unimplemented
495 */
496BOOL
497WINAPI
499 HANDLE hWlx,
500 HANDLE hToken,
501 DWORD Flags,
502 PWSTR pszDesktopName,
503 PWLX_DESKTOP* ppDesktop)
504{
508 UNREFERENCED_PARAMETER(pszDesktopName);
509 UNREFERENCED_PARAMETER(ppDesktop);
510
512 return FALSE;
513}
514
515/*
516 * @unimplemented
517 */
518int
519WINAPI
521 HANDLE hWlx,
522 PWLX_MPR_NOTIFY_INFO pMprInfo,
523 DWORD dwChangeInfo,
524 PWSTR ProviderName,
526{
528 UNREFERENCED_PARAMETER(pMprInfo);
529 UNREFERENCED_PARAMETER(dwChangeInfo);
530 UNREFERENCED_PARAMETER(ProviderName);
532
534 return 0;
535}
536
537/*
538 * @unimplemented
539 */
540BOOL
541WINAPI
543 HANDLE hWlx,
544 PWLX_DESKTOP pDesktop,
545 HANDLE hToken)
546{
548 UNREFERENCED_PARAMETER(pDesktop);
550
552 return FALSE;
553}
554
555/*
556 * @implemented
557 */
558BOOL
559WINAPI
561 HANDLE hWlx,
562 DWORD Option,
564 ULONG_PTR* OldValue)
565{
566 PWLSESSION Session = (PWLSESSION)hWlx;
567
568 TRACE("WlxSetOption(%lu)\n", Option);
569
570 switch (Option)
571 {
573 *OldValue = (ULONG_PTR)Session->Gina.UseCtrlAltDelete;
574 Session->Gina.UseCtrlAltDelete = (BOOL)Value;
575 return TRUE;
577 *OldValue = (ULONG_PTR)Session->Gina.Context;
578 Session->Gina.Context = (PVOID)Value;
579 return TRUE;
582 return FALSE;
583 }
584
585 return FALSE;
586}
587
588/*
589 * @implemented
590 */
591BOOL
592WINAPI
594 HANDLE hWlx,
595 DWORD Option,
597{
598 PWLSESSION Session = (PWLSESSION)hWlx;
599
600 TRACE("WlxGetOption(%lu)\n", Option);
601
602 switch (Option)
603 {
606 return TRUE;
608 {
609 *Value = (ULONG_PTR)Session->Gina.Context;
610 return TRUE;
611 }
616 return FALSE;
618 {
619 switch (Session->Gina.Version)
620 {
621 case WLX_VERSION_1_0:
623 break;
624 case WLX_VERSION_1_1:
626 break;
627 case WLX_VERSION_1_2:
629 break;
630 case WLX_VERSION_1_3:
632 break;
633 case WLX_VERSION_1_4:
635 break;
636 default:
637 return FALSE;
638 }
639 return TRUE;
640 }
641 }
642
643 return FALSE;
644}
645
646/*
647 * @unimplemented
648 */
649VOID
650WINAPI
652 HANDLE hWlx)
653{
655
657}
658
659/*
660 * @unimplemented
661 */
662BOOL
663WINAPI
666{
668
670 return FALSE;
671}
672
673/*
674 * @unimplemented
675 */
676BOOL
677WINAPI
680{
682
684 return FALSE;
685}
686
687/*
688 * @unimplemented
689 */
690BOOL
691WINAPI
693{
695 return FALSE;
696}
697
698/*
699 * @unimplemented
700 */
701DWORD
702WINAPI
704 HANDLE hWlx,
706 WCHAR* UserName,
707 WCHAR* Domain)
708{
710 UNREFERENCED_PARAMETER(pTSData);
711 UNREFERENCED_PARAMETER(UserName);
713
715 return 0;
716}
717
718/*
719 * @unimplemented
720 */
721DWORD
722WINAPI
725{
727
729 return 0;
730}
731
732/*
733 * @unimplemented
734 */
735BOOL
736WINAPI
739{
741
743 return FALSE;
744}
745
746static
775};
776
777/******************************************************************************/
778
779static
780BOOL
783 IN DWORD Len)
784{
785 LONG Status;
786 DWORD Type, Size;
787 HKEY hKey;
788
791 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
792 0,
794 &hKey);
795 if (Status != ERROR_SUCCESS)
796 {
797 /* Default value */
798 wcsncpy(Path, L"msgina.dll", Len);
799 return TRUE;
800 }
801
802 Size = Len * sizeof(WCHAR);
804 hKey,
805 L"GinaDLL",
806 NULL,
807 &Type,
808 (LPBYTE)Path,
809 &Size);
810 if (Status != ERROR_SUCCESS || Type != REG_SZ || Size == 0)
811 wcsncpy(Path, L"msgina.dll", Len);
813 return TRUE;
814}
815
816static
817BOOL
818WINAPI
820 IN PVOID pWlxContext,
821 IN OUT BOOL *pSecure)
822{
823 if (*pSecure)
824 *pSecure = WLSession->Gina.Functions.WlxIsLogoffOk(pWlxContext);
825 return TRUE;
826}
827
828static
829BOOL
831 IN OUT PGINAFUNCTIONS Functions,
832 OUT DWORD *DllVersion,
833 OUT HMODULE *GinaInstance)
834{
835 HMODULE hGina = NULL;
836 WCHAR GinaDll[MAX_PATH + 1];
837 BOOL ret = FALSE;
838
839 GinaDll[0] = '\0';
840 if (!GetGinaPath(GinaDll, MAX_PATH))
841 goto cleanup;
842 /* Terminate string */
843 GinaDll[MAX_PATH] = '\0';
844
845 hGina = LoadLibraryW(GinaDll);
846 if (!hGina)
847 goto cleanup;
848
849 Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate");
850 Functions->WlxInitialize = (PFWLXINITIALIZE)GetProcAddress(hGina, "WlxInitialize");
851
852 if (!Functions->WlxInitialize)
853 goto cleanup;
854
855 if (!Functions->WlxNegotiate)
856 {
857 /* Assume current version */
858 *DllVersion = WLX_CURRENT_VERSION;
859 }
860 else
861 {
862 TRACE("About to negotiate with Gina %S. Winlogon uses version %x\n",
863 GinaDll, WLX_CURRENT_VERSION);
864 if (!Functions->WlxNegotiate(WLX_CURRENT_VERSION, DllVersion))
865 goto cleanup;
866 }
867
868 TRACE("Gina uses WLX_VERSION %lx\n", *DllVersion);
869
870 if (*DllVersion >= WLX_VERSION_1_0)
871 {
872 Functions->WlxActivateUserShell = (PFWLXACTIVATEUSERSHELL)GetProcAddress(hGina, "WlxActivateUserShell");
873 if (!Functions->WlxActivateUserShell) goto cleanup;
874 Functions->WlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hGina, "WlxDisplayLockedNotice");
875 if (!Functions->WlxDisplayLockedNotice) goto cleanup;
876 Functions->WlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE)GetProcAddress(hGina, "WlxDisplaySASNotice");
877 if (!Functions->WlxDisplaySASNotice) goto cleanup;
878 Functions->WlxIsLockOk = (PFWLXISLOCKOK)GetProcAddress(hGina, "WlxIsLockOk");
879 if (!Functions->WlxIsLockOk) goto cleanup;
880 Functions->WlxIsLogoffOk = (PFWLXISLOGOFFOK)GetProcAddress(hGina, "WlxIsLogoffOk");
881 if (!Functions->WlxIsLogoffOk) goto cleanup;
882 Functions->WlxLoggedOnSAS = (PFWLXLOGGEDONSAS)GetProcAddress(hGina, "WlxLoggedOnSAS");
883 if (!Functions->WlxLoggedOnSAS) goto cleanup;
884 Functions->WlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS)GetProcAddress(hGina, "WlxLoggedOutSAS");
885 if (!Functions->WlxLoggedOutSAS) goto cleanup;
886 Functions->WlxLogoff = (PFWLXLOGOFF)GetProcAddress(hGina, "WlxLogoff");
887 if (!Functions->WlxLogoff) goto cleanup;
888 Functions->WlxShutdown = (PFWLXSHUTDOWN)GetProcAddress(hGina, "WlxShutdown");
889 if (!Functions->WlxShutdown) goto cleanup;
890 Functions->WlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS)GetProcAddress(hGina, "WlxWkstaLockedSAS");
891 if (!Functions->WlxWkstaLockedSAS) goto cleanup;
892 }
893
894 if (*DllVersion >= WLX_VERSION_1_1)
895 {
896 Functions->WlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY)GetProcAddress(hGina, "WlxScreenSaverNotify");
897 Functions->WlxStartApplication = (PFWLXSTARTAPPLICATION)GetProcAddress(hGina, "WlxStartApplication");
898 }
899
900 if (*DllVersion >= WLX_VERSION_1_3)
901 {
902 Functions->WlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE)GetProcAddress(hGina, "WlxDisplayStatusMessage");
903 if (!Functions->WlxDisplayStatusMessage) goto cleanup;
904 Functions->WlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE)GetProcAddress(hGina, "WlxGetStatusMessage");
905 if (!Functions->WlxGetStatusMessage) goto cleanup;
906 Functions->WlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD)GetProcAddress(hGina, "WlxNetworkProviderLoad");
907 if (!Functions->WlxNetworkProviderLoad) goto cleanup;
908 Functions->WlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE)GetProcAddress(hGina, "WlxRemoveStatusMessage");
909 if (!Functions->WlxRemoveStatusMessage) goto cleanup;
910 }
911
912 /* Provide some default functions */
913 if (!Functions->WlxScreenSaverNotify)
914 Functions->WlxScreenSaverNotify = DefaultWlxScreenSaverNotify;
915
916 ret = TRUE;
917
918cleanup:
919 if (!ret)
920 {
921 if (hGina)
922 FreeLibrary(hGina);
923 }
924 else
925 *GinaInstance = hGina;
926 return ret;
927}
928
929BOOL
931 IN OUT PWLSESSION Session)
932{
933 DWORD GinaDllVersion;
934
935 if (!LoadGina(&Session->Gina.Functions, &GinaDllVersion, &Session->Gina.hDllInstance))
936 return FALSE;
937
938 Session->Gina.Context = NULL;
939 Session->Gina.Version = GinaDllVersion;
940 Session->Gina.UseCtrlAltDelete = FALSE;
941 Session->SuppressStatus = FALSE;
942
943 TRACE("Calling WlxInitialize(\"%S\")\n", Session->InteractiveWindowStationName);
944 return Session->Gina.Functions.WlxInitialize(
945 Session->InteractiveWindowStationName,
946 (HANDLE)Session,
947 NULL,
949 &Session->Gina.Context);
950}
951
952BOOL
954 _Inout_ PWLSESSION Session)
955{
956 SECURITY_ATTRIBUTES WinstaSecurity;
957 SECURITY_ATTRIBUTES ApplicationDesktopSecurity;
958 SECURITY_ATTRIBUTES WinlogonDesktopSecurity;
959 SECURITY_ATTRIBUTES ScreenSaverDesktopSecurity;
960 PSECURITY_DESCRIPTOR WlWinstaSecurityDescriptor;
961 PSECURITY_DESCRIPTOR WlApplicationDesktopSecurityDescriptor;
962 PSECURITY_DESCRIPTOR WlWinlogonDesktopSecurityDescriptor;
963 PSECURITY_DESCRIPTOR WlScreenSaverDesktopSecurityDescriptor;
964 BOOL ret = FALSE;
965
966 if (!CreateWinstaSecurity(&WlWinstaSecurityDescriptor))
967 {
968 ERR("WL: Failed to create winsta security!\n");
969 return ret;
970 }
971
972 WinstaSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
973 WinstaSecurity.lpSecurityDescriptor = WlWinstaSecurityDescriptor;
974 WinstaSecurity.bInheritHandle = TRUE;
975
976 if (!CreateApplicationDesktopSecurity(&WlApplicationDesktopSecurityDescriptor))
977 {
978 ERR("WL: Failed to create application desktop security!\n");
979 goto cleanup;
980 }
981
982 ApplicationDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
983 ApplicationDesktopSecurity.lpSecurityDescriptor = WlApplicationDesktopSecurityDescriptor;
984 ApplicationDesktopSecurity.bInheritHandle = TRUE;
985
986 if (!CreateWinlogonDesktopSecurity(&WlWinlogonDesktopSecurityDescriptor))
987 {
988 ERR("WL: Failed to create winlogon desktop security!\n");
989 goto cleanup;
990 }
991
992 WinlogonDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
993 WinlogonDesktopSecurity.lpSecurityDescriptor = WlWinlogonDesktopSecurityDescriptor;
994 WinlogonDesktopSecurity.bInheritHandle = FALSE;
995
996 if (!CreateScreenSaverSecurity(&WlScreenSaverDesktopSecurityDescriptor))
997 {
998 ERR("WL: Failed to create winlogon desktop security!\n");
999 goto cleanup;
1000 }
1001
1002 ScreenSaverDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
1003 ScreenSaverDesktopSecurity.lpSecurityDescriptor = WlScreenSaverDesktopSecurityDescriptor;
1004 ScreenSaverDesktopSecurity.bInheritHandle = TRUE;
1005
1006 /*
1007 * Create the interactive window station
1008 */
1009 Session->InteractiveWindowStationName = L"WinSta0";
1010 Session->InteractiveWindowStation = CreateWindowStationW(
1011 Session->InteractiveWindowStationName,
1012 0,
1014 &WinstaSecurity);
1015 if (!Session->InteractiveWindowStation)
1016 {
1017 ERR("WL: Failed to create window station (%lu)\n", GetLastError());
1018 goto cleanup;
1019 }
1020
1021 if (!SetProcessWindowStation(Session->InteractiveWindowStation))
1022 {
1023 ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError());
1024 goto cleanup;
1025 }
1026
1027 /*
1028 * Create the application desktop
1029 */
1030 Session->ApplicationDesktop = CreateDesktopW(
1031 L"Default",
1032 NULL,
1033 NULL,
1034 0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */
1036 &ApplicationDesktopSecurity);
1037 if (!Session->ApplicationDesktop)
1038 {
1039 ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError());
1040 goto cleanup;
1041 }
1042
1043 /*
1044 * Create the winlogon desktop
1045 */
1046 Session->WinlogonDesktop = CreateDesktopW(
1047 L"Winlogon",
1048 NULL,
1049 NULL,
1050 0,
1052 &WinlogonDesktopSecurity);
1053 if (!Session->WinlogonDesktop)
1054 {
1055 ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError());
1056 goto cleanup;
1057 }
1058
1059 /*
1060 * Create the screen saver desktop
1061 */
1062 Session->ScreenSaverDesktop = CreateDesktopW(
1063 L"Screen-Saver",
1064 NULL,
1065 NULL,
1066 0,
1068 &ScreenSaverDesktopSecurity);
1069 if(!Session->ScreenSaverDesktop)
1070 {
1071 ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError());
1072 goto cleanup;
1073 }
1074
1075 /*
1076 * Switch to winlogon desktop
1077 */
1078 if (!SetThreadDesktop(Session->WinlogonDesktop) ||
1079 !SwitchDesktop(Session->WinlogonDesktop))
1080 {
1081 ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError());
1082 goto cleanup;
1083 }
1084
1085 SetWindowStationUser(Session->InteractiveWindowStation,
1086 &LuidNone, NULL, 0);
1087
1088 ret = TRUE;
1089
1090cleanup:
1091 if (!ret)
1092 {
1093 if (Session->ApplicationDesktop)
1094 {
1095 CloseDesktop(Session->ApplicationDesktop);
1096 Session->ApplicationDesktop = NULL;
1097 }
1098 if (Session->WinlogonDesktop)
1099 {
1100 CloseDesktop(Session->WinlogonDesktop);
1101 Session->WinlogonDesktop = NULL;
1102 }
1103 if (Session->ScreenSaverDesktop)
1104 {
1105 CloseDesktop(Session->ScreenSaverDesktop);
1106 Session->ScreenSaverDesktop = NULL;
1107 }
1108 if (Session->InteractiveWindowStation)
1109 {
1110 CloseWindowStation(Session->InteractiveWindowStation);
1111 Session->InteractiveWindowStation = NULL;
1112 }
1113 if (WlWinstaSecurityDescriptor)
1114 {
1115 RtlFreeHeap(RtlGetProcessHeap(), 0, WlWinstaSecurityDescriptor);
1116 }
1117 if (WlApplicationDesktopSecurityDescriptor)
1118 {
1119 RtlFreeHeap(RtlGetProcessHeap(), 0, WlApplicationDesktopSecurityDescriptor);
1120 }
1121 if (WlWinlogonDesktopSecurityDescriptor)
1122 {
1123 RtlFreeHeap(RtlGetProcessHeap(), 0, WlWinlogonDesktopSecurityDescriptor);
1124 }
1125 if (WlScreenSaverDesktopSecurityDescriptor)
1126 {
1127 RtlFreeHeap(RtlGetProcessHeap(), 0, WlScreenSaverDesktopSecurityDescriptor);
1128 }
1129 }
1130
1131 return ret;
1132}
PRTL_UNICODE_STRING_BUFFER Path
Type
Definition: Type.h:7
#define ERR(fmt,...)
Definition: precomp.h:57
BOOL CreateApplicationDesktopSecurity(_Out_ PSECURITY_DESCRIPTOR *ApplicationDesktopSd)
Creates a security descriptor for the default application desktop upon its creation.
Definition: security.c:359
BOOL CreateWinstaSecurity(_Out_ PSECURITY_DESCRIPTOR *WinstaSd)
Creates a security descriptor for the default window station upon its creation.
Definition: security.c:112
BOOL CreateWinlogonDesktopSecurity(_Out_ PSECURITY_DESCRIPTOR *WinlogonDesktopSd)
Creates a security descriptor for the default Winlogon desktop. This descriptor serves as a security ...
Definition: security.c:541
BOOL CreateScreenSaverSecurity(_Out_ PSECURITY_DESCRIPTOR *ScreenSaverDesktopSd)
Creates a security descriptor for the screen saver desktop.
Definition: security.c:690
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
#define RegCloseKey(hKey)
Definition: registry.h:49
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
wcsncpy
#define Len
Definition: deflate.h:82
#define DLGPROC
Definition: maze.c:62
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
#define GetProcAddress(x, y)
Definition: compat.h:753
#define FreeLibrary(x)
Definition: compat.h:748
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
#define LoadLibraryW(x)
Definition: compat.h:747
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static void cleanup(void)
Definition: main.c:1335
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
#define ULONG_PTR
Definition: config.h:101
HINSTANCE hInst
Definition: dxdiag.c:13
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertHeadList(ListHead, Entry)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
#define REG_SZ
Definition: layer.c:22
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:28
#define _Inout_
Definition: no_sal2.h:162
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
long LONG
Definition: pedump.c:60
static ULONG Timeout
Definition: ping.c:61
LUID LuidNone
Definition: sas.c:49
#define TRACE(s)
Definition: solgame.cpp:4
base of all file and directory entries
Definition: entries.h:83
Definition: wlx.c:16
HWND hWnd
Definition: wlx.c:18
LIST_ENTRY Entry
Definition: wlx.c:17
DLGPROC DlgProc
Definition: wlx.c:19
LPARAM lParam
Definition: wlx.c:20
PFWLXISLOGOFFOK WlxIsLogoffOk
Definition: winlogon.h:107
PVOID Context
Definition: winlogon.h:130
GINAFUNCTIONS Functions
Definition: winlogon.h:129
BOOL UseCtrlAltDelete
Definition: winlogon.h:132
DWORD Version
Definition: winlogon.h:131
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LPVOID lpSecurityDescriptor
Definition: compat.h:193
DWORD DialogTimeout
Definition: winlogon.h:238
HDESK WinlogonDesktop
Definition: winlogon.h:232
HWND SASWindow
Definition: winlogon.h:228
GINAINSTANCE Gina
Definition: winlogon.h:222
HDESK ApplicationDesktop
Definition: winlogon.h:231
uint16_t * PWSTR
Definition: typedefs.h:56
int32_t INT_PTR
Definition: typedefs.h:64
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define OUT
Definition: typedefs.h:40
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
HDESK WINAPI CreateDesktopW(LPCWSTR lpszDesktop, LPCWSTR lpszDevice, LPDEVMODEW pDevmode, DWORD dwFlags, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa)
Definition: desktop.c:473
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
PWLSESSION WLSession
Definition: winlogon.c:20
int(WINAPI * PFWLXWKSTALOCKEDSAS)(PVOID, DWORD)
Definition: winlogon.h:75
VOID(WINAPI * PFWLXDISPLAYLOCKEDNOTICE)(PVOID)
Definition: winlogon.h:74
int(WINAPI * PFWLXLOGGEDOUTSAS)(PVOID, DWORD, PLUID, PSID, PDWORD, PHANDLE, PWLX_MPR_NOTIFY_INFO, PVOID *)
Definition: winlogon.h:69
BOOL(WINAPI * PFWLXNEGOTIATE)(DWORD, DWORD *)
Definition: winlogon.h:66
VOID(WINAPI * PFWLXSHUTDOWN)(PVOID, DWORD)
Definition: winlogon.h:79
BOOL WINAPI SetWindowStationUser(IN HWINSTA hWindowStation, IN PLUID pluid, IN PSID psid OPTIONAL, IN DWORD size)
Definition: winsta.c:419
BOOL(WINAPI * PFWLXISLOGOFFOK)(PVOID)
Definition: winlogon.h:77
VOID(WINAPI * PFWLXLOGOFF)(PVOID)
Definition: winlogon.h:78
BOOL(WINAPI * PFWLXREMOVESTATUSMESSAGE)(PVOID)
Definition: winlogon.h:91
BOOL(WINAPI * PFWLXSTARTAPPLICATION)(PVOID, PWSTR, PVOID, PWSTR)
Definition: winlogon.h:84
BOOL(WINAPI * PFWLXINITIALIZE)(LPWSTR, HANDLE, PVOID, PVOID, PVOID *)
Definition: winlogon.h:67
BOOL(WINAPI * PFWLXSCREENSAVERNOTIFY)(PVOID, BOOL *)
Definition: winlogon.h:83
struct _WLSESSION * PWLSESSION
BOOL(WINAPI * PFWLXNETWORKPROVIDERLOAD)(PVOID, PWLX_MPR_NOTIFY_INFO)
Definition: winlogon.h:88
BOOL(WINAPI * PFWLXGETSTATUSMESSAGE)(PVOID, DWORD *, PWSTR, DWORD)
Definition: winlogon.h:90
BOOL(WINAPI * PFWLXISLOCKOK)(PVOID)
Definition: winlogon.h:76
BOOL(WINAPI * PFWLXDISPLAYSTATUSMESSAGE)(PVOID, HDESK, DWORD, PWSTR, PWSTR)
Definition: winlogon.h:89
VOID(WINAPI * PFWLXDISPLAYSASNOTICE)(PVOID)
Definition: winlogon.h:68
int(WINAPI * PFWLXLOGGEDONSAS)(PVOID, DWORD, PVOID)
Definition: winlogon.h:73
BOOL(WINAPI * PFWLXACTIVATEUSERSHELL)(PVOID, PWSTR, PWSTR, PVOID)
Definition: winlogon.h:72
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
INT_PTR WINAPI DialogBoxIndirectParamW(_In_opt_ HINSTANCE, _In_ LPCDLGTEMPLATE, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
BOOL WINAPI SwitchDesktop(_In_ HDESK)
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI SetThreadDesktop(_In_ HDESK)
HWINSTA WINAPI CreateWindowStationW(_In_opt_ LPCWSTR lpwinsta, _In_ DWORD dwFlags, _In_ ACCESS_MASK dwDesiredAccess, _In_opt_ LPSECURITY_ATTRIBUTES lpsa)
BOOL WINAPI CloseWindowStation(_In_ HWINSTA)
#define WM_INITDIALOG
Definition: winuser.h:1767
BOOL WINAPI SetProcessWindowStation(_In_ HWINSTA)
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define PostMessage
Definition: winuser.h:5943
BOOL WINAPI CloseDesktop(_In_ HDESK)
INT_PTR WINAPI DialogBoxParamW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
#define WLX_SAS_TYPE_TIMEOUT
Definition: winwlx.h:35
#define WLX_OPTION_USE_CTRL_ALT_DEL
Definition: winwlx.h:322
#define WLX_SAS_TYPE_CTRL_ALT_DEL
Definition: winwlx.h:36
#define WLX_DLG_SAS
Definition: winwlx.h:73
#define WLX_VERSION_1_1
Definition: winwlx.h:29
#define WLX_WM_SAS
Definition: winwlx.h:71
#define WLX_SAS_TYPE_SCRNSVR_TIMEOUT
Definition: winwlx.h:37
#define WLX_CURRENT_VERSION
Definition: winwlx.h:33
#define WLX_VERSION_1_3
Definition: winwlx.h:31
struct _WLX_DISPATCH_VERSION_1_3 WLX_DISPATCH_VERSION_1_3
#define WLX_OPTION_USE_SMART_CARD
Definition: winwlx.h:324
#define WLX_SAS_TYPE_USER_LOGOFF
Definition: winwlx.h:39
#define WLX_DLG_USER_LOGOFF
Definition: winwlx.h:76
#define WLX_VERSION_1_4
Definition: winwlx.h:32
#define WLX_OPTION_SMART_CARD_PRESENT
Definition: winwlx.h:329
#define WLX_OPTION_DISPATCH_TABLE_SIZE
Definition: winwlx.h:331
#define WLX_VERSION_1_2
Definition: winwlx.h:30
struct _WLX_DISPATCH_VERSION_1_0 WLX_DISPATCH_VERSION_1_0
struct _WLX_DISPATCH_VERSION_1_1 WLX_DISPATCH_VERSION_1_1
struct _WLX_DISPATCH_VERSION_1_2 WLX_DISPATCH_VERSION_1_2
#define WLX_OPTION_CONTEXT_POINTER
Definition: winwlx.h:323
#define WLX_VERSION_1_0
Definition: winwlx.h:28
#define WLX_OPTION_SMART_CARD_INFO
Definition: winwlx.h:330
struct _WLX_DISPATCH_VERSION_1_4 WLX_DISPATCH_VERSION_1_4
#define WLX_DLG_SCREEN_SAVER_TIMEOUT
Definition: winwlx.h:75
#define WLX_SAS_TYPE_MAX_MSFT_VALUE
Definition: winwlx.h:46
#define WLX_DLG_INPUT_TIMEOUT
Definition: winwlx.h:74
static VOID RemoveDialogListEntry(PDIALOG_LIST_ENTRY ListEntry)
Definition: wlx.c:58
BOOL WINAPI WlxCloseUserDesktop(HANDLE hWlx, PWLX_DESKTOP pDesktop, HANDLE hToken)
Definition: wlx.c:542
DWORD WINAPI WlxQueryConsoleSwitchCredentials(PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred)
Definition: wlx.c:723
int WINAPI WlxDialogBoxParam(HANDLE hWlx, HANDLE hInst, LPWSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc, LPARAM dwInitParam)
Definition: wlx.c:323
BOOL WINAPI WlxCreateUserDesktop(HANDLE hWlx, HANDLE hToken, DWORD Flags, PWSTR pszDesktopName, PWLX_DESKTOP *ppDesktop)
Definition: wlx.c:498
int WINAPI WlxAssignShellProtection(HANDLE hWlx, HANDLE hToken, HANDLE hProcess, HANDLE hThread)
Definition: wlx.c:265
static PDIALOG_LIST_ENTRY AddDialogListEntry(VOID)
Definition: wlx.c:39
int WINAPI WlxDialogBoxIndirectParam(HANDLE hWlx, HANDLE hInst, LPCDLGTEMPLATE hDialogTemplate, HWND hwndOwner, DLGPROC dlgprc, LPARAM dwInitParam)
Definition: wlx.c:376
struct _DIALOG_LIST_ENTRY * PDIALOG_LIST_ENTRY
BOOL WINAPI WlxSetTimeout(HANDLE hWlx, DWORD Timeout)
Definition: wlx.c:248
BOOL WINAPI WlxSetOption(HANDLE hWlx, DWORD Option, ULONG_PTR Value, ULONG_PTR *OldValue)
Definition: wlx.c:560
static WLX_DISPATCH_VERSION_1_4 FunctionTable
Definition: wlx.c:747
DWORD WINAPI WlxQueryTerminalServicesData(HANDLE hWlx, PWLX_TERMINAL_SERVICES_DATA pTSData, WCHAR *UserName, WCHAR *Domain)
Definition: wlx.c:703
struct _DIALOG_LIST_ENTRY DIALOG_LIST_ENTRY
int WINAPI WlxSwitchDesktopToUser(HANDLE hWlx)
Definition: wlx.c:410
BOOL WINAPI WlxQueryClientCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred)
Definition: wlx.c:664
static PDIALOG_LIST_ENTRY GetDialogListEntry(HWND hwndDlg)
Definition: wlx.c:69
int WINAPI WlxChangePasswordNotifyEx(HANDLE hWlx, PWLX_MPR_NOTIFY_INFO pMprInfo, DWORD dwChangeInfo, PWSTR ProviderName, PVOID Reserved)
Definition: wlx.c:520
VOID WINAPI WlxSasNotify(HANDLE hWlx, DWORD dwSasType)
Definition: wlx.c:231
static BOOL LoadGina(IN OUT PGINAFUNCTIONS Functions, OUT DWORD *DllVersion, OUT HMODULE *GinaInstance)
Definition: wlx.c:830
int WINAPI WlxDialogBoxIndirect(HANDLE hWlx, HANDLE hInst, LPCDLGTEMPLATE hDialogTemplate, HWND hwndOwner, DLGPROC dlgprc)
Definition: wlx.c:357
BOOL GinaInit(IN OUT PWLSESSION Session)
Definition: wlx.c:930
VOID WINAPI WlxWin31Migrate(HANDLE hWlx)
Definition: wlx.c:651
VOID WINAPI WlxUseCtrlAltDel(HANDLE hWlx)
Definition: wlx.c:200
int WINAPI WlxChangePasswordNotify(HANDLE hWlx, PWLX_MPR_NOTIFY_INFO pMprInfo, DWORD dwChangeInfo)
Definition: wlx.c:448
BOOL WINAPI WlxQueryTsLogonCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred)
Definition: wlx.c:737
BOOL WINAPI WlxDisconnect(VOID)
Definition: wlx.c:692
BOOL WINAPI WlxGetOption(HANDLE hWlx, DWORD Option, ULONG_PTR *Value)
Definition: wlx.c:593
VOID WINAPI WlxSetContextPointer(HANDLE hWlx, PVOID pWlxContext)
Definition: wlx.c:215
static LIST_ENTRY DialogListHead
Definition: wlx.c:26
static BOOL GetGinaPath(OUT LPWSTR Path, IN DWORD Len)
Definition: wlx.c:781
static BOOL WINAPI DefaultWlxScreenSaverNotify(IN PVOID pWlxContext, IN OUT BOOL *pSecure)
Definition: wlx.c:819
VOID InitDialogListHead(VOID)
Definition: wlx.c:31
int WINAPI WlxSwitchDesktopToWinlogon(HANDLE hWlx)
Definition: wlx.c:429
int WINAPI WlxDialogBox(HANDLE hWlx, HANDLE hInst, LPWSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc)
Definition: wlx.c:304
static INT_PTR CALLBACK DefaultWlxWindowProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
Definition: wlx.c:117
BOOL WINAPI WlxGetSourceDesktop(HANDLE hWlx, PWLX_DESKTOP *ppDesktop)
Definition: wlx.c:466
BOOL CreateWindowStationAndDesktops(_Inout_ PWLSESSION Session)
Definition: wlx.c:953
VOID CloseAllDialogWindows(VOID)
Definition: wlx.c:95
int WINAPI WlxMessageBox(HANDLE hWlx, HWND hwndOwner, LPWSTR lpszText, LPWSTR lpszTitle, UINT fuStyle)
Definition: wlx.c:285
BOOL WINAPI WlxQueryInetConnectorCredentials(PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred)
Definition: wlx.c:678
BOOL WINAPI WlxSetReturnDesktop(HANDLE hWlx, PWLX_DESKTOP pDesktop)
Definition: wlx.c:482
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184