test: csrinit.c File Reference

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

# csrinit.c File Reference

`#include "csrdll.h"`
`#include "ldrp.h"`

Go to the source code of this file.

## Functions

BOOLEAN | CsrDllInitialize (IN PVOID DllHandle, IN ULONG Reason, IN PCONTEXT Context OPTIONAL)
NTSTATUS | CsrOneTimeInitialize (VOID)
NTSTATUS | CsrClientConnectToServer (IN PWSTR ObjectDirectory, IN ULONG ServerDllIndex, IN PCSR_CALLBACK_INFO CallbackInformation OPTIONAL, IN PVOID ConnectionInformation, IN OUT PULONG ConnectionInformationLength OPTIONAL, OUT PBOOLEAN CalledFromServer OPTIONAL)
BOOLEAN | xProtectHandle (HANDLE hObject)
NTSTATUS | CsrpConnectToServer (IN PWSTR ObjectDirectory)

## Function Documentation

NTSTATUS CsrClientConnectToServer | ( | IN PWSTR | ObjectDirectory,
|  | IN ULONG | ServerDllIndex,
|  | IN PCSR_CALLBACK_INFO CallbackInformation | OPTIONAL,
|  | IN PVOID | ConnectionInformation,
|  | IN OUT PULONG ConnectionInformationLength | OPTIONAL,
|  | OUT PBOOLEAN CalledFromServer | OPTIONAL
| ) |

Definition at line 106 of file csrinit.c.

References ASSERT, CSR_TAG, CsrAllocateCaptureBuffer(), CsrAllocateMessagePointer(), CsrClientCallServer(), CsrFreeCaptureBuffer(), CsrHeap, CsrInitOnceDone, CsrLoadedClientDll, CsrOneTimeInitialize(), CsrpConnectToServer(), CsrPortBaseTag, CsrPortHandle, CsrPortHeap, CsrServerApiRoutine, CsrServerProcess, FALSE, L, LdrDisableThreadCalloutsForDll(), LdrGetDllHandle(), LdrGetProcedureAddress(), MAKE_TAG, NT_SUCCESS, NtDllBase, NTSTATUS(), NULL, RtlAllocateHeap, RtlAnsiStringToUnicodeString(), RtlCreateTagHeap(), RtlFreeUnicodeString(), RtlImageNtHeader(), RtlInitAnsiString(), RtlInitString(), Status, and TRUE.

    00117                    :
    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 }

BOOLEAN CsrDllInitialize | ( | IN PVOID | DllHandle,
|  | IN ULONG | Reason,
|  | IN PCONTEXT Context | OPTIONAL
| ) |

Definition at line 30 of file csrinit.c.

References CsrDllHandle, and TRUE.

    00038                    :
    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 }

NTSTATUS CsrOneTimeInitialize | ( | VOID |  | ) |

Definition at line 76 of file csrinit.c.

References CsrHeap, CsrInitOnceDone, CsrNtSysInfo, NT_SUCCESS, NtQuerySystemInformation(), NTSTATUS(), NULL, Status, and TRUE.

Referenced by CsrClientConnectToServer().

    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 }

NTSTATUS CsrpConnectToServer | ( | IN PWSTR | ObjectDirectory | ) |

Definition at line 359 of file csrinit.c.

References CSR_PORT_MEMORY_SIZE, CSR_TAG, CsrHeap, CsrNtSysInfo, CsrObjectDirectory, CsrPortBaseTag, CsrPortHandle, CsrPortHeap, CsrPortMemoryRemoteDelta, CsrPortName, DbgPrint, DynamicQos, IF_CSR_DEBUG, IF_DEBUG, L, MAKE_TAG, n, NT_SUCCESS, NtClose(), NtCreateSection(), NtSecureConnectPort(), NTSTATUS(), NULL, RtlAllocateAndInitializeSid(), RtlAllocateHeap, RtlAppendUnicodeToString(), RtlCreateHeap(), RtlCreateTagHeap(), RtlFreeSid(), Status, TRUE, USHORT, and xProtectHandle().

Referenced by CsrClientConnectToServer().

    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 }

BOOLEAN xProtectHandle | ( | HANDLE | hObject | ) |

Definition at line 329 of file csrinit.c.

References FALSE, NT_SUCCESS, NtQueryObject(), NtSetInformationObject(), NTSTATUS(), NULL, Status, and TRUE.

Referenced by CsrpConnectToServer().

    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 }