- use inlined probing macros for basic types
[reactos.git] / reactos / ntoskrnl / rtl / capture.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/rtl/capture.c
6 * PURPOSE: Helper routines for system calls.
7 *
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* FUNCTIONS *****************************************************************/
18
19 NTSTATUS
20 RtlCaptureUnicodeString(OUT PUNICODE_STRING Dest,
21 IN KPROCESSOR_MODE CurrentMode,
22 IN POOL_TYPE PoolType,
23 IN BOOLEAN CaptureIfKernel,
24 IN PUNICODE_STRING UnsafeSrc)
25 {
26 UNICODE_STRING Src;
27 NTSTATUS Status = STATUS_SUCCESS;
28
29 ASSERT(Dest != NULL);
30
31 /*
32 * Copy the source string structure to kernel space.
33 */
34
35 if(CurrentMode != KernelMode)
36 {
37 RtlZeroMemory(&Src, sizeof(Src));
38
39 _SEH_TRY
40 {
41 ProbeForRead(UnsafeSrc,
42 sizeof(UNICODE_STRING),
43 sizeof(ULONG));
44 Src = *UnsafeSrc;
45 if(Src.Length > 0)
46 {
47 ProbeForRead(Src.Buffer,
48 Src.Length,
49 sizeof(WCHAR));
50 }
51 }
52 _SEH_HANDLE
53 {
54 Status = _SEH_GetExceptionCode();
55 }
56 _SEH_END;
57
58 if(!NT_SUCCESS(Status))
59 {
60 return Status;
61 }
62 }
63 else if(!CaptureIfKernel)
64 {
65 /* just copy the UNICODE_STRING structure, the pointers are considered valid */
66 *Dest = *UnsafeSrc;
67 return STATUS_SUCCESS;
68 }
69 else
70 {
71 /* capture the string even though it is considered to be valid */
72 Src = *UnsafeSrc;
73 }
74
75 /*
76 * Initialize the destination string.
77 */
78 Dest->Length = Src.Length;
79 if(Src.Length > 0)
80 {
81 Dest->MaximumLength = Src.Length + sizeof(WCHAR);
82 Dest->Buffer = ExAllocatePool(PoolType, Dest->MaximumLength);
83 if (Dest->Buffer == NULL)
84 {
85 Dest->Length = Dest->MaximumLength = 0;
86 Dest->Buffer = NULL;
87 return STATUS_INSUFFICIENT_RESOURCES;
88 }
89 /*
90 * Copy the source string to kernel space.
91 */
92 _SEH_TRY
93 {
94 RtlCopyMemory(Dest->Buffer, Src.Buffer, Src.Length);
95 Dest->Buffer[Src.Length / sizeof(WCHAR)] = L'\0';
96 }
97 _SEH_HANDLE
98 {
99 Status = _SEH_GetExceptionCode();
100 }
101 _SEH_END;
102
103 if(!NT_SUCCESS(Status))
104 {
105 ExFreePool(Dest->Buffer);
106 Dest->Buffer = NULL;
107 Dest->Length = Dest->MaximumLength = 0;
108 }
109 }
110 else
111 {
112 Dest->MaximumLength = 0;
113 Dest->Buffer = NULL;
114 }
115
116 return Status;
117 }
118
119 VOID
120 RtlReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString,
121 IN KPROCESSOR_MODE CurrentMode,
122 IN BOOLEAN CaptureIfKernel)
123 {
124 if(CurrentMode != KernelMode || CaptureIfKernel )
125 {
126 ExFreePool(CapturedString->Buffer);
127 }
128 }
129
130 /*
131 * @unimplemented
132 */
133 VOID
134 STDCALL
135 RtlCaptureContext (
136 OUT PCONTEXT ContextRecord
137 )
138 {
139 UNIMPLEMENTED;
140 }
141
142 /*
143 * @unimplemented
144 */
145 USHORT
146 STDCALL
147 RtlCaptureStackBackTrace (
148 IN ULONG FramesToSkip,
149 IN ULONG FramesToCapture,
150 OUT PVOID *BackTrace,
151 OUT PULONG BackTraceHash OPTIONAL
152 )
153 {
154 UNIMPLEMENTED;
155 return 0;
156 }
157
158 /* EOF */
159