2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/lsasrv/database.c
5 * PURPOSE: LSA object database
6 * COPYRIGHT: Copyright 2011 Eric Kohl
9 /* INCLUDES ****************************************************************/
13 WINE_DEFAULT_DEBUG_CHANNEL(lsasrv
);
16 /* GLOBALS *****************************************************************/
18 static HANDLE SecurityKeyHandle
= NULL
;
20 SID_IDENTIFIER_AUTHORITY NullSidAuthority
= {SECURITY_NULL_SID_AUTHORITY
};
21 SID_IDENTIFIER_AUTHORITY WorldSidAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
22 SID_IDENTIFIER_AUTHORITY LocalSidAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
23 SID_IDENTIFIER_AUTHORITY CreatorSidAuthority
= {SECURITY_CREATOR_SID_AUTHORITY
};
24 SID_IDENTIFIER_AUTHORITY NtAuthority
= {SECURITY_NT_AUTHORITY
};
26 PSID BuiltinDomainSid
= NULL
;
27 PSID AccountDomainSid
= NULL
;
28 UNICODE_STRING BuiltinDomainName
= {0, 0, NULL
};
29 UNICODE_STRING AccountDomainName
= {0, 0, NULL
};
32 /* FUNCTIONS ***************************************************************/
35 LsapOpenServiceKey(VOID
)
37 OBJECT_ATTRIBUTES ObjectAttributes
;
38 UNICODE_STRING KeyName
;
41 RtlInitUnicodeString(&KeyName
,
42 L
"\\Registry\\Machine\\SECURITY");
44 InitializeObjectAttributes(&ObjectAttributes
,
50 Status
= RtlpNtOpenKey(&SecurityKeyHandle
,
51 KEY_READ
| KEY_CREATE_SUB_KEY
| KEY_ENUMERATE_SUB_KEYS
,
60 LsapIsDatabaseInstalled(VOID
)
62 OBJECT_ATTRIBUTES ObjectAttributes
;
63 UNICODE_STRING KeyName
;
67 RtlInitUnicodeString(&KeyName
,
70 InitializeObjectAttributes(&ObjectAttributes
,
76 Status
= RtlpNtOpenKey(&KeyHandle
,
80 if (!NT_SUCCESS(Status
))
90 LsapCreateDatabaseKeys(VOID
)
92 OBJECT_ATTRIBUTES ObjectAttributes
;
93 UNICODE_STRING KeyName
;
94 HANDLE PolicyKeyHandle
= NULL
;
95 HANDLE AccountsKeyHandle
= NULL
;
96 HANDLE DomainsKeyHandle
= NULL
;
97 HANDLE SecretsKeyHandle
= NULL
;
98 NTSTATUS Status
= STATUS_SUCCESS
;
100 TRACE("LsapInstallDatabase()\n");
102 /* Create the 'Policy' key */
103 RtlInitUnicodeString(&KeyName
,
106 InitializeObjectAttributes(&ObjectAttributes
,
108 OBJ_CASE_INSENSITIVE
,
112 Status
= NtCreateKey(&PolicyKeyHandle
,
119 if (!NT_SUCCESS(Status
))
121 ERR("Failed to create the 'Policy' key (Status: 0x%08lx)\n", Status
);
125 /* Create the 'Accounts' key */
126 RtlInitUnicodeString(&KeyName
,
129 InitializeObjectAttributes(&ObjectAttributes
,
131 OBJ_CASE_INSENSITIVE
,
135 Status
= NtCreateKey(&AccountsKeyHandle
,
142 if (!NT_SUCCESS(Status
))
144 ERR("Failed to create the 'Accounts' key (Status: 0x%08lx)\n", Status
);
148 /* Create the 'Domains' key */
149 RtlInitUnicodeString(&KeyName
,
152 InitializeObjectAttributes(&ObjectAttributes
,
154 OBJ_CASE_INSENSITIVE
,
158 Status
= NtCreateKey(&DomainsKeyHandle
,
165 if (!NT_SUCCESS(Status
))
167 ERR("Failed to create the 'Domains' key (Status: 0x%08lx)\n", Status
);
171 /* Create the 'Secrets' key */
172 RtlInitUnicodeString(&KeyName
,
175 InitializeObjectAttributes(&ObjectAttributes
,
177 OBJ_CASE_INSENSITIVE
,
181 Status
= NtCreateKey(&SecretsKeyHandle
,
188 if (!NT_SUCCESS(Status
))
190 ERR("Failed to create the 'Secrets' key (Status: 0x%08lx)\n", Status
);
195 if (SecretsKeyHandle
!= NULL
)
196 NtClose(SecretsKeyHandle
);
198 if (DomainsKeyHandle
!= NULL
)
199 NtClose(DomainsKeyHandle
);
201 if (AccountsKeyHandle
!= NULL
)
202 NtClose(AccountsKeyHandle
);
204 if (PolicyKeyHandle
!= NULL
)
205 NtClose(PolicyKeyHandle
);
207 TRACE("LsapInstallDatabase() done (Status: 0x%08lx)\n", Status
);
214 LsapCreateRandomDomainSid(OUT PSID
*Sid
)
216 LARGE_INTEGER SystemTime
;
219 NtQuerySystemTime(&SystemTime
);
220 Seed
= &SystemTime
.u
.LowPart
;
222 return RtlAllocateAndInitializeSid(&NtAuthority
,
224 SECURITY_NT_NON_UNIQUE
,
237 LsapCreateDatabaseObjects(VOID
)
239 PLSAP_POLICY_AUDIT_EVENTS_DATA AuditEventsInfo
= NULL
;
240 POLICY_DEFAULT_QUOTA_INFO QuotaInfo
;
241 POLICY_MODIFICATION_INFO ModificationInfo
;
242 POLICY_AUDIT_FULL_QUERY_INFO AuditFullInfo
= {FALSE
, FALSE
};
243 POLICY_AUDIT_LOG_INFO AuditLogInfo
;
245 PLSA_DB_OBJECT PolicyObject
= NULL
;
246 PSID AccountDomainSid
= NULL
;
247 PSECURITY_DESCRIPTOR PolicySd
= NULL
;
248 ULONG PolicySdSize
= 0;
249 ULONG AuditEventsCount
;
250 ULONG AuditEventsSize
;
254 /* Initialize the default quota limits */
255 QuotaInfo
.QuotaLimits
.PagedPoolLimit
= 0x2000000;
256 QuotaInfo
.QuotaLimits
.NonPagedPoolLimit
= 0x100000;
257 QuotaInfo
.QuotaLimits
.MinimumWorkingSetSize
= 0x10000;
258 QuotaInfo
.QuotaLimits
.MaximumWorkingSetSize
= 0xF000000;
259 QuotaInfo
.QuotaLimits
.PagefileLimit
= 0;
260 QuotaInfo
.QuotaLimits
.TimeLimit
.QuadPart
= 0;
262 /* Initialize the audit log attribute */
263 AuditLogInfo
.AuditLogPercentFull
= 0;
264 AuditLogInfo
.MaximumLogSize
= 0; // DWORD
265 AuditLogInfo
.AuditRetentionPeriod
.QuadPart
= 0; // LARGE_INTEGER
266 AuditLogInfo
.AuditLogFullShutdownInProgress
= 0; // BYTE
267 AuditLogInfo
.TimeToShutdown
.QuadPart
= 0; // LARGE_INTEGER
268 AuditLogInfo
.NextAuditRecordId
= 0; // DWORD
270 /* Initialize the Audit Events attribute */
271 AuditEventsCount
= AuditCategoryAccountLogon
- AuditCategorySystem
+ 1;
272 AuditEventsSize
= sizeof(LSAP_POLICY_AUDIT_EVENTS_DATA
) + AuditEventsCount
* sizeof(DWORD
);
273 AuditEventsInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
276 if (AuditEventsInfo
== NULL
)
277 return STATUS_INSUFFICIENT_RESOURCES
;
279 AuditEventsInfo
->AuditingMode
= FALSE
;
280 AuditEventsInfo
->MaximumAuditEventCount
= AuditEventsCount
;
281 for (i
= 0; i
< AuditEventsCount
; i
++)
282 AuditEventsInfo
->AuditEvents
[i
] = 0;
284 /* Initialize the DNS Domain GUID attribute */
285 memset(&DnsDomainGuid
, 0, sizeof(GUID
));
287 /* Initialize the modification attribute */
288 ModificationInfo
.ModifiedId
.QuadPart
= 0;
289 NtQuerySystemTime(&ModificationInfo
.DatabaseCreationTime
);
291 /* Create a random domain SID */
292 Status
= LsapCreateRandomDomainSid(&AccountDomainSid
);
293 if (!NT_SUCCESS(Status
))
296 Status
= LsapCreatePolicySd(&PolicySd
,
298 if (!NT_SUCCESS(Status
))
301 /* Open the 'Policy' object */
302 Status
= LsapOpenDbObject(NULL
,
308 if (!NT_SUCCESS(Status
))
311 LsapSetObjectAttribute(PolicyObject
,
316 LsapSetObjectAttribute(PolicyObject
,
321 LsapSetObjectAttribute(PolicyObject
,
326 LsapSetObjectAttribute(PolicyObject
,
329 RtlLengthSid(AccountDomainSid
));
331 /* Set the default quota limits attribute */
332 LsapSetObjectAttribute(PolicyObject
,
335 sizeof(POLICY_DEFAULT_QUOTA_INFO
));
337 /* Set the modification attribute */
338 LsapSetObjectAttribute(PolicyObject
,
341 sizeof(POLICY_MODIFICATION_INFO
));
343 /* Set the audit full attribute */
344 LsapSetObjectAttribute(PolicyObject
,
347 sizeof(POLICY_AUDIT_FULL_QUERY_INFO
));
349 /* Set the audit log attribute */
350 LsapSetObjectAttribute(PolicyObject
,
353 sizeof(POLICY_AUDIT_LOG_INFO
));
355 /* Set the audit events attribute */
356 LsapSetObjectAttribute(PolicyObject
,
361 /* Set the DNS Domain Name attribute */
362 LsapSetObjectAttribute(PolicyObject
,
367 /* Set the DNS Forest Name attribute */
368 LsapSetObjectAttribute(PolicyObject
,
373 /* Set the DNS Domain GUID attribute */
374 LsapSetObjectAttribute(PolicyObject
,
379 /* Set the Sceurity Descriptor */
380 LsapSetObjectAttribute(PolicyObject
,
386 if (AuditEventsInfo
!= NULL
)
387 RtlFreeHeap(RtlGetProcessHeap(), 0, AuditEventsInfo
);
389 if (PolicyObject
!= NULL
)
390 LsapCloseDbObject(PolicyObject
);
392 if (AccountDomainSid
!= NULL
)
393 RtlFreeSid(AccountDomainSid
);
395 if (PolicySd
!= NULL
)
396 RtlFreeHeap(RtlGetProcessHeap(), 0, PolicySd
);
403 LsapUpdateDatabase(VOID
)
405 return STATUS_SUCCESS
;
410 LsapGetDomainInfo(VOID
)
412 PLSA_DB_OBJECT PolicyObject
= NULL
;
413 PUNICODE_STRING DomainName
= NULL
;
415 LPWSTR SidString
= NULL
;
418 /* Get the built-in domain SID and name */
419 Status
= RtlAllocateAndInitializeSid(&NtAuthority
,
421 SECURITY_BUILTIN_DOMAIN_RID
,
424 if (!NT_SUCCESS(Status
))
428 RtlInitUnicodeString(&BuiltinDomainName
,
431 /* Open the 'Policy' object */
432 Status
= LsapOpenDbObject(NULL
,
438 if (!NT_SUCCESS(Status
))
441 /* Get the account domain SID */
443 Status
= LsapGetObjectAttribute(PolicyObject
,
447 if (!NT_SUCCESS(Status
))
450 if (AttributeSize
> 0)
452 AccountDomainSid
= RtlAllocateHeap(RtlGetProcessHeap(),
455 if (AccountDomainSid
== NULL
)
457 Status
= STATUS_INSUFFICIENT_RESOURCES
;
461 Status
= LsapGetObjectAttribute(PolicyObject
,
465 if (!NT_SUCCESS(Status
))
469 /* Get the account domain name */
471 Status
= LsapGetObjectAttribute(PolicyObject
,
475 if (!NT_SUCCESS(Status
))
478 if (AttributeSize
> 0)
480 DomainName
= RtlAllocateHeap(RtlGetProcessHeap(),
483 if (DomainName
== NULL
)
485 Status
= STATUS_INSUFFICIENT_RESOURCES
;
489 Status
= LsapGetObjectAttribute(PolicyObject
,
493 if (!NT_SUCCESS(Status
))
496 DomainName
->Buffer
= (LPWSTR
)((ULONG_PTR
)DomainName
+ (ULONG_PTR
)DomainName
->Buffer
);
498 AccountDomainName
.Length
= DomainName
->Length
;
499 AccountDomainName
.MaximumLength
= DomainName
->Length
+ sizeof(WCHAR
);
500 AccountDomainName
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
502 AccountDomainName
.MaximumLength
);
503 if (AccountDomainName
.Buffer
== NULL
)
505 ERR("Failed to allocate the account domain name buffer\n");
506 Status
= STATUS_INSUFFICIENT_RESOURCES
;
510 RtlCopyMemory(AccountDomainName
.Buffer
,
515 ConvertSidToStringSidW(BuiltinDomainSid
, &SidString
);
516 TRACE("Builtin Domain SID: %S\n", SidString
);
517 LocalFree(SidString
);
520 TRACE("Builtin Domain Name: %wZ\n", &BuiltinDomainName
);
522 ConvertSidToStringSidW(AccountDomainSid
, &SidString
);
523 TRACE("Account Domain SID: %S\n", SidString
);
524 LocalFree(SidString
);
527 TRACE("Account Domain Name: %wZ\n", &AccountDomainName
);
530 if (DomainName
!= NULL
)
531 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainName
);
533 if (PolicyObject
!= NULL
)
534 LsapCloseDbObject(PolicyObject
);
541 LsapInitDatabase(VOID
)
545 TRACE("LsapInitDatabase()\n");
547 Status
= LsapOpenServiceKey();
548 if (!NT_SUCCESS(Status
))
550 ERR("Failed to open the service key (Status: 0x%08lx)\n", Status
);
554 if (!LsapIsDatabaseInstalled())
556 Status
= LsapCreateDatabaseKeys();
557 if (!NT_SUCCESS(Status
))
559 ERR("Failed to create the LSA database keys (Status: 0x%08lx)\n", Status
);
563 Status
= LsapCreateDatabaseObjects();
564 if (!NT_SUCCESS(Status
))
566 ERR("Failed to create the LSA database objects (Status: 0x%08lx)\n", Status
);
572 Status
= LsapUpdateDatabase();
573 if (!NT_SUCCESS(Status
))
575 ERR("Failed to update the LSA database (Status: 0x%08lx)\n", Status
);
580 Status
= LsapGetDomainInfo();
581 if (!NT_SUCCESS(Status
))
583 ERR("Failed to get the domain information (Status: 0x%08lx)\n", Status
);
587 TRACE("LsapInitDatabase() done\n");
589 return STATUS_SUCCESS
;
594 LsapCreateDbObject(IN PLSA_DB_OBJECT ParentObject
,
595 IN LPWSTR ContainerName
,
596 IN LPWSTR ObjectName
,
597 IN LSA_DB_OBJECT_TYPE ObjectType
,
598 IN ACCESS_MASK DesiredAccess
,
599 OUT PLSA_DB_OBJECT
*DbObject
)
601 PLSA_DB_OBJECT NewObject
;
602 OBJECT_ATTRIBUTES ObjectAttributes
;
603 UNICODE_STRING KeyName
;
604 HANDLE ParentKeyHandle
;
605 HANDLE ContainerKeyHandle
= NULL
;
606 HANDLE ObjectKeyHandle
= NULL
;
609 if (DbObject
== NULL
)
610 return STATUS_INVALID_PARAMETER
;
612 if (ParentObject
== NULL
)
613 ParentKeyHandle
= SecurityKeyHandle
;
615 ParentKeyHandle
= ParentObject
->KeyHandle
;
617 if (ContainerName
!= NULL
)
619 /* Open the container key */
620 RtlInitUnicodeString(&KeyName
,
623 InitializeObjectAttributes(&ObjectAttributes
,
625 OBJ_CASE_INSENSITIVE
,
629 Status
= NtOpenKey(&ContainerKeyHandle
,
632 if (!NT_SUCCESS(Status
))
637 /* Open the object key */
638 RtlInitUnicodeString(&KeyName
,
641 InitializeObjectAttributes(&ObjectAttributes
,
643 OBJ_CASE_INSENSITIVE
,
647 Status
= NtCreateKey(&ObjectKeyHandle
,
655 NtClose(ContainerKeyHandle
);
657 if (!NT_SUCCESS(Status
))
664 RtlInitUnicodeString(&KeyName
,
667 InitializeObjectAttributes(&ObjectAttributes
,
669 OBJ_CASE_INSENSITIVE
,
673 Status
= NtCreateKey(&ObjectKeyHandle
,
680 if (!NT_SUCCESS(Status
))
686 NewObject
= RtlAllocateHeap(RtlGetProcessHeap(),
688 sizeof(LSA_DB_OBJECT
));
689 if (NewObject
== NULL
)
691 NtClose(ObjectKeyHandle
);
692 return STATUS_NO_MEMORY
;
695 NewObject
->Signature
= LSAP_DB_SIGNATURE
;
696 NewObject
->RefCount
= 1;
697 NewObject
->ObjectType
= ObjectType
;
698 NewObject
->Access
= DesiredAccess
;
699 NewObject
->KeyHandle
= ObjectKeyHandle
;
700 NewObject
->ParentObject
= ParentObject
;
702 if (ParentObject
!= NULL
)
703 ParentObject
->RefCount
++;
705 *DbObject
= NewObject
;
707 return STATUS_SUCCESS
;
712 LsapOpenDbObject(IN PLSA_DB_OBJECT ParentObject
,
713 IN LPWSTR ContainerName
,
714 IN LPWSTR ObjectName
,
715 IN LSA_DB_OBJECT_TYPE ObjectType
,
716 IN ACCESS_MASK DesiredAccess
,
717 OUT PLSA_DB_OBJECT
*DbObject
)
719 PLSA_DB_OBJECT NewObject
;
720 OBJECT_ATTRIBUTES ObjectAttributes
;
721 UNICODE_STRING KeyName
;
722 HANDLE ParentKeyHandle
;
723 HANDLE ContainerKeyHandle
= NULL
;
724 HANDLE ObjectKeyHandle
= NULL
;
727 if (DbObject
== NULL
)
728 return STATUS_INVALID_PARAMETER
;
730 if (ParentObject
== NULL
)
731 ParentKeyHandle
= SecurityKeyHandle
;
733 ParentKeyHandle
= ParentObject
->KeyHandle
;
735 if (ContainerName
!= NULL
)
737 /* Open the container key */
738 RtlInitUnicodeString(&KeyName
,
741 InitializeObjectAttributes(&ObjectAttributes
,
743 OBJ_CASE_INSENSITIVE
,
747 Status
= NtOpenKey(&ContainerKeyHandle
,
750 if (!NT_SUCCESS(Status
))
755 /* Open the object key */
756 RtlInitUnicodeString(&KeyName
,
759 InitializeObjectAttributes(&ObjectAttributes
,
761 OBJ_CASE_INSENSITIVE
,
765 Status
= NtOpenKey(&ObjectKeyHandle
,
769 NtClose(ContainerKeyHandle
);
771 if (!NT_SUCCESS(Status
))
778 /* Open the object key */
779 RtlInitUnicodeString(&KeyName
,
782 InitializeObjectAttributes(&ObjectAttributes
,
784 OBJ_CASE_INSENSITIVE
,
788 Status
= NtOpenKey(&ObjectKeyHandle
,
791 if (!NT_SUCCESS(Status
))
797 NewObject
= RtlAllocateHeap(RtlGetProcessHeap(),
799 sizeof(LSA_DB_OBJECT
));
800 if (NewObject
== NULL
)
802 NtClose(ObjectKeyHandle
);
803 return STATUS_NO_MEMORY
;
806 NewObject
->Signature
= LSAP_DB_SIGNATURE
;
807 NewObject
->RefCount
= 1;
808 NewObject
->ObjectType
= ObjectType
;
809 NewObject
->Access
= DesiredAccess
;
810 NewObject
->KeyHandle
= ObjectKeyHandle
;
811 NewObject
->ParentObject
= ParentObject
;
813 if (ParentObject
!= NULL
)
814 ParentObject
->RefCount
++;
816 *DbObject
= NewObject
;
818 return STATUS_SUCCESS
;
823 LsapValidateDbObject(LSAPR_HANDLE Handle
,
824 LSA_DB_OBJECT_TYPE ObjectType
,
825 ACCESS_MASK DesiredAccess
,
826 PLSA_DB_OBJECT
*DbObject
)
828 PLSA_DB_OBJECT LocalObject
= (PLSA_DB_OBJECT
)Handle
;
829 BOOLEAN bValid
= FALSE
;
833 if (LocalObject
->Signature
== LSAP_DB_SIGNATURE
)
835 if ((ObjectType
== LsaDbIgnoreObject
) ||
836 (LocalObject
->ObjectType
== ObjectType
))
840 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
847 return STATUS_INVALID_HANDLE
;
849 if (DesiredAccess
!= 0)
851 /* Check for granted access rights */
852 if ((LocalObject
->Access
& DesiredAccess
) != DesiredAccess
)
854 ERR("LsapValidateDbObject access check failed %08lx %08lx\n",
855 LocalObject
->Access
, DesiredAccess
);
856 return STATUS_ACCESS_DENIED
;
860 if (DbObject
!= NULL
)
861 *DbObject
= LocalObject
;
863 return STATUS_SUCCESS
;
868 LsapCloseDbObject(PLSA_DB_OBJECT DbObject
)
870 PLSA_DB_OBJECT ParentObject
= NULL
;
871 NTSTATUS Status
= STATUS_SUCCESS
;
873 DbObject
->RefCount
--;
875 if (DbObject
->RefCount
> 0)
876 return STATUS_SUCCESS
;
878 if (DbObject
->KeyHandle
!= NULL
)
879 NtClose(DbObject
->KeyHandle
);
881 if (DbObject
->ParentObject
!= NULL
)
882 ParentObject
= DbObject
->ParentObject
;
884 RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject
);
886 if (ParentObject
!= NULL
)
888 ParentObject
->RefCount
--;
890 if (ParentObject
->RefCount
== 0)
891 Status
= LsapCloseDbObject(ParentObject
);
899 LsapDeleteDbObject(IN PLSA_DB_OBJECT DbObject
)
901 PLSA_DB_OBJECT ParentObject
= NULL
;
904 NTSTATUS Status
= STATUS_SUCCESS
;
906 DbObject
->RefCount
--;
908 if (DbObject
->RefCount
> 0)
909 return STATUS_SUCCESS
;
911 if (DbObject
->KeyHandle
!= NULL
)
917 Status
= LsapRegEnumerateSubKey(DbObject
->KeyHandle
,
921 if (!NT_SUCCESS(Status
))
924 TRACE("Index: %lu\n", Index
);
925 TRACE("Key name: %S\n", KeyName
);
927 Status
= LsapRegDeleteSubKey(DbObject
->KeyHandle
,
929 if (!NT_SUCCESS(Status
))
933 if (Status
== STATUS_NO_MORE_ENTRIES
)
934 Status
= STATUS_SUCCESS
;
936 LsapRegDeleteKey(DbObject
->KeyHandle
);
938 NtClose(DbObject
->KeyHandle
);
941 if (DbObject
->ParentObject
!= NULL
)
942 ParentObject
= DbObject
->ParentObject
;
944 RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject
);
946 if (ParentObject
!= NULL
)
948 ParentObject
->RefCount
--;
950 if (ParentObject
->RefCount
== 0)
951 Status
= LsapCloseDbObject(ParentObject
);
959 LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject
,
960 LPWSTR AttributeName
,
961 LPVOID AttributeData
,
964 OBJECT_ATTRIBUTES ObjectAttributes
;
965 UNICODE_STRING KeyName
;
969 RtlInitUnicodeString(&KeyName
,
972 InitializeObjectAttributes(&ObjectAttributes
,
974 OBJ_CASE_INSENSITIVE
,
978 Status
= NtCreateKey(&AttributeKey
,
983 REG_OPTION_NON_VOLATILE
,
985 if (!NT_SUCCESS(Status
))
991 Status
= RtlpNtSetValueKey(AttributeKey
,
996 NtClose(AttributeKey
);
1003 LsapGetObjectAttribute(PLSA_DB_OBJECT DbObject
,
1004 LPWSTR AttributeName
,
1005 LPVOID AttributeData
,
1006 PULONG AttributeSize
)
1008 OBJECT_ATTRIBUTES ObjectAttributes
;
1009 UNICODE_STRING KeyName
;
1010 HANDLE AttributeKey
;
1014 RtlInitUnicodeString(&KeyName
,
1017 InitializeObjectAttributes(&ObjectAttributes
,
1019 OBJ_CASE_INSENSITIVE
,
1020 DbObject
->KeyHandle
,
1023 Status
= NtOpenKey(&AttributeKey
,
1026 if (!NT_SUCCESS(Status
))
1031 ValueSize
= *AttributeSize
;
1032 Status
= RtlpNtQueryValueKey(AttributeKey
,
1037 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
1042 if (AttributeData
== NULL
|| *AttributeSize
== 0)
1044 *AttributeSize
= ValueSize
;
1045 Status
= STATUS_SUCCESS
;
1048 else if (*AttributeSize
< ValueSize
)
1050 *AttributeSize
= ValueSize
;
1051 Status
= STATUS_BUFFER_OVERFLOW
;
1055 Status
= RtlpNtQueryValueKey(AttributeKey
,
1060 if (NT_SUCCESS(Status
))
1062 *AttributeSize
= ValueSize
;
1066 NtClose(AttributeKey
);