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

csrinit.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 dllinit.c 00008 00009 Abstract: 00010 00011 This module contains the initialization code for the Client-Server (CS) 00012 Client DLL. 00013 00014 Author: 00015 00016 Steve Wood (stevewo) 8-Oct-1990 00017 00018 Environment: 00019 00020 User Mode only 00021 00022 Revision History: 00023 00024 --*/ 00025 00026 #include "csrdll.h" 00027 #include "ldrp.h" 00028 00029 BOOLEAN 00030 CsrDllInitialize( 00031 IN PVOID DllHandle, 00032 IN ULONG Reason, 00033 IN PCONTEXT Context OPTIONAL 00034 ) 00035 00036 /*++ 00037 00038 Routine Description: 00039 00040 This function is the DLL initialization routine for the Client DLL 00041 This function gets control when the application links to this DLL 00042 are snapped. 00043 00044 Arguments: 00045 00046 Context - Supplies an optional context buffer that will be restore 00047 after all DLL initialization has been completed. If this 00048 parameter is NULL then this is a dynamic snap of this module. 00049 Otherwise this is a static snap prior to the user process 00050 gaining control. 00051 00052 Return Value: 00053 00054 Status value. 00055 00056 --*/ 00057 00058 { 00059 Context; 00060 00061 if (Reason != DLL_PROCESS_ATTACH) { 00062 return( TRUE ); 00063 } 00064 00065 // 00066 // Remember our DLL handle in a global variable. 00067 // 00068 00069 CsrDllHandle = DllHandle; 00070 00071 return( TRUE ); 00072 } 00073 00074 00075 NTSTATUS 00076 CsrOneTimeInitialize( VOID ) 00077 { 00078 NTSTATUS Status; 00079 00080 // 00081 // Save away system information in a global variable 00082 // 00083 00084 Status = NtQuerySystemInformation( SystemBasicInformation, 00085 &CsrNtSysInfo, 00086 sizeof( CsrNtSysInfo ), 00087 NULL 00088 ); 00089 if (!NT_SUCCESS( Status )) { 00090 return( Status ); 00091 } 00092 00093 // 00094 // Use the process heap for memory allocation. 00095 // 00096 00097 CsrHeap = RtlProcessHeap(); 00098 00099 CsrInitOnceDone = TRUE; 00100 00101 return( STATUS_SUCCESS ); 00102 } 00103 00104 00105 NTSTATUS 00106 CsrClientConnectToServer( 00107 IN PWSTR ObjectDirectory, 00108 IN ULONG ServerDllIndex, 00109 IN PCSR_CALLBACK_INFO CallbackInformation OPTIONAL, 00110 IN PVOID ConnectionInformation, 00111 IN OUT PULONG ConnectionInformationLength OPTIONAL, 00112 OUT PBOOLEAN CalledFromServer OPTIONAL 00113 ) 00114 00115 /*++ 00116 00117 Routine Description: 00118 00119 This function is called by the client side DLL to connect with its 00120 server side DLL. 00121 00122 Arguments: 00123 00124 ObjectDirectory - Points to a null terminate string that is the same 00125 as the value of the ObjectDirectory= argument passed to the CSRSS 00126 program. 00127 00128 ServerDllIndex - Index of the server DLL that is being connected to. 00129 It should match one of the ServerDll= arguments passed to the CSRSS 00130 program. 00131 00132 CallbackInformation - An optional pointer to a structure that contains 00133 a pointer to the client callback function dispatch table. 00134 00135 ConnectionInformation - An optional pointer to uninterpreted data. 00136 This data is intended for clients to pass package, version and 00137 protocol identification information to the server to allow the 00138 server to determine if it can satisify the client before 00139 accepting the connection. Upon return to the client, the 00140 ConnectionInformation data block contains any information passed 00141 back from the server DLL by its call to the 00142 CsrCompleteConnection call. The output data overwrites the 00143 input data. 00144 00145 ConnectionInformationLength - Pointer to the length of the 00146 ConnectionInformation data block. The output value is the 00147 length of the data stored in the ConnectionInformation data 00148 block by the server's call to the NtCompleteConnectPort 00149 service. This parameter is OPTIONAL only if the 00150 ConnectionInformation parameter is NULL, otherwise it is 00151 required. 00152 00153 CalledFromServer - On output, TRUE if the dll has been called from 00154 a server process. 00155 00156 Return Value: 00157 00158 Status value. 00159 00160 --*/ 00161 00162 { 00163 NTSTATUS Status; 00164 CSR_API_MSG m; 00165 PCSR_CLIENTCONNECT_MSG a = &m.u.ClientConnect; 00166 PCSR_CAPTURE_HEADER CaptureBuffer; 00167 HANDLE CsrServerModuleHandle; 00168 STRING ProcedureName; 00169 ANSI_STRING DllName; 00170 UNICODE_STRING DllName_U; 00171 PIMAGE_NT_HEADERS NtHeaders; 00172 00173 if (ARGUMENT_PRESENT( ConnectionInformation ) && 00174 (!ARGUMENT_PRESENT( ConnectionInformationLength ) || 00175 *ConnectionInformationLength == 0 00176 ) 00177 ) { 00178 return( STATUS_INVALID_PARAMETER ); 00179 } 00180 00181 if (!CsrInitOnceDone) { 00182 Status = CsrOneTimeInitialize(); 00183 if (!NT_SUCCESS( Status )) { 00184 return( Status ); 00185 } 00186 } 00187 00188 if (ARGUMENT_PRESENT( CallbackInformation )) { 00189 CsrLoadedClientDll[ ServerDllIndex ] = RtlAllocateHeap( CsrHeap, MAKE_TAG( CSR_TAG ), sizeof(CSR_CALLBACK_INFO) ); 00190 if ( !CsrLoadedClientDll[ ServerDllIndex ] ) { 00191 return STATUS_NO_MEMORY; 00192 } 00193 CsrLoadedClientDll[ ServerDllIndex ]->ApiNumberBase = 00194 CallbackInformation->ApiNumberBase; 00195 CsrLoadedClientDll[ ServerDllIndex ]->MaxApiNumber = 00196 CallbackInformation->MaxApiNumber; 00197 CsrLoadedClientDll[ ServerDllIndex ]->CallbackDispatchTable = 00198 CallbackInformation->CallbackDispatchTable; 00199 } 00200 00201 // 00202 // if we are being called by a server process, skip lpc port initialization 00203 // and call to server connect routine and just initialize heap. the 00204 // dll initialization routine will do any necessary initialization. this 00205 // stuff only needs to be done for the first connect. 00206 // 00207 00208 if ( CsrServerProcess == TRUE ) { 00209 *CalledFromServer = CsrServerProcess; 00210 return STATUS_SUCCESS; 00211 } 00212 00213 // 00214 // If the image is an NT Native image, we are running in the 00215 // context of the server. 00216 // 00217 00218 NtHeaders = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); 00219 CsrServerProcess = 00220 (NtHeaders->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE) ? TRUE : FALSE; 00221 00222 if ( CsrServerProcess ) { 00223 extern PVOID NtDllBase; 00224 RtlInitAnsiString( &DllName, "csrsrv" ); 00225 Status = RtlAnsiStringToUnicodeString(&DllName_U, &DllName, TRUE); 00226 ASSERT(NT_SUCCESS(Status)); 00227 00228 LdrDisableThreadCalloutsForDll(NtDllBase); 00229 00230 Status = LdrGetDllHandle( 00231 UNICODE_NULL, 00232 NULL, 00233 &DllName_U, 00234 (PVOID *)&CsrServerModuleHandle 00235 ); 00236 00237 RtlFreeUnicodeString(&DllName_U); 00238 00239 CsrServerProcess = TRUE; 00240 00241 RtlInitString(&ProcedureName,"CsrCallServerFromServer"); 00242 Status = LdrGetProcedureAddress( 00243 CsrServerModuleHandle, 00244 &ProcedureName, 00245 0L, 00246 (PVOID *)&CsrServerApiRoutine 00247 ); 00248 ASSERT(NT_SUCCESS(Status)); 00249 00250 ASSERT (CsrPortHeap==NULL); 00251 CsrPortHeap = RtlProcessHeap(); 00252 00253 CsrPortBaseTag = RtlCreateTagHeap( CsrPortHeap, 00254 0, 00255 L"CSRPORT!", 00256 L"CAPTURE\0" 00257 ); 00258 00259 if (ARGUMENT_PRESENT(CalledFromServer)) { 00260 *CalledFromServer = CsrServerProcess; 00261 } 00262 return STATUS_SUCCESS; 00263 } 00264 00265 if ( ARGUMENT_PRESENT(ConnectionInformation) ) { 00266 CsrServerProcess = FALSE; 00267 if (CsrPortHandle == NULL) { 00268 Status = CsrpConnectToServer( ObjectDirectory ); 00269 if (!NT_SUCCESS( Status )) { 00270 return( Status ); 00271 } 00272 } 00273 00274 a->ServerDllIndex = ServerDllIndex; 00275 a->ConnectionInformationLength = *ConnectionInformationLength; 00276 if (ARGUMENT_PRESENT( ConnectionInformation )) { 00277 CaptureBuffer = CsrAllocateCaptureBuffer( 1, 00278 a->ConnectionInformationLength 00279 ); 00280 if (CaptureBuffer == NULL) { 00281 return( STATUS_NO_MEMORY ); 00282 } 00283 00284 CsrAllocateMessagePointer( CaptureBuffer, 00285 a->ConnectionInformationLength, 00286 (PVOID *)&a->ConnectionInformation 00287 ); 00288 RtlMoveMemory( a->ConnectionInformation, 00289 ConnectionInformation, 00290 a->ConnectionInformationLength 00291 ); 00292 00293 *ConnectionInformationLength = a->ConnectionInformationLength; 00294 } 00295 else { 00296 CaptureBuffer = NULL; 00297 } 00298 00299 Status = CsrClientCallServer( &m, 00300 CaptureBuffer, 00301 CSR_MAKE_API_NUMBER( CSRSRV_SERVERDLL_INDEX, 00302 CsrpClientConnect 00303 ), 00304 sizeof( *a ) 00305 ); 00306 00307 if (CaptureBuffer != NULL) { 00308 if (ARGUMENT_PRESENT( ConnectionInformation )) { 00309 RtlMoveMemory( ConnectionInformation, 00310 a->ConnectionInformation, 00311 *ConnectionInformationLength 00312 ); 00313 } 00314 00315 CsrFreeCaptureBuffer( CaptureBuffer ); 00316 } 00317 } 00318 else { 00319 Status = STATUS_SUCCESS; 00320 } 00321 00322 if (ARGUMENT_PRESENT(CalledFromServer)) { 00323 *CalledFromServer = CsrServerProcess; 00324 } 00325 return( Status ); 00326 } 00327 00328 BOOLEAN 00329 xProtectHandle( 00330 HANDLE hObject 00331 ) 00332 { 00333 NTSTATUS Status; 00334 OBJECT_HANDLE_FLAG_INFORMATION HandleInfo; 00335 00336 Status = NtQueryObject( hObject, 00337 ObjectHandleFlagInformation, 00338 &HandleInfo, 00339 sizeof( HandleInfo ), 00340 NULL 00341 ); 00342 if (NT_SUCCESS( Status )) { 00343 HandleInfo.ProtectFromClose = TRUE; 00344 00345 Status = NtSetInformationObject( hObject, 00346 ObjectHandleFlagInformation, 00347 &HandleInfo, 00348 sizeof( HandleInfo ) 00349 ); 00350 if (NT_SUCCESS( Status )) { 00351 return TRUE; 00352 } 00353 } 00354 00355 return FALSE; 00356 } 00357 00358 NTSTATUS 00359 CsrpConnectToServer( 00360 IN PWSTR ObjectDirectory 00361 ) 00362 { 00363 NTSTATUS Status; 00364 REMOTE_PORT_VIEW ServerView; 00365 ULONG MaxMessageLength; 00366 ULONG ConnectionInformationLength; 00367 CSR_API_CONNECTINFO ConnectionInformation; 00368 SECURITY_QUALITY_OF_SERVICE DynamicQos; 00369 HANDLE PortSection; 00370 PORT_VIEW ClientView; 00371 ULONG n; 00372 LARGE_INTEGER SectionSize; 00373 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; 00374 PSID SystemSid; 00375 00376 // 00377 // Create the port name string by combining the passed in object directory 00378 // name with the port name. 00379 // 00380 00381 n = ((wcslen( ObjectDirectory ) + 1) * sizeof( WCHAR )) + 00382 sizeof( CSR_API_PORT_NAME ); 00383 CsrPortName.Length = 0; 00384 CsrPortName.MaximumLength = (USHORT)n; 00385 CsrPortName.Buffer = RtlAllocateHeap( CsrHeap, MAKE_TAG( CSR_TAG ), n ); 00386 if (CsrPortName.Buffer == NULL) { 00387 return( STATUS_NO_MEMORY ); 00388 } 00389 RtlAppendUnicodeToString( &CsrPortName, ObjectDirectory ); 00390 RtlAppendUnicodeToString( &CsrPortName, L"\\" ); 00391 RtlAppendUnicodeToString( &CsrPortName, CSR_API_PORT_NAME ); 00392 00393 // 00394 // Set up the security quality of service parameters to use over the 00395 // port. Use the most efficient (least overhead) - which is dynamic 00396 // rather than static tracking. 00397 // 00398 00399 DynamicQos.ImpersonationLevel = SecurityImpersonation; 00400 DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 00401 DynamicQos.EffectiveOnly = TRUE; 00402 00403 00404 // 00405 // Create a section to contain the Port Memory. Port Memory is private 00406 // memory that is shared between the client and server processes. 00407 // This allows data that is too large to fit into an API request message 00408 // to be passed to the server. 00409 // 00410 00411 SectionSize.LowPart = CSR_PORT_MEMORY_SIZE; 00412 SectionSize.HighPart = 0; 00413 00414 Status = NtCreateSection( &PortSection, 00415 SECTION_ALL_ACCESS, 00416 NULL, 00417 &SectionSize, 00418 PAGE_READWRITE, 00419 SEC_RESERVE, 00420 NULL 00421 ); 00422 if (!NT_SUCCESS( Status )) { 00423 return( Status ); 00424 } 00425 00426 // 00427 // Connect to the server. This includes a description of the Port Memory 00428 // section so that the LPC connection logic can make the section visible 00429 // to both the client and server processes. Also pass information the 00430 // server needs in the connection information structure. 00431 // 00432 00433 ClientView.Length = sizeof( ClientView ); 00434 ClientView.SectionHandle = PortSection; 00435 ClientView.SectionOffset = 0; 00436 ClientView.ViewSize = SectionSize.LowPart; 00437 ClientView.ViewBase = 0; 00438 ClientView.ViewRemoteBase = 0; 00439 00440 ServerView.Length = sizeof( ServerView ); 00441 ServerView.ViewSize = 0; 00442 ServerView.ViewBase = 0; 00443 00444 ConnectionInformationLength = sizeof( ConnectionInformation ); 00445 ConnectionInformation.ExpectedVersion = CSR_VERSION; 00446 00447 SystemSid = NULL; 00448 Status = RtlAllocateAndInitializeSid( &NtAuthority, 00449 1, 00450 SECURITY_LOCAL_SYSTEM_RID, 00451 0, 0, 0, 0, 0, 0, 0, 00452 &SystemSid 00453 ); 00454 Status = NtSecureConnectPort( &CsrPortHandle, 00455 &CsrPortName, 00456 &DynamicQos, 00457 &ClientView, 00458 SystemSid, 00459 &ServerView, 00460 (PULONG)&MaxMessageLength, 00461 (PVOID)&ConnectionInformation, 00462 (PULONG)&ConnectionInformationLength 00463 ); 00464 RtlFreeSid( SystemSid ); 00465 NtClose( PortSection ); 00466 if (!NT_SUCCESS( Status )) { 00467 IF_DEBUG { 00468 DbgPrint( "CSRDLL: Unable to connect to %wZ Server - Status == %X\n", 00469 &CsrPortName, 00470 Status 00471 ); 00472 } 00473 00474 return( Status ); 00475 } 00476 xProtectHandle(CsrPortHandle); 00477 00478 NtCurrentPeb()->ReadOnlySharedMemoryBase = ConnectionInformation.SharedSectionBase; 00479 NtCurrentPeb()->ReadOnlySharedMemoryHeap = ConnectionInformation.SharedSectionHeap; 00480 NtCurrentPeb()->ReadOnlyStaticServerData = (PVOID *)ConnectionInformation.SharedStaticServerData; 00481 00482 #if DBG 00483 CsrDebug = ConnectionInformation.DebugFlags; 00484 #endif 00485 CsrObjectDirectory = ConnectionInformation.ObjectDirectory; 00486 00487 CsrPortMemoryRemoteDelta = (ULONG_PTR)ClientView.ViewRemoteBase - 00488 (ULONG_PTR)ClientView.ViewBase; 00489 00490 IF_CSR_DEBUG( LPC ) { 00491 DbgPrint( "CSRDLL: ClientView: Base=%p RemoteBase=%p Delta: %lX Size=%lX\n", 00492 ClientView.ViewBase, 00493 ClientView.ViewRemoteBase, 00494 CsrPortMemoryRemoteDelta, 00495 (ULONG)ClientView.ViewSize 00496 ); 00497 } 00498 00499 // 00500 // Create a sparse heap in the share memory section. Initially 00501 // commit just one page. 00502 // 00503 00504 CsrPortHeap = RtlCreateHeap( HEAP_CLASS_8, // Flags 00505 ClientView.ViewBase, // HeapBase 00506 ClientView.ViewSize, // ReserveSize 00507 CsrNtSysInfo.PageSize, // CommitSize 00508 0, // Reserved 00509 0 // GrowthThreshold 00510 ); 00511 if (CsrPortHeap == NULL) { 00512 NtClose( CsrPortHandle ); 00513 CsrPortHandle = NULL; 00514 00515 return( STATUS_NO_MEMORY ); 00516 } 00517 00518 CsrPortBaseTag = RtlCreateTagHeap( CsrPortHeap, 00519 0, 00520 L"CSRPORT!", 00521 L"!CSRPORT\0" 00522 L"CAPTURE\0" 00523 ); 00524 00525 return( STATUS_SUCCESS ); 00526 }

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