ReactOS 0.4.16-dev-334-g4d9f67c
stringutil.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 StringUtil.cpp
8
9Abstract:
10
11 This module implements string utlities in the framework
12
13Author:
14
15
16
17Environment:
18
19 Both kernel and user mode
20
21Revision History:
22
23--*/
24
25#include "fxsupportpch.hpp"
26
27extern "C" {
28// #include "StringUtil.tmh"
29}
30
31size_t
33 __in FxCollectionInternal *StringCollection,
35 __out_opt PBOOLEAN ContainsOnlyStrings
36 )
37{
38 size_t cbLength;
41
42 cbLength = 0;
43
44 end = StringCollection->End();
45 for (cur = StringCollection->Start();
46 cur != end;
47 cur = cur->Next()) {
49
51 *ContainsOnlyStrings = FALSE;
52 return 0;
53 }
54
55 cbLength += pString->ByteLength(TRUE);
56 }
57
58 if (ContainsOnlyStrings != NULL) {
59 *ContainsOnlyStrings = TRUE;
60 }
61
62 if (StringCollection->Count() == 0) {
63 //
64 // If there are not entries, we still need 2 NULLs
65 //
66 cbLength = sizeof(UNICODE_NULL) * 2;
67 }
68 else {
69 //
70 // Extra NULL
71 //
72 cbLength += sizeof(UNICODE_NULL);
73 }
74
75 //
76 // ASSERT that we are reporting an integral number of WCHARs in bytes
77 //
78 ASSERT((cbLength % sizeof(WCHAR)) == 0);
79
80 return cbLength;
81}
82
83size_t
86 )
87{
89 size_t cbSize, cbLength;
90
91 cbSize = 0;
92
93 pCur = MultiSz;
94
95 while (*pCur != NULL) {
96 //
97 // Compute length of string including terminating NULL
98 //
99 cbLength = (wcslen(pCur) + 1) * sizeof(WCHAR);
100
101 cbSize += cbLength;
102 pCur = (PWSTR) WDF_PTR_ADD_OFFSET(pCur, cbLength);
103 }
104
105 if (cbSize == 0) {
106 //
107 // If there are no strings, we still need 2 NULLs
108 //
109 cbSize = sizeof(UNICODE_NULL);
110 }
111
112 //
113 // Final NULL which makes this a multi sz
114 //
115 cbSize += sizeof(UNICODE_NULL);
116
117 //
118 // ASSERT that we are reporting an integral number of WCHARs in bytes
119 //
120 ASSERT((cbSize % sizeof(WCHAR)) == 0);
121
122 return cbSize;
123}
124
125#pragma prefast(push)
126// Caller is responsible for allocating the correct amount of memory.
127#pragma prefast(disable:__WARNING_INCORRECT_ANNOTATION_STRING )
128PWSTR
131 __in FxCollectionInternal* StringCollection
132 )
133{
134 LPWSTR pCur;
137
138 pCur = Buffer;
139 end = StringCollection->End();
140
141 for (cur = StringCollection->Start(); cur != end; cur = cur->Next()) {
142 FxString* pSourceString;
143
144 pSourceString = (FxString *) cur->m_Object;
145
146 length = pSourceString->ByteLength(TRUE);
147 RtlCopyMemory(pCur, pSourceString->Buffer(), length);
148
149 //
150 // Length is expressed in number of bytes, not number of
151 // characters.
152 //
153 // length includes the NULL.
154 //
156 }
157
158 //
159 // If there are no entries, we still need 2 NULLs.
160 //
161 if (StringCollection->Count() == 0) {
163 pCur++;
164 }
165
166 //
167 // double NULL terminate the string
168 //
170
171 //
172 // Return the start of the next location in the buffer
173 //
174 return pCur + 1;
175}
176#pragma prefast(pop)
177
181 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
184 )
185/*++
186
187Routine Description:
188 Makes a deep copy from Source to Destination.
189
190 Destination is assumed to have been initialized by the caller, be owned by
191 an internal Fx object. Destination could already contain a previously
192 allocated buffer. If one exists and is large enough, it will be reused
193 for the copy.
194
195 This function guarantees that the Buffer will be NULL terminated. While
196 this is not necessary because Length describes the length of the buffer, the
197 resulting buffer can be copied back to the client driver and we cannot trust
198 the client driver to treat the string as an unterminated buffer, typically
199 the client driver will just extract the buffer and treat it as NULL
200 terminated. To be defensive with this type of (mis)use, we always NULL
201 terminate the resuling Buffer.
202
203Arguments:
204 Source - source struct to copy from. This string can originate from the
205 client driver.
206
207 Destination - destination struct to copy to. This struct is assumed to be
208 internal and is not given to the outside caller
209
210Return Value:
211 NTSTATUS
212
213 --*/
214{
216 USHORT srcCbLength, srcCbLengthAndNull, dstMaxCbLength;
217
218 //
219 // NOTE: We assume the sources string will be smaller than 64k.
220 //
221 srcCbLength = Source->Length;
222 dstMaxCbLength = Destination->MaximumLength;
223
224 status = RtlUShortAdd(srcCbLength,
225 sizeof(UNICODE_NULL),
226 &srcCbLengthAndNull);
227 if (!NT_SUCCESS(status)) {
229 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
230 "Interger overflow occured when duplicating string %!STATUS!",
231 status);
232 return status;
233 }
234
235 //
236 // First see if we already have enough memory to hold the string + a NULL
237 //
238 if (dstMaxCbLength < srcCbLengthAndNull) {
239 //
240 // Allocate enough memory for the source string and a NULL character
241 //
242 dstMaxCbLength = srcCbLengthAndNull;
243
244 //
245 // We need to allocate memory. Free any old memory first.
246 //
247 if (Destination->Buffer != NULL) {
249
251 }
252
253 Destination->Buffer = (PWSTR) FxPoolAllocate(
254 FxDriverGlobals, PagedPool, dstMaxCbLength);
255
256 if (Destination->Buffer == NULL) {
259 FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
260 "Failed to allocate memory when duplicating string %!STATUS!",
261 status);
262 return status;
263 }
264
265 Destination->MaximumLength = dstMaxCbLength;
266 }
267
268 //
269 // If we get here and we have a buffer, then we can just copy the
270 // string into the buffer.
271 //
272 RtlCopyMemory(Destination->Buffer, Source->Buffer, srcCbLength);
273 Destination->Length = srcCbLength;
274
275 //
276 // Make sure the string is NULL terminated and there is room for the NULL
277 //
281
282 return STATUS_SUCCESS;
283}
284
286PWCHAR
288 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
290 )
291{
292 PWSTR pDuplicate;
293
294 pDuplicate = (PWSTR) FxPoolAllocate(
295 FxDriverGlobals, PagedPool, Source->Length + sizeof(UNICODE_NULL));
296
297 if (pDuplicate != NULL) {
298 RtlCopyMemory(pDuplicate, Source->Buffer, Source->Length);
299
300 //
301 // Make sure the string is NULL terminated. We can safely do this
302 // because we allocated an extra WCHAR for the null terminator.
303 //
304 pDuplicate[Source->Length/sizeof(WCHAR)] = UNICODE_NULL;
305 }
306
307 return pDuplicate;
308}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
FxObject * m_Object
FxCollectionEntry * Next(VOID)
WDFTYPE GetType(VOID)
Definition: fxobject.hpp:742
__inline USHORT ByteLength(__in BOOLEAN IncludeNull)
Definition: fxstring.hpp:94
__inline PWCHAR Buffer(VOID)
Definition: fxstring.hpp:144
#define __out_opt
Definition: dbghelp.h:65
#define __in
Definition: dbghelp.h:35
#define __out
Definition: dbghelp.h:62
#define TRACINGERROR
Definition: dbgtrace.h:63
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
@ Verify
Definition: msg.c:1065
#define PagedPool
Definition: env_spec_w32.h:308
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxString * pString
SINGLE_LIST_ENTRY * pCur
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
FxCollectionEntry * cur
@ FX_TYPE_STRING
Definition: fxtypes.h:52
GLuint GLuint end
Definition: gl.h:1545
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3016
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define UNICODE_NULL
unsigned short USHORT
Definition: pedump.c:61
#define __nullnullterminated
Definition: sal_old.h:271
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
PWSTR FxCopyMultiSz(__out LPWSTR Buffer, __in FxCollectionInternal *StringCollection)
Definition: stringutil.cpp:129
size_t FxCalculateTotalMultiSzStringSize(__in __nullnullterminated PCWSTR MultiSz)
Definition: stringutil.cpp:84
size_t FxCalculateTotalStringSize(__in FxCollectionInternal *StringCollection, __in BOOLEAN Verify, __out_opt PBOOLEAN ContainsOnlyStrings)
Definition: stringutil.cpp:32
_Must_inspect_result_ PWCHAR FxDuplicateUnicodeStringToString(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in const UNICODE_STRING *Source)
Definition: stringutil.cpp:287
_Must_inspect_result_ NTSTATUS FxDuplicateUnicodeString(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in const UNICODE_STRING *Source, __out PUNICODE_STRING Destination)
Definition: stringutil.cpp:180
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: ps.c:97
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WDF_PTR_ADD_OFFSET_TYPE(_ptr, _offset, _type)
Definition: wdfcore.h:141
#define WDF_PTR_ADD_OFFSET(_ptr, _offset)
Definition: wdfcore.h:144
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184