2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: lib/ntdll/csr/capture.c
5 * PURPOSE: Routines for probing and capturing CSR API Messages
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES *****************************************************************/
15 /* GLOBALS *******************************************************************/
16 extern HANDLE CsrPortHeap
;
18 /* FUNCTIONS *****************************************************************/
25 CsrProbeForRead(IN PVOID Address
,
33 if (Length
== 0) return;
35 /* Validate alignment */
36 if ((ULONG_PTR
)Address
& (Alignment
- 1))
38 /* Raise exception if it doesn't match */
39 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT
);
43 Pointer
= (PUCHAR
)Address
;
45 Pointer
= (PUCHAR
)((ULONG
)Address
+ Length
-1);
54 CsrProbeForWrite(IN PVOID Address
,
62 if (Length
== 0) return;
64 /* Validate alignment */
65 if ((ULONG_PTR
)Address
& (Alignment
- 1))
67 /* Raise exception if it doesn't match */
68 RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT
);
72 Pointer
= (PUCHAR
)Address
;
75 Pointer
= (PUCHAR
)((ULONG
)Address
+ Length
-1);
85 CsrAllocateCaptureBuffer(ULONG ArgumentCount
,
88 PCSR_CAPTURE_BUFFER CaptureBuffer
;
91 if (BufferSize
>= MAXLONG
) return NULL
;
93 /* Add the size of the header and for each pointer to the pointers */
94 BufferSize
+= sizeof(CSR_CAPTURE_BUFFER
) + (ArgumentCount
* sizeof(PVOID
));
96 /* Allocate memory from the port heap */
97 CaptureBuffer
= RtlAllocateHeap(CsrPortHeap
, 0, BufferSize
);
98 if (CaptureBuffer
== NULL
) return NULL
;
100 /* Initialize the header */
101 CaptureBuffer
->Size
= BufferSize
;
102 CaptureBuffer
->PointerCount
= 0;
104 /* Initialize all the pointers */
105 RtlZeroMemory(CaptureBuffer
->PointerArray
,
106 ArgumentCount
* sizeof(ULONG_PTR
));
108 /* Point the start of the free buffer */
109 CaptureBuffer
->BufferEnd
= (ULONG_PTR
)CaptureBuffer
->PointerArray
+
110 ArgumentCount
* sizeof(ULONG_PTR
);
112 /* Return the address of the buffer */
113 return CaptureBuffer
;
121 CsrAllocateMessagePointer(PCSR_CAPTURE_BUFFER CaptureBuffer
,
125 /* If there's no data, our job is easy. */
126 if (MessageLength
== 0)
133 /* Set the capture data at our current available buffer */
134 *CaptureData
= (PVOID
)CaptureBuffer
->BufferEnd
;
136 /* Validate the size */
137 if (MessageLength
>= MAXLONG
) return 0;
139 /* Align it to a 4-byte boundary */
140 MessageLength
= (MessageLength
+ 3) & ~3;
142 /* Move our available buffer beyond this space */
143 CaptureBuffer
->BufferEnd
+= MessageLength
;
146 /* Write down this pointer in the array */
147 CaptureBuffer
->PointerArray
[CaptureBuffer
->PointerCount
] = (ULONG_PTR
)CaptureData
;
149 /* Increase the pointer count */
150 CaptureBuffer
->PointerCount
++;
152 /* Return the aligned length */
153 return MessageLength
;
161 CsrCaptureMessageBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer
,
166 /* Simply allocate a message pointer in the buffer */
167 CsrAllocateMessagePointer(CaptureBuffer
, StringLength
, CapturedData
);
169 /* Check if there was any data */
170 if (!MessageString
|| !StringLength
) return;
172 /* Copy the data into the buffer */
173 RtlMoveMemory(*CapturedData
, MessageString
, StringLength
);
181 CsrFreeCaptureBuffer(PCSR_CAPTURE_BUFFER CaptureBuffer
)
183 /* Free it from the heap */
184 RtlFreeHeap(CsrPortHeap
, 0, CaptureBuffer
);
192 CsrCaptureMessageMultiUnicodeStringsInPlace(IN PCSR_CAPTURE_BUFFER
*CaptureBuffer
,
193 IN ULONG MessageCount
,
194 IN PVOID MessageStrings
)
196 /* FIXME: allocate a buffer if we don't have one, and return it */
197 /* FIXME: call CsrCaptureMessageUnicodeStringInPlace for each string */
199 return STATUS_NOT_IMPLEMENTED
;
207 CsrCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer
,
209 IN ULONG StringLength
,
210 IN ULONG MaximumLength
,
211 OUT PANSI_STRING CapturedString
)
213 ULONG ReturnedLength
;
215 /* If we don't have a string, initialize an empty one */
218 CapturedString
->Length
= 0;
219 CapturedString
->MaximumLength
= MaximumLength
;
221 /* Allocate a pointer for it */
222 CsrAllocateMessagePointer(CaptureBuffer
,
224 (PVOID
*)&CapturedString
->Buffer
);
228 /* Initialize this string */
229 CapturedString
->Length
= StringLength
;
231 /* Allocate a buffer and get its size */
232 ReturnedLength
= CsrAllocateMessagePointer(CaptureBuffer
,
234 (PVOID
*)&CapturedString
->Buffer
);
235 CapturedString
->MaximumLength
= ReturnedLength
;
237 /* If the string had data */
240 /* Copy it into the capture buffer */
241 RtlMoveMemory(CapturedString
->Buffer
, String
, MaximumLength
);
243 /* If we don't take up the whole space */
244 if (CapturedString
->Length
< CapturedString
->MaximumLength
)
246 /* Null-terminate it */
247 CapturedString
->Buffer
[CapturedString
->Length
] = '\0';
257 CsrCaptureTimeout(LONG Milliseconds
,
258 PLARGE_INTEGER Timeout
)
260 /* Validate the time */
261 if (Milliseconds
== -1) return NULL
;
263 /* Convert to relative ticks */
264 Timeout
->QuadPart
= Milliseconds
* -100000;