Use free Windows DDK and compile with latest MinGW releases.
[reactos.git] / reactos / ntoskrnl / se / sid.c
1 /* $Id: sid.c,v 1.11 2002/09/07 15:13:06 chorns Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
6 * FILE: ntoskrnl/se/sid.c
7 * PROGRAMER: David Welch <welch@cwcom.net>
8 * REVISION HISTORY:
9 * 26/07/98: Added stubs for security functions
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ntoskrnl.h>
15
16 #define NDEBUG
17 #include <internal/debug.h>
18
19
20 #define TAG_SID TAG('S', 'I', 'D', 'T')
21
22
23 /* GLOBALS ******************************************************************/
24
25 SID_IDENTIFIER_AUTHORITY SeNullSidAuthority = {SECURITY_NULL_SID_AUTHORITY};
26 SID_IDENTIFIER_AUTHORITY SeWorldSidAuthority = {SECURITY_WORLD_SID_AUTHORITY};
27 SID_IDENTIFIER_AUTHORITY SeLocalSidAuthority = {SECURITY_LOCAL_SID_AUTHORITY};
28 SID_IDENTIFIER_AUTHORITY SeCreatorSidAuthority = {SECURITY_CREATOR_SID_AUTHORITY};
29 SID_IDENTIFIER_AUTHORITY SeNtSidAuthority = {SECURITY_NT_AUTHORITY};
30
31 PSID SeNullSid = NULL;
32 PSID SeWorldSid = NULL;
33 PSID SeLocalSid = NULL;
34 PSID SeCreatorOwnerSid = NULL;
35 PSID SeCreatorGroupSid = NULL;
36 PSID SeCreatorOwnerServerSid = NULL;
37 PSID SeCreatorGroupServerSid = NULL;
38 PSID SeNtAuthoritySid = NULL;
39 PSID SeDialupSid = NULL;
40 PSID SeNetworkSid = NULL;
41 PSID SeBatchSid = NULL;
42 PSID SeInteractiveSid = NULL;
43 PSID SeServiceSid = NULL;
44 PSID SeAnonymousLogonSid = NULL;
45 PSID SePrincipalSelfSid = NULL;
46 PSID SeLocalSystemSid = NULL;
47 PSID SeAuthenticatedUserSid = NULL;
48 PSID SeRestrictedCodeSid = NULL;
49 PSID SeAliasAdminsSid = NULL;
50 PSID SeAliasUsersSid = NULL;
51 PSID SeAliasGuestsSid = NULL;
52 PSID SeAliasPowerUsersSid = NULL;
53 PSID SeAliasAccountOpsSid = NULL;
54 PSID SeAliasSystemOpsSid = NULL;
55 PSID SeAliasPrintOpsSid = NULL;
56 PSID SeAliasBackupOpsSid = NULL;
57
58
59 /* FUNCTIONS ****************************************************************/
60
61
62 BOOLEAN
63 SepInitSecurityIDs(VOID)
64 {
65 ULONG SidLength0;
66 ULONG SidLength1;
67 ULONG SidLength2;
68 PULONG SubAuthority;
69
70 SidLength0 = RtlLengthRequiredSid(0);
71 SidLength1 = RtlLengthRequiredSid(1);
72 SidLength2 = RtlLengthRequiredSid(2);
73
74 /* create NullSid */
75 SeNullSid = ExAllocatePoolWithTag(NonPagedPool,
76 SidLength1,
77 TAG_SID);
78 if (SeNullSid == NULL)
79 return(FALSE);
80
81 RtlInitializeSid(SeNullSid,
82 &SeNullSidAuthority,
83 1);
84 SubAuthority = RtlSubAuthoritySid(SeNullSid,
85 0);
86 *SubAuthority = SECURITY_NULL_RID;
87
88 /* create WorldSid */
89 SeWorldSid = ExAllocatePoolWithTag(NonPagedPool,
90 SidLength1,
91 TAG_SID);
92 if (SeWorldSid == NULL)
93 return(FALSE);
94
95 RtlInitializeSid(SeWorldSid,
96 &SeWorldSidAuthority,
97 1);
98 SubAuthority = RtlSubAuthoritySid(SeWorldSid,
99 0);
100 *SubAuthority = SECURITY_WORLD_RID;
101
102 /* create LocalSid */
103 SeLocalSid = ExAllocatePoolWithTag(NonPagedPool,
104 SidLength1,
105 TAG_SID);
106 if (SeLocalSid == NULL)
107 return(FALSE);
108
109 RtlInitializeSid(SeLocalSid,
110 &SeLocalSidAuthority,
111 1);
112 SubAuthority = RtlSubAuthoritySid(SeLocalSid,
113 0);
114 *SubAuthority = SECURITY_LOCAL_RID;
115
116 /* create CreatorOwnerSid */
117 SeCreatorOwnerSid = ExAllocatePoolWithTag(NonPagedPool,
118 SidLength1,
119 TAG_SID);
120 if (SeCreatorOwnerSid == NULL)
121 return(FALSE);
122
123 RtlInitializeSid(SeCreatorOwnerSid,
124 &SeCreatorSidAuthority,
125 1);
126 SubAuthority = RtlSubAuthoritySid(SeCreatorOwnerSid,
127 0);
128 *SubAuthority = SECURITY_CREATOR_OWNER_RID;
129
130 /* create CreatorGroupSid */
131 SeCreatorGroupSid = ExAllocatePoolWithTag(NonPagedPool,
132 SidLength1,
133 TAG_SID);
134 if (SeCreatorGroupSid == NULL)
135 return(FALSE);
136
137 RtlInitializeSid(SeCreatorGroupSid,
138 &SeCreatorSidAuthority,
139 1);
140 SubAuthority = RtlSubAuthoritySid(SeCreatorGroupSid,
141 0);
142 *SubAuthority = SECURITY_CREATOR_GROUP_RID;
143
144 /* create CreatorOwnerServerSid */
145 SeCreatorOwnerServerSid = ExAllocatePoolWithTag(NonPagedPool,
146 SidLength1,
147 TAG_SID);
148 if (SeCreatorOwnerServerSid == NULL)
149 return(FALSE);
150
151 RtlInitializeSid(SeCreatorOwnerServerSid,
152 &SeCreatorSidAuthority,
153 1);
154 SubAuthority = RtlSubAuthoritySid(SeCreatorOwnerServerSid,
155 0);
156 *SubAuthority = SECURITY_CREATOR_OWNER_SERVER_RID;
157
158 /* create CreatorGroupServerSid */
159 SeCreatorGroupServerSid = ExAllocatePoolWithTag(NonPagedPool,
160 SidLength1,
161 TAG_SID);
162 if (SeCreatorGroupServerSid == NULL)
163 return(FALSE);
164
165 RtlInitializeSid(SeCreatorGroupServerSid,
166 &SeCreatorSidAuthority,
167 1);
168 SubAuthority = RtlSubAuthoritySid(SeCreatorGroupServerSid,
169 0);
170 *SubAuthority = SECURITY_CREATOR_GROUP_SERVER_RID;
171
172
173 /* create NtAuthoritySid */
174 SeNtAuthoritySid = ExAllocatePoolWithTag(NonPagedPool,
175 SidLength0,
176 TAG_SID);
177 if (SeNtAuthoritySid == NULL)
178 return(FALSE);
179
180 RtlInitializeSid(SeNtAuthoritySid,
181 &SeNtSidAuthority,
182 0);
183
184 /* create DialupSid */
185 SeDialupSid = ExAllocatePoolWithTag(NonPagedPool,
186 SidLength1,
187 TAG_SID);
188 if (SeDialupSid == NULL)
189 return(FALSE);
190
191 RtlInitializeSid(SeDialupSid,
192 &SeNtSidAuthority,
193 1);
194 SubAuthority = RtlSubAuthoritySid(SeDialupSid,
195 0);
196 *SubAuthority = SECURITY_DIALUP_RID;
197
198 /* create NetworkSid */
199 SeNetworkSid = ExAllocatePoolWithTag(NonPagedPool,
200 SidLength1,
201 TAG_SID);
202 if (SeNetworkSid == NULL)
203 return(FALSE);
204
205 RtlInitializeSid(SeNetworkSid,
206 &SeNtSidAuthority,
207 1);
208 SubAuthority = RtlSubAuthoritySid(SeNetworkSid,
209 0);
210 *SubAuthority = SECURITY_NETWORK_RID;
211
212 /* create BatchSid */
213 SeBatchSid = ExAllocatePoolWithTag(NonPagedPool,
214 SidLength1,
215 TAG_SID);
216 if (SeBatchSid == NULL)
217 return(FALSE);
218
219 RtlInitializeSid(SeBatchSid,
220 &SeNtSidAuthority,
221 1);
222 SubAuthority = RtlSubAuthoritySid(SeBatchSid,
223 0);
224 *SubAuthority = SECURITY_BATCH_RID;
225
226 /* create InteractiveSid */
227 SeInteractiveSid = ExAllocatePoolWithTag(NonPagedPool,
228 SidLength1,
229 TAG_SID);
230 if (SeInteractiveSid == NULL)
231 return(FALSE);
232
233 RtlInitializeSid(SeInteractiveSid,
234 &SeNtSidAuthority,
235 1);
236 SubAuthority = RtlSubAuthoritySid(SeInteractiveSid,
237 0);
238 *SubAuthority = SECURITY_INTERACTIVE_RID;
239
240 /* create ServiceSid */
241 SeServiceSid = ExAllocatePoolWithTag(NonPagedPool,
242 SidLength1,
243 TAG_SID);
244 if (SeServiceSid == NULL)
245 return(FALSE);
246
247 RtlInitializeSid(SeServiceSid,
248 &SeNtSidAuthority,
249 1);
250 SubAuthority = RtlSubAuthoritySid(SeServiceSid,
251 0);
252 *SubAuthority = SECURITY_SERVICE_RID;
253
254 /* create AnonymousLogonSid */
255 SeAnonymousLogonSid = ExAllocatePoolWithTag(NonPagedPool,
256 SidLength1,
257 TAG_SID);
258 if (SeAnonymousLogonSid == NULL)
259 return(FALSE);
260
261 RtlInitializeSid(SeAnonymousLogonSid,
262 &SeNtSidAuthority,
263 1);
264 SubAuthority = RtlSubAuthoritySid(SeAnonymousLogonSid,
265 0);
266 *SubAuthority = SECURITY_ANONYMOUS_LOGON_RID;
267
268 /* create PrincipalSelfSid */
269 SePrincipalSelfSid = ExAllocatePoolWithTag(NonPagedPool,
270 SidLength1,
271 TAG_SID);
272 if (SePrincipalSelfSid == NULL)
273 return(FALSE);
274
275 RtlInitializeSid(SePrincipalSelfSid,
276 &SeNtSidAuthority,
277 1);
278 SubAuthority = RtlSubAuthoritySid(SePrincipalSelfSid,
279 0);
280 *SubAuthority = SECURITY_PRINCIPAL_SELF_RID;
281
282 /* create LocalSystemSid */
283 SeLocalSystemSid = ExAllocatePoolWithTag(NonPagedPool,
284 SidLength1,
285 TAG_SID);
286 if (SeLocalSystemSid == NULL)
287 return(FALSE);
288
289 RtlInitializeSid(SeLocalSystemSid,
290 &SeNtSidAuthority,
291 1);
292 SubAuthority = RtlSubAuthoritySid(SeLocalSystemSid,
293 0);
294 *SubAuthority = SECURITY_LOCAL_SYSTEM_RID;
295
296 /* create AuthenticatedUserSid */
297 SeAuthenticatedUserSid = ExAllocatePoolWithTag(NonPagedPool,
298 SidLength1,
299 TAG_SID);
300 if (SeAuthenticatedUserSid == NULL)
301 return(FALSE);
302
303 RtlInitializeSid(SeAuthenticatedUserSid,
304 &SeNtSidAuthority,
305 1);
306 SubAuthority = RtlSubAuthoritySid(SeAuthenticatedUserSid,
307 0);
308 *SubAuthority = SECURITY_AUTHENTICATED_USER_RID;
309
310 /* create RestrictedCodeSid */
311 SeRestrictedCodeSid = ExAllocatePoolWithTag(NonPagedPool,
312 SidLength1,
313 TAG_SID);
314 if (SeRestrictedCodeSid == NULL)
315 return(FALSE);
316
317 RtlInitializeSid(SeRestrictedCodeSid,
318 &SeNtSidAuthority,
319 1);
320 SubAuthority = RtlSubAuthoritySid(SeRestrictedCodeSid,
321 0);
322 *SubAuthority = SECURITY_RESTRICTED_CODE_RID;
323
324 /* create AliasAdminsSid */
325 SeAliasAdminsSid = ExAllocatePoolWithTag(NonPagedPool,
326 SidLength2,
327 TAG_SID);
328 if (SeAliasAdminsSid == NULL)
329 return(FALSE);
330
331 RtlInitializeSid(SeAliasAdminsSid,
332 &SeNtSidAuthority,
333 2);
334 SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid,
335 0);
336 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
337
338 SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid,
339 1);
340 *SubAuthority = DOMAIN_ALIAS_RID_ADMINS;
341
342 /* create AliasUsersSid */
343 SeAliasUsersSid = ExAllocatePoolWithTag(NonPagedPool,
344 SidLength2,
345 TAG_SID);
346 if (SeAliasUsersSid == NULL)
347 return(FALSE);
348
349 RtlInitializeSid(SeAliasUsersSid,
350 &SeNtSidAuthority,
351 2);
352 SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid,
353 0);
354 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
355
356 SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid,
357 1);
358 *SubAuthority = DOMAIN_ALIAS_RID_USERS;
359
360 /* create AliasGuestsSid */
361 SeAliasGuestsSid = ExAllocatePoolWithTag(NonPagedPool,
362 SidLength2,
363 TAG_SID);
364 if (SeAliasGuestsSid == NULL)
365 return(FALSE);
366
367 RtlInitializeSid(SeAliasGuestsSid,
368 &SeNtSidAuthority,
369 2);
370 SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid,
371 0);
372 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
373
374 SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid,
375 1);
376 *SubAuthority = DOMAIN_ALIAS_RID_GUESTS;
377
378 /* create AliasPowerUsersSid */
379 SeAliasPowerUsersSid = ExAllocatePoolWithTag(NonPagedPool,
380 SidLength2,
381 TAG_SID);
382 if (SeAliasPowerUsersSid == NULL)
383 return(FALSE);
384
385 RtlInitializeSid(SeAliasPowerUsersSid,
386 &SeNtSidAuthority,
387 2);
388 SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid,
389 0);
390 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
391
392 SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid,
393 1);
394 *SubAuthority = DOMAIN_ALIAS_RID_POWER_USERS;
395
396 /* create AliasAccountOpsSid */
397 SeAliasAccountOpsSid = ExAllocatePoolWithTag(NonPagedPool,
398 SidLength2,
399 TAG_SID);
400 if (SeAliasAccountOpsSid == NULL)
401 return(FALSE);
402
403 RtlInitializeSid(SeAliasAccountOpsSid,
404 &SeNtSidAuthority,
405 2);
406 SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid,
407 0);
408 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
409
410 SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid,
411 1);
412 *SubAuthority = DOMAIN_ALIAS_RID_ACCOUNT_OPS;
413
414 /* create AliasSystemOpsSid */
415 SeAliasSystemOpsSid = ExAllocatePoolWithTag(NonPagedPool,
416 SidLength2,
417 TAG_SID);
418 if (SeAliasSystemOpsSid == NULL)
419 return(FALSE);
420
421 RtlInitializeSid(SeAliasSystemOpsSid,
422 &SeNtSidAuthority,
423 2);
424 SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid,
425 0);
426 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
427
428 SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid,
429 1);
430 *SubAuthority = DOMAIN_ALIAS_RID_SYSTEM_OPS;
431
432 /* create AliasPrintOpsSid */
433 SeAliasPrintOpsSid = ExAllocatePoolWithTag(NonPagedPool,
434 SidLength2,
435 TAG_SID);
436 if (SeAliasPrintOpsSid == NULL)
437 return(FALSE);
438
439 RtlInitializeSid(SeAliasPrintOpsSid,
440 &SeNtSidAuthority,
441 2);
442 SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid,
443 0);
444 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
445
446 SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid,
447 1);
448 *SubAuthority = DOMAIN_ALIAS_RID_PRINT_OPS;
449
450 /* create AliasBackupOpsSid */
451 SeAliasBackupOpsSid = ExAllocatePoolWithTag(NonPagedPool,
452 SidLength2,
453 TAG_SID);
454 if (SeAliasBackupOpsSid == NULL)
455 return(FALSE);
456
457 RtlInitializeSid(SeAliasBackupOpsSid,
458 &SeNtSidAuthority,
459 2);
460 SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid,
461 0);
462 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID;
463
464 SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid,
465 1);
466 *SubAuthority = DOMAIN_ALIAS_RID_BACKUP_OPS;
467
468 return(TRUE);
469 }
470
471
472 BOOLEAN STDCALL
473 RtlValidSid(PSID Sid)
474 {
475 PISID iSid = (PISID)Sid;
476
477 if ((iSid->Revision & 0xf) != 1)
478 {
479 return(FALSE);
480 }
481 if (iSid->SubAuthorityCount > 15)
482 {
483 return(FALSE);
484 }
485 return(TRUE);
486 }
487
488
489 ULONG STDCALL
490 RtlLengthRequiredSid(UCHAR SubAuthorityCount)
491 {
492 return(sizeof(SID) + (SubAuthorityCount - 1) * sizeof(ULONG));
493 }
494
495
496 NTSTATUS STDCALL
497 RtlInitializeSid(PSID Sid,
498 PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
499 UCHAR SubAuthorityCount)
500 {
501 PISID iSid = (PISID)Sid;
502
503 iSid->Revision = 1;
504 iSid->SubAuthorityCount = SubAuthorityCount;
505 RtlCopyMemory(&iSid->IdentifierAuthority,
506 IdentifierAuthority,
507 sizeof(SID_IDENTIFIER_AUTHORITY));
508 return(STATUS_SUCCESS);
509 }
510
511
512 PULONG STDCALL
513 RtlSubAuthoritySid(PSID Sid,
514 ULONG SubAuthority)
515 {
516 PISID iSid = (PISID)Sid;
517
518 return(&iSid->SubAuthority[SubAuthority]);
519 }
520
521
522 PUCHAR STDCALL
523 RtlSubAuthorityCountSid(PSID Sid)
524 {
525 PISID iSid = (PISID)Sid;
526
527 return(&iSid->SubAuthorityCount);
528 }
529
530
531 BOOLEAN STDCALL
532 RtlEqualSid(PSID Sid1,
533 PSID Sid2)
534 {
535 PISID iSid1 = (PISID)Sid1;
536 PISID iSid2 = (PISID)Sid2;
537
538 if (iSid1->Revision != iSid2->Revision)
539 {
540 return(FALSE);
541 }
542 if ((*RtlSubAuthorityCountSid(Sid1)) !=
543 (*RtlSubAuthorityCountSid(Sid2)))
544 {
545 return(FALSE);
546 }
547 if (memcmp(Sid1, Sid2, RtlLengthSid(Sid1)) != 0)
548 {
549 return(FALSE);
550 }
551 return(TRUE);
552 }
553
554
555 ULONG STDCALL
556 RtlLengthSid(PSID Sid)
557 {
558 PISID iSid = (PISID)Sid;
559
560 return(sizeof(SID) + (iSid->SubAuthorityCount-1)*4);
561 }
562
563
564 NTSTATUS STDCALL
565 RtlCopySid(ULONG BufferLength,
566 PSID Dest,
567 PSID Src)
568 {
569 if (BufferLength < RtlLengthSid(Src))
570 {
571 return(STATUS_UNSUCCESSFUL);
572 }
573 memmove(Dest, Src, RtlLengthSid(Src));
574 return(STATUS_SUCCESS);
575 }
576
577
578 NTSTATUS STDCALL
579 RtlCopySidAndAttributesArray(ULONG Count,
580 PSID_AND_ATTRIBUTES_ARRAY Src,
581 ULONG SidAreaSize,
582 PSID_AND_ATTRIBUTES_ARRAY Dest,
583 PVOID SidArea,
584 PVOID* RemainingSidArea,
585 PULONG RemainingSidAreaSize)
586 {
587 ULONG Length;
588 ULONG i;
589
590 Length = SidAreaSize;
591
592 for (i=0; i<Count; i++)
593 {
594 if (RtlLengthSid(Src[i]->Sid) > Length)
595 {
596 return(STATUS_BUFFER_TOO_SMALL);
597 }
598 Length = Length - RtlLengthSid(Src[i]->Sid);
599 Dest[i]->Sid = SidArea;
600 Dest[i]->Attributes = Src[i]->Attributes;
601 RtlCopySid(RtlLengthSid(Src[i]->Sid), SidArea, Src[i]->Sid);
602 SidArea = SidArea + RtlLengthSid(Src[i]->Sid);
603 }
604 *RemainingSidArea = SidArea;
605 *RemainingSidAreaSize = Length;
606 return(STATUS_SUCCESS);
607 }
608
609
610 NTSTATUS STDCALL
611 RtlConvertSidToUnicodeString(PUNICODE_STRING String,
612 PSID Sid,
613 BOOLEAN AllocateString)
614 {
615 PISID iSid = (PISID)Sid;
616 WCHAR Buffer[256];
617 PWSTR Ptr;
618 ULONG Length;
619 ULONG i;
620
621 if (!RtlValidSid(Sid))
622 return STATUS_INVALID_SID;
623
624 Ptr = Buffer;
625 Ptr += swprintf (Ptr,
626 L"S-%u-",
627 iSid->Revision);
628
629 if(!iSid->IdentifierAuthority.Value[0] &&
630 !iSid->IdentifierAuthority.Value[1])
631 {
632 Ptr += swprintf(Ptr,
633 L"%u",
634 (ULONG)iSid->IdentifierAuthority.Value[2] << 24 |
635 (ULONG)iSid->IdentifierAuthority.Value[3] << 16 |
636 (ULONG)iSid->IdentifierAuthority.Value[4] << 8 |
637 (ULONG)iSid->IdentifierAuthority.Value[5]);
638 }
639 else
640 {
641 Ptr += swprintf(Ptr,
642 L"0x%02hx%02hx%02hx%02hx%02hx%02hx",
643 iSid->IdentifierAuthority.Value[0],
644 iSid->IdentifierAuthority.Value[1],
645 iSid->IdentifierAuthority.Value[2],
646 iSid->IdentifierAuthority.Value[3],
647 iSid->IdentifierAuthority.Value[4],
648 iSid->IdentifierAuthority.Value[5]);
649 }
650
651 for (i = 0; i < iSid->SubAuthorityCount; i++)
652 {
653 Ptr += swprintf(Ptr,
654 L"-%u",
655 iSid->SubAuthority[i]);
656 }
657
658 Length = (Ptr - Buffer) * sizeof(WCHAR);
659
660 if (AllocateString)
661 {
662 String->Buffer = ExAllocatePool(NonPagedPool,
663 Length + sizeof(WCHAR));
664 if (String->Buffer == NULL)
665 return STATUS_NO_MEMORY;
666
667 String->MaximumLength = Length + sizeof(WCHAR);
668 }
669 else
670 {
671 if (Length > String->MaximumLength)
672 return STATUS_BUFFER_TOO_SMALL;
673 }
674 String->Length = Length;
675 memmove(String->Buffer,
676 Buffer,
677 Length);
678 if (Length < String->MaximumLength)
679 String->Buffer[Length] = 0;
680
681 return STATUS_SUCCESS;
682 }
683
684 /* EOF */