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
)
55 /* Validate the key information */
56 if (KeyValueInformation
->Type
!= REG_MULTI_SZ
) return STATUS_INVALID_PARAMETER
;
58 /* Set the pointers */
59 p
= (PWCHAR
)((ULONG_PTR
)KeyValueInformation
+
60 KeyValueInformation
->DataOffset
);
61 pp
= (PWCHAR
)((ULONG_PTR
)p
+ KeyValueInformation
->DataLength
);
66 /* If we find a NULL, that means one string is done */
69 /* Add to our string count */
72 /* Check for a double-NULL, which means we're done */
73 if (((p
+ 1) == pp
) || !(*(p
+ 1))) break;
76 /* Go to the next character */
80 /* If we looped the whole list over, we missed increment a string, do it */
83 /* Allocate the list now that we know how big it is */
84 *UnicodeStringList
= ExAllocatePoolWithTag(PagedPool
,
85 sizeof(UNICODE_STRING
) * Count
,
87 if (!(*UnicodeStringList
)) return STATUS_INSUFFICIENT_RESOURCES
;
89 /* Set pointers for second loop */
90 ps
= p
= (PWCHAR
)((ULONG_PTR
)KeyValueInformation
+
91 KeyValueInformation
->DataOffset
);
93 /* Loop again, to do the copy this time */
96 /* If we find a NULL, that means one string is done */
99 /* Check how long this string is */
100 n
= (ULONG_PTR
)p
- (ULONG_PTR
)ps
+ sizeof(UNICODE_NULL
);
102 /* Allocate the buffer */
103 (*UnicodeStringList
)[i
].Buffer
= ExAllocatePoolWithTag(PagedPool
,
106 if (!(*UnicodeStringList
)[i
].Buffer
)
108 /* Back out of everything */
109 PnpFreeUnicodeStringList(*UnicodeStringList
, i
);
110 return STATUS_INSUFFICIENT_RESOURCES
;
113 /* Copy the string into the buffer */
114 RtlCopyMemory((*UnicodeStringList
)[i
].Buffer
, ps
, n
);
116 /* Set the lengths */
117 (*UnicodeStringList
)[i
].MaximumLength
= n
;
118 (*UnicodeStringList
)[i
].Length
= n
- sizeof(UNICODE_NULL
);
120 /* One more entry done */
123 /* Check for a double-NULL, which means we're done */
124 if (((p
+ 1) == pp
) || !(*(p
+ 1))) break;
134 /* Check if we've reached the last string */
137 /* Calculate the string length */
138 n
= (ULONG_PTR
)p
- (ULONG_PTR
)ps
;
140 /* Allocate the buffer for it */
141 (*UnicodeStringList
)[i
].Buffer
= ExAllocatePoolWithTag(PagedPool
,
143 sizeof(UNICODE_NULL
),
145 if (!(*UnicodeStringList
)[i
].Buffer
)
147 /* Back out of everything */
148 PnpFreeUnicodeStringList(*UnicodeStringList
, i
);
149 return STATUS_INSUFFICIENT_RESOURCES
;
152 /* Make sure there's an actual string here */
153 if (n
) RtlCopyMemory((*UnicodeStringList
)[i
].Buffer
, ps
, n
);
155 /* Null-terminate the string ourselves */
156 (*UnicodeStringList
)[i
].Buffer
[n
/ sizeof(WCHAR
)] = UNICODE_NULL
;
158 /* Set the lenghts */
159 (*UnicodeStringList
)[i
].Length
= n
;
160 (*UnicodeStringList
)[i
].MaximumLength
= n
+ sizeof(UNICODE_NULL
);
164 *UnicodeStringCount
= Count
;
165 return STATUS_SUCCESS
;
170 PnpRegSzToString(IN PWCHAR RegSzData
,
171 IN ULONG RegSzLength
,
172 OUT PUSHORT StringLength OPTIONAL
)
177 pp
= RegSzData
+ RegSzLength
;
178 for (p
= RegSzData
; p
< pp
; p
++) if (!*p
) break;
181 if (StringLength
) *StringLength
= p
- RegSzData
;