Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

server.c

Go to the documentation of this file.
00001 /**************************************************************************\ 00002 * Module Name: server.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Server support routines for the CSR stuff. This basically performs the 00007 * startup/initialization for USER. 00008 * 00009 \**************************************************************************/ 00010 00011 #include "precomp.h" 00012 #pragma hdrstop 00013 00014 extern WORD gDispatchTableValues; 00015 00016 BOOL gbUserInitialized; 00017 00018 /* 00019 * Initialization Routines (external). 00020 */ 00021 NTSTATUS InitQEntryLookaside(VOID); 00022 NTSTATUS InitSMSLookaside(VOID); 00023 00024 NTSTATUS InitCreateSharedSection(VOID); 00025 NTSTATUS InitCreateObjectDirectory(VOID); 00026 BOOL InitCreateUserSubsystem(VOID); 00027 VOID InitFunctionTables(VOID); 00028 VOID InitMessageTables(VOID); 00029 VOID InitWindowMsgTable(PBYTE*, PUINT, CONST WORD*); 00030 00031 VOID VerifySyncOnlyMessages(VOID); 00032 BOOL InitOLEFormats(VOID); 00033 NTSTATUS Win32UserInitialize(VOID); 00034 00035 #pragma alloc_text(INIT, InitCreateSharedSection) 00036 #pragma alloc_text(INIT, InitCreateUserCrit) 00037 #pragma alloc_text(INIT, InitCreateObjectDirectory) 00038 #pragma alloc_text(INIT, InitCreateUserSubsystem) 00039 //#pragma alloc_text(INIT, InitDbgTags) 00040 #pragma alloc_text(INIT, InitFunctionTables) 00041 #pragma alloc_text(INIT, InitMessageTables) 00042 #pragma alloc_text(INIT, InitWindowMsgTable) 00043 00044 #pragma alloc_text(INIT, VerifySyncOnlyMessages) 00045 #pragma alloc_text(INIT, InitOLEFormats) 00046 #pragma alloc_text(INIT, Win32UserInitialize) 00047 00048 /* 00049 * Constants pertaining to the user-initialization. 00050 */ 00051 #define USRINIT_SHAREDSECT_SIZE 32 00052 #define USRINIT_ATOMBUCKET_SIZE 37 00053 00054 #define USRINIT_WINDOWSECT_SIZE 512 00055 #define USRINIT_NOIOSECT_SIZE 128 00056 00057 #define USRINIT_SHAREDSECT_BUFF_SIZE 640 00058 #define USRINIT_SHAREDSECT_READ_SIZE (USRINIT_SHAREDSECT_BUFF_SIZE-33) 00059 00060 00061 /***************************************************************************\ 00062 * Globals stored in the INIT section. These should only be accessed at 00063 * load time! 00064 \***************************************************************************/ 00065 #ifdef ALLOC_DATA_PRAGMA 00066 #pragma data_seg("INIT$Data") 00067 #endif 00068 00069 CONST WCHAR szCHECKPOINT_PROP_NAME[] = L"SysCP"; 00070 CONST WCHAR szDDETRACK_PROP_NAME[] = L"SysDT"; 00071 CONST WCHAR szQOS_PROP_NAME[] = L"SysQOS"; 00072 CONST WCHAR szDDEIMP_PROP_NAME[] = L"SysDDEI"; 00073 CONST WCHAR szWNDOBJ_PROP_NAME[] = L"SysWNDO"; 00074 CONST WCHAR szIMELEVEL_PROP_NAME[] = L"SysIMEL"; 00075 CONST WCHAR szLAYER_PROP_NAME[] = L"SysLayer"; 00076 CONST WCHAR szUSER32[] = L"USER32"; 00077 CONST WCHAR szMESSAGE[] = L"Message"; 00078 CONST WCHAR szCONTEXTHELPIDPROP[] = L"SysCH"; 00079 CONST WCHAR szICONSM_PROP_NAME[] = L"SysICS"; 00080 CONST WCHAR szICON_PROP_NAME[] = ICON_PROP_NAME; 00081 CONST WCHAR szSHELLHOOK[] = L"SHELLHOOK"; 00082 CONST WCHAR szACTIVATESHELLWINDOW[] = L"ACTIVATESHELLWINDOW"; 00083 CONST WCHAR szOTHERWINDOWCREATED[] = L"OTHERWINDOWCREATED"; 00084 CONST WCHAR szOTHERWINDOWDESTROYED[] = L"OTHERWINDOWDESTROYED"; 00085 CONST WCHAR szOLEMAINTHREADWNDCLASS[] = L"OleMainThreadWndClass"; 00086 CONST WCHAR szFLASHWSTATE[] = L"FlashWState"; 00087 00088 #ifdef HUNGAPP_GHOSTING 00089 CONST WCHAR szGHOST[] = L"Ghost"; 00090 #endif // HUNGAPP_GHOSTING 00091 00092 00093 /***************************************************************************\ 00094 * Message Tables 00095 * 00096 * DefDlgProc 00097 * MenuWndProc 00098 * ScrollBarWndProc 00099 * StaticWndProc 00100 * ButtonWndProc 00101 * ListboxWndProc 00102 * ComboWndProc 00103 * EditWndProc 00104 * DefWindowMsgs 00105 * DefWindowSpecMsgs 00106 * 00107 * These are used in InitMessageTables() to initialize gSharedInfo.awmControl[] 00108 * using the INITMSGTABLE() macro. 00109 * 00110 * 25-Aug-1995 ChrisWil Created comment block. 00111 \***************************************************************************/ 00112 00113 CONST WORD gawDefDlgProc[] = { 00114 WM_COMPAREITEM, 00115 WM_VKEYTOITEM, 00116 WM_CHARTOITEM, 00117 WM_INITDIALOG, 00118 WM_QUERYDRAGICON, 00119 WM_CTLCOLOR, 00120 WM_CTLCOLORMSGBOX, 00121 WM_CTLCOLOREDIT, 00122 WM_CTLCOLORLISTBOX, 00123 WM_CTLCOLORBTN, 00124 WM_CTLCOLORDLG, 00125 WM_CTLCOLORSCROLLBAR, 00126 WM_CTLCOLORSTATIC, 00127 WM_ERASEBKGND, 00128 WM_SHOWWINDOW, 00129 WM_SYSCOMMAND, 00130 WM_SYSKEYDOWN, 00131 WM_ACTIVATE, 00132 WM_SETFOCUS, 00133 WM_CLOSE, 00134 WM_NCDESTROY, 00135 WM_FINALDESTROY, 00136 DM_REPOSITION, 00137 DM_SETDEFID, 00138 DM_GETDEFID, 00139 WM_NEXTDLGCTL, 00140 WM_ENTERMENULOOP, 00141 WM_LBUTTONDOWN, 00142 WM_NCLBUTTONDOWN, 00143 WM_GETFONT, 00144 WM_NOTIFYFORMAT, 00145 WM_INPUTLANGCHANGEREQUEST, 00146 0 00147 }; 00148 00149 CONST WORD gawMenuWndProc[] = { 00150 WM_NCCREATE, 00151 WM_FINALDESTROY, 00152 WM_PAINT, 00153 WM_NCCALCSIZE, 00154 WM_CHAR, 00155 WM_SYSCHAR, 00156 WM_KEYDOWN, 00157 WM_SYSKEYDOWN, 00158 WM_TIMER, 00159 MN_SETHMENU, 00160 MN_SIZEWINDOW, 00161 MN_OPENHIERARCHY, 00162 MN_CLOSEHIERARCHY, 00163 MN_SELECTITEM, 00164 MN_SELECTFIRSTVALIDITEM, 00165 MN_CANCELMENUS, 00166 MN_FINDMENUWINDOWFROMPOINT, 00167 MN_SHOWPOPUPWINDOW, 00168 MN_BUTTONDOWN, 00169 MN_MOUSEMOVE, 00170 MN_BUTTONUP, 00171 MN_SETTIMERTOOPENHIERARCHY, 00172 WM_ACTIVATE, 00173 MN_GETHMENU, 00174 MN_DBLCLK, 00175 MN_ACTIVATEPOPUP, 00176 MN_ENDMENU, 00177 MN_DODRAGDROP, 00178 WM_ACTIVATEAPP, 00179 WM_MOUSELEAVE, 00180 WM_SIZE, 00181 WM_MOVE, 00182 WM_NCHITTEST, 00183 WM_NCPAINT, 00184 WM_PRINT, 00185 WM_PRINTCLIENT, 00186 WM_ERASEBKGND, 00187 WM_WINDOWPOSCHANGING, 00188 WM_WINDOWPOSCHANGED, 00189 0 00190 }; 00191 00192 CONST WORD gawDesktopWndProc[] = { 00193 WM_PAINT, 00194 WM_ERASEBKGND, 00195 0 00196 }; 00197 00198 CONST WORD gawScrollBarWndProc[] = { 00199 WM_CREATE, 00200 WM_SETFOCUS, 00201 WM_KILLFOCUS, 00202 WM_ERASEBKGND, 00203 WM_PAINT, 00204 WM_LBUTTONDBLCLK, 00205 WM_LBUTTONDOWN, 00206 WM_KEYUP, 00207 WM_KEYDOWN, 00208 WM_ENABLE, 00209 SBM_ENABLE_ARROWS, 00210 SBM_SETPOS, 00211 SBM_SETRANGEREDRAW, 00212 SBM_SETRANGE, 00213 SBM_SETSCROLLINFO, 00214 SBM_GETSCROLLINFO, 00215 WM_PRINTCLIENT, 00216 WM_MOUSEMOVE, 00217 WM_MOUSELEAVE, 00218 0 00219 }; 00220 00221 CONST WORD gawStaticWndProc[] = { 00222 STM_GETICON, 00223 STM_GETIMAGE, 00224 STM_SETICON, 00225 STM_SETIMAGE, 00226 WM_ERASEBKGND, 00227 WM_PAINT, 00228 WM_PRINTCLIENT, 00229 WM_CREATE, 00230 WM_DESTROY, 00231 WM_NCCREATE, 00232 WM_NCDESTROY, 00233 WM_FINALDESTROY, 00234 WM_NCHITTEST, 00235 WM_LBUTTONDOWN, 00236 WM_NCLBUTTONDOWN, 00237 WM_LBUTTONDBLCLK, 00238 WM_NCLBUTTONDBLCLK, 00239 WM_SETTEXT, 00240 WM_ENABLE, 00241 WM_GETDLGCODE, 00242 WM_SETFONT, 00243 WM_GETFONT, 00244 WM_GETTEXT, 00245 WM_TIMER, 00246 WM_INPUTLANGCHANGEREQUEST, 00247 WM_UPDATEUISTATE, 00248 0 00249 }; 00250 00251 CONST WORD gawButtonWndProc[] = { 00252 WM_NCHITTEST, 00253 WM_ERASEBKGND, 00254 WM_PRINTCLIENT, 00255 WM_PAINT, 00256 WM_SETFOCUS, 00257 WM_GETDLGCODE, 00258 WM_CAPTURECHANGED, 00259 WM_KILLFOCUS, 00260 WM_LBUTTONDBLCLK, 00261 WM_LBUTTONUP, 00262 WM_MOUSEMOVE, 00263 WM_LBUTTONDOWN, 00264 WM_CHAR, 00265 BM_CLICK, 00266 WM_KEYDOWN, 00267 WM_KEYUP, 00268 WM_SYSKEYUP, 00269 BM_GETSTATE, 00270 BM_SETSTATE, 00271 BM_GETCHECK, 00272 BM_SETCHECK, 00273 BM_SETSTYLE, 00274 WM_SETTEXT, 00275 WM_ENABLE, 00276 WM_SETFONT, 00277 WM_GETFONT, 00278 BM_GETIMAGE, 00279 BM_SETIMAGE, 00280 WM_NCDESTROY, 00281 WM_FINALDESTROY, 00282 WM_NCCREATE, 00283 WM_INPUTLANGCHANGEREQUEST, 00284 WM_UPDATEUISTATE, 00285 0 00286 }; 00287 00288 CONST WORD gawListboxWndProc[] = { 00289 LB_GETTOPINDEX, 00290 LB_SETTOPINDEX, 00291 WM_SIZE, 00292 WM_ERASEBKGND, 00293 LB_RESETCONTENT, 00294 WM_TIMER, 00295 WM_MOUSEMOVE, 00296 WM_MBUTTONDOWN, 00297 WM_LBUTTONDOWN, 00298 WM_LBUTTONUP, 00299 WM_LBUTTONDBLCLK, 00300 WM_CAPTURECHANGED, 00301 LBCB_STARTTRACK, 00302 LBCB_ENDTRACK, 00303 WM_PRINTCLIENT, 00304 WM_PAINT, 00305 WM_NCDESTROY, 00306 WM_FINALDESTROY, 00307 WM_SETFOCUS, 00308 WM_KILLFOCUS, 00309 WM_VSCROLL, 00310 WM_HSCROLL, 00311 WM_GETDLGCODE, 00312 WM_CREATE, 00313 WM_SETREDRAW, 00314 WM_ENABLE, 00315 WM_SETFONT, 00316 WM_GETFONT, 00317 WM_DRAGSELECT, 00318 WM_DRAGLOOP, 00319 WM_DRAGMOVE, 00320 WM_DROPFILES, 00321 WM_QUERYDROPOBJECT, 00322 WM_DROPOBJECT, 00323 LB_GETITEMRECT, 00324 LB_GETITEMDATA, 00325 LB_SETITEMDATA, 00326 LB_ADDSTRINGUPPER, 00327 LB_ADDSTRINGLOWER, 00328 LB_ADDSTRING, 00329 LB_INSERTSTRINGUPPER, 00330 LB_INSERTSTRINGLOWER, 00331 LB_INSERTSTRING, 00332 LB_INITSTORAGE, 00333 LB_DELETESTRING, 00334 LB_DIR, 00335 LB_ADDFILE, 00336 LB_SETSEL, 00337 LB_SETCURSEL, 00338 LB_GETSEL, 00339 LB_GETCURSEL, 00340 LB_SELITEMRANGE, 00341 LB_SELITEMRANGEEX, 00342 LB_GETTEXTLEN, 00343 LB_GETTEXT, 00344 LB_GETCOUNT, 00345 LB_SETCOUNT, 00346 LB_SELECTSTRING, 00347 LB_FINDSTRING, 00348 LB_GETLOCALE, 00349 LB_SETLOCALE, 00350 WM_KEYDOWN, 00351 WM_CHAR, 00352 LB_GETSELITEMS, 00353 LB_GETSELCOUNT, 00354 LB_SETTABSTOPS, 00355 LB_GETHORIZONTALEXTENT, 00356 LB_SETHORIZONTALEXTENT, 00357 LB_SETCOLUMNWIDTH, 00358 LB_SETANCHORINDEX, 00359 LB_GETANCHORINDEX, 00360 LB_SETCARETINDEX, 00361 LB_GETCARETINDEX, 00362 LB_SETITEMHEIGHT, 00363 LB_GETITEMHEIGHT, 00364 LB_FINDSTRINGEXACT, 00365 LB_ITEMFROMPOINT, 00366 LB_SETLOCALE, 00367 LB_GETLOCALE, 00368 LBCB_CARETON, 00369 LBCB_CARETOFF, 00370 WM_NCCREATE, 00371 WM_WINDOWPOSCHANGED, 00372 WM_MOUSEWHEEL, 00373 WM_STYLECHANGED, 00374 WM_STYLECHANGING, 00375 0 00376 }; 00377 00378 CONST WORD gawComboWndProc[] = { 00379 CBEC_KILLCOMBOFOCUS, 00380 WM_COMMAND, 00381 WM_CTLCOLORMSGBOX, 00382 WM_CTLCOLOREDIT, 00383 WM_CTLCOLORLISTBOX, 00384 WM_CTLCOLORBTN, 00385 WM_CTLCOLORDLG, 00386 WM_CTLCOLORSCROLLBAR, 00387 WM_CTLCOLORSTATIC, 00388 WM_CTLCOLOR, 00389 WM_GETTEXT, 00390 WM_GETTEXTLENGTH, 00391 WM_CLEAR, 00392 WM_CUT, 00393 WM_PASTE, 00394 WM_COPY, 00395 WM_SETTEXT, 00396 WM_CREATE, 00397 WM_ERASEBKGND, 00398 WM_GETFONT, 00399 WM_PRINT, 00400 WM_PRINTCLIENT, 00401 WM_PAINT, 00402 WM_GETDLGCODE, 00403 WM_SETFONT, 00404 WM_SYSKEYDOWN, 00405 WM_KEYDOWN, 00406 WM_CHAR, 00407 WM_LBUTTONDBLCLK, 00408 WM_LBUTTONDOWN, 00409 WM_CAPTURECHANGED, 00410 WM_LBUTTONUP, 00411 WM_MOUSEMOVE, 00412 WM_NCDESTROY, 00413 WM_FINALDESTROY, 00414 WM_SETFOCUS, 00415 WM_KILLFOCUS, 00416 WM_SETREDRAW, 00417 WM_ENABLE, 00418 WM_SIZE, 00419 CB_GETDROPPEDSTATE, 00420 CB_GETDROPPEDCONTROLRECT, 00421 CB_SETDROPPEDWIDTH, 00422 CB_GETDROPPEDWIDTH, 00423 CB_DIR, 00424 CB_SETEXTENDEDUI, 00425 CB_GETEXTENDEDUI, 00426 CB_GETEDITSEL, 00427 CB_LIMITTEXT, 00428 CB_SETEDITSEL, 00429 CB_ADDSTRING, 00430 CB_DELETESTRING, 00431 CB_INITSTORAGE, 00432 CB_SETTOPINDEX, 00433 CB_GETTOPINDEX, 00434 CB_GETCOUNT, 00435 CB_GETCURSEL, 00436 CB_GETLBTEXT, 00437 CB_GETLBTEXTLEN, 00438 CB_INSERTSTRING, 00439 CB_RESETCONTENT, 00440 CB_GETHORIZONTALEXTENT, 00441 CB_SETHORIZONTALEXTENT, 00442 CB_FINDSTRING, 00443 CB_FINDSTRINGEXACT, 00444 CB_SELECTSTRING, 00445 CB_SETCURSEL, 00446 CB_GETITEMDATA, 00447 CB_SETITEMDATA, 00448 CB_SETITEMHEIGHT, 00449 CB_GETITEMHEIGHT, 00450 CB_SHOWDROPDOWN, 00451 CB_SETLOCALE, 00452 CB_GETLOCALE, 00453 WM_MEASUREITEM, 00454 WM_DELETEITEM, 00455 WM_DRAWITEM, 00456 WM_COMPAREITEM, 00457 WM_NCCREATE, 00458 WM_HELP, 00459 WM_MOUSEWHEEL, 00460 WM_MOUSELEAVE, 00461 WM_STYLECHANGED, 00462 WM_STYLECHANGING, 00463 WM_UPDATEUISTATE, 00464 0 00465 }; 00466 00467 CONST WORD gawEditWndProc[] = { 00468 EM_CANUNDO, 00469 EM_CHARFROMPOS, 00470 EM_EMPTYUNDOBUFFER, 00471 EM_FMTLINES, 00472 EM_GETFIRSTVISIBLELINE, 00473 EM_GETFIRSTVISIBLELINE, 00474 EM_GETHANDLE, 00475 EM_GETLIMITTEXT, 00476 EM_GETLINE, 00477 EM_GETLINECOUNT, 00478 EM_GETMARGINS, 00479 EM_GETMODIFY, 00480 EM_GETPASSWORDCHAR, 00481 EM_GETRECT, 00482 EM_GETSEL, 00483 EM_GETWORDBREAKPROC, 00484 EM_SETIMESTATUS, 00485 EM_GETIMESTATUS, 00486 EM_LINEFROMCHAR, 00487 EM_LINEINDEX, 00488 EM_LINELENGTH, 00489 EM_LINESCROLL, 00490 EM_POSFROMCHAR, 00491 EM_REPLACESEL, 00492 EM_SCROLL, 00493 EM_SCROLLCARET, 00494 EM_SETHANDLE, 00495 EM_SETLIMITTEXT, 00496 EM_SETMARGINS, 00497 EM_SETMODIFY, 00498 EM_SETPASSWORDCHAR, 00499 EM_SETREADONLY, 00500 EM_SETRECT, 00501 EM_SETRECTNP, 00502 EM_SETSEL, 00503 EM_SETTABSTOPS, 00504 EM_SETWORDBREAKPROC, 00505 EM_UNDO, 00506 WM_CAPTURECHANGED, 00507 WM_CHAR, 00508 WM_CLEAR, 00509 WM_CONTEXTMENU, 00510 WM_COPY, 00511 WM_CREATE, 00512 WM_CUT, 00513 WM_ENABLE, 00514 WM_ERASEBKGND, 00515 WM_GETDLGCODE, 00516 WM_GETFONT, 00517 WM_GETTEXT, 00518 WM_GETTEXTLENGTH, 00519 WM_HSCROLL, 00520 WM_IME_STARTCOMPOSITION, 00521 WM_IME_ENDCOMPOSITION, 00522 WM_IME_COMPOSITION, 00523 WM_IME_SETCONTEXT, 00524 WM_IME_NOTIFY, 00525 WM_IME_COMPOSITIONFULL, 00526 WM_IME_SELECT, 00527 WM_IME_CHAR, 00528 WM_IME_REQUEST, 00529 WM_INPUTLANGCHANGE, 00530 WM_KEYUP, 00531 WM_KEYDOWN, 00532 WM_KILLFOCUS, 00533 WM_MBUTTONDOWN, 00534 WM_LBUTTONDBLCLK, 00535 WM_LBUTTONDOWN, 00536 WM_LBUTTONUP, 00537 WM_MOUSEMOVE, 00538 WM_NCCREATE, 00539 WM_NCDESTROY, 00540 WM_RBUTTONDOWN, 00541 WM_RBUTTONUP, 00542 WM_FINALDESTROY, 00543 #if 0 00544 WM_NCPAINT, 00545 #endif 00546 WM_PAINT, 00547 WM_PASTE, 00548 WM_PRINTCLIENT, 00549 WM_SETFOCUS, 00550 WM_SETFONT, 00551 WM_SETREDRAW, 00552 WM_SETTEXT, 00553 WM_SIZE, 00554 WM_STYLECHANGED, 00555 WM_STYLECHANGING, 00556 WM_SYSCHAR, 00557 WM_SYSKEYDOWN, 00558 WM_SYSTIMER, 00559 WM_UNDO, 00560 WM_VSCROLL, 00561 WM_MOUSEWHEEL, 00562 0 00563 }; 00564 00565 CONST WORD gawImeWndProc[] = { 00566 WM_ERASEBKGND, 00567 WM_PAINT, 00568 WM_DESTROY, 00569 WM_NCDESTROY, 00570 WM_FINALDESTROY, 00571 WM_CREATE, 00572 WM_IME_SYSTEM, 00573 WM_IME_SELECT, 00574 WM_IME_CONTROL, 00575 WM_IME_SETCONTEXT, 00576 WM_IME_NOTIFY, 00577 WM_IME_COMPOSITION, 00578 WM_IME_STARTCOMPOSITION, 00579 WM_IME_ENDCOMPOSITION, 00580 WM_IME_REQUEST, 00581 WM_COPYDATA, 00582 0 00583 }; 00584 00585 /* 00586 * This array is for all the messages that need to be passed straight 00587 * across to the server for handling. 00588 */ 00589 CONST WORD gawDefWindowMsgs[] = { 00590 WM_GETHOTKEY, 00591 WM_SETHOTKEY, 00592 WM_SETREDRAW, 00593 WM_SETTEXT, 00594 WM_PAINT, 00595 WM_CLOSE, 00596 WM_ERASEBKGND, 00597 WM_CANCELMODE, 00598 WM_SETCURSOR, 00599 WM_PAINTICON, 00600 WM_ICONERASEBKGND, 00601 WM_DRAWITEM, 00602 WM_KEYF1, 00603 WM_ISACTIVEICON, 00604 WM_NCCREATE, 00605 WM_SETICON, 00606 WM_NCCALCSIZE, 00607 WM_NCPAINT, 00608 WM_NCACTIVATE, 00609 WM_NCMOUSEMOVE, 00610 WM_NCRBUTTONUP, 00611 WM_NCRBUTTONDOWN, 00612 WM_NCLBUTTONDOWN, 00613 WM_NCLBUTTONUP, 00614 WM_NCLBUTTONDBLCLK, 00615 WM_KEYUP, 00616 WM_SYSKEYUP, 00617 WM_SYSCHAR, 00618 WM_SYSCOMMAND, 00619 WM_QUERYDROPOBJECT, 00620 WM_CLIENTSHUTDOWN, 00621 WM_SYNCPAINT, 00622 WM_PRINT, 00623 WM_GETICON, 00624 WM_CONTEXTMENU, 00625 WM_SYSMENU, 00626 WM_INPUTLANGCHANGEREQUEST, 00627 WM_INPUTLANGCHANGE, 00628 WM_UPDATEUISTATE, 00629 0 00630 }; 00631 00632 /* 00633 * This array is for all messages that can be handled with some special 00634 * code by the client. DefWindowProcWorker returns 0 for all messages 00635 * that aren't in this array or the one above. 00636 */ 00637 CONST WORD gawDefWindowSpecMsgs[] = { 00638 WM_ACTIVATE, 00639 WM_GETTEXT, 00640 WM_GETTEXTLENGTH, 00641 WM_RBUTTONUP, 00642 WM_QUERYENDSESSION, 00643 WM_QUERYOPEN, 00644 WM_SHOWWINDOW, 00645 WM_MOUSEACTIVATE, 00646 WM_HELP, 00647 WM_VKEYTOITEM, 00648 WM_CHARTOITEM, 00649 WM_KEYDOWN, 00650 WM_SYSKEYDOWN, 00651 WM_DROPOBJECT, 00652 WM_WINDOWPOSCHANGING, 00653 WM_WINDOWPOSCHANGED, 00654 WM_KLUDGEMINRECT, 00655 WM_CTLCOLOR, 00656 WM_CTLCOLORMSGBOX, 00657 WM_CTLCOLOREDIT, 00658 WM_CTLCOLORLISTBOX, 00659 WM_CTLCOLORBTN, 00660 WM_CTLCOLORDLG, 00661 WM_CTLCOLORSCROLLBAR, 00662 WM_NCHITTEST, 00663 WM_NCXBUTTONUP, 00664 WM_CTLCOLORSTATIC, 00665 WM_NOTIFYFORMAT, 00666 WM_DEVICECHANGE, 00667 WM_POWERBROADCAST, 00668 WM_MOUSEWHEEL, 00669 WM_XBUTTONUP, 00670 WM_IME_KEYDOWN, 00671 WM_IME_KEYUP, 00672 WM_IME_CHAR, 00673 WM_IME_COMPOSITION, 00674 WM_IME_STARTCOMPOSITION, 00675 WM_IME_ENDCOMPOSITION, 00676 WM_IME_COMPOSITIONFULL, 00677 WM_IME_SETCONTEXT, 00678 WM_IME_CONTROL, 00679 WM_IME_NOTIFY, 00680 WM_IME_SELECT, 00681 WM_IME_SYSTEM, 00682 WM_LPKDRAWSWITCHWND, 00683 WM_QUERYDRAGICON, 00684 WM_CHANGEUISTATE, 00685 WM_QUERYUISTATE, 00686 WM_APPCOMMAND, 00687 0 00688 }; 00689 00690 static CONST LPCWSTR lpszOLEFormats[] = { 00691 L"ObjectLink", 00692 L"OwnerLink", 00693 L"Native", 00694 L"Binary", 00695 L"FileName", 00696 L"FileNameW", 00697 L"NetworkName", 00698 L"DataObject", 00699 L"Embedded Object", 00700 L"Embed Source", 00701 L"Custom Link Source", 00702 L"Link Source", 00703 L"Object Descriptor", 00704 L"Link Source Descriptor", 00705 L"OleDraw", 00706 L"PBrush", 00707 L"MSDraw", 00708 L"Ole Private Data", 00709 L"Screen Picture", 00710 L"OleClipboardPersistOnFlush", 00711 L"MoreOlePrivateData" 00712 }; 00713 00714 static CONST LPCWSTR lpszControls[] = { 00715 L"Button", 00716 L"Edit", 00717 L"Static", 00718 L"ListBox", 00719 L"ScrollBar", 00720 L"ComboBox", 00721 L"MDIClient", 00722 L"ComboLBox", 00723 L"DDEMLEvent", 00724 L"DDEMLMom", 00725 L"DMGClass", 00726 L"DDEMLAnsiClient", 00727 L"DDEMLUnicodeClient", 00728 L"DDEMLAnsiServer", 00729 L"DDEMLUnicodeServer", 00730 L"IME", 00731 }; 00732 00733 00734 #ifdef ALLOC_DATA_PRAGMA 00735 #pragma data_seg() 00736 #endif 00737 00738 /***************************************************************************\ 00739 * DispatchServerMessage 00740 * 00741 * 00742 * 19-Aug-1992 MikeKe Created 00743 \***************************************************************************/ 00744 00745 #define WRAPPFN(pfn, type) \ 00746 LRESULT xxxWrap ## pfn( \ 00747 PWND pwnd, \ 00748 UINT message, \ 00749 WPARAM wParam, \ 00750 LPARAM lParam, \ 00751 ULONG_PTR xParam) \ 00752 { \ 00753 DBG_UNREFERENCED_PARAMETER(xParam); \ 00754 \ 00755 return xxx ## pfn((type)pwnd, message, wParam, lParam); \ 00756 } 00757 00758 WRAPPFN(SBWndProc, PSBWND) 00759 WRAPPFN(MenuWindowProc, PWND) 00760 WRAPPFN(DesktopWndProc, PWND); 00761 WRAPPFN(DefWindowProc, PWND) 00762 00763 LRESULT xxxWrapSendMessage( 00764 PWND pwnd, 00765 UINT message, 00766 WPARAM wParam, 00767 LPARAM lParam, 00768 ULONG_PTR xParam) 00769 { 00770 DBG_UNREFERENCED_PARAMETER(xParam); 00771 00772 return xxxSendMessageTimeout(pwnd, 00773 message, 00774 wParam, 00775 lParam, 00776 SMTO_NORMAL, 00777 0, 00778 NULL); 00779 } 00780 00781 LRESULT xxxWrapSendMessageBSM( 00782 PWND pwnd, 00783 UINT message, 00784 WPARAM wParam, 00785 LPARAM lParam, 00786 ULONG_PTR xParam) 00787 { 00788 BROADCASTSYSTEMMSGPARAMS bsmParams; 00789 00790 try { 00791 bsmParams = ProbeAndReadBroadcastSystemMsgParams((LPBROADCASTSYSTEMMSGPARAMS)xParam); 00792 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 00793 return 0; 00794 } 00795 00796 /* 00797 * If this broadcast is going to all desktops, make sure the thread has 00798 * sufficient privileges. Do the check here, so we don't effect kernel 00799 * generated broadcasts (i.e power messages). 00800 */ 00801 if (bsmParams.dwRecipients & (BSM_ALLDESKTOPS)) { 00802 if (!IsPrivileged(&psTcb)) { 00803 bsmParams.dwRecipients &= ~(BSM_ALLDESKTOPS); 00804 } 00805 } 00806 00807 return xxxSendMessageBSM(pwnd, 00808 message, 00809 wParam, 00810 lParam, 00811 &bsmParams); 00812 } 00813 00814 /***************************************************************************\ 00815 * xxxUnusedFunctionId 00816 * 00817 * This function is catches attempts to access invalid entries in the server 00818 * side function dispatch table. 00819 * 00820 \***************************************************************************/ 00821 00822 LRESULT xxxUnusedFunctionId( 00823 PWND pwnd, 00824 UINT message, 00825 WPARAM wParam, 00826 LPARAM lParam, 00827 ULONG_PTR xParam) 00828 { 00829 DBG_UNREFERENCED_PARAMETER(pwnd); 00830 DBG_UNREFERENCED_PARAMETER(message); 00831 DBG_UNREFERENCED_PARAMETER(wParam); 00832 DBG_UNREFERENCED_PARAMETER(lParam); 00833 DBG_UNREFERENCED_PARAMETER(xParam); 00834 00835 UserAssert(FALSE); 00836 return 0; 00837 } 00838 00839 /***************************************************************************\ 00840 * xxxWrapCallWindowProc 00841 * 00842 * Warning should only be called with valid CallProc Handles or the 00843 * EditWndProc special handlers. 00844 * 00845 * 00846 * 21-Apr-1993 JohnC Created 00847 \***************************************************************************/ 00848 00849 LRESULT xxxWrapCallWindowProc( 00850 PWND pwnd, 00851 UINT message, 00852 WPARAM wParam, 00853 LPARAM lParam, 00854 ULONG_PTR xParam) 00855 { 00856 PCALLPROCDATA pCPD; 00857 LRESULT lRet = 0; 00858 00859 if (pCPD = HMValidateHandleNoRip((PVOID)xParam, TYPE_CALLPROC)) { 00860 00861 lRet = ScSendMessage(pwnd, 00862 message, 00863 wParam, 00864 lParam, 00865 pCPD->pfnClientPrevious, 00866 gpsi->apfnClientW.pfnDispatchMessage, 00867 (pCPD->wType & CPD_UNICODE_TO_ANSI) ? 00868 SCMS_FLAGS_ANSI : 0); 00869 00870 } else { 00871 00872 /* 00873 * If it is not a real call proc handle it must be a special 00874 * handler for editwndproc or regular EditWndProc 00875 */ 00876 lRet = ScSendMessage(pwnd, 00877 message, 00878 wParam, 00879 lParam, 00880 xParam, 00881 gpsi->apfnClientA.pfnDispatchMessage, 00882 (xParam == (ULONG_PTR)gpsi->apfnClientA.pfnEditWndProc) ? 00883 SCMS_FLAGS_ANSI : 0); 00884 } 00885 00886 return lRet; 00887 } 00888 00889 #if DBG 00890 VOID VerifySyncOnlyMessages(VOID) 00891 { 00892 int i; 00893 00894 TRACE_INIT(("UserInit: Verify Sync Only Messages\n")); 00895 00896 /* 00897 * There are a couple of thunks that just pass parameters. There are other 00898 * thunks besides SfnDWORD that do a straight pass through because they 00899 * do other processing beside the wparam and lparam 00900 */ 00901 00902 /* 00903 * Allow posting of LB_DIR and CB_DIR because DlgDirList allows a DDL_POSTMSGS 00904 * flag that makes the API post the messages. This should be OK as long as we 00905 * don't handle these messages in the kernel. NT 3.51 allowed posting these. 00906 */ 00907 for (i=0; i<WM_USER; i++) { 00908 if ( i != LB_DIR 00909 && i != CB_DIR 00910 && (gapfnScSendMessage[MessageTable[i].iFunction] != SfnDWORD) 00911 && (gapfnScSendMessage[MessageTable[i].iFunction] != SfnINWPARAMCHAR) 00912 && (gapfnScSendMessage[MessageTable[i].iFunction] != SfnINWPARAMDBCSCHAR) 00913 && (gapfnScSendMessage[MessageTable[i].iFunction] != SfnSENTDDEMSG) 00914 && (gapfnScSendMessage[MessageTable[i].iFunction] != SfnPOWERBROADCAST) 00915 && (gapfnScSendMessage[MessageTable[i].iFunction] != SfnLOGONNOTIFY) 00916 && (gapfnScSendMessage[MessageTable[i].iFunction] != SfnINDESTROYCLIPBRD)) { 00917 if (!(TESTSYNCONLYMESSAGE(i,0x8000))) 00918 RIPMSG1(RIP_ERROR, "InitSyncOnly: is this message sync-only 0x%lX", i); 00919 } else { 00920 if (TESTSYNCONLYMESSAGE(i,0)) 00921 RIPMSG1(RIP_VERBOSE, "InitSyncOnly: is this message not sync-only 0x%lX", i); 00922 } 00923 00924 } 00925 } 00926 #endif // DBG 00927 00928 /***************************************************************************\ 00929 * InitWindowMsgTables 00930 * 00931 * This function generates a bit-array lookup table from a list of messages. 00932 * The lookup table is used to determine whether the message needs to be 00933 * passed over to the server for handling or whether it can be handled 00934 * directly on the client. 00935 * 00936 * LATER: Some memory (a couple hundred bytes per process) could be saved 00937 * by putting this in the shared read-only heap. 00938 * 00939 * 00940 * 27-Mar-1992 DarrinM Created. 00941 * 06-Dec-1993 MikeKe Added support for all of our window procs. 00942 \***************************************************************************/ 00943 00944 VOID InitWindowMsgTable( 00945 PBYTE *ppbyte, 00946 PUINT pmax, 00947 CONST WORD *pw) 00948 { 00949 UINT i; 00950 WORD msg; 00951 UINT cbTable; 00952 00953 *pmax = 0; 00954 for (i = 0; (msg = pw[i]) != 0; i++) { 00955 if (msg > *pmax) 00956 *pmax = msg; 00957 } 00958 00959 cbTable = *pmax / 8 + 1; 00960 *ppbyte = SharedAlloc(cbTable); 00961 00962 for (i = 0; (msg = pw[i]) != 0; i++) 00963 (*ppbyte)[msg / 8] |= (BYTE)(1 << (msg & 7)); 00964 } 00965 00966 /***************************************************************************\ 00967 * InitFunctionTables 00968 * 00969 * Initialize the procedures and function tables. 00970 * 00971 * 00972 * 25-Aug-1995 ChrisWil Created comment block. 00973 \***************************************************************************/ 00974 00975 VOID InitFunctionTables(VOID) 00976 { 00977 UINT i; 00978 00979 TRACE_INIT(("UserInit: Initialize Function Tables\n")); 00980 00981 UserAssert(sizeof(CLIENTINFO) <= sizeof(NtCurrentTeb()->Win32ClientInfo)); 00982 00983 /* 00984 * This table is used to convert from server procs to client procs. 00985 */ 00986 STOCID(FNID_SCROLLBAR) = (WNDPROC_PWND)xxxSBWndProc; 00987 STOCID(FNID_ICONTITLE) = xxxDefWindowProc; 00988 STOCID(FNID_MENU) = xxxMenuWindowProc; 00989 STOCID(FNID_DESKTOP) = xxxDesktopWndProc; 00990 STOCID(FNID_DEFWINDOWPROC) = xxxDefWindowProc; 00991 00992 /* 00993 * This table is used to determine the number minimum number 00994 * of reserved windows words required for the server proc. 00995 */ 00996 CBFNID(FNID_SCROLLBAR) = sizeof(SBWND); 00997 CBFNID(FNID_ICONTITLE) = sizeof(WND); 00998 CBFNID(FNID_MENU) = sizeof(MENUWND); 00999 01000 /* 01001 * Initialize this data structure (api function table). 01002 */ 01003 for (i = 0; i < FNID_ARRAY_SIZE; i++) { 01004 FNID((i + FNID_START)) = xxxUnusedFunctionId; 01005 } 01006 FNID(FNID_SCROLLBAR) = xxxWrapSBWndProc; 01007 FNID(FNID_ICONTITLE) = xxxWrapDefWindowProc; 01008 FNID(FNID_MENU) = xxxWrapMenuWindowProc; 01009 FNID(FNID_DESKTOP) = xxxWrapDesktopWndProc; 01010 FNID(FNID_DEFWINDOWPROC) = xxxWrapDefWindowProc; 01011 FNID(FNID_SENDMESSAGE) = xxxWrapSendMessage; 01012 FNID(FNID_HKINLPCWPEXSTRUCT) = fnHkINLPCWPEXSTRUCT; 01013 FNID(FNID_HKINLPCWPRETEXSTRUCT) = fnHkINLPCWPRETEXSTRUCT; 01014 FNID(FNID_SENDMESSAGEFF) = xxxSendMessageFF; 01015 FNID(FNID_SENDMESSAGEEX) = xxxSendMessageEx; 01016 FNID(FNID_CALLWINDOWPROC) = xxxWrapCallWindowProc; 01017 FNID(FNID_SENDMESSAGEBSM) = xxxWrapSendMessageBSM; 01018 01019 #if DBG 01020 { 01021 PULONG_PTR pdw; 01022 01023 /* 01024 * Make sure that everyone got initialized. 01025 */ 01026 for (pdw=(PULONG_PTR)&STOCID(FNID_START); 01027 (ULONG_PTR)pdw<(ULONG_PTR)(&STOCID(FNID_WNDPROCEND)); pdw++) { 01028 UserAssert(*pdw); 01029 } 01030 01031 for (pdw=(PULONG_PTR)&FNID(FNID_START); 01032 (ULONG_PTR)pdw<(ULONG_PTR)(&FNID(FNID_WNDPROCEND)); pdw++) { 01033 UserAssert(*pdw); 01034 } 01035 } 01036 #endif 01037 01038 } 01039 01040 /***************************************************************************\ 01041 * InitMessageTables 01042 * 01043 * Initialize the message tables. 01044 * 01045 * 01046 * 25-Aug-1995 ChrisWil Created. 01047 \***************************************************************************/ 01048 01049 VOID InitMessageTables(VOID) 01050 { 01051 TRACE_INIT(("UserInit: Initialize Message Tables\n")); 01052 01053 #define INITMSGTABLE(member, procname) \ 01054 InitWindowMsgTable(&(gSharedInfo.member.abMsgs), \ 01055 &(gSharedInfo.member.maxMsgs), \ 01056 gaw ## procname); 01057 01058 INITMSGTABLE(DefWindowMsgs, DefWindowMsgs); 01059 INITMSGTABLE(DefWindowSpecMsgs, DefWindowSpecMsgs); 01060 01061 INITMSGTABLE(awmControl[FNID_DIALOG - FNID_START], DefDlgProc); 01062 INITMSGTABLE(awmControl[FNID_SCROLLBAR - FNID_START], ScrollBarWndProc); 01063 INITMSGTABLE(awmControl[FNID_MENU - FNID_START], MenuWndProc); 01064 INITMSGTABLE(awmControl[FNID_DESKTOP - FNID_START], DesktopWndProc); 01065 INITMSGTABLE(awmControl[FNID_STATIC - FNID_START], StaticWndProc); 01066 INITMSGTABLE(awmControl[FNID_BUTTON - FNID_START], ButtonWndProc); 01067 INITMSGTABLE(awmControl[FNID_LISTBOX - FNID_START], ListboxWndProc); 01068 INITMSGTABLE(awmControl[FNID_COMBOBOX - FNID_START], ComboWndProc); 01069 INITMSGTABLE(awmControl[FNID_COMBOLISTBOX - FNID_START], ListboxWndProc); 01070 INITMSGTABLE(awmControl[FNID_EDIT - FNID_START], EditWndProc); 01071 INITMSGTABLE(awmControl[FNID_IME - FNID_START], ImeWndProc); 01072 } 01073 01074 /***************************************************************************\ 01075 * InitOLEFormats 01076 * 01077 * OLE performance hack. OLE was previously having to call the server 01078 * 15 times for clipboard formats and another 15 LPC calls for the global 01079 * atoms. Now we preregister them. We also assert they are in order so 01080 * OLE only has to query the first to know them all. We call AddAtom 01081 * directly instead of RegisterClipboardFormat. 01082 * 01083 * 01084 * 25-Aug-1995 ChrisWil Created. 01085 \***************************************************************************/ 01086 01087 BOOL InitOLEFormats(VOID) 01088 { 01089 UINT idx; 01090 ATOM a1; 01091 ATOM a2; 01092 BOOL fSuccess = TRUE; 01093 01094 TRACE_INIT(("UserInit: Initialize OLE Formats\n")); 01095 01096 a1 = UserAddAtom(lpszOLEFormats[0], TRUE); 01097 01098 for (idx = 1; idx < ARRAY_SIZE(lpszOLEFormats); idx++) { 01099 a2 = UserAddAtom(lpszOLEFormats[idx], TRUE); 01100 fSuccess &= !!a2; 01101 01102 UserAssert(((a1 + 1) == a2) && (a1 = a2)); 01103 } 01104 01105 if (!fSuccess) { 01106 RIPMSG0(RIP_ERROR, "InitOLEFormats: at least one atom not registered"); 01107 } 01108 01109 return fSuccess; 01110 } 01111 01112 /***************************************************************************\ 01113 * InitGlobalRIPFlags (debug only) 01114 * 01115 * This initializes the global RIP flags from the registry. 01116 * 01117 * 01118 * 25-Aug-1995 ChrisWil Created. 01119 \***************************************************************************/ 01120 #if DBG 01121 VOID 01122 InitGlobalRIPFlags() 01123 { 01124 01125 UINT idx; 01126 UINT nCount; 01127 DWORD dwFlag; 01128 01129 static CONST struct { 01130 LPWSTR lpszKey; 01131 DWORD dwDef; 01132 DWORD dwFlag; 01133 } aRIPFlags[] = { 01134 {L"fPromptOnError" , 1, RIPF_PROMPTONERROR }, 01135 {L"fPromptOnWarning", 0, RIPF_PROMPTONWARNING}, 01136 {L"fPromptOnVerbose", 0, RIPF_PROMPTONVERBOSE}, 01137 {L"fPrintError" , 1, RIPF_PRINTONERROR }, 01138 {L"fPrintWarning" , 1, RIPF_PRINTONWARNING }, 01139 {L"fPrintVerbose" , 0, RIPF_PRINTONVERBOSE }, 01140 {L"fPrintFileLine" , 0, RIPF_PRINTFILELINE }, 01141 }; 01142 01143 TRACE_INIT(("UserInit: Initialize Global RIP Flags\n")); 01144 01145 nCount = sizeof(aRIPFlags) / sizeof(aRIPFlags[0]); 01146 01147 /* 01148 * Turn off the rip-on-warning bit. This is necessary to prevent 01149 * the FastGetProfileDwordW() routine from breaking into the 01150 * debugger if an entry can't be found. Since we provide default 01151 * values, there's no sense to break. 01152 */ 01153 UserAssert(gpsi != NULL); 01154 01155 CLEAR_FLAG(gpsi->wRIPFlags, RIPF_PROMPTONWARNING); 01156 CLEAR_FLAG(gpsi->wRIPFlags, RIPF_PRINTONWARNING); 01157 01158 for (idx=0; idx < nCount; idx++) { 01159 01160 dwFlag = FastGetProfileDwordW(NULL, PMAP_WINDOWSM, 01161 aRIPFlags[idx].lpszKey, 01162 aRIPFlags[idx].dwDef 01163 ); 01164 01165 SET_OR_CLEAR_FLAG(gpsi->wRIPFlags, aRIPFlags[idx].dwFlag, dwFlag); 01166 } 01167 01168 } 01169 01170 #else // DBG 01171 01172 #define InitGlobalRIPFlags() 01173 01174 #endif // DBG 01175 01176 01177 /***************************************************************************\ 01178 * _GetTextMetricsW 01179 * _TextOutW 01180 * 01181 * Server shared function thunks. 01182 * 01183 * History: 01184 * 10-Nov-1993 MikeKe Created 01185 \***************************************************************************/ 01186 01187 BOOL _GetTextMetricsW( 01188 HDC hdc, 01189 LPTEXTMETRICW ptm) 01190 { 01191 TMW_INTERNAL tmi; 01192 BOOL fret; 01193 01194 fret = GreGetTextMetricsW(hdc, &tmi); 01195 01196 *ptm = tmi.tmw; 01197 01198 return fret; 01199 } 01200 01201 BOOL _TextOutW( 01202 HDC hdc, 01203 int x, 01204 int y, 01205 LPCWSTR lp, 01206 UINT cc) 01207 { 01208 return GreExtTextOutW(hdc, x, y, 0, NULL, (LPWSTR)lp, cc, NULL); 01209 } 01210 01211 01212 01213 #ifndef PAGE_SIZE 01214 #define PAGE_SIZE 0x1000 01215 #endif 01216 01217 #define ROUND_UP_TO_PAGES(SIZE) \ 01218 (((ULONG)(SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) 01219 01220 /***************************************************************************\ 01221 * InitCreateSharedSection 01222 * 01223 * This creates the shared section. 01224 * 01225 * 01226 * 25-Aug-1995 ChrisWil Created comment block. 01227 \***************************************************************************/ 01228 01229 NTSTATUS InitCreateSharedSection(VOID) 01230 { 01231 ULONG ulHeapSize; 01232 ULONG ulHandleTableSize; 01233 NTSTATUS Status; 01234 LARGE_INTEGER SectionSize; 01235 SIZE_T ViewSize; 01236 PVOID pHeapBase; 01237 01238 TRACE_INIT(("UserInit: Create Shared Memory Section\n")); 01239 01240 UserAssert(ghSectionShared == NULL); 01241 01242 ulHeapSize = ROUND_UP_TO_PAGES(USRINIT_SHAREDSECT_SIZE * 1024); 01243 ulHandleTableSize = ROUND_UP_TO_PAGES(0x10000 * sizeof(HANDLEENTRY)); 01244 01245 TRACE_INIT(("UserInit: Share: TableSize = %X; HeapSize = %X\n", 01246 ulHandleTableSize, ulHeapSize)); 01247 01248 SectionSize.LowPart = ulHeapSize + ulHandleTableSize; 01249 SectionSize.HighPart = 0; 01250 01251 Status = Win32CreateSection(&ghSectionShared, 01252 SECTION_ALL_ACCESS, 01253 (POBJECT_ATTRIBUTES)NULL, 01254 &SectionSize, 01255 PAGE_EXECUTE_READWRITE, 01256 SEC_RESERVE, 01257 (HANDLE)NULL, 01258 NULL, 01259 TAG_SECTION_SHARED); 01260 01261 if (!NT_SUCCESS(Status)) { 01262 RIPMSG1(RIP_WARNING, 01263 "MmCreateSection failed in InitCreateSharedSection with Status %x", 01264 Status); 01265 return Status; 01266 } 01267 01268 ViewSize = 0; 01269 gpvSharedBase = NULL; 01270 01271 Status = Win32MapViewInSessionSpace(ghSectionShared, &gpvSharedBase, &ViewSize); 01272 01273 if (!NT_SUCCESS(Status)) { 01274 RIPMSG1(RIP_WARNING, "Win32MapViewInSessionSpace failed with Status %x", 01275 Status); 01276 Win32DestroySection(ghSectionShared); 01277 ghSectionShared = NULL; 01278 return Status; 01279 } 01280 01281 pHeapBase = ((PBYTE)gpvSharedBase + ulHandleTableSize); 01282 01283 TRACE_INIT(("UserInit: Share: BaseAddr = %X; Heap = %X, ViewSize = %X\n", 01284 gpvSharedBase, pHeapBase, ViewSize)); 01285 01286 /* 01287 * Create shared heap. 01288 */ 01289 if ((gpvSharedAlloc = UserCreateHeap( 01290 ghSectionShared, 01291 ulHandleTableSize, 01292 pHeapBase, 01293 ulHeapSize, 01294 UserCommitSharedMemory)) == NULL) { 01295 01296 RIPERR0(ERROR_NOT_ENOUGH_MEMORY, RIP_WARNING, "Can't create shared memory heap."); 01297 01298 Win32UnmapViewInSessionSpace(gpvSharedBase); 01299 01300 Win32DestroySection(ghSectionShared); 01301 gpvSharedAlloc = NULL; 01302 gpvSharedBase = NULL; 01303 ghSectionShared = NULL; 01304 01305 return STATUS_NO_MEMORY; 01306 } 01307 01308 UserAssert(Win32HeapGetHandle(gpvSharedAlloc) == pHeapBase); 01309 01310 return STATUS_SUCCESS; 01311 } 01312 01313 /**************************************************************************\ 01314 * InitCreateUserCrit 01315 * 01316 * Create and initialize the user critical sections needed throughout the 01317 * system. 01318 * 01319 * 23-Jan-1996 ChrisWil Created. 01320 \**************************************************************************/ 01321 01322 BOOL InitCreateUserCrit(VOID) 01323 { 01324 TRACE_INIT(("Win32UserInit: InitCreateUserCrit()\n")); 01325 01326 /* 01327 * Initialize a critical section structure that will be used to protect 01328 * all of the User Server's critical sections (except a few special 01329 * cases like the RIT -- see below). 01330 */ 01331 gpresUser = ExAllocatePoolWithTag(NonPagedPoolMustSucceed, 01332 sizeof(ERESOURCE), 01333 TAG_ERESOURCE); 01334 if (!gpresUser) { 01335 goto InitCreateUserCritExit; 01336 } 01337 if (!NT_SUCCESS(ExInitializeResourceLite(gpresUser))) { 01338 goto InitCreateUserCritExit; 01339 } 01340 01341 /* 01342 * Initialize a critical section to be used in [Un]QueueMouseEvent 01343 * to protect the queue of mouse input events that the desktop thread 01344 * uses to pass input on to the RIT, after having moved the cursor 01345 * without obtaining gpresUser itself. 01346 */ 01347 gpresMouseEventQueue = ExAllocatePoolWithTag(NonPagedPoolMustSucceed, 01348 sizeof(ERESOURCE), 01349 TAG_ERESOURCE); 01350 if (!gpresMouseEventQueue) { 01351 goto InitCreateUserCritExit; 01352 } 01353 if (!NT_SUCCESS(ExInitializeResourceLite(gpresMouseEventQueue))) { 01354 goto InitCreateUserCritExit; 01355 } 01356 01357 /* 01358 * Initialize a critical section to protect the list of DEVICEINFO structs 01359 * kept under gpDeviceInfoList. This is used by the RIT when reading kbd 01360 * input, the desktop thread when reading mouse input, and the PnP callback 01361 * routines DeviceClassNotify() and DeviceNotify() when devices come and go. 01362 */ 01363 gpresDeviceInfoList = ExAllocatePoolWithTag(NonPagedPoolMustSucceed, 01364 sizeof(ERESOURCE), 01365 TAG_ERESOURCE); 01366 if (!gpresDeviceInfoList) { 01367 goto InitCreateUserCritExit; 01368 } 01369 if (!NT_SUCCESS(ExInitializeResourceLite(gpresDeviceInfoList))) { 01370 goto InitCreateUserCritExit; 01371 } 01372 01373 /* 01374 * Create the handle flag mutex. We'll need this once we start creating 01375 * windowstations and desktops. 01376 */ 01377 gpHandleFlagsMutex = ExAllocatePoolWithTag(NonPagedPoolMustSucceed, 01378 sizeof(FAST_MUTEX), 01379 TAG_SYSTEM); 01380 if (gpHandleFlagsMutex == NULL) { 01381 goto InitCreateUserCritExit; 01382 } 01383 ExInitializeFastMutex(gpHandleFlagsMutex); 01384 01385 TRACE_INIT(("Win32UserInit: gpHandleFlagsMutex = 0x%p\n", gpHandleFlagsMutex)); 01386 TRACE_INIT(("Win32UserInit: gpresDeviceInfoList = 0x%X\n", gpresDeviceInfoList)); 01387 TRACE_INIT(("Win32UserInit: gpresMouseEventQueue = 0x%X\n", gpresMouseEventQueue)); 01388 TRACE_INIT(("Win32UserInit: gpresUser = 0x%X\n", gpresUser)); 01389 01390 TRACE_INIT(("Win32UserInit: exit InitCreateUserCrit()\n")); 01391 return TRUE; 01392 01393 InitCreateUserCritExit: 01394 RIPERR0(ERROR_NOT_ENOUGH_MEMORY, RIP_ERROR, 01395 "Win32UserInit: InitCreateUserCrit failed"); 01396 01397 if (gpresUser) { 01398 ExFreePool(gpresUser); 01399 } 01400 if (gpresMouseEventQueue) { 01401 ExFreePool(gpresMouseEventQueue); 01402 } 01403 if (gpresDeviceInfoList) { 01404 ExFreePool(gpresDeviceInfoList); 01405 } 01406 return FALSE; 01407 } 01408 01409 /**************************************************************************\ 01410 * InitCreateObjectDirectory 01411 * 01412 * Create and initialize the user critical sections needed throughout the 01413 * system. 01414 * 01415 * 23-Jan-1996 ChrisWil Created. 01416 \**************************************************************************/ 01417 NTSTATUS InitCreateObjectDirectory(VOID) 01418 { 01419 HANDLE hDir; 01420 NTSTATUS Status; 01421 OBJECT_ATTRIBUTES ObjectAttributes; 01422 UNICODE_STRING UnicodeString; 01423 ULONG attributes = OBJ_CASE_INSENSITIVE | OBJ_PERMANENT; 01424 01425 TRACE_INIT(("UserInit: Create User Object-Directory\n")); 01426 01427 RtlInitUnicodeString(&UnicodeString, szWindowStationDirectory); 01428 01429 if (gbRemoteSession) { 01430 /* 01431 * Remote sessions don't use this flag 01432 */ 01433 attributes &= ~OBJ_PERMANENT; 01434 } 01435 01436 InitializeObjectAttributes(&ObjectAttributes, 01437 &UnicodeString, 01438 attributes, 01439 NULL, 01440 gpsdInitWinSta); 01441 01442 Status = ZwCreateDirectoryObject(&hDir, 01443 DIRECTORY_CREATE_OBJECT, 01444 &ObjectAttributes); 01445 01446 UserFreePool(gpsdInitWinSta); 01447 01448 /* 01449 * Do not close this handle for remote session because 01450 * if we do close it then the directory will go away and 01451 * we don't want that to happen. When CSRSS will go away 01452 * this handle will be freed also. 01453 */ 01454 if (!gbRemoteSession) 01455 ZwClose(hDir); 01456 01457 gpsdInitWinSta = NULL; 01458 01459 return Status; 01460 } 01461 01462 /**************************************************************************\ 01463 * InitCreateUserSubsystem 01464 * 01465 * Create and initialize the user subsystem stuff. 01466 * system. 01467 * 01468 * 23-Jan-1996 ChrisWil Created. 01469 \**************************************************************************/ 01470 BOOL 01471 InitCreateUserSubsystem() 01472 { 01473 LPWSTR lpszSubSystem; 01474 LPWSTR lpszT; 01475 UNICODE_STRING strSize; 01476 01477 TRACE_INIT(("UserInit: Create User SubSystem\n")); 01478 01479 /* 01480 * Initialize the subsystem section. This identifies the default 01481 * user-heap size. 01482 */ 01483 lpszSubSystem = UserAllocPoolWithQuota(USRINIT_SHAREDSECT_BUFF_SIZE * sizeof(WCHAR), 01484 TAG_SYSTEM); 01485 01486 if (lpszSubSystem == NULL) { 01487 return FALSE; 01488 } 01489 01490 if (FastGetProfileStringW(NULL, PMAP_SUBSYSTEMS, 01491 L"Windows", 01492 L"SharedSection=,3072", 01493 lpszSubSystem, 01494 USRINIT_SHAREDSECT_READ_SIZE 01495 ) == 0) { 01496 RIPMSG0(RIP_WARNING, 01497 "UserInit: Windows subsystem definition not found"); 01498 UserFreePool(lpszSubSystem); 01499 return FALSE; 01500 } 01501 01502 /* 01503 * Locate the SharedSection portion of the definition and extract 01504 * the second value. 01505 */ 01506 gdwDesktopSectionSize = USRINIT_WINDOWSECT_SIZE; 01507 gdwNOIOSectionSize = USRINIT_NOIOSECT_SIZE; 01508 01509 if (lpszT = wcsstr(lpszSubSystem, L"SharedSection")) { 01510 01511 *(lpszT + 32) = UNICODE_NULL; 01512 01513 if (lpszT = wcschr(lpszT, L',')) { 01514 01515 RtlInitUnicodeString(&strSize, ++lpszT); 01516 RtlUnicodeStringToInteger(&strSize, 0, &gdwDesktopSectionSize); 01517 01518 /* 01519 * Assert this logic doesn't need to change. 01520 */ 01521 UserAssert(gdwDesktopSectionSize >= USRINIT_WINDOWSECT_SIZE); 01522 01523 gdwDesktopSectionSize = max(USRINIT_WINDOWSECT_SIZE, gdwDesktopSectionSize); 01524 gdwNOIOSectionSize = gdwDesktopSectionSize; 01525 01526 /* 01527 * Now see if the optional non-interactive desktop 01528 * heap size was specified. 01529 */ 01530 if (lpszT = wcschr(lpszT, L',')) { 01531 01532 RtlInitUnicodeString(&strSize, ++lpszT); 01533 RtlUnicodeStringToInteger(&strSize, 0, &gdwNOIOSectionSize); 01534 01535 UserAssert(gdwNOIOSectionSize >= USRINIT_NOIOSECT_SIZE); 01536 gdwNOIOSectionSize = max(USRINIT_NOIOSECT_SIZE, gdwNOIOSectionSize); 01537 } 01538 } 01539 } 01540 01541 UserFreePool(lpszSubSystem); 01542 01543 return TRUE; 01544 } 01545 01546 extern UNICODE_STRING *gpastrSetupExe; // These are used in 01547 extern int giSetupExe; // SetAppImeCompatFlags in 01548 // queue.c 01549 01550 WCHAR* glpSetupPrograms; 01551 01552 /****************************************************** 01553 * 01554 * Create and initialize the arrary of setup app names. 01555 * We inherited this hack From Chicago. See queue.c for 01556 * more details. 01557 *******************************************************/ 01558 01559 BOOL CreateSetupNameArray() { 01560 DWORD dwProgNames; 01561 int iSetupProgramCount = 0; 01562 WCHAR* lpTemp; 01563 int ic, icnt, icMax; 01564 01565 dwProgNames = FastGetProfileValue(NULL, PMAP_SETUPPROGRAMNAMES, 01566 L"SetupProgramNames",NULL,NULL, 0); 01567 01568 /* 01569 * This key is a multi-string, so is best to read as a value. 01570 * First, get the length and create the buffer to hold all of 01571 * the strings. 01572 */ 01573 if (dwProgNames == 0) { 01574 return FALSE; 01575 } 01576 01577 glpSetupPrograms = UserAllocPoolWithQuota(dwProgNames, 01578 TAG_SYSTEM); 01579 01580 if (glpSetupPrograms == NULL) { 01581 RIPMSG0(RIP_WARNING, "CreateSetupNameArray: Memory allocation failure"); 01582 return FALSE; 01583 } 01584 01585 FastGetProfileValue(NULL, 01586 PMAP_SETUPPROGRAMNAMES, 01587 L"SetupProgramNames", 01588 NULL, 01589 (PBYTE)glpSetupPrograms, 01590 dwProgNames); 01591 01592 lpTemp = glpSetupPrograms; 01593 icMax = dwProgNames/2; 01594 ic = 0; icnt=0; 01595 /* 01596 * Now count the strings. 01597 */ 01598 while (ic < icMax) { 01599 if (*(lpTemp+ic) == 0) { 01600 ic++; 01601 continue; 01602 } 01603 ic += wcslen(lpTemp+ic)+1; 01604 icnt++; 01605 } 01606 01607 /* 01608 * gpastrSetupExe is a pointer to an array of UNICODE_STRING structures. 01609 * Each structure is the name of one setup program. 01610 */ 01611 giSetupExe = icnt; 01612 gpastrSetupExe = UserAllocPoolWithQuota(giSetupExe * sizeof(UNICODE_STRING), 01613 TAG_SYSTEM); 01614 01615 if (gpastrSetupExe == NULL) { 01616 RIPMSG0(RIP_WARNING, "CreateSetupNameArray: Memory allocation failure"); 01617 giSetupExe = 0; 01618 UserFreePool(glpSetupPrograms); 01619 glpSetupPrograms = NULL; 01620 return FALSE; 01621 } 01622 01623 ic = 0; icnt=0; 01624 while (ic < icMax) { 01625 if (*(lpTemp+ic) == 0) { 01626 ic++; 01627 continue; 01628 } 01629 gpastrSetupExe[icnt].Buffer = lpTemp+ic; 01630 gpastrSetupExe[icnt].Length = sizeof(WCHAR)*wcslen(lpTemp+ic); 01631 gpastrSetupExe[icnt].MaximumLength = gpastrSetupExe[icnt].Length + sizeof(WCHAR); 01632 ic += wcslen(lpTemp+ic)+1; 01633 icnt++; 01634 01635 } 01636 01637 return TRUE; 01638 } 01639 01640 #define CALC_DELTA(element) \ 01641 (PVOID)((PBYTE)pClientBase + \ 01642 ((PBYTE)gSharedInfo.element - \ 01643 (PBYTE)gpvSharedBase)) 01644 01645 /***************************************************************************\ 01646 * InitMapSharedSection 01647 * 01648 * This maps the shared section. 01649 * 01650 * 01651 * 25-Aug-1995 ChrisWil Created comment block. 01652 \***************************************************************************/ 01653 01654 NTSTATUS InitMapSharedSection( 01655 PEPROCESS Process, 01656 PUSERCONNECT pUserConnect) 01657 { 01658 int i; 01659 PVOID pClientBase = NULL; 01660 ULONG_PTR ulSharedDelta; 01661 01662 TRACE_INIT(("UserInit: Map Shared Memory Section\n")); 01663 01664 UserAssert(ghSectionShared != NULL); 01665 01666 ValidateProcessSessionId(Process); 01667 01668 /* 01669 * Check to see if we haven't already mapped the section 01670 * This might happen for multiple LoadLibrary()/FreeLibrary calls 01671 * in one process. MCostea #56946 01672 */ 01673 if (Process->Win32Process == NULL || 01674 ((PPROCESSINFO)Process->Win32Process)->pClientBase == NULL) { 01675 01676 SIZE_T ViewSize; 01677 LARGE_INTEGER liOffset; 01678 NTSTATUS Status; 01679 01680 ViewSize = 0; 01681 liOffset.QuadPart = 0; 01682 01683 Status = MmMapViewOfSection(ghSectionShared, 01684 Process, 01685 &pClientBase, 01686 0, 01687 0, 01688 &liOffset, 01689 &ViewSize, 01690 ViewUnmap, 01691 SEC_NO_CHANGE, 01692 PAGE_EXECUTE_READ); 01693 if (NT_SUCCESS(Status)) { 01694 TRACE_INIT(("UserInit: Map: Client SharedInfo Base = %x\n", pClientBase)); 01695 01696 UserAssert(gpvSharedBase > pClientBase); 01697 if (Process->Win32Process != NULL) { 01698 ((PPROCESSINFO)Process->Win32Process)->pClientBase = pClientBase; 01699 } 01700 } else { 01701 return Status; 01702 } 01703 01704 } else { 01705 pClientBase = ((PPROCESSINFO)Process->Win32Process)->pClientBase; 01706 } 01707 ulSharedDelta = (PBYTE)gpvSharedBase - (PBYTE)pClientBase; 01708 pUserConnect->siClient.ulSharedDelta = ulSharedDelta; 01709 01710 pUserConnect->siClient.psi = CALC_DELTA(psi); 01711 pUserConnect->siClient.aheList = CALC_DELTA(aheList); 01712 pUserConnect->siClient.pDispInfo = CALC_DELTA(pDispInfo); 01713 01714 01715 pUserConnect->siClient.DefWindowMsgs.maxMsgs = gSharedInfo.DefWindowMsgs.maxMsgs; 01716 pUserConnect->siClient.DefWindowMsgs.abMsgs = CALC_DELTA(DefWindowMsgs.abMsgs); 01717 pUserConnect->siClient.DefWindowSpecMsgs.maxMsgs = gSharedInfo.DefWindowSpecMsgs.maxMsgs; 01718 pUserConnect->siClient.DefWindowSpecMsgs.abMsgs = CALC_DELTA(DefWindowSpecMsgs.abMsgs); 01719 01720 for (i = 0; i < (FNID_END - FNID_START + 1); ++i) { 01721 01722 pUserConnect->siClient.awmControl[i].maxMsgs = gSharedInfo.awmControl[i].maxMsgs; 01723 01724 if (gSharedInfo.awmControl[i].abMsgs) 01725 pUserConnect->siClient.awmControl[i].abMsgs = CALC_DELTA(awmControl[i].abMsgs); 01726 else 01727 pUserConnect->siClient.awmControl[i].abMsgs = NULL; 01728 } 01729 return STATUS_SUCCESS; 01730 } 01731 /**************************************************************************\ 01732 * InitLoadResources 01733 * 01734 * 01735 * 25-Aug-1995 ChrisWil Created. 01736 \**************************************************************************/ 01737 01738 VOID InitLoadResources() 01739 { 01740 PRECT prc; 01741 01742 DISPLAYRESOURCE dr = { 01743 17, // Height of vertical thumb 01744 17, // Width of horizontal thumb 01745 2, // Icon horiz compression factor 01746 2, // Icon vert compression factor 01747 1, // Cursor horz compression factor 01748 1, // Cursor vert compression factor 01749 0, // Kanji window height 01750 1, // cxBorder (thickness of vertical lines) 01751 1 // cyBorder (thickness of horizontal lines) 01752 }; 01753 01754 01755 TRACE_INIT(("UserInit: Load Display Resources\n")); 01756 01757 if (dr.xCompressIcon > 10) { 01758 01759 /* 01760 * If so, the actual dimensions of icons and cursors are 01761 * kept in OEMBIN. 01762 */ 01763 SYSMET(CXICON) = dr.xCompressIcon; 01764 SYSMET(CYICON) = dr.yCompressIcon; 01765 SYSMET(CXCURSOR) = dr.xCompressCursor; 01766 SYSMET(CYCURSOR) = dr.yCompressCursor; 01767 01768 } else { 01769 01770 /* 01771 * Else, only the ratio of (64/icon dimensions) is kept there. 01772 */ 01773 SYSMET(CXICON) = (64 / dr.xCompressIcon); 01774 SYSMET(CYICON) = (64 / dr.yCompressIcon); 01775 SYSMET(CXCURSOR) = (32 / dr.xCompressCursor); 01776 SYSMET(CYCURSOR) = (32 / dr.yCompressCursor); 01777 } 01778 01779 SYSMET(CXSMICON) = SYSMET(CXICON) / 2; 01780 SYSMET(CYSMICON) = SYSMET(CYICON) / 2; 01781 01782 SYSMET(CYKANJIWINDOW) = dr.yKanji; 01783 01784 /* 01785 * Get border thicknesses. 01786 */ 01787 SYSMET(CXBORDER) = dr.cxBorder; 01788 SYSMET(CYBORDER) = dr.cyBorder; 01789 01790 /* 01791 * Edge is two borders. 01792 */ 01793 SYSMET(CXEDGE) = 2 * SYSMET(CXBORDER); 01794 SYSMET(CYEDGE) = 2 * SYSMET(CYBORDER); 01795 01796 /* 01797 * Fixed frame is outer edge + border. 01798 */ 01799 SYSMET(CXDLGFRAME) = SYSMET(CXEDGE) + SYSMET(CXBORDER); 01800 SYSMET(CYDLGFRAME) = SYSMET(CYEDGE) + SYSMET(CYBORDER); 01801 01802 if (gbRemoteSession) { 01803 return; 01804 } 01805 01806 prc = &GetPrimaryMonitor()->rcMonitor; 01807 SYSMET(CXFULLSCREEN) = prc->right; 01808 SYSMET(CYFULLSCREEN) = prc->bottom - SYSMET(CYCAPTION); 01809 01810 /* 01811 * Set the initial cursor position to the center of the primary screen. 01812 */ 01813 gpsi->ptCursor.x = prc->right / 2; 01814 gpsi->ptCursor.y = prc->bottom / 2; 01815 } 01816 01817 /***************************************************************************\ 01818 * GetCharDimensions 01819 * 01820 * This function loads the Textmetrics of the font currently selected into 01821 * the hDC and returns the Average char width of the font; Pl Note that the 01822 * AveCharWidth value returned by the Text metrics call is wrong for 01823 * proportional fonts. So, we compute them On return, lpTextMetrics contains 01824 * the text metrics of the currently selected font. 01825 * 01826 * History: 01827 * 10-Nov-1993 mikeke Created 01828 \***************************************************************************/ 01829 int GetCharDimensions( 01830 HDC hdc, 01831 TEXTMETRIC* lptm, 01832 LPINT lpcy 01833 ) 01834 { 01835 TEXTMETRIC tm; 01836 01837 /* 01838 * Didn't find it in cache, store the font metrics info. 01839 */ 01840 if (!_GetTextMetricsW(hdc, &tm)) { 01841 RIPMSG1(RIP_WARNING, "GetCharDimensions: _GetTextMetricsW failed. hdc %#lx", hdc); 01842 tm = gpsi->tmSysFont; // damage control 01843 01844 if (tm.tmAveCharWidth == 0) { 01845 RIPMSG0(RIP_WARNING, "GetCharDimensions: _GetTextMetricsW first time failure"); 01846 tm.tmAveCharWidth = 8; 01847 } 01848 } 01849 if (lptm != NULL) 01850 *lptm = tm; 01851 if (lpcy != NULL) 01852 *lpcy = tm.tmHeight; 01853 01854 /* 01855 * If variable_width font 01856 */ 01857 if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH) { 01858 SIZE size; 01859 static CONST WCHAR wszAvgChars[] = 01860 L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 01861 01862 /* 01863 * Change from tmAveCharWidth. We will calculate a true average 01864 * as opposed to the one returned by tmAveCharWidth. This works 01865 * better when dealing with proportional spaced fonts. 01866 */ 01867 if (GreGetTextExtentW( 01868 hdc, (LPWSTR)wszAvgChars, 01869 (sizeof(wszAvgChars) / sizeof(WCHAR)) - 1, 01870 &size, GGTE_WIN3_EXTENT)) { 01871 01872 UserAssert((((size.cx / 26) + 1) / 2) > 0); 01873 return ((size.cx / 26) + 1) / 2; // round up 01874 } else { 01875 RIPMSG1(RIP_WARNING, "GetCharDimensions: GreGetTextExtentW failed. hdc %#lx", hdc); 01876 } 01877 } 01878 01879 UserAssert(tm.tmAveCharWidth > 0); 01880 01881 return tm.tmAveCharWidth; 01882 } 01883 01884 01885 /**************************************************************************\ 01886 * InitVideo 01887 * 01888 * Create pmdev. 01889 * 01890 * 03-March-1998 CLupu Moved from UserInitialize code 01891 \**************************************************************************/ 01892 01893 PMDEV InitVideo( 01894 BOOL bReenumerationNeeded) 01895 { 01896 PMDEV pmdev; 01897 LONG ChangeStatus; 01898 01899 /* 01900 * BUGBUG !!! Need to get a status return from this call. 01901 */ 01902 DrvInitConsole(bReenumerationNeeded); 01903 01904 /* 01905 * BASEVIDEO may be on or off, whether we are in setup or not. 01906 */ 01907 01908 ChangeStatus = DrvChangeDisplaySettings(NULL, 01909 NULL, 01910 NULL, 01911 (PVOID) (GW_DESKTOP_ID), 01912 KernelMode, 01913 FALSE, 01914 TRUE, 01915 NULL, 01916 &pmdev, 01917 GRE_DEFAULT, 01918 TRUE); 01919 01920 if (ChangeStatus != GRE_DISP_CHANGE_SUCCESSFUL) { 01921 01922 /* 01923 * If we fail, try BASEVIDEO temporarily 01924 */ 01925 01926 DrvSetBaseVideo(TRUE); 01927 01928 ChangeStatus = DrvChangeDisplaySettings(NULL, 01929 NULL, 01930 NULL, 01931 (PVOID) (GW_DESKTOP_ID), 01932 KernelMode, 01933 FALSE, 01934 TRUE, 01935 NULL, 01936 &pmdev, 01937 GRE_DEFAULT, 01938 TRUE); 01939 01940 DrvSetBaseVideo(FALSE); 01941 01942 /* 01943 * Give it one last try, not in basevideo, to handle TGA 01944 * (non-vgacompatible) during GUI-mode setup (BASEVIDEO is on by 01945 * default) 01946 */ 01947 01948 if (ChangeStatus != GRE_DISP_CHANGE_SUCCESSFUL) { 01949 01950 ChangeStatus = DrvChangeDisplaySettings(NULL, 01951 NULL, 01952 NULL, 01953 (PVOID) (GW_DESKTOP_ID), 01954 KernelMode, 01955 FALSE, 01956 TRUE, 01957 NULL, 01958 &pmdev, 01959 GRE_DEFAULT, 01960 TRUE); 01961 01962 } 01963 } 01964 01965 if (ChangeStatus != GRE_DISP_CHANGE_SUCCESSFUL) { 01966 RIPMSG0(RIP_WARNING, "InitVideo: No working display driver found"); 01967 return NULL; 01968 } 01969 01970 gpDispInfo->hDev = pmdev->hdevParent; 01971 gpDispInfo->pmdev = pmdev; 01972 01973 GreUpdateSharedDevCaps(gpDispInfo->hDev); 01974 01975 if (!InitUserScreen()) { 01976 RIPMSG0(RIP_WARNING, "InitUserScreen failed"); 01977 return NULL; 01978 } 01979 01980 HYDRA_HINT(HH_INITVIDEO); 01981 01982 return pmdev; 01983 } 01984 01985 void DrvDriverFailure(void) 01986 { 01987 KeBugCheckEx(VIDEO_DRIVER_INIT_FAILURE, 01988 0, 01989 0, 01990 0, 01991 USERCURRENTVERSION); 01992 } 01993 01994 01995 /**************************************************************************\ 01996 * UserInitialize 01997 * 01998 * Worker routine for user initialization. 01999 * 02000 * 25-Aug-1995 ChrisWil Created comment block/Multiple desktop support. 02001 * 15-Dec-1995 BradG Modified to return MediaChangeEvent Handle. 02002 \**************************************************************************/ 02003 02004 NTSTATUS UserInitialize(VOID) 02005 { 02006 NTSTATUS Status; 02007 02008 /* 02009 * Allow a trace of all the init stuff going on related to display drivers. 02010 * Usefull to debug boot time problems related to graphics. 02011 */ 02012 if (**((PULONG *)&NtGlobalFlag) & FLG_SHOW_LDR_SNAPS) 02013 TraceInitialization = 1; 02014 02015 TRACE_INIT(("Entering UserInitialize\n")); 02016 02017 EnterCrit(); 02018 02019 HYDRA_HINT(HH_USERINITIALIZE); 02020 02021 if (ISTS()) { 02022 02023 if (gbRemoteSession) { 02024 swprintf(szWindowStationDirectory, L"%ws\\%ld%ws", 02025 SESSION_ROOT, gSessionId, WINSTA_DIR); 02026 } else { 02027 wcscpy(szWindowStationDirectory, WINSTA_DIR); 02028 } 02029 } else { 02030 wcscpy(szWindowStationDirectory, WINSTA_DIR); 02031 } 02032 02033 /* 02034 * Create WindowStation object directory. 02035 */ 02036 Status = InitCreateObjectDirectory(); 02037 02038 if (!NT_SUCCESS(Status)) { 02039 RIPMSG1(RIP_WARNING, "InitCreateObjectDirectory failed with Status %x", 02040 Status); 02041 02042 goto Exit; 02043 } 02044 02045 /* 02046 * WinStations get init'ed on the first connect 02047 */ 02048 if (gbRemoteSession) { 02049 02050 /* 02051 * Create the event for the diconnect desktop creation 02052 */ 02053 gpEventDiconnectDesktop = CreateKernelEvent(SynchronizationEvent, FALSE); 02054 02055 if (gpEventDiconnectDesktop == NULL) { 02056 RIPMSG0(RIP_WARNING, "Failed to create gpEventDiconnectDesktop"); 02057 Status = STATUS_NO_MEMORY; 02058 goto Exit; 02059 } 02060 02061 goto SkipRemote; 02062 } 02063 02064 if (InitVideo(TRUE) == NULL) { 02065 DrvDriverFailure(); 02066 } 02067 02068 /* 02069 * Do this here so power callouts 02070 * have the pmdev in gpDispInfo set 02071 */ 02072 gbVideoInitialized = TRUE; 02073 02074 SkipRemote: 02075 02076 gbUserInitialized = TRUE; 02077 02078 /* 02079 * Now that the system is initialized, allocate 02080 * a pti for this thread. 02081 */ 02082 Status = xxxCreateThreadInfo(PsGetCurrentThread(), FALSE); 02083 02084 if (!NT_SUCCESS(Status)) { 02085 RIPMSG1(RIP_WARNING, "xxxCreateThreadInfo failed during UserInitialize with Status", 02086 Status); 02087 goto Exit; 02088 } 02089 02090 /* 02091 * Initialize Global RIP flags (debug only). 02092 */ 02093 InitGlobalRIPFlags(); 02094 02095 /* 02096 * WinStations get init'ed on the first connect 02097 */ 02098 if (!gbRemoteSession) 02099 UserVerify(LW_BrushInit()); 02100 02101 InitLoadResources(); 02102 02103 Exit: 02104 LeaveCrit(); 02105 02106 TRACE_INIT(("Leaving UserInitialize\n")); 02107 02108 return Status; 02109 } 02110 02111 /**************************************************************************\ 02112 * IsDBCSEnabledSystem 02113 * 02114 * check if the system is configured as FE Enabled 02115 * 02116 * 07-Feb-1997 HiroYama Created 02117 \**************************************************************************/ 02118 BOOL IsDBCSEnabledSystem() 02119 { 02120 extern BOOLEAN* NlsMbCodePageTag; 02121 return !!*NlsMbCodePageTag; 02122 } 02123 02124 02125 BOOL IsIMMEnabledSystem() 02126 { 02127 // if the entire system is DBCS enabled, IMM/IME should be activated anyway 02128 if (IsDBCSEnabledSystem()) 02129 return TRUE; 02130 02131 return FastGetProfileDwordW(NULL, PMAP_IMM, TEXT("LoadIMM"), 0); 02132 } 02133 02134 // Get ACP and check if the system is configured as ME Enabled 02135 BOOL IsMidEastEnabledSystem() 02136 { 02137 extern __declspec(dllimport) USHORT NlsAnsiCodePage; 02138 //1255 Hebrew and 1256 Arabic 02139 if ((NlsAnsiCodePage == 1255) || (NlsAnsiCodePage == 1256)) { 02140 return TRUE; 02141 } 02142 return FALSE; 02143 } 02144 02145 /***************************************************************************\ 02146 * SetupClassAtoms 02147 * 02148 * 10/01/1998 clupu moved from Win32UserInitialize 02149 \***************************************************************************/ 02150 02151 BOOL SetupClassAtoms( 02152 VOID) 02153 { 02154 BOOL fSuccess = TRUE; 02155 int ind; 02156 02157 /* 02158 * Set up class atoms 02159 */ 02160 /* 02161 * HACK: Controls are registered on the client side so we can't 02162 * fill in their atomSysClass entry the same way we do for the other 02163 * classes. 02164 */ 02165 for (ind = ICLS_BUTTON; ind < ICLS_CTL_MAX; ind++) { 02166 gpsi->atomSysClass[ind] = UserAddAtom(lpszControls[ind], TRUE); 02167 fSuccess &= !!gpsi->atomSysClass[ind]; 02168 } 02169 02170 gpsi->atomSysClass[ICLS_DIALOG] = PTR_TO_ID(DIALOGCLASS); 02171 gpsi->atomSysClass[ICLS_ICONTITLE] = PTR_TO_ID(ICONTITLECLASS); 02172 gpsi->atomSysClass[ICLS_TOOLTIP] = PTR_TO_ID(TOOLTIPCLASS); 02173 gpsi->atomSysClass[ICLS_DESKTOP] = PTR_TO_ID(DESKTOPCLASS); 02174 gpsi->atomSysClass[ICLS_SWITCH] = PTR_TO_ID(SWITCHWNDCLASS); 02175 gpsi->atomSysClass[ICLS_MENU] = PTR_TO_ID(MENUCLASS); 02176 02177 gpsi->atomContextHelpIdProp = UserAddAtom(szCONTEXTHELPIDPROP, TRUE); 02178 fSuccess &= !!gpsi->atomContextHelpIdProp; 02179 02180 gpsi->atomIconSmProp = UserAddAtom(szICONSM_PROP_NAME, TRUE); 02181 fSuccess &= !!gpsi->atomIconSmProp; 02182 02183 gpsi->atomIconProp = UserAddAtom(szICON_PROP_NAME, TRUE); 02184 fSuccess &= !!gpsi->atomIconProp; 02185 02186 gpsi->uiShellMsg = UserAddAtom(szSHELLHOOK, TRUE); 02187 fSuccess &= !!gpsi->uiShellMsg; 02188 02189 /* 02190 * Initialize the integer atoms for our magic window properties 02191 */ 02192 atomCheckpointProp = UserAddAtom(szCHECKPOINT_PROP_NAME, TRUE); 02193 fSuccess &= !!atomCheckpointProp; 02194 02195 atomDDETrack = UserAddAtom(szDDETRACK_PROP_NAME, TRUE); 02196 fSuccess &= !!atomDDETrack; 02197 02198 atomQOS = UserAddAtom(szQOS_PROP_NAME, TRUE); 02199 fSuccess &= !!atomQOS; 02200 02201 atomDDEImp = UserAddAtom(szDDEIMP_PROP_NAME, TRUE); 02202 fSuccess &= !!atomDDEImp; 02203 02204 atomWndObj = UserAddAtom(szWNDOBJ_PROP_NAME, TRUE); 02205 fSuccess &= !!atomWndObj; 02206 02207 atomImeLevel = UserAddAtom(szIMELEVEL_PROP_NAME, TRUE); 02208 fSuccess &= !!atomImeLevel; 02209 02210 atomLayer = UserAddAtom(szLAYER_PROP_NAME, TRUE); 02211 fSuccess &= !!atomLayer; 02212 02213 guiActivateShellWindow = UserAddAtom(szACTIVATESHELLWINDOW, TRUE); 02214 fSuccess &= !!guiActivateShellWindow; 02215 02216 guiOtherWindowCreated = UserAddAtom(szOTHERWINDOWCREATED, TRUE); 02217 fSuccess &= !!guiOtherWindowCreated; 02218 02219 guiOtherWindowDestroyed = UserAddAtom(szOTHERWINDOWDESTROYED, TRUE); 02220 fSuccess &= !!guiOtherWindowDestroyed; 02221 02222 gatomMessage = UserAddAtom(szMESSAGE, TRUE); 02223 fSuccess &= !!gatomMessage; 02224 02225 #ifdef HUNGAPP_GHOSTING 02226 gatomGhost = UserAddAtom(szGHOST, TRUE); 02227 fSuccess &= !!gatomGhost; 02228 #endif // HUNGAPP_GHOSTING 02229 02230 gaOleMainThreadWndClass = UserAddAtom(szOLEMAINTHREADWNDCLASS, TRUE); 02231 fSuccess &= !!gaOleMainThreadWndClass; 02232 02233 gaFlashWState = UserAddAtom(szFLASHWSTATE, TRUE); 02234 fSuccess &= !!gaFlashWState; 02235 02236 gatomLastPinned = gaOleMainThreadWndClass; 02237 02238 return fSuccess; 02239 } 02240 02241 02242 /**************************************************************************\ 02243 * Win32UserInitialize 02244 * 02245 * Worker routine for user initialization called from Win32k.sys DriverEntry() 02246 * 02247 \**************************************************************************/ 02248 02249 NTSTATUS Win32UserInitialize(VOID) 02250 { 02251 NTSTATUS Status; 02252 POBJECT_TYPE_INITIALIZER pTypeInfo; 02253 LONG lTemp; 02254 02255 TRACE_INIT(("Entering Win32UserInitialize\n")); 02256 02257 /* 02258 * Create the shared section. 02259 */ 02260 Status = InitCreateSharedSection(); 02261 if (!NT_SUCCESS(Status)) { 02262 RIPMSG0(RIP_WARNING, "InitCreateSharedSection failed"); 02263 return Status; 02264 } 02265 02266 EnterCrit(); 02267 02268 /* 02269 * Initialize security stuff. 02270 */ 02271 if (!InitSecurity()) { 02272 RIPMSG0(RIP_WARNING, "InitSecurity failed"); 02273 goto ExitWin32UserInitialize; 02274 } 02275 02276 /* 02277 * Fill in windowstation and desktop object types 02278 */ 02279 pTypeInfo = &(*ExWindowStationObjectType)->TypeInfo; 02280 pTypeInfo->DefaultNonPagedPoolCharge = sizeof(WINDOWSTATION) + sizeof(KEVENT); 02281 pTypeInfo->DefaultPagedPoolCharge = 0; 02282 pTypeInfo->MaintainHandleCount = TRUE; 02283 pTypeInfo->CloseProcedure = DestroyWindowStation; 02284 pTypeInfo->DeleteProcedure = FreeWindowStation; 02285 pTypeInfo->ParseProcedure = ParseWindowStation; 02286 pTypeInfo->OkayToCloseProcedure = OkayToCloseWindowStation; 02287 pTypeInfo->ValidAccessMask = WinStaMapping.GenericAll; 02288 pTypeInfo->GenericMapping = WinStaMapping; 02289 02290 pTypeInfo = &(*ExDesktopObjectType)->TypeInfo; 02291 pTypeInfo->DefaultNonPagedPoolCharge = sizeof(DESKTOP); 02292 pTypeInfo->DefaultPagedPoolCharge = 0; 02293 pTypeInfo->MaintainHandleCount = TRUE; 02294 pTypeInfo->CloseProcedure = UnmapDesktop; 02295 pTypeInfo->OpenProcedure = MapDesktop; 02296 pTypeInfo->DeleteProcedure = FreeDesktop; 02297 pTypeInfo->OkayToCloseProcedure = OkayToCloseDesktop; 02298 pTypeInfo->ValidAccessMask = DesktopMapping.GenericAll; 02299 pTypeInfo->GenericMapping = DesktopMapping; 02300 02301 /* 02302 * Get this process so we can use the profiles. 02303 */ 02304 gpepInit = PsGetCurrentProcess(); 02305 02306 Status = InitQEntryLookaside(); 02307 Status |= InitSMSLookaside(); 02308 Status |= UserRtlCreateAtomTable(USRINIT_ATOMBUCKET_SIZE); 02309 02310 if (!NT_SUCCESS(Status)) { 02311 RIPMSG0(RIP_WARNING, "Initialization failure"); 02312 goto ExitWin32UserInitialize; 02313 } 02314 02315 atomUSER32 = UserAddAtom(szUSER32, TRUE); 02316 02317 gatomFirstPinned = atomUSER32; 02318 02319 if (gatomFirstPinned == 0) { 02320 RIPMSG0(RIP_WARNING, "Could not create atomUSER32"); 02321 goto ExitWin32UserInitialize; 02322 } 02323 02324 /* 02325 * Initialize the user subsystem information. 02326 */ 02327 if (!InitCreateUserSubsystem()) { 02328 RIPMSG0(RIP_WARNING, "InitCreateUserSubsystem failed"); 02329 goto ExitWin32UserInitialize; 02330 } 02331 02332 /* 02333 * Don't bail out if CreateSetupNameArray fails 02334 * MCostea #326652 02335 */ 02336 CreateSetupNameArray(); 02337 02338 /* 02339 * Allocated shared SERVERINFO structure. 02340 */ 02341 if ((gpsi = (PSERVERINFO)SharedAlloc(sizeof(SERVERINFO))) == NULL) { 02342 RIPMSG0(RIP_WARNING, "Could not allocate SERVERINFO"); 02343 goto ExitWin32UserInitialize; 02344 } 02345 02346 /* 02347 * Set the default rip-flags to rip on just about 02348 * everything. We'll truly set this in the InitGlobalRIPFlags() 02349 * routine. These are needed so that we can do appropriate ripping 02350 * during the rest of the init-calls. 02351 */ 02352 02353 SET_FLAG(gpsi->wRIPFlags, RIPF_DEFAULT); 02354 02355 /* 02356 * Make sure we will not get a division by zero if the initialization 02357 * will not complete correctly. Set these to their normal values. 02358 */ 02359 gpsi->cxMsgFontChar = 6; 02360 gpsi->cyMsgFontChar = 13; 02361 gpsi->cxSysFontChar = 8; 02362 gpsi->cySysFontChar = 16; 02363 02364 /* 02365 * Initialize the DISPLAYINFO structure. 02366 */ 02367 gpDispInfo = SharedAlloc(sizeof(*gpDispInfo)); 02368 if (!gpDispInfo) { 02369 RIPMSG0(RIP_WARNING, "Could not allocate gpDispInfo"); 02370 goto ExitWin32UserInitialize; 02371 } 02372 02373 InitDbgTags(); 02374 02375 SET_OR_CLEAR_SRVIF(SRVIF_DBCS, IsDBCSEnabledSystem()); 02376 SET_OR_CLEAR_SRVIF(SRVIF_IME, IsIMMEnabledSystem()); 02377 02378 SET_OR_CLEAR_SRVIF(SRVIF_MIDEAST, IsMidEastEnabledSystem()); 02379 02380 #if DBG 02381 SET_SRVIF(SRVIF_CHECKED); 02382 02383 RIPMSG3(RIP_WARNING, "*** win32k: DBCS:[%d] IME:[%d] MiddleEast:[%d]", 02384 IS_DBCS_ENABLED(), 02385 IS_IME_ENABLED(), 02386 IS_MIDEAST_ENABLED()); 02387 #endif 02388 02389 gpsi->dwDefaultHeapSize = gdwDesktopSectionSize * 1024; 02390 02391 /* 02392 * Initialize procedures and message tables. 02393 * Initialize the class structures for Get/SetClassWord/Long. 02394 * Initialize message-box strings. 02395 * Initialize OLE-Formats (performance-hack). 02396 */ 02397 InitFunctionTables(); 02398 InitMessageTables(); 02399 #if DBG 02400 VerifySyncOnlyMessages(); 02401 #endif 02402 if (!InitOLEFormats()) { 02403 RIPMSG0(RIP_WARNING, "InitOLEFormats failed"); 02404 goto ExitWin32UserInitialize; 02405 } 02406 02407 /* 02408 * Set up class atoms 02409 */ 02410 if (!SetupClassAtoms()) { 02411 RIPMSG0(RIP_WARNING, "SetupClassAtoms failed to register atoms"); 02412 goto ExitWin32UserInitialize; 02413 } 02414 02415 LW_LoadSomeStrings(); 02416 02417 /* 02418 * Initialize the handle manager. 02419 */ 02420 if (!HMInitHandleTable(gpvSharedBase)) { 02421 RIPMSG0(RIP_WARNING, "HMInitHandleTable failed"); 02422 goto ExitWin32UserInitialize; 02423 } 02424 02425 /* 02426 * Setup shared info block. 02427 */ 02428 gSharedInfo.psi = gpsi; 02429 gSharedInfo.pDispInfo = gpDispInfo; 02430 02431 /* 02432 * Determine if we have unsigned drivers installed 02433 * Use 2BD63D28D7BCD0E251195AEB519243C13142EBC3 as current key to check. 02434 * Old key: 300B971A74F97E098B67A4FCEBBBF6B9AE2F404C 02435 */ 02436 if (NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, 02437 L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\SystemCertificates\\Root\\Certificates\\2BD63D28D7BCD0E251195AEB519243C13142EBC3")) 02438 || 02439 NT_SUCCESS(RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, 02440 L"\\Registry\\Machine\\SOFTWARE\\Policies\\Microsoft\\SystemCertificates\\Root\\Certificates\\2BD63D28D7BCD0E251195AEB519243C13142EBC3"))) { 02441 02442 gfUnsignedDrivers = TRUE; 02443 } 02444 02445 /* 02446 * Set up a desktop info structure that is visible in all 02447 * clients. 02448 */ 02449 lTemp = FastGetProfileDwordW(NULL, 02450 PMAP_WINDOWSM, 02451 L"USERProcessHandleQuota", 02452 gUserProcessHandleQuota); 02453 02454 if ((lTemp > MINIMUM_USER_HANDLE_QUOTA) && (lTemp <= INITIAL_USER_HANDLE_QUOTA)) { 02455 gUserProcessHandleQuota = lTemp; 02456 } 02457 02458 /* 02459 * The maximum number of posted message for a thread. 02460 */ 02461 lTemp = FastGetProfileDwordW(NULL, 02462 PMAP_WINDOWSM, 02463 L"USERPostMessageLimit", 02464 gUserPostMessageLimit); 02465 if (lTemp > MINIMUM_POSTMESSAGE_LIMIT) { 02466 gUserPostMessageLimit = lTemp; 02467 } else if (lTemp == 0) { 02468 /* 02469 * 0 means (virtually) No Limit. 02470 */ 02471 gUserPostMessageLimit = ~0; 02472 } else { 02473 RIPMSG1(RIP_WARNING, "Win32UserInitialize: USERPostMessageLimit value (%d) is too low.", lTemp); 02474 } 02475 02476 if (!gDrawVersionAlways) { 02477 gDrawVersionAlways = FastGetProfileDwordW(NULL, 02478 PMAP_WINDOWSM, 02479 L"DisplayVersion", 02480 0); 02481 } 02482 02483 gbSecureDesktop = FastGetProfileDwordW(NULL, 02484 PMAP_WINDOWSM, 02485 L"SecureDesktop", 02486 TRUE); 02487 02488 /* 02489 * Initialize SMWP structure 02490 */ 02491 if (!AllocateCvr(&gSMWP, 4)) { 02492 RIPMSG0(RIP_WARNING, "AllocateCvr failed"); 02493 goto ExitWin32UserInitialize; 02494 } 02495 LeaveCrit(); 02496 02497 UserAssert(NT_SUCCESS(Status)); 02498 return Status; 02499 02500 ExitWin32UserInitialize: 02501 LeaveCrit(); 02502 02503 if (NT_SUCCESS(Status)) { 02504 Status = STATUS_NO_MEMORY; 02505 } 02506 02507 RIPMSG1(RIP_WARNING, "UserInitialize failed with Status = %x", Status); 02508 return Status; 02509 } 02510 02511 02512 /**************************************************************************\ 02513 * UserGetDesktopDC 02514 * 02515 * 09-Jan-1992 mikeke created 02516 * Dec-1993 andreva changed to support desktops. 02517 \**************************************************************************/ 02518 02519 HDC UserGetDesktopDC( 02520 ULONG type, 02521 BOOL bAltType, 02522 BOOL bValidate) 02523 { 02524 PETHREAD Thread; 02525 HDC hdc; 02526 PTHREADINFO pti = PtiCurrentShared(); // This is called from outside the crit sec 02527 HDEV hdev = gpDispInfo->hDev; 02528 02529 if (bValidate && type != DCTYPE_INFO && 02530 IS_THREAD_RESTRICTED(pti, JOB_OBJECT_UILIMIT_HANDLES)) { 02531 02532 UserAssert(pti->rpdesk != NULL); 02533 02534 if (!ValidateHwnd(PtoH(pti->rpdesk->pDeskInfo->spwnd))) { 02535 RIPMSG0(RIP_WARNING, 02536 "UserGetDesktopDC fails desktop window validation"); 02537 return NULL; 02538 } 02539 } 02540 02541 /* 02542 * !!! BUGBUG 02543 * This is a real nasty trick to get both DCs created on a desktop on 02544 * a different device to work (for the video applet) and to be able 02545 * to clip DCs that are actually on the same device ... 02546 */ 02547 if (pti && pti->rpdesk) 02548 hdev = pti->rpdesk->pDispInfo->hDev; 02549 02550 /* 02551 * We want to turn this call that was originally OpenDC("Display", ...) 02552 * into GetDC null call so this DC will be clipped to the current 02553 * desktop or else the DC can write to any desktop. Only do this 02554 * for client apps; let the server do whatever it wants. 02555 */ 02556 Thread = PsGetCurrentThread(); 02557 if ((type != DCTYPE_DIRECT) || 02558 (hdev != gpDispInfo->hDev) || 02559 IS_SYSTEM_THREAD(Thread) || 02560 (Thread->ThreadsProcess == gpepCSRSS)) { 02561 02562 hdc = GreCreateDisplayDC(hdev, type, bAltType); 02563 02564 } else { 02565 02566 PDESKTOP pdesk; 02567 02568 EnterCrit(); 02569 02570 if (pdesk = PtiCurrent()->rpdesk) { 02571 02572 hdc = _GetDCEx(pdesk->pDeskInfo->spwnd, 02573 NULL, 02574 DCX_WINDOW | DCX_CACHE | DCX_CREATEDC); 02575 } else { 02576 hdc = NULL; 02577 } 02578 02579 LeaveCrit(); 02580 } 02581 02582 return hdc; 02583 } 02584 02585 02586 /**************************************************************************\ 02587 * UserThreadCallout 02588 * 02589 * 02590 * Called by the kernel when a thread starts or ends. 02591 * 02592 * Dec-1993 andreva created. 02593 \**************************************************************************/ 02594 02595 NTSTATUS UserThreadCallout( 02596 IN PETHREAD pEThread, 02597 IN PSW32THREADCALLOUTTYPE CalloutType) 02598 { 02599 PTHREADINFO pti; 02600 NTSTATUS Status = STATUS_SUCCESS; 02601 02602 UserAssert(gpresUser != NULL); 02603 02604 switch (CalloutType) { 02605 case PsW32ThreadCalloutInitialize: 02606 TRACE_INIT(("Entering UserThreadCallout PsW32ThreadCalloutInitialize\n")); 02607 02608 if (gbNoMorePowerCallouts) { 02609 RIPMSG0(RIP_WARNING, "No more GUI threads allowed"); 02610 return STATUS_UNSUCCESSFUL; 02611 } 02612 02613 /* 02614 * Only create a thread info structure if we're initialized. 02615 */ 02616 if (gbUserInitialized) { 02617 EnterCrit(); 02618 UserAssert(gpepCSRSS != NULL); 02619 02620 /* 02621 * Initialize this thread 02622 */ 02623 Status = xxxCreateThreadInfo(pEThread, FALSE); 02624 02625 LeaveCrit(); 02626 } 02627 break; 02628 02629 case PsW32ThreadCalloutExit: 02630 02631 TRACE_INIT(("Entering UserThreadCallout PsW32ThreadCalloutExit\n")); 02632 02633 /* 02634 * If we aren't already inside the critical section, enter it. 02635 * Because this is the first pass, we remain in the critical 02636 * section when we return so that our try/finally handlers 02637 * are protected by the critical section. 02638 * EnterCrit here before GreUnlockDisplay() provides a pti which 02639 * may be required if unlocking the display may release some 02640 * deferred WinEvents, for which a pti is required. 02641 */ 02642 EnterCrit(); 02643 02644 pti = (PTHREADINFO)pEThread->Tcb.Win32Thread; 02645 02646 /* 02647 * WinStations that haven't gone through the first connect do not 02648 * have any of the graphics setup. 02649 */ 02650 if (!gbRemoteSession || gbVideoInitialized) { 02651 02652 /* 02653 * Assert that we did not cleaned up gpDispInfo->hDev 02654 */ 02655 UserAssert(!gbCleanedUpResources); 02656 02657 GreLockDisplay(gpDispInfo->hDev); 02658 GreUnlockDisplay(gpDispInfo->hDev); 02659 } 02660 02661 02662 /* 02663 * Mark this thread as in the middle of cleanup. This is useful for 02664 * several problems in USER where we need to know this information. 02665 */ 02666 pti->TIF_flags |= TIF_INCLEANUP; 02667 02668 /* 02669 * If we died during a full screen switch make sure we cleanup 02670 * correctly 02671 */ 02672 FullScreenCleanup(); 02673 /* 02674 * Cleanup gpDispInfo->hdcScreen - if we crashed while using it, 02675 * it may have owned objects still selected into it. Cleaning 02676 * it this way will ensure that gdi doesn't try to delete these 02677 * objects while they are still selected into this public hdc. 02678 */ 02679 02680 /* 02681 * WinStations that haven't gone through the first connect do not 02682 * have any of the graphics setup. 02683 */ 02684 if (!gbRemoteSession || gbVideoInitialized) { 02685 GreCleanDC(gpDispInfo->hdcScreen); 02686 } 02687 02688 /* 02689 * This thread is exiting execution; xxxDestroyThreadInfo cleans 02690 * up everything that can go now 02691 */ 02692 UserAssert(pti == PtiCurrent()); 02693 xxxDestroyThreadInfo(); 02694 LeaveCrit(); 02695 02696 break; 02697 } 02698 02699 TRACE_INIT(("Leaving UserThreadCallout\n")); 02700 02701 return Status; 02702 } 02703 02704 /**************************************************************************\ 02705 * NtUserInitialize 02706 * 02707 * 01-Dec-1993 andreva created. 02708 * 01-Dec-1995 BradG Modified to return handle to Media Change Event 02709 \**************************************************************************/ 02710 02711 BOOL TellGdiToGetReady(); 02712 02713 NTSTATUS NtUserInitialize( 02714 IN DWORD dwVersion, 02715 IN HANDLE hPowerRequestEvent, 02716 IN HANDLE hMediaRequestEvent) 02717 { 02718 NTSTATUS Status; 02719 02720 TRACE_INIT(("Entering NtUserInitialize\n")); 02721 02722 /* 02723 * Make sure we're not trying to load this twice. 02724 */ 02725 if (gpepCSRSS != NULL) { 02726 RIPMSG0(RIP_ERROR, "Can't initialize more than once"); 02727 return STATUS_UNSUCCESSFUL; 02728 } 02729 02730 /* 02731 * Check version number 02732 */ 02733 if (dwVersion != USERCURRENTVERSION) { 02734 KeBugCheckEx(WIN32K_INIT_OR_RIT_FAILURE, 02735 0, 02736 0, 02737 dwVersion, 02738 USERCURRENTVERSION); 02739 } 02740 02741 /* 02742 * Get the session ID from the EPROCESS structure 02743 */ 02744 gSessionId = PsGetCurrentProcess()->SessionId; 02745 02746 UserAssert(gSessionId == 0 || gbRemoteSession == TRUE); 02747 02748 /* 02749 * Initialize the power request list. 02750 */ 02751 Status = InitializePowerRequestList(hPowerRequestEvent); 02752 if (!NT_SUCCESS(Status)) { 02753 return Status; 02754 } 02755 02756 InitializeMediaChange(hMediaRequestEvent); 02757 02758 /* 02759 * Save the system process structure. 02760 */ 02761 gpepCSRSS = PsGetCurrentProcess(); 02762 02763 if (!TellGdiToGetReady()) 02764 { 02765 RIPMSG0(RIP_WARNING, "TellGdiToGetReady failed"); 02766 Status = STATUS_UNSUCCESSFUL; 02767 return Status; 02768 } 02769 02770 /* 02771 * Allow CSR to read the screen 02772 */ 02773 ((PW32PROCESS)gpepCSRSS->Win32Process)->W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED|W32PF_IOWINSTA); 02774 02775 02776 Status = UserInitialize(); 02777 02778 TRACE_INIT(("Leaving NtUserInitialize\n")); 02779 return Status; 02780 } 02781 02782 /**************************************************************************\ 02783 * NtUserProcessConnect 02784 * 02785 * 01-Dec-1993 Andreva Created. 02786 \**************************************************************************/ 02787 02788 NTSTATUS NtUserProcessConnect( 02789 IN HANDLE hProcess, 02790 IN OUT PVOID pConnectInfo, 02791 IN ULONG cbConnectInfo) 02792 { 02793 PEPROCESS Process; 02794 PUSERCONNECT pucConnect = (PUSERCONNECT)pConnectInfo; 02795 USERCONNECT ucLocal; 02796 NTSTATUS Status = STATUS_SUCCESS; 02797 02798 02799 TRACE_INIT(("Entering NtUserProcessConnect\n")); 02800 02801 if (!pucConnect || (cbConnectInfo != sizeof(USERCONNECT))) { 02802 return STATUS_UNSUCCESSFUL; 02803 } 02804 02805 try { 02806 ProbeForWrite(pucConnect, cbConnectInfo, sizeof(DWORD)); 02807 02808 ucLocal = *pucConnect; 02809 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 02810 return GetExceptionCode(); 02811 } 02812 02813 /* 02814 * Check client/server versions. 02815 */ 02816 if (ucLocal.ulVersion != USERCURRENTVERSION) { 02817 02818 RIPMSG2(RIP_ERROR, 02819 "Client version %lx > server version %lx\n", 02820 ucLocal.ulVersion, USERCURRENTVERSION); 02821 return STATUS_UNSUCCESSFUL; 02822 } 02823 02824 02825 02826 if (ucLocal.dwDispatchCount != gDispatchTableValues) { 02827 RIPMSG2(RIP_ERROR, 02828 "!!!! Client Dispatch info %lX != Server %lX\n", 02829 ucLocal.dwDispatchCount, gDispatchTableValues); 02830 } 02831 02832 02833 /* 02834 * Reference the process. 02835 */ 02836 Status = ObReferenceObjectByHandle(hProcess, 02837 PROCESS_VM_OPERATION, 02838 *PsProcessType, 02839 UserMode, 02840 &Process, 02841 NULL); 02842 if (!NT_SUCCESS(Status)) 02843 return Status; 02844 /* 02845 * Return client's view of shared data. 02846 */ 02847 Status = InitMapSharedSection(Process, &ucLocal); 02848 02849 if (!NT_SUCCESS(Status) && 02850 (Status != STATUS_NO_MEMORY) && 02851 (Status != STATUS_PROCESS_IS_TERMINATING) && 02852 (Status != STATUS_QUOTA_EXCEEDED) && 02853 (Status != STATUS_COMMITMENT_LIMIT)) { 02854 02855 RIPMSG2(RIP_ERROR, 02856 "Failed to map shared data into client %x, status = %x\n", 02857 GetCurrentProcessId(), Status); 02858 } 02859 02860 ObDereferenceObject(Process); 02861 02862 if (NT_SUCCESS(Status)) { 02863 02864 try { 02865 *pucConnect = ucLocal; 02866 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 02867 Status = GetExceptionCode(); 02868 } 02869 } 02870 02871 TRACE_INIT(("Leaving NtUserProcessConnect\n")); 02872 02873 return Status; 02874 } 02875 02876 /**************************************************************************\ 02877 * xxxUserProcessCallout 02878 * 02879 * 01-Dec-1993 andreva Created. 02880 \**************************************************************************/ 02881 02882 NTSTATUS xxxUserProcessCallout( 02883 IN PW32PROCESS Process, 02884 IN BOOLEAN Initialize) 02885 { 02886 NTSTATUS Status = STATUS_SUCCESS; 02887 02888 if (Initialize) { 02889 02890 TRACE_INIT(("Entering xxxUserProcessCallout Initialize\n")); 02891 02892 UserAssert(gpresUser != NULL); 02893 EnterCrit(); 02894 02895 /* 02896 * Initialize the important process level stuff. 02897 */ 02898 Status = xxxInitProcessInfo(Process); 02899 02900 LeaveCrit(); 02901 02902 if (Status == STATUS_SUCCESS) { 02903 02904 if (Process->Process && 02905 Process->Process->Job && 02906 Process->Process->Job->UIRestrictionsClass != 0) { 02907 02908 WIN32_JOBCALLOUT_PARAMETERS Parms; 02909 02910 PEJOB Job = Process->Process->Job; 02911 02912 /* 02913 * aquire the job's lock and after that enter the user 02914 * critical section. 02915 */ 02916 KeEnterCriticalRegion(); 02917 ExAcquireResourceExclusive(&Job->JobLock, TRUE); 02918 02919 Parms.Job = Job; 02920 Parms.CalloutType = PsW32JobCalloutAddProcess; 02921 Parms.Data = Process; 02922 02923 UserAssert(Job->SessionId == Process->Process->SessionId); 02924 02925 UserJobCallout(&Parms); 02926 02927 ExReleaseResource(&Job->JobLock); 02928 KeLeaveCriticalRegion(); 02929 } 02930 } 02931 } else { 02932 02933 int i; 02934 PHE phe; 02935 PDCE *ppdce; 02936 PDCE pdce; 02937 02938 TRACE_INIT(("Entering xxxUserProcessCallout Cleanup\n")); 02939 02940 UserAssert(gpresUser != NULL); 02941 02942 EnterCrit(); 02943 02944 #if DBG 02945 if (Process->Process == gpepCSRSS) { 02946 02947 /* 02948 * CSRSS should be the last to go ... 02949 */ 02950 UserAssert(gppiList->ppiNextRunning == NULL); 02951 } 02952 #endif // DBG 02953 02954 if (Process->Process && Process->Process->Job != NULL) { 02955 RemoveProcessFromJob((PPROCESSINFO)Process); 02956 } 02957 02958 /* 02959 * DestroyProcessInfo will return TRUE if any threads ever 02960 * connected. If nothing ever connected, we needn't do 02961 * this cleanup. 02962 */ 02963 if (DestroyProcessInfo(Process)) { 02964 02965 /* 02966 * See if we can compact the handle table. 02967 */ 02968 i = giheLast; 02969 phe = &gSharedInfo.aheList[giheLast]; 02970 while ((phe > &gSharedInfo.aheList[0]) && (phe->bType == TYPE_FREE)) { 02971 phe--; 02972 giheLast--; 02973 } 02974 02975 /* 02976 * Scan the DC cache to find any DC's that need to be destroyed. 02977 */ 02978 for (ppdce = &gpDispInfo->pdceFirst; *ppdce != NULL; ) { 02979 02980 pdce = *ppdce; 02981 if (pdce->DCX_flags & DCX_DESTROYTHIS) 02982 DestroyCacheDC(ppdce, pdce->hdc); 02983 02984 /* 02985 * Step to the next DC. If the DC was deleted, there 02986 * is no need to calculate address of the next entry. 02987 */ 02988 if (pdce == *ppdce) 02989 ppdce = &pdce->pdceNext; 02990 } 02991 } 02992 02993 UserAssert(gpresUser != NULL); 02994 02995 LeaveCrit(); 02996 } 02997 02998 TRACE_INIT(("Leaving xxxUserProcessCallout\n")); 02999 03000 return Status; 03001 } 03002 03003 /**************************************************************************\ 03004 * UserGetHDEV 03005 * 03006 * Provided as a means for GDI to get a hold of USER's hDev. 03007 * 03008 * 01-Jan-1996 ChrisWil Created. 03009 \**************************************************************************/ 03010 03011 HDEV UserGetHDEV(VOID) 03012 { 03013 03014 /* 03015 * BUGBUG This is busted. 03016 * This need to return the device for the current desktop. 03017 * The graphics device may not be the same for all desktops. 03018 * -Andre 03019 */ 03020 return gpDispInfo->hDev; 03021 } 03022 03023 /**************************************************************************\ 03024 * _UserGetGlobalAtomTable 03025 * 03026 * This function is called by the kernel mode global atom manager to get the 03027 * address of the current thread's global atom table. 03028 * 03029 * Pointer to the global atom table for the current thread or NULL if unable 03030 * to access it. 03031 * 03032 * 03033 \**************************************************************************/ 03034 03035 PVOID UserGlobalAtomTableCallout(VOID) 03036 { 03037 PETHREAD Thread; 03038 PTHREADINFO pti; 03039 PWINDOWSTATION pwinsta; 03040 PW32JOB pW32Job; 03041 PEJOB Job; 03042 PVOID GlobalAtomTable = NULL; 03043 03044 Thread = PsGetCurrentThread(); 03045 03046 pti = PtiFromThread(Thread); 03047 03048 EnterCrit(); 03049 03050 /* 03051 * For restricted threads access the atom table off of the job object 03052 */ 03053 if (pti != NULL && IS_THREAD_RESTRICTED(pti, JOB_OBJECT_UILIMIT_GLOBALATOMS)) { 03054 03055 UserAssert(pti->ppi != NULL); 03056 03057 pW32Job = pti->ppi->pW32Job; 03058 03059 UserAssert(pW32Job != NULL && pW32Job->pAtomTable != NULL); 03060 03061 GlobalAtomTable = pW32Job->pAtomTable; 03062 03063 goto End; 03064 } 03065 03066 Job = PsGetCurrentProcess()->Job; 03067 03068 /* 03069 * Now handle the case where this si not a GUI thread/process 03070 * but it is assigned to a job that has JOB_OBJECT_UILIMIT_GLOBALATOMS 03071 * restrictions set. There is no easy way to convert this thread 03072 * to GUI. 03073 */ 03074 if (pti == NULL && Job != NULL && 03075 (Job->UIRestrictionsClass & JOB_OBJECT_UILIMIT_GLOBALATOMS)) { 03076 03077 /* 03078 * find the W32JOB in the global list 03079 */ 03080 pW32Job = gpJobsList; 03081 03082 while (pW32Job) { 03083 if (pW32Job->Job == Job) { 03084 break; 03085 } 03086 pW32Job = pW32Job->pNext; 03087 } 03088 03089 UserAssert(pW32Job != NULL && pW32Job->pAtomTable != NULL); 03090 03091 GlobalAtomTable = pW32Job->pAtomTable; 03092 03093 goto End; 03094 } 03095 03096 #if DBG 03097 pwinsta = NULL; 03098 #endif 03099 03100 if (NT_SUCCESS(ReferenceWindowStation(Thread, 03101 PsGetCurrentProcess()->Win32WindowStation, 03102 WINSTA_ACCESSGLOBALATOMS, 03103 &pwinsta, 03104 TRUE))) { 03105 UserAssert(pwinsta != NULL); 03106 03107 GlobalAtomTable = pwinsta->pGlobalAtomTable; 03108 } 03109 03110 End: 03111 LeaveCrit(); 03112 03113 #if DBG 03114 if (GlobalAtomTable == NULL) { 03115 RIPMSG1(RIP_WARNING, 03116 "_UserGetGlobalAtomTable: NULL Atom Table for pwinsta=0x%x", 03117 pwinsta); 03118 } 03119 #endif 03120 03121 return GlobalAtomTable; 03122 }

Generated on Sat May 15 19:41:47 2004 for test by doxygen 1.3.7