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

dllinit.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1985 - 1999, Microsoft Corporation 00004 00005 Module Name: 00006 00007 dllinit.c 00008 00009 Abstract: 00010 00011 This module implements console dll initialization 00012 00013 Author: 00014 00015 Therese Stowell (thereses) 11-Nov-1990 00016 00017 Revision History: 00018 00019 --*/ 00020 00021 #include "precomp.h" 00022 #pragma hdrstop 00023 00024 #if !defined(BUILD_WOW64) 00025 00026 #include <cpl.h> 00027 00028 #define DEFAULT_WINDOW_TITLE (L"Command Prompt") 00029 00030 extern HANDLE InputWaitHandle; 00031 extern WCHAR ExeNameBuffer[]; 00032 extern USHORT ExeNameLength; 00033 extern WCHAR StartDirBuffer[]; 00034 extern USHORT StartDirLength; 00035 00036 DWORD 00037 CtrlRoutine( 00038 IN LPVOID lpThreadParameter 00039 ); 00040 00041 DWORD 00042 PropRoutine( 00043 IN LPVOID lpThreadParameter 00044 ); 00045 00046 #if defined(FE_SB) 00047 #if defined(FE_IME) 00048 DWORD 00049 ConsoleIMERoutine( 00050 IN LPVOID lpThreadParameter 00051 ); 00052 #endif // FE_IME 00053 #endif // FE_SB 00054 00055 00056 #define MAX_SESSION_PATH 256 00057 #define SESSION_ROOT L"\\Sessions" 00058 00059 VOID 00060 InitExeName( VOID ); 00061 00062 BOOLEAN 00063 ConsoleApp( VOID ) 00064 00065 /*++ 00066 00067 This routine determines whether the current process is a console or 00068 windows app. 00069 00070 Parameters: 00071 00072 none. 00073 00074 Return Value: 00075 00076 TRUE if console app. 00077 00078 --*/ 00079 00080 { 00081 PIMAGE_NT_HEADERS NtHeaders; 00082 00083 NtHeaders = RtlImageNtHeader(GetModuleHandle(NULL)); 00084 return (NtHeaders->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI) ? TRUE : FALSE; 00085 } 00086 00087 00088 VOID 00089 SetUpAppName( 00090 IN OUT LPDWORD CurDirLength, 00091 OUT LPWSTR CurDir, 00092 IN OUT LPDWORD AppNameLength, 00093 OUT LPWSTR AppName 00094 ) 00095 { 00096 DWORD Length; 00097 00098 *CurDirLength -= sizeof(WCHAR); 00099 Length = (StartDirLength*sizeof(WCHAR)) > *CurDirLength ? *CurDirLength : (StartDirLength*sizeof(WCHAR)); 00100 RtlCopyMemory(CurDir,StartDirBuffer,Length+sizeof(WCHAR)); 00101 *CurDirLength = Length + sizeof(WCHAR); // add terminating NULL 00102 00103 *AppNameLength -= sizeof(WCHAR); 00104 Length = (ExeNameLength*sizeof(WCHAR)) > *AppNameLength ? *AppNameLength : (ExeNameLength*sizeof(WCHAR)); 00105 RtlCopyMemory(AppName,ExeNameBuffer,Length+sizeof(WCHAR)); 00106 *AppNameLength = Length + sizeof(WCHAR); // add terminating NULL 00107 } 00108 00109 00110 ULONG 00111 ParseReserved( 00112 WCHAR *pchReserved, 00113 WCHAR *pchFind 00114 ) 00115 { 00116 ULONG dw; 00117 WCHAR *pch, *pchT, ch; 00118 UNICODE_STRING uString; 00119 00120 dw = 0; 00121 if ((pch = wcsstr(pchReserved, pchFind)) != NULL) { 00122 pch += lstrlenW(pchFind); 00123 00124 pchT = pch; 00125 while (*pchT >= '0' && *pchT <= '9') 00126 pchT++; 00127 00128 ch = *pchT; 00129 *pchT = 0; 00130 RtlInitUnicodeString(&uString, pch); 00131 *pchT = ch; 00132 00133 RtlUnicodeStringToInteger(&uString, 0, &dw); 00134 } 00135 00136 return dw; 00137 } 00138 00139 00140 VOID 00141 SetUpConsoleInfo( 00142 IN BOOL DllInit, 00143 OUT LPDWORD TitleLength, 00144 OUT LPWSTR Title OPTIONAL, 00145 OUT LPDWORD DesktopLength, 00146 OUT LPWSTR *Desktop OPTIONAL, 00147 OUT PCONSOLE_INFO ConsoleInfo 00148 ) 00149 00150 /*++ 00151 00152 This routine fills in the ConsoleInfo structure with the values 00153 specified by the user. 00154 00155 Parameters: 00156 00157 ConsoleInfo - pointer to structure to fill in. 00158 00159 Return Value: 00160 00161 none. 00162 00163 --*/ 00164 00165 { 00166 STARTUPINFOW StartupInfo; 00167 HANDLE h; 00168 int id; 00169 HANDLE ghInstance; 00170 BOOL Success; 00171 00172 00173 GetStartupInfoW(&StartupInfo); 00174 ghInstance = (HANDLE)((PVOID)NtCurrentPeb()->ImageBaseAddress ); 00175 00176 // these will eventually be filled in using menu input 00177 00178 ConsoleInfo->nFont = 0; 00179 ConsoleInfo->nInputBufferSize = 0; 00180 ConsoleInfo->hIcon = NULL; 00181 ConsoleInfo->hSmIcon = NULL; 00182 ConsoleInfo->iIconId = 0; 00183 ConsoleInfo->dwStartupFlags = StartupInfo.dwFlags; 00184 #if defined(FE_SB) 00185 ConsoleInfo->uCodePage = GetOEMCP(); 00186 #endif 00187 if (StartupInfo.lpTitle == NULL) { 00188 StartupInfo.lpTitle = DEFAULT_WINDOW_TITLE; 00189 } 00190 00191 // 00192 // if the desktop name was specified, set up the pointers. 00193 // 00194 00195 if (DllInit && Desktop != NULL && 00196 StartupInfo.lpDesktop != NULL && *StartupInfo.lpDesktop != 0) { 00197 *DesktopLength = (lstrlenW(StartupInfo.lpDesktop) + 1) * sizeof(WCHAR); 00198 *Desktop = StartupInfo.lpDesktop; 00199 } else { 00200 *DesktopLength = 0; 00201 if (Desktop != NULL) 00202 *Desktop = NULL; 00203 } 00204 00205 // Nope, do normal initialization (TitleLength is in BYTES, not CHARS!) 00206 *TitleLength = (USHORT)((lstrlenW(StartupInfo.lpTitle)+1)*sizeof(WCHAR)); 00207 *TitleLength = (USHORT)(min(*TitleLength,MAX_TITLE_LENGTH)); 00208 if (DllInit) { 00209 RtlCopyMemory(Title,StartupInfo.lpTitle,*TitleLength); 00210 // ensure the title is NULL terminated 00211 if (*TitleLength == MAX_TITLE_LENGTH) 00212 Title[ (MAX_TITLE_LENGTH/sizeof(WCHAR)) - 1 ] = L'\0'; 00213 } 00214 00215 if (StartupInfo.dwFlags & STARTF_USESHOWWINDOW) { 00216 ConsoleInfo->wShowWindow = StartupInfo.wShowWindow; 00217 } 00218 if (StartupInfo.dwFlags & STARTF_USEFILLATTRIBUTE) { 00219 ConsoleInfo->wFillAttribute = (WORD)StartupInfo.dwFillAttribute; 00220 } 00221 if (StartupInfo.dwFlags & STARTF_USECOUNTCHARS) { 00222 ConsoleInfo->dwScreenBufferSize.X = (WORD)(StartupInfo.dwXCountChars); 00223 ConsoleInfo->dwScreenBufferSize.Y = (WORD)(StartupInfo.dwYCountChars); 00224 } 00225 if (StartupInfo.dwFlags & STARTF_USESIZE) { 00226 ConsoleInfo->dwWindowSize.X = (WORD)(StartupInfo.dwXSize); 00227 ConsoleInfo->dwWindowSize.Y = (WORD)(StartupInfo.dwYSize); 00228 } 00229 if (StartupInfo.dwFlags & STARTF_USEPOSITION) { 00230 ConsoleInfo->dwWindowOrigin.X = (WORD)(StartupInfo.dwX); 00231 ConsoleInfo->dwWindowOrigin.Y = (WORD)(StartupInfo.dwY); 00232 } 00233 00234 // 00235 // Grab information passed on lpReserved line... 00236 // 00237 00238 if (StartupInfo.lpReserved != 0) { 00239 00240 // 00241 // the program manager has an icon for the exe. store the 00242 // index in the iIconId field. 00243 // 00244 00245 ConsoleInfo->iIconId = ParseReserved(StartupInfo.lpReserved, L"dde."); 00246 00247 // 00248 // The new "Chicago" way of doing things is to pass the hotkey in the 00249 // hStdInput field and set the STARTF_USEHOTKEY flag. So, if this is 00250 // specified, we get the hotkey from there instead 00251 // 00252 00253 if (StartupInfo.dwFlags & STARTF_USEHOTKEY) { 00254 ConsoleInfo->dwHotKey = HandleToUlong(StartupInfo.hStdInput); 00255 } else { 00256 ConsoleInfo->dwHotKey = ParseReserved(StartupInfo.lpReserved, L"hotkey."); 00257 } 00258 } 00259 00260 } 00261 00262 VOID 00263 SetUpHandles( 00264 IN PCONSOLE_INFO ConsoleInfo 00265 ) 00266 00267 /*++ 00268 00269 This routine sets up the console and std* handles for the process. 00270 00271 Parameters: 00272 00273 ConsoleInfo - pointer to structure containing handles. 00274 00275 Return Value: 00276 00277 none. 00278 00279 --*/ 00280 00281 { 00282 SET_CONSOLE_HANDLE(ConsoleInfo->ConsoleHandle); 00283 if (!(ConsoleInfo->dwStartupFlags & STARTF_USESTDHANDLES)) { 00284 SetStdHandle(STD_INPUT_HANDLE,ConsoleInfo->StdIn); 00285 SetStdHandle(STD_OUTPUT_HANDLE,ConsoleInfo->StdOut); 00286 SetStdHandle(STD_ERROR_HANDLE,ConsoleInfo->StdErr); 00287 } 00288 } 00289 00290 #endif 00291 00292 #if !defined(BUILD_WOW6432) 00293 00294 BOOL 00295 WINAPI 00296 GetConsoleLangId( 00297 OUT LANGID *lpLangId 00298 ) 00299 00300 /*++ 00301 00302 Parameters: 00303 00304 lpLangId - Supplies a pointer to a LANGID in which to store the Language ID. 00305 00306 Return Value: 00307 00308 TRUE - The operation was successful. 00309 00310 FALSE/NULL - The operation failed. Extended error status is available 00311 using GetLastError. 00312 00313 00314 --*/ 00315 00316 { 00317 CONSOLE_API_MSG m; 00318 PCONSOLE_LANGID_MSG a = &m.u.GetConsoleLangId; 00319 00320 a->ConsoleHandle = GET_CONSOLE_HANDLE; 00321 CsrClientCallServer( (PCSR_API_MSG)&m, 00322 NULL, 00323 CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX, 00324 ConsolepGetLangId 00325 ), 00326 sizeof( *a ) 00327 ); 00328 if (NT_SUCCESS( m.ReturnValue )) { 00329 try { 00330 *lpLangId = a->LangId; 00331 } except( EXCEPTION_EXECUTE_HANDLER ) { 00332 return FALSE; 00333 } 00334 return TRUE; 00335 } else { 00336 return FALSE; 00337 } 00338 00339 } 00340 00341 #endif 00342 00343 #if !defined(BUILD_WOW64) 00344 00345 VOID 00346 SetTEBLangID( 00347 VOID 00348 ) 00349 00350 /*++ 00351 00352 Sets the Language Id in the TEB to Far East if code page CP are 00353 Japanese/Korean/Chinese. This is done in order for FormatMessage 00354 to display any Far East character when cmd is running in its code page. 00355 All messages displayed in non-FE code page will be displayed in English. 00356 00357 --*/ 00358 00359 { 00360 LANGID LangId; 00361 00362 if (GetConsoleLangId(&LangId)) { 00363 SetThreadLocale( MAKELCID(LangId, SORT_DEFAULT) ); 00364 } 00365 } 00366 00367 #endif 00368 00369 #if !defined(BUILD_WOW6432) 00370 00371 BOOL 00372 APIENTRY 00373 ConnectConsoleInternal(IN PWSTR pObjectDirectory, 00374 IN OUT PCONSOLE_API_CONNECTINFO pConnectInfo, 00375 OUT PBOOLEAN pServerProcess 00376 ) 00377 /*++ 00378 00379 Routine Description: 00380 00381 Helper function for establishing a connection with the console server. 00382 Waits for the server to signal completion. 00383 00384 Arguments: 00385 00386 pObjectDirectory - Supplies a null terminated string that is the same 00387 as the value of the ObjectDirectory= argument passed to the CSRSS 00388 program. 00389 00390 pConnectInfo - Supplies and recieves the connection information. 00391 00392 pServerProcess - Recieves TRUE if this is a server process. 00393 00394 Return Value: 00395 00396 TRUE - Success 00397 00398 FALSE - An error occured. 00399 00400 --*/ 00401 { 00402 00403 NTSTATUS Status; 00404 ULONG ConnectionInformationLength; 00405 00406 ConnectionInformationLength = sizeof(CONSOLE_API_CONNECTINFO); 00407 00408 Status = CsrClientConnectToServer( pObjectDirectory, 00409 CONSRV_SERVERDLL_INDEX, 00410 NULL, 00411 pConnectInfo, 00412 &ConnectionInformationLength, 00413 pServerProcess 00414 ); 00415 00416 if (!NT_SUCCESS( Status )) { 00417 return FALSE; 00418 } 00419 00420 // 00421 // we return success although no console api can be called because 00422 // loading shouldn't fail. we'll fail the api calls later. 00423 // 00424 00425 if (*pServerProcess) { 00426 return TRUE; 00427 } 00428 00429 00430 // 00431 // if this is not a console app, return success - nothing else to do. 00432 // 00433 00434 if (!pConnectInfo->ConsoleApp) { 00435 return TRUE; 00436 } 00437 00438 // 00439 // wait for initialization to complete. we have to use the NT 00440 // wait because the heap hasn't been initialized yet. 00441 // 00442 00443 Status = NtWaitForMultipleObjects(NUMBER_OF_INITIALIZATION_EVENTS, 00444 pConnectInfo->ConsoleInfo.InitEvents, 00445 WaitAny, 00446 FALSE, 00447 NULL 00448 ); 00449 00450 if (!NT_SUCCESS(Status)) { 00451 SET_LAST_NT_ERROR(Status); 00452 return FALSE; 00453 } 00454 00455 NtClose(pConnectInfo->ConsoleInfo.InitEvents[INITIALIZATION_SUCCEEDED]); 00456 NtClose(pConnectInfo->ConsoleInfo.InitEvents[INITIALIZATION_FAILED]); 00457 if (Status != INITIALIZATION_SUCCEEDED) { 00458 SET_CONSOLE_HANDLE(NULL); 00459 return FALSE; 00460 } 00461 00462 return TRUE; 00463 } 00464 00465 #endif 00466 00467 #if !defined(BUILD_WOW64) 00468 00469 BOOLEAN 00470 ConDllInitialize( 00471 IN PVOID DllHandle, 00472 IN ULONG Reason, 00473 IN PCONTEXT Context OPTIONAL 00474 ) 00475 00476 /*++ 00477 00478 Routine Description: 00479 00480 This function implements console dll initialization. 00481 00482 Arguments: 00483 00484 DllHandle - Not Used 00485 00486 Context - Not Used 00487 00488 Return Value: 00489 00490 STATUS_SUCCESS 00491 00492 --*/ 00493 00494 { 00495 NTSTATUS Status; 00496 BOOL bStatus; 00497 CONSOLE_API_CONNECTINFO ConnectionInformation; 00498 BOOLEAN ServerProcess; 00499 00500 ULONG SessionId = NtCurrentPeb()->SessionId; 00501 WCHAR szSessionDir[MAX_SESSION_PATH]; 00502 00503 Status = STATUS_SUCCESS; 00504 00505 // 00506 // if we're attaching the DLL, we need to connect to the server. 00507 // if no console exists, we also need to create it and set up stdin, 00508 // stdout, and stderr. 00509 // 00510 00511 if ( Reason == DLL_PROCESS_ATTACH ) { 00512 00513 // 00514 // Remember in the connect information if this app is a console 00515 // app. need to actually connect to the console server for windowed 00516 // apps so that we know NOT to do any special work during 00517 // ConsoleClientDisconnectRoutine(). Store ConsoleApp info in the 00518 // CSR managed per-process data. 00519 // 00520 00521 Status = RtlInitializeCriticalSection(&DllLock); 00522 if (!NT_SUCCESS(Status)) { 00523 return FALSE; 00524 } 00525 00526 ConnectionInformation.CtrlRoutine = CtrlRoutine; 00527 ConnectionInformation.PropRoutine = PropRoutine; 00528 #if defined(FE_SB) 00529 #if defined(FE_IME) 00530 ConnectionInformation.ConsoleIMERoutine = ConsoleIMERoutine; 00531 #endif // FE_IME 00532 #endif // FE_SB 00533 00534 ConnectionInformation.WindowVisible = TRUE; 00535 ConnectionInformation.ConsoleApp = ConsoleApp(); 00536 if (GET_CONSOLE_HANDLE == (HANDLE)CONSOLE_DETACHED_PROCESS) { 00537 SET_CONSOLE_HANDLE(NULL); 00538 ConnectionInformation.ConsoleApp = FALSE; 00539 } 00540 else if (GET_CONSOLE_HANDLE == (HANDLE)CONSOLE_NEW_CONSOLE) { 00541 SET_CONSOLE_HANDLE(NULL); 00542 } else if (GET_CONSOLE_HANDLE == (HANDLE)CONSOLE_CREATE_NO_WINDOW) { 00543 SET_CONSOLE_HANDLE(NULL); 00544 ConnectionInformation.WindowVisible = FALSE; 00545 } 00546 if (!ConnectionInformation.ConsoleApp) { 00547 SET_CONSOLE_HANDLE(NULL); 00548 } 00549 ConnectionInformation.ConsoleInfo.ConsoleHandle = GET_CONSOLE_HANDLE; 00550 00551 // 00552 // if no console exists, pass parameters for console creation 00553 // 00554 00555 if (GET_CONSOLE_HANDLE == NULL && ConnectionInformation.ConsoleApp) { 00556 SetUpConsoleInfo(TRUE, 00557 &ConnectionInformation.TitleLength, 00558 ConnectionInformation.Title, 00559 &ConnectionInformation.DesktopLength, 00560 &ConnectionInformation.Desktop, 00561 &ConnectionInformation.ConsoleInfo); 00562 } else { 00563 ConnectionInformation.TitleLength = 0; 00564 ConnectionInformation.DesktopLength = 0; 00565 } 00566 00567 if (ConnectionInformation.ConsoleApp) { 00568 InitExeName(); 00569 ConnectionInformation.CurDirLength = sizeof(ConnectionInformation.CurDir); 00570 ConnectionInformation.AppNameLength = sizeof(ConnectionInformation.AppName); 00571 SetUpAppName(&ConnectionInformation.CurDirLength, 00572 ConnectionInformation.CurDir, 00573 &ConnectionInformation.AppNameLength, 00574 ConnectionInformation.AppName); 00575 } else { 00576 ConnectionInformation.AppNameLength = 0; 00577 ConnectionInformation.CurDirLength = 0; 00578 } 00579 00580 // 00581 // initialize ctrl handling. This should work for all apps, so 00582 // initialize it before we check for ConsoleApp (which means the 00583 // console bit was set in the module header). 00584 // 00585 00586 InitializeCtrlHandling(); 00587 00588 // 00589 // Connect to the server process 00590 // 00591 00592 if ( SessionId == 0 ) { 00593 // 00594 // Console Session 00595 // 00596 wcscpy(szSessionDir, WINSS_OBJECT_DIRECTORY_NAME); 00597 } else { 00598 swprintf(szSessionDir,L"%ws\\%ld%ws",SESSION_ROOT,SessionId,WINSS_OBJECT_DIRECTORY_NAME); 00599 } 00600 00601 bStatus = ConnectConsoleInternal(szSessionDir, 00602 &ConnectionInformation, 00603 &ServerProcess 00604 ); 00605 00606 if (!bStatus) { 00607 return FALSE; 00608 } 00609 00610 // 00611 // we return success although no console api can be called because 00612 // loading shouldn't fail. we'll fail the api calls later. 00613 // 00614 if (ServerProcess) { 00615 return TRUE; 00616 } 00617 00618 // 00619 // if this is not a console app, return success - nothing else to do. 00620 // 00621 00622 if (!ConnectionInformation.ConsoleApp) { 00623 return TRUE; 00624 } 00625 00626 // 00627 // if console was just created, fill in peb values 00628 // 00629 00630 if (GET_CONSOLE_HANDLE == NULL) { 00631 SetUpHandles(&ConnectionInformation.ConsoleInfo 00632 ); 00633 } 00634 00635 InputWaitHandle = ConnectionInformation.ConsoleInfo.InputWaitHandle; 00636 00637 SetTEBLangID(); 00638 00639 } 00640 else if ( Reason == DLL_THREAD_ATTACH ) { 00641 if (ConsoleApp()) { 00642 SetTEBLangID(); 00643 } 00644 } 00645 return TRUE; 00646 UNREFERENCED_PARAMETER(DllHandle); 00647 UNREFERENCED_PARAMETER(Context); 00648 } 00649 00650 #endif 00651 00652 #if !defined(BUILD_WOW6432) 00653 00654 BOOL 00655 APIENTRY 00656 AllocConsoleInternal(IN LPWSTR lpTitle, 00657 IN DWORD dwTitleLength, 00658 IN LPWSTR lpDesktop, 00659 IN DWORD dwDesktopLength, 00660 IN LPWSTR lpCurDir, 00661 IN DWORD dwCurDirLength, 00662 IN LPWSTR lpAppName, 00663 IN DWORD dwAppNameLength, 00664 IN LPTHREAD_START_ROUTINE CtrlRoutine, 00665 IN LPTHREAD_START_ROUTINE PropRoutine, 00666 IN OUT PCONSOLE_INFO pConsoleInfo 00667 ) 00668 /*++ 00669 00670 Routine Description: 00671 00672 Marshels the parameters for the ConsolepAlloc command. 00673 00674 Arguments: 00675 00676 See the CONSOLE_ALLOC_MSG structure and AllocConsole. 00677 00678 Return Value: 00679 00680 TRUE - Success 00681 00682 FALSE - An error occured. 00683 00684 --*/ 00685 { 00686 CONSOLE_API_MSG m; 00687 PCONSOLE_ALLOC_MSG a = &m.u.AllocConsole; 00688 PCSR_CAPTURE_HEADER CaptureBuffer = NULL; 00689 BOOL Status = FALSE; 00690 NTSTATUS St; 00691 00692 try { 00693 00694 a->CtrlRoutine = CtrlRoutine; 00695 a->PropRoutine = PropRoutine; 00696 00697 // Allocate 4 extra pointer sizes to compensate for any alignment done 00698 // by CsrCaptureMessageBuffer. 00699 00700 CaptureBuffer = CsrAllocateCaptureBuffer( 5, 00701 dwTitleLength + dwDesktopLength + dwCurDirLength + 00702 dwAppNameLength + sizeof( CONSOLE_INFO ) + (4 * sizeof(PVOID)) 00703 ); 00704 if (CaptureBuffer == NULL) { 00705 SET_LAST_ERROR(ERROR_NOT_ENOUGH_MEMORY); 00706 Status = FALSE; 00707 leave; 00708 } 00709 00710 // Allocate the CONSOLE_INFO first so that it is aligned on a pointer 00711 // boundry. This is necessary since NtWaitForMultipleObject expects 00712 // its arguments aligned on a handle boundry. 00713 00714 CsrCaptureMessageBuffer( CaptureBuffer, 00715 pConsoleInfo, 00716 sizeof( CONSOLE_INFO ), 00717 (PVOID *) &a->ConsoleInfo 00718 ); 00719 00720 a->TitleLength = dwTitleLength; 00721 CsrCaptureMessageBuffer( CaptureBuffer, 00722 lpTitle, 00723 dwTitleLength, 00724 (PVOID *) &a->Title 00725 ); 00726 00727 a->DesktopLength = dwDesktopLength; 00728 CsrCaptureMessageBuffer( CaptureBuffer, 00729 lpDesktop, 00730 dwDesktopLength, 00731 (PVOID *) &a->Desktop 00732 ); 00733 00734 a->CurDirLength = dwCurDirLength; 00735 CsrCaptureMessageBuffer( CaptureBuffer, 00736 lpCurDir, 00737 dwCurDirLength, 00738 (PVOID *) &a->CurDir 00739 ); 00740 00741 a->AppNameLength = dwAppNameLength; 00742 CsrCaptureMessageBuffer( CaptureBuffer, 00743 lpAppName, 00744 dwAppNameLength, 00745 (PVOID *) &a->AppName 00746 ); 00747 00748 // 00749 // Connect to the server process 00750 // 00751 00752 CsrClientCallServer( (PCSR_API_MSG)&m, 00753 CaptureBuffer, 00754 CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX, 00755 ConsolepAlloc 00756 ), 00757 sizeof( *a ) 00758 ); 00759 if (!NT_SUCCESS( m.ReturnValue )) { 00760 SET_LAST_NT_ERROR (m.ReturnValue); 00761 Status = FALSE; 00762 leave; 00763 } 00764 00765 St = NtWaitForMultipleObjects(NUMBER_OF_INITIALIZATION_EVENTS, 00766 a->ConsoleInfo->InitEvents, 00767 WaitAny, 00768 FALSE, 00769 NULL 00770 ); 00771 if (!NT_SUCCESS(St)) { 00772 SET_LAST_NT_ERROR(St); 00773 Status = FALSE; 00774 leave; 00775 } 00776 00777 //The handles to be closed are events, so NtClose works fine. 00778 NtClose(a->ConsoleInfo->InitEvents[INITIALIZATION_SUCCEEDED]); 00779 NtClose(a->ConsoleInfo->InitEvents[INITIALIZATION_FAILED]); 00780 if (St != INITIALIZATION_SUCCEEDED) { 00781 SET_CONSOLE_HANDLE(NULL); 00782 Status = FALSE; 00783 leave; 00784 } 00785 RtlCopyMemory(pConsoleInfo, a->ConsoleInfo, sizeof(CONSOLE_INFO)); 00786 Status = TRUE; 00787 } 00788 finally { 00789 if (CaptureBuffer) { 00790 CsrFreeCaptureBuffer( CaptureBuffer ); 00791 } 00792 } 00793 00794 return Status; 00795 } 00796 00797 #endif 00798 00799 #if !defined(BUILD_WOW64) 00800 00801 BOOL 00802 APIENTRY 00803 AllocConsole( VOID ) 00804 00805 /*++ 00806 00807 Routine Description: 00808 00809 This API creates a console for the calling process. 00810 00811 Arguments: 00812 00813 none. 00814 00815 Return Value: 00816 00817 TRUE - function was successful. 00818 00819 --*/ 00820 00821 { 00822 CONSOLE_INFO ConsoleInfo; 00823 STARTUPINFOW StartupInfo; 00824 WCHAR CurDir[MAX_PATH+1]; 00825 WCHAR AppName[MAX_APP_NAME_LENGTH/2]; 00826 BOOL Status = FALSE; 00827 00828 DWORD dwTitleLength; 00829 DWORD dwDesktopLength; 00830 DWORD dwCurDirLength; 00831 DWORD dwAppNameLength; 00832 00833 LockDll(); 00834 try { 00835 if (GET_CONSOLE_HANDLE != NULL) { 00836 SetLastError(ERROR_ACCESS_DENIED); 00837 Status = FALSE; 00838 leave; 00839 } 00840 00841 // 00842 // set up initialization parameters 00843 // 00844 00845 SetUpConsoleInfo(FALSE, 00846 &dwTitleLength, 00847 NULL, 00848 &dwDesktopLength, 00849 NULL, 00850 &ConsoleInfo); 00851 00852 InitExeName(); 00853 dwCurDirLength = sizeof(CurDir); 00854 dwAppNameLength = sizeof(AppName); 00855 SetUpAppName(&dwCurDirLength, 00856 CurDir, 00857 &dwAppNameLength, 00858 AppName); 00859 00860 GetStartupInfoW(&StartupInfo); 00861 00862 if (StartupInfo.lpTitle == NULL) { 00863 StartupInfo.lpTitle = DEFAULT_WINDOW_TITLE; 00864 } 00865 dwTitleLength = (USHORT)((lstrlenW(StartupInfo.lpTitle)+1)*sizeof(WCHAR)); 00866 dwTitleLength = (USHORT)(min(dwTitleLength,MAX_TITLE_LENGTH)); 00867 if (StartupInfo.lpDesktop != NULL && *StartupInfo.lpDesktop != 0) { 00868 dwDesktopLength = (USHORT)((lstrlenW(StartupInfo.lpDesktop)+1)*sizeof(WCHAR)); 00869 dwDesktopLength = (USHORT)(min(dwDesktopLength,MAX_TITLE_LENGTH)); 00870 } else { 00871 dwDesktopLength = 0; 00872 } 00873 00874 Status = AllocConsoleInternal(StartupInfo.lpTitle, 00875 dwTitleLength, 00876 StartupInfo.lpDesktop, 00877 dwDesktopLength, 00878 CurDir, 00879 dwCurDirLength, 00880 AppName, 00881 dwAppNameLength, 00882 CtrlRoutine, 00883 PropRoutine, 00884 &ConsoleInfo 00885 ); 00886 00887 if (!Status) { 00888 leave; 00889 } 00890 00891 // 00892 // fill in peb values 00893 // 00894 00895 SetUpHandles(&ConsoleInfo); 00896 00897 // 00898 // create ctrl-c thread 00899 // 00900 00901 InitializeCtrlHandling(); 00902 00903 InputWaitHandle = ConsoleInfo.InputWaitHandle; 00904 00905 SetTEBLangID(); 00906 00907 Status = TRUE; 00908 00909 } finally { 00910 UnlockDll(); 00911 } 00912 00913 return Status; 00914 } 00915 00916 #endif 00917 00918 #if !defined(BUILD_WOW6432) 00919 00920 BOOL 00921 APIENTRY 00922 FreeConsoleInternal( 00923 VOID 00924 ) 00925 /*++ 00926 00927 Routine Description: 00928 00929 Marshels the parameters for the ConsolepFree command. 00930 00931 Arguments: 00932 00933 See the CONSOLE_FREE_MSG structure and FreeConsole. 00934 00935 Return Value: 00936 00937 TRUE - Success 00938 00939 FALSE - An error occured. 00940 00941 --*/ 00942 { 00943 00944 CONSOLE_API_MSG m; 00945 PCONSOLE_FREE_MSG a = &m.u.FreeConsole; 00946 00947 a->ConsoleHandle = GET_CONSOLE_HANDLE; 00948 00949 // 00950 // Connect to the server process 00951 // 00952 00953 CsrClientCallServer( (PCSR_API_MSG)&m, 00954 NULL, 00955 CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX, 00956 ConsolepFree 00957 ), 00958 sizeof( *a ) 00959 ); 00960 00961 if (!NT_SUCCESS( m.ReturnValue )) { 00962 SET_LAST_NT_ERROR (m.ReturnValue); 00963 return FALSE; 00964 00965 } else { 00966 00967 SET_CONSOLE_HANDLE(NULL); 00968 return TRUE; 00969 } 00970 00971 } 00972 00973 #endif 00974 00975 #if !defined(BUILD_WOW64) 00976 00977 BOOL 00978 APIENTRY 00979 FreeConsole( VOID ) 00980 00981 /*++ 00982 00983 Routine Description: 00984 00985 This API frees the calling process's console. 00986 00987 Arguments: 00988 00989 none. 00990 00991 Return Value: 00992 00993 TRUE - function was successful. 00994 00995 --*/ 00996 00997 { 00998 BOOL Success=TRUE; 00999 01000 LockDll(); 01001 if (GET_CONSOLE_HANDLE == NULL) { 01002 SET_LAST_ERROR(ERROR_INVALID_PARAMETER); 01003 Success = FALSE; 01004 } else { 01005 01006 Success = FreeConsoleInternal(); 01007 01008 if (Success) { 01009 CloseHandle(InputWaitHandle); 01010 } 01011 01012 } 01013 UnlockDll(); 01014 return Success; 01015 } 01016 01017 01018 DWORD 01019 PropRoutine( 01020 IN LPVOID lpThreadParameter 01021 ) 01022 01023 /*++ 01024 01025 Routine Description: 01026 01027 This thread is created when the user tries to change console 01028 properties from the system menu. It invokes the control panel 01029 applet. 01030 01031 Arguments: 01032 01033 lpThreadParameter - not used. 01034 01035 Return Value: 01036 01037 STATUS_SUCCESS - function was successful 01038 01039 --*/ 01040 01041 { 01042 NTSTATUS Status; 01043 HANDLE hLibrary; 01044 APPLET_PROC pfnCplApplet; 01045 static BOOL fInPropRoutine = FALSE; 01046 01047 // 01048 // Prevent the user from launching multiple applets attached 01049 // to a single console 01050 // 01051 01052 if (fInPropRoutine) { 01053 if (lpThreadParameter) { 01054 CloseHandle((HANDLE)lpThreadParameter); 01055 } 01056 return (ULONG)STATUS_UNSUCCESSFUL; 01057 } 01058 01059 fInPropRoutine = TRUE; 01060 hLibrary = LoadLibraryW(L"CONSOLE.DLL"); 01061 if (hLibrary != NULL) { 01062 pfnCplApplet = (APPLET_PROC)GetProcAddress(hLibrary, "CPlApplet"); 01063 if (pfnCplApplet != NULL) { 01064 (*pfnCplApplet)((HWND)lpThreadParameter, CPL_INIT, 0, 0); 01065 (*pfnCplApplet)((HWND)lpThreadParameter, CPL_DBLCLK, 0, 0); 01066 (*pfnCplApplet)((HWND)lpThreadParameter, CPL_EXIT, 0, 0); 01067 Status = STATUS_SUCCESS; 01068 } else { 01069 Status = STATUS_UNSUCCESSFUL; 01070 } 01071 FreeLibrary(hLibrary); 01072 } else { 01073 Status = STATUS_UNSUCCESSFUL; 01074 } 01075 fInPropRoutine = FALSE; 01076 01077 return Status; 01078 } 01079 01080 #endif

Generated on Sat May 15 19:39:45 2004 for test by doxygen 1.3.7