2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/io/pnpmgr/pnputil.c
5 * PURPOSE: PnP Utility Code
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS ********************************************************************/
17 /* FUNCTIONS ******************************************************************/
21 PnpFreeUnicodeStringList(IN PUNICODE_STRING UnicodeStringList
,
26 /* Go through the list */
27 if (UnicodeStringList
)
29 /* Go through each string */
30 for (i
= 0; i
< StringCount
; i
++)
32 /* Check if it exists */
33 if (UnicodeStringList
[i
].Buffer
)
36 ExFreePool(UnicodeStringList
[i
].Buffer
);
40 /* Free the whole list */
41 ExFreePool(UnicodeStringList
);
47 PnpRegMultiSzToUnicodeStrings(IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation
,
48 OUT PUNICODE_STRING
*UnicodeStringList
,
49 OUT PULONG UnicodeStringCount
)
56 /* Validate the key information */
57 if (KeyValueInformation
->Type
!= REG_MULTI_SZ
) return STATUS_INVALID_PARAMETER
;
59 /* Set the pointers */
60 p
= (PWCHAR
)((ULONG_PTR
)KeyValueInformation
+
61 KeyValueInformation
->DataOffset
);
62 pp
= (PWCHAR
)((ULONG_PTR
)p
+ KeyValueInformation
->DataLength
);
67 /* If we find a NULL, that means one string is done */
70 /* Add to our string count */
73 /* Check for a double-NULL, which means we're done */
74 if (((p
+ 1) == pp
) || !(*(p
+ 1))) break;
77 /* Go to the next character */
81 /* If we looped the whole list over, we missed increment a string, do it */
84 /* Allocate the list now that we know how big it is */
85 *UnicodeStringList
= ExAllocatePoolWithTag(PagedPool
,
86 sizeof(UNICODE_STRING
) * Count
,
88 if (!(*UnicodeStringList
)) return STATUS_INSUFFICIENT_RESOURCES
;
90 /* Set pointers for second loop */
91 ps
= p
= (PWCHAR
)((ULONG_PTR
)KeyValueInformation
+
92 KeyValueInformation
->DataOffset
);
94 /* Loop again, to do the copy this time */
97 /* If we find a NULL, that means one string is done */
100 /* Check how long this string is */
101 n
= (ULONG_PTR
)p
- (ULONG_PTR
)ps
+ sizeof(UNICODE_NULL
);
103 /* Allocate the buffer */
104 (*UnicodeStringList
)[i
].Buffer
= ExAllocatePoolWithTag(PagedPool
,
107 if (!(*UnicodeStringList
)[i
].Buffer
)
109 /* Back out of everything */
110 PnpFreeUnicodeStringList(*UnicodeStringList
, i
);
111 return STATUS_INSUFFICIENT_RESOURCES
;
114 /* Copy the string into the buffer */
115 RtlCopyMemory((*UnicodeStringList
)[i
].Buffer
, ps
, n
);
117 /* Set the lengths */
118 (*UnicodeStringList
)[i
].MaximumLength
= (USHORT
)n
;
119 (*UnicodeStringList
)[i
].Length
= (USHORT
)(n
- sizeof(UNICODE_NULL
));
121 /* One more entry done */
124 /* Check for a double-NULL, which means we're done */
125 if (((p
+ 1) == pp
) || !(*(p
+ 1))) break;
135 /* Check if we've reached the last string */
138 /* Calculate the string length */
139 n
= (ULONG_PTR
)p
- (ULONG_PTR
)ps
;
141 /* Allocate the buffer for it */
142 (*UnicodeStringList
)[i
].Buffer
= ExAllocatePoolWithTag(PagedPool
,
144 sizeof(UNICODE_NULL
),
146 if (!(*UnicodeStringList
)[i
].Buffer
)
148 /* Back out of everything */
149 PnpFreeUnicodeStringList(*UnicodeStringList
, i
);
150 return STATUS_INSUFFICIENT_RESOURCES
;
153 /* Make sure there's an actual string here */
154 if (n
) RtlCopyMemory((*UnicodeStringList
)[i
].Buffer
, ps
, n
);
156 /* Null-terminate the string ourselves */
157 (*UnicodeStringList
)[i
].Buffer
[n
/ sizeof(WCHAR
)] = UNICODE_NULL
;
159 /* Set the lenghts */
160 (*UnicodeStringList
)[i
].Length
= (USHORT
)n
;
161 (*UnicodeStringList
)[i
].MaximumLength
= (USHORT
)(n
+ sizeof(UNICODE_NULL
));
165 *UnicodeStringCount
= Count
;
166 return STATUS_SUCCESS
;
171 PnpRegSzToString(IN PWCHAR RegSzData
,
172 IN ULONG RegSzLength
,
173 OUT PUSHORT StringLength OPTIONAL
)
178 pp
= RegSzData
+ RegSzLength
;
179 for (p
= RegSzData
; p
< pp
; p
++) if (!*p
) break;
182 if (StringLength
) *StringLength
= (USHORT
)(p
- RegSzData
) * sizeof(WCHAR
);