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

csrutil.c File Reference

#include "csrdll.h"

Go to the source code of this file.

Functions

NTSTATUS CsrClientCallServer (IN OUT PCSR_API_MSG m, IN OUT PCSR_CAPTURE_HEADER CaptureBuffer OPTIONAL, IN CSR_API_NUMBER ApiNumber, IN ULONG ArgLength)
PCSR_CAPTURE_HEADER CsrAllocateCaptureBuffer (IN ULONG CountMessagePointers, IN ULONG Size)
VOID CsrFreeCaptureBuffer (IN PCSR_CAPTURE_HEADER CaptureBuffer)
ULONG CsrAllocateMessagePointer (IN OUT PCSR_CAPTURE_HEADER CaptureBuffer, IN ULONG Length, OUT PVOID *Pointer)
VOID CsrCaptureMessageBuffer (IN OUT PCSR_CAPTURE_HEADER CaptureBuffer, IN PVOID Buffer OPTIONAL, IN ULONG Length, OUT PVOID *CapturedBuffer)
VOID CsrCaptureMessageString (IN OUT PCSR_CAPTURE_HEADER CaptureBuffer, IN PCSTR String OPTIONAL, IN ULONG Length, IN ULONG MaximumLength, OUT PSTRING CapturedString)
PLARGE_INTEGER CsrCaptureTimeout (IN ULONG MilliSeconds, OUT PLARGE_INTEGER Timeout)
VOID CsrProbeForWrite (IN PVOID Address, IN ULONG Length, IN ULONG Alignment)
VOID CsrProbeForRead (IN PVOID Address, IN ULONG Length, IN ULONG Alignment)


Function Documentation

PCSR_CAPTURE_HEADER CsrAllocateCaptureBuffer IN ULONG  CountMessagePointers,
IN ULONG  Size
 

Definition at line 223 of file csrutil.c.

References CAPTURE_TAG, CsrPortHeap, MAKE_CSRPORT_TAG, NULL, RtlAllocateHeap, and Size.

00230 : 00231 00232 This function allocates a buffer from the Port Memory section for 00233 use by the client in capture arguments into Port Memory. In addition to 00234 specifying the size of the data that needs to be captured, the caller 00235 needs to specify how many pointers to captured data will be passed. 00236 Pointers can be located in either the request message itself, and/or 00237 the capture buffer. 00238 00239 Arguments: 00240 00241 CountMessagePointers - Number of pointers within the request message 00242 that will point to locations within the allocated capture buffer. 00243 00244 Size - Total size of the data that will be captured into the capture 00245 buffer. 00246 00247 Return Value: 00248 00249 A pointer to the capture buffer header. 00250 00251 --*/ 00252 00253 { 00254 PCSR_CAPTURE_HEADER CaptureBuffer; 00255 ULONG CountPointers; 00256 00257 // 00258 // Calculate the total number of pointers that will be passed 00259 // 00260 00261 CountPointers = CountMessagePointers; 00262 00263 // 00264 // Calculate the total size of the capture buffer. This includes the 00265 // header, the array of pointer offsets and the data length. We round 00266 // the data length to a 32-bit boundary, assuming that each pointer 00267 // points to data whose length is not aligned on a 32-bit boundary. 00268 // 00269 00270 if (Size >= MAXLONG) { 00271 // 00272 // Bail early if too big 00273 // 00274 return NULL; 00275 } 00276 Size += FIELD_OFFSET(CSR_CAPTURE_HEADER, MessagePointerOffsets) + (CountPointers * sizeof( PVOID )); 00277 Size = (Size + (3 * (CountPointers+1))) & ~3; 00278 00279 // 00280 // Allocate the capture buffer from the Port Memory Heap. 00281 // 00282 00283 CaptureBuffer = RtlAllocateHeap( CsrPortHeap, MAKE_CSRPORT_TAG( CAPTURE_TAG ), Size ); 00284 if (CaptureBuffer == NULL) { 00285 00286 // 00287 // FIX, FIX - need to attempt the receive lost reply messages to 00288 // to see if they contain CaptureBuffer pointers that can be freed. 00289 // 00290 00291 return( NULL ); 00292 } 00293 00294 // 00295 // Initialize the capture buffer header 00296 // 00297 00298 CaptureBuffer->Length = Size; 00299 CaptureBuffer->CountMessagePointers = 0; 00300 00301 // 00302 // If there are pointers being passed then initialize the arrays of 00303 // pointer offsets to zero. In either case set the free space pointer 00304 // in the capture buffer header to point to the first 32-bit aligned 00305 // location after the header, the arrays of pointer offsets are considered 00306 // part of the header. 00307 // 00308 00309 RtlZeroMemory( CaptureBuffer->MessagePointerOffsets, 00310 CountPointers * sizeof( ULONG_PTR ) 00311 ); 00312 00313 CaptureBuffer->FreeSpace = (PCHAR) 00314 (CaptureBuffer->MessagePointerOffsets + CountPointers); 00315 00316 // 00317 // Returned the address of the capture buffer. 00318 // 00319 00320 return( CaptureBuffer ); 00321 }

ULONG CsrAllocateMessagePointer IN OUT PCSR_CAPTURE_HEADER  CaptureBuffer,
IN ULONG  Length,
OUT PVOID *  Pointer
 

Definition at line 356 of file csrutil.c.

References NULL.

00364 : 00365 00366 This function allocates space from the capture buffer along with a 00367 pointer to point to it. The pointer is presumed to be located in 00368 the request message structure. 00369 00370 Arguments: 00371 00372 CaptureBuffer - Pointer to a capture buffer allocated by 00373 CsrAllocateCaptureBuffer. 00374 00375 Length - Size of data being allocated from the capture buffer. 00376 00377 Pointer - Address of the pointer within the request message that 00378 is to point to the space allocated out of the capture buffer. 00379 00380 Return Value: 00381 00382 The actual length of the buffer allocated, after it has been rounded 00383 up to a multiple of 4. 00384 00385 --*/ 00386 00387 { 00388 if (Length == 0) { 00389 *Pointer = NULL; 00390 Pointer = NULL; 00391 } 00392 00393 else { 00394 00395 // 00396 // Set the returned pointer value to point to the next free byte in 00397 // the capture buffer. 00398 // 00399 00400 *Pointer = CaptureBuffer->FreeSpace; 00401 00402 // 00403 // Round the length up to a multiple of 4 00404 // 00405 00406 if (Length >= MAXLONG) { 00407 // 00408 // Bail early if too big 00409 // 00410 return 0; 00411 } 00412 00413 Length = (Length + 3) & ~3; 00414 00415 // 00416 // Update the free space pointer to point to the next available byte 00417 // in the capture buffer. 00418 // 00419 00420 CaptureBuffer->FreeSpace += Length; 00421 } 00422 00423 00424 // 00425 // Remember the location of this pointer so that CsrClientCallServer can 00426 // convert it into a server pointer prior to sending the request to 00427 // the server. 00428 // 00429 00430 CaptureBuffer->MessagePointerOffsets[ CaptureBuffer->CountMessagePointers++ ] = 00431 (ULONG_PTR)Pointer; 00432 00433 // 00434 // Returned the actual length allocated. 00435 // 00436 00437 return( Length ); 00438 }

VOID CsrCaptureMessageBuffer IN OUT PCSR_CAPTURE_HEADER  CaptureBuffer,
IN PVOID Buffer  OPTIONAL,
IN ULONG  Length,
OUT PVOID *  CapturedBuffer
 

Definition at line 442 of file csrutil.c.

References Buffer, and CsrAllocateMessagePointer().

00451 : 00452 00453 This function captures an ASCII string into a counted string data 00454 structure located in an API request message. 00455 00456 Arguments: 00457 00458 CaptureBuffer - Pointer to a capture buffer allocated by 00459 CsrAllocateCaptureBuffer. 00460 00461 Buffer - Optional pointer to the buffer. If this parameter is 00462 not present, then the counted string data structure is set to 00463 the null string and no space is allocated from the capture 00464 buffer. 00465 00466 Length - Length of the buffer. 00467 00468 CaptureString - Pointer to the field in the message that will 00469 be filled in to point to the capture buffer. 00470 00471 Return Value: 00472 00473 None. 00474 00475 --*/ 00476 00477 { 00478 // 00479 // Set the length fields of the captured string structure and allocated 00480 // the Length for the string from the capture buffer. 00481 // 00482 00483 CsrAllocateMessagePointer( CaptureBuffer, 00484 Length, 00485 CapturedBuffer 00486 ); 00487 00488 // 00489 // If Buffer parameter is not present or the length of the data is zero, 00490 // return. 00491 // 00492 00493 if (!ARGUMENT_PRESENT( Buffer ) || (Length == 0)) { 00494 return; 00495 } 00496 00497 // 00498 // Copy the buffer data to the capture area. 00499 // 00500 00501 RtlMoveMemory( *CapturedBuffer, Buffer, Length ); 00502 00503 return; 00504 }

VOID CsrCaptureMessageString IN OUT PCSR_CAPTURE_HEADER  CaptureBuffer,
IN PCSTR String  OPTIONAL,
IN ULONG  Length,
IN ULONG  MaximumLength,
OUT PSTRING  CapturedString
 

Definition at line 507 of file csrutil.c.

References CsrAllocateMessagePointer(), String, and USHORT.

00517 : 00518 00519 This function captures an ASCII string into a counted string data 00520 structure located in an API request message. 00521 00522 Arguments: 00523 00524 CaptureBuffer - Pointer to a capture buffer allocated by 00525 CsrAllocateCaptureBuffer. 00526 00527 String - Optional pointer to the ASCII string. If this parameter is 00528 not present, then the counted string data structure is set to 00529 the null string and no space is allocated from the capture 00530 buffer. 00531 00532 Length - Length of the ASCII string. 00533 00534 MaximumLength - Maximum length of the string. Different for null 00535 terminated strings, where Length does not include the null and 00536 MaximumLength does. 00537 00538 CaptureString - Pointer to the counted string data structure that will 00539 be filled in to point to the capture ASCII string. 00540 00541 Return Value: 00542 00543 None. 00544 00545 --*/ 00546 00547 { 00548 // 00549 // If String parameter is not present, then set the captured string 00550 // to be the null string and returned. 00551 // 00552 00553 if (!ARGUMENT_PRESENT( String )) { 00554 CapturedString->Length = 0; 00555 CapturedString->MaximumLength = (USHORT)MaximumLength; 00556 CsrAllocateMessagePointer( CaptureBuffer, 00557 MaximumLength, 00558 (PVOID *)&CapturedString->Buffer 00559 ); 00560 return; 00561 } 00562 00563 // 00564 // Set the length fields of the captured string structure and allocated 00565 // the MaximumLength for the string from the capture buffer. 00566 // 00567 00568 CapturedString->Length = (USHORT)Length; 00569 CapturedString->MaximumLength = (USHORT) 00570 CsrAllocateMessagePointer( CaptureBuffer, 00571 MaximumLength, 00572 (PVOID *)&CapturedString->Buffer 00573 ); 00574 // 00575 // If the Length of the ASCII string is non-zero then move it to the 00576 // capture area. 00577 // 00578 00579 if (Length != 0) { 00580 RtlMoveMemory( CapturedString->Buffer, String, MaximumLength ); 00581 if (CapturedString->Length < CapturedString->MaximumLength) { 00582 CapturedString->Buffer[ CapturedString->Length ] = '\0'; 00583 } 00584 } 00585 00586 return; 00587 }

PLARGE_INTEGER CsrCaptureTimeout IN ULONG  MilliSeconds,
OUT PLARGE_INTEGER  Timeout
 

Definition at line 592 of file csrutil.c.

References NULL.

00596 { 00597 if (MilliSeconds == -1) { 00598 return( NULL ); 00599 } 00600 else { 00601 Timeout->QuadPart = Int32x32To64( MilliSeconds, -10000 ); 00602 return( (PLARGE_INTEGER)Timeout ); 00603 } 00604 }

NTSTATUS CsrClientCallServer IN OUT PCSR_API_MSG  m,
IN OUT PCSR_CAPTURE_HEADER CaptureBuffer  OPTIONAL,
IN CSR_API_NUMBER  ApiNumber,
IN ULONG  ArgLength
 

Definition at line 25 of file csrutil.c.

References CsrPortHandle, CsrPortMemoryRemoteDelta, CsrServerApiRoutine, CsrServerProcess, DbgPrint, FALSE, IF_DEBUG, NT_SUCCESS, NtRequestWaitReplyPort(), NTSTATUS(), NULL, and Status.

00034 : 00035 00036 This function sends an API request to the Windows Emulation Subsystem 00037 Server and waits for a reply. 00038 00039 Arguments: 00040 00041 m - Pointer to the API request message to send. 00042 00043 CaptureBuffer - Optional pointer to a capture buffer located in the 00044 Port Memory section that contains additional data being sent 00045 to the server. Since Port Memory is also visible to the server, 00046 no data needs to be copied, but pointers to locations within the 00047 capture buffer need to be converted into pointers valid in the 00048 server's process context, since the server's view of the Port Memory 00049 is not at the same virtual address as the client's view. 00050 00051 ApiNumber - Small integer that is the number of the API being called. 00052 00053 ArgLength - Length, in bytes, of the argument portion located at the 00054 end of the request message. Used to calculate the length of the 00055 request message. 00056 00057 Return Value: 00058 00059 Status Code from either client or server 00060 00061 --*/ 00062 00063 { 00064 NTSTATUS Status; 00065 PULONG_PTR PointerOffsets; 00066 ULONG CountPointers; 00067 ULONG_PTR Pointer; 00068 00069 // 00070 // Initialize the header of the message. 00071 // 00072 00073 if ((LONG)ArgLength < 0) { 00074 ArgLength = (ULONG)(-(LONG)ArgLength); 00075 m->h.u2.s2.Type = 0; 00076 } 00077 else { 00078 m->h.u2.ZeroInit = 0; 00079 } 00080 00081 ArgLength |= (ArgLength << 16); 00082 ArgLength += ((sizeof( CSR_API_MSG ) - sizeof( m->u )) << 16) | 00083 (FIELD_OFFSET( CSR_API_MSG, u ) - sizeof( m->h )); 00084 m->h.u1.Length = ArgLength; 00085 m->CaptureBuffer = NULL; 00086 m->ApiNumber = ApiNumber; 00087 00088 // 00089 // if the caller is within the server process, do the API call directly 00090 // and skip the capture buffer fixups and LPC call. 00091 // 00092 00093 if (CsrServerProcess == FALSE) { 00094 00095 // 00096 // If the CaptureBuffer argument is present, then there is data located 00097 // in the Port Memory section that is being passed to the server. All 00098 // Port Memory pointers need to be converted so they are valid in the 00099 // Server's view of the Port Memory. 00100 // 00101 00102 if (ARGUMENT_PRESENT( CaptureBuffer )) { 00103 // 00104 // Store a pointer to the capture buffer in the message that is valid 00105 // in the server process's context. 00106 // 00107 00108 m->CaptureBuffer = (PCSR_CAPTURE_HEADER) 00109 ((PCHAR)CaptureBuffer + CsrPortMemoryRemoteDelta); 00110 00111 // 00112 // Mark the fact that we are done allocating space from the end of 00113 // the capture buffer. 00114 // 00115 00116 CaptureBuffer->FreeSpace = NULL; 00117 00118 // 00119 // Loop over all of the pointers to Port Memory within the message 00120 // itself and convert them into server pointers. Also, convert 00121 // the pointers to pointers into offsets. 00122 // 00123 00124 PointerOffsets = CaptureBuffer->MessagePointerOffsets; 00125 CountPointers = CaptureBuffer->CountMessagePointers; 00126 while (CountPointers--) { 00127 Pointer = *PointerOffsets++; 00128 if (Pointer != 0) { 00129 *(PULONG_PTR)Pointer += CsrPortMemoryRemoteDelta; 00130 PointerOffsets[ -1 ] = Pointer - (ULONG_PTR)m; 00131 } 00132 } 00133 } 00134 00135 // 00136 // Send the request to the server and wait for a reply. The wait is 00137 // NOT alertable, because ? FIX,FIX 00138 // 00139 00140 Status = NtRequestWaitReplyPort( CsrPortHandle, 00141 (PPORT_MESSAGE)m, 00142 (PPORT_MESSAGE)m 00143 ); 00144 // 00145 // If the CaptureBuffer argument is present then reverse what we did 00146 // to the pointers above so that the client side code can use them 00147 // again. 00148 // 00149 00150 if (ARGUMENT_PRESENT( CaptureBuffer )) { 00151 // 00152 // Convert the capture buffer pointer back to a client pointer. 00153 // 00154 00155 m->CaptureBuffer = (PCSR_CAPTURE_HEADER) 00156 ((PCHAR)m->CaptureBuffer - CsrPortMemoryRemoteDelta); 00157 00158 // 00159 // Loop over all of the pointers to Port Memory within the message 00160 // itself and convert them into client pointers. Also, convert 00161 // the offsets pointers to pointers into back into pointers 00162 // 00163 00164 PointerOffsets = CaptureBuffer->MessagePointerOffsets; 00165 CountPointers = CaptureBuffer->CountMessagePointers; 00166 while (CountPointers--) { 00167 Pointer = *PointerOffsets++; 00168 if (Pointer != 0) { 00169 Pointer += (ULONG_PTR)m; 00170 PointerOffsets[ -1 ] = Pointer; 00171 *(PULONG_PTR)Pointer -= CsrPortMemoryRemoteDelta; 00172 } 00173 } 00174 } 00175 00176 // 00177 // Check for failed status and do something. 00178 // 00179 if (!NT_SUCCESS( Status )) { 00180 IF_DEBUG { 00181 if (Status != STATUS_PORT_DISCONNECTED && 00182 Status != STATUS_INVALID_HANDLE 00183 ) { 00184 DbgPrint( "CSRDLL: NtRequestWaitReplyPort failed - Status == %X\n", 00185 Status 00186 ); 00187 } 00188 } 00189 00190 m->ReturnValue = Status; 00191 } 00192 } 00193 else { 00194 m->h.ClientId = NtCurrentTeb()->ClientId; 00195 Status = (CsrServerApiRoutine)((PCSR_API_MSG)m, 00196 (PCSR_API_MSG)m 00197 ); 00198 00199 // 00200 // Check for failed status and do something. 00201 // 00202 00203 if (!NT_SUCCESS( Status )) { 00204 IF_DEBUG { 00205 DbgPrint( "CSRDLL: Server side client call failed - Status == %X\n", 00206 Status 00207 ); 00208 } 00209 00210 m->ReturnValue = Status; 00211 } 00212 } 00213 00214 // 00215 // The value of this function is whatever the server function returned. 00216 // 00217 00218 return( m->ReturnValue ); 00219 }

VOID CsrFreeCaptureBuffer IN PCSR_CAPTURE_HEADER  CaptureBuffer  ) 
 

Definition at line 325 of file csrutil.c.

References CsrPortHeap, and RtlFreeHeap.

00331 : 00332 00333 This function frees a capture buffer allocated by CsrAllocateCaptureBuffer. 00334 00335 Arguments: 00336 00337 CaptureBuffer - Pointer to a capture buffer allocated by 00338 CsrAllocateCaptureBuffer. 00339 00340 Return Value: 00341 00342 None. 00343 00344 --*/ 00345 00346 { 00347 // 00348 // Free the capture buffer back to the Port Memory heap. 00349 // 00350 00351 RtlFreeHeap( CsrPortHeap, 0, CaptureBuffer ); 00352 }

VOID CsrProbeForRead IN PVOID  Address,
IN ULONG  Length,
IN ULONG  Alignment
 

Definition at line 678 of file csrutil.c.

References ASSERT, CHAR, and RtlRaiseStatus().

00686 : 00687 00688 This function probes a structure for read accessibility. 00689 If the structure is not accessible, then an exception is raised. 00690 00691 Arguments: 00692 00693 Address - Supplies a pointer to the structure to be probed. 00694 00695 Length - Supplies the length of the structure. 00696 00697 Alignment - Supplies the required alignment of the structure expressed 00698 as the number of bytes in the primitive datatype (e.g., 1 for char, 00699 2 for short, 4 for long, and 8 for quad). 00700 00701 Return Value: 00702 00703 None. 00704 00705 --*/ 00706 00707 { 00708 volatile CHAR *StartAddress; 00709 volatile CHAR *EndAddress; 00710 CHAR Temp; 00711 00712 // 00713 // If the structure has zero length, then do not probe the structure for 00714 // read accessibility or alignment. 00715 // 00716 00717 if (Length != 0) { 00718 00719 // 00720 // If the structure is not properly aligned, then raise a data 00721 // misalignment exception. 00722 // 00723 00724 ASSERT((Alignment == 1) || (Alignment == 2) || 00725 (Alignment == 4) || (Alignment == 8)); 00726 StartAddress = (volatile CHAR *)Address; 00727 00728 if (((ULONG_PTR)StartAddress & (Alignment - 1)) != 0) { 00729 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT); 00730 } else { 00731 Temp = *StartAddress; 00732 EndAddress = StartAddress + Length - 1; 00733 Temp = *EndAddress; 00734 } 00735 } 00736 } }

VOID CsrProbeForWrite IN PVOID  Address,
IN ULONG  Length,
IN ULONG  Alignment
 

Definition at line 607 of file csrutil.c.

References ASSERT, CHAR, CsrNtSysInfo, and RtlRaiseStatus().

00615 : 00616 00617 This function probes a structure for read accessibility. 00618 If the structure is not accessible, then an exception is raised. 00619 00620 Arguments: 00621 00622 Address - Supplies a pointer to the structure to be probed. 00623 00624 Length - Supplies the length of the structure. 00625 00626 Alignment - Supplies the required alignment of the structure expressed 00627 as the number of bytes in the primitive datatype (e.g., 1 for char, 00628 2 for short, 4 for long, and 8 for quad). 00629 00630 Return Value: 00631 00632 None. 00633 00634 --*/ 00635 00636 { 00637 volatile CHAR *StartAddress; 00638 volatile CHAR *EndAddress; 00639 CHAR Temp; 00640 00641 // 00642 // If the structure has zero length, then do not probe the structure for 00643 // write accessibility or alignment. 00644 // 00645 00646 if (Length != 0) { 00647 00648 // 00649 // If the structure is not properly aligned, then raise a data 00650 // misalignment exception. 00651 // 00652 00653 ASSERT((Alignment == 1) || (Alignment == 2) || 00654 (Alignment == 4) || (Alignment == 8)); 00655 StartAddress = (volatile CHAR *)Address; 00656 00657 if (((ULONG_PTR)StartAddress & (Alignment - 1)) != 0) { 00658 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT); 00659 } else { 00660 // 00661 // BUG, BUG - this should not be necessary once the 386 kernel 00662 // makes system space inaccessable to user mode. 00663 // 00664 if ((ULONG_PTR)StartAddress > CsrNtSysInfo.MaximumUserModeAddress) { 00665 RtlRaiseStatus(STATUS_ACCESS_VIOLATION); 00666 } 00667 00668 Temp = *StartAddress; 00669 *StartAddress = Temp; 00670 EndAddress = StartAddress + Length - 1; 00671 Temp = *EndAddress; 00672 *EndAddress = Temp; 00673 } 00674 } 00675 }


Generated on Sat May 15 19:43:20 2004 for test by doxygen 1.3.7