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
,
309 if (!NT_SUCCESS(Status
))
312 LsapSetObjectAttribute(PolicyObject
,
317 LsapSetObjectAttribute(PolicyObject
,
322 LsapSetObjectAttribute(PolicyObject
,
327 LsapSetObjectAttribute(PolicyObject
,
330 RtlLengthSid(AccountDomainSid
));
332 /* Set the default quota limits attribute */
333 LsapSetObjectAttribute(PolicyObject
,
336 sizeof(POLICY_DEFAULT_QUOTA_INFO
));
338 /* Set the modification attribute */
339 LsapSetObjectAttribute(PolicyObject
,
342 sizeof(POLICY_MODIFICATION_INFO
));
344 /* Set the audit full attribute */
345 LsapSetObjectAttribute(PolicyObject
,
348 sizeof(POLICY_AUDIT_FULL_QUERY_INFO
));
350 /* Set the audit log attribute */
351 LsapSetObjectAttribute(PolicyObject
,
354 sizeof(POLICY_AUDIT_LOG_INFO
));
356 /* Set the audit events attribute */
357 LsapSetObjectAttribute(PolicyObject
,
362 /* Set the DNS Domain Name attribute */
363 LsapSetObjectAttribute(PolicyObject
,
368 /* Set the DNS Forest Name attribute */
369 LsapSetObjectAttribute(PolicyObject
,
374 /* Set the DNS Domain GUID attribute */
375 LsapSetObjectAttribute(PolicyObject
,
380 /* Set the Sceurity Descriptor */
381 LsapSetObjectAttribute(PolicyObject
,
387 if (AuditEventsInfo
!= NULL
)
388 RtlFreeHeap(RtlGetProcessHeap(), 0, AuditEventsInfo
);
390 if (PolicyObject
!= NULL
)
391 LsapCloseDbObject(PolicyObject
);
393 if (AccountDomainSid
!= NULL
)
394 RtlFreeSid(AccountDomainSid
);
396 if (PolicySd
!= NULL
)
397 RtlFreeHeap(RtlGetProcessHeap(), 0, PolicySd
);
404 LsapUpdateDatabase(VOID
)
406 return STATUS_SUCCESS
;
411 LsapGetDomainInfo(VOID
)
413 PLSA_DB_OBJECT PolicyObject
= NULL
;
414 PUNICODE_STRING DomainName
= NULL
;
416 LPWSTR SidString
= NULL
;
419 /* Get the built-in domain SID and name */
420 Status
= RtlAllocateAndInitializeSid(&NtAuthority
,
422 SECURITY_BUILTIN_DOMAIN_RID
,
425 if (!NT_SUCCESS(Status
))
429 RtlInitUnicodeString(&BuiltinDomainName
,
432 /* Open the 'Policy' object */
433 Status
= LsapOpenDbObject(NULL
,
440 if (!NT_SUCCESS(Status
))
443 /* Get the account domain SID */
445 Status
= LsapGetObjectAttribute(PolicyObject
,
449 if (!NT_SUCCESS(Status
))
452 if (AttributeSize
> 0)
454 AccountDomainSid
= RtlAllocateHeap(RtlGetProcessHeap(),
457 if (AccountDomainSid
== NULL
)
459 Status
= STATUS_INSUFFICIENT_RESOURCES
;
463 Status
= LsapGetObjectAttribute(PolicyObject
,
467 if (!NT_SUCCESS(Status
))
471 /* Get the account domain name */
473 Status
= LsapGetObjectAttribute(PolicyObject
,
477 if (!NT_SUCCESS(Status
))
480 if (AttributeSize
> 0)
482 DomainName
= RtlAllocateHeap(RtlGetProcessHeap(),
485 if (DomainName
== NULL
)
487 Status
= STATUS_INSUFFICIENT_RESOURCES
;
491 Status
= LsapGetObjectAttribute(PolicyObject
,
495 if (!NT_SUCCESS(Status
))
498 DomainName
->Buffer
= (LPWSTR
)((ULONG_PTR
)DomainName
+ (ULONG_PTR
)DomainName
->Buffer
);
500 AccountDomainName
.Length
= DomainName
->Length
;
501 AccountDomainName
.MaximumLength
= DomainName
->Length
+ sizeof(WCHAR
);
502 AccountDomainName
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
504 AccountDomainName
.MaximumLength
);
505 if (AccountDomainName
.Buffer
== NULL
)
507 ERR("Failed to allocate the account domain name buffer\n");
508 Status
= STATUS_INSUFFICIENT_RESOURCES
;
512 RtlCopyMemory(AccountDomainName
.Buffer
,
517 ConvertSidToStringSidW(BuiltinDomainSid
, &SidString
);
518 TRACE("Builtin Domain SID: %S\n", SidString
);
519 LocalFree(SidString
);
522 TRACE("Builtin Domain Name: %wZ\n", &BuiltinDomainName
);
524 ConvertSidToStringSidW(AccountDomainSid
, &SidString
);
525 TRACE("Account Domain SID: %S\n", SidString
);
526 LocalFree(SidString
);
529 TRACE("Account Domain Name: %wZ\n", &AccountDomainName
);
532 if (DomainName
!= NULL
)
533 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainName
);
535 if (PolicyObject
!= NULL
)
536 LsapCloseDbObject(PolicyObject
);
543 LsapInitDatabase(VOID
)
547 TRACE("LsapInitDatabase()\n");
549 Status
= LsapOpenServiceKey();
550 if (!NT_SUCCESS(Status
))
552 ERR("Failed to open the service key (Status: 0x%08lx)\n", Status
);
556 if (!LsapIsDatabaseInstalled())
558 Status
= LsapCreateDatabaseKeys();
559 if (!NT_SUCCESS(Status
))
561 ERR("Failed to create the LSA database keys (Status: 0x%08lx)\n", Status
);
565 Status
= LsapCreateDatabaseObjects();
566 if (!NT_SUCCESS(Status
))
568 ERR("Failed to create the LSA database objects (Status: 0x%08lx)\n", Status
);
574 Status
= LsapUpdateDatabase();
575 if (!NT_SUCCESS(Status
))
577 ERR("Failed to update the LSA database (Status: 0x%08lx)\n", Status
);
582 Status
= LsapGetDomainInfo();
583 if (!NT_SUCCESS(Status
))
585 ERR("Failed to get the domain information (Status: 0x%08lx)\n", Status
);
589 TRACE("LsapInitDatabase() done\n");
591 return STATUS_SUCCESS
;
596 LsapCreateDbObject(IN PLSA_DB_OBJECT ParentObject
,
597 IN LPWSTR ContainerName
,
598 IN LPWSTR ObjectName
,
599 IN LSA_DB_OBJECT_TYPE ObjectType
,
600 IN ACCESS_MASK DesiredAccess
,
602 OUT PLSA_DB_OBJECT
*DbObject
)
604 PLSA_DB_OBJECT NewObject
;
605 OBJECT_ATTRIBUTES ObjectAttributes
;
606 UNICODE_STRING KeyName
;
607 HANDLE ParentKeyHandle
;
608 HANDLE ContainerKeyHandle
= NULL
;
609 HANDLE ObjectKeyHandle
= NULL
;
612 if (DbObject
== NULL
)
613 return STATUS_INVALID_PARAMETER
;
615 if (ParentObject
== NULL
)
616 ParentKeyHandle
= SecurityKeyHandle
;
618 ParentKeyHandle
= ParentObject
->KeyHandle
;
620 if (ContainerName
!= NULL
)
622 /* Open the container key */
623 RtlInitUnicodeString(&KeyName
,
626 InitializeObjectAttributes(&ObjectAttributes
,
628 OBJ_CASE_INSENSITIVE
,
632 Status
= NtOpenKey(&ContainerKeyHandle
,
635 if (!NT_SUCCESS(Status
))
640 /* Open the object key */
641 RtlInitUnicodeString(&KeyName
,
644 InitializeObjectAttributes(&ObjectAttributes
,
646 OBJ_CASE_INSENSITIVE
,
650 Status
= NtCreateKey(&ObjectKeyHandle
,
658 NtClose(ContainerKeyHandle
);
660 if (!NT_SUCCESS(Status
))
667 RtlInitUnicodeString(&KeyName
,
670 InitializeObjectAttributes(&ObjectAttributes
,
672 OBJ_CASE_INSENSITIVE
,
676 Status
= NtCreateKey(&ObjectKeyHandle
,
683 if (!NT_SUCCESS(Status
))
689 NewObject
= RtlAllocateHeap(RtlGetProcessHeap(),
691 sizeof(LSA_DB_OBJECT
));
692 if (NewObject
== NULL
)
694 NtClose(ObjectKeyHandle
);
695 return STATUS_NO_MEMORY
;
698 NewObject
->Signature
= LSAP_DB_SIGNATURE
;
699 NewObject
->RefCount
= 1;
700 NewObject
->ObjectType
= ObjectType
;
701 NewObject
->Access
= DesiredAccess
;
702 NewObject
->KeyHandle
= ObjectKeyHandle
;
703 NewObject
->ParentObject
= ParentObject
;
704 NewObject
->Trusted
= Trusted
;
706 if (ParentObject
!= NULL
)
707 ParentObject
->RefCount
++;
709 *DbObject
= NewObject
;
711 return STATUS_SUCCESS
;
716 LsapOpenDbObject(IN PLSA_DB_OBJECT ParentObject
,
717 IN LPWSTR ContainerName
,
718 IN LPWSTR ObjectName
,
719 IN LSA_DB_OBJECT_TYPE ObjectType
,
720 IN ACCESS_MASK DesiredAccess
,
722 OUT PLSA_DB_OBJECT
*DbObject
)
724 PLSA_DB_OBJECT NewObject
;
725 OBJECT_ATTRIBUTES ObjectAttributes
;
726 UNICODE_STRING KeyName
;
727 HANDLE ParentKeyHandle
;
728 HANDLE ContainerKeyHandle
= NULL
;
729 HANDLE ObjectKeyHandle
= NULL
;
732 if (DbObject
== NULL
)
733 return STATUS_INVALID_PARAMETER
;
735 if (ParentObject
== NULL
)
736 ParentKeyHandle
= SecurityKeyHandle
;
738 ParentKeyHandle
= ParentObject
->KeyHandle
;
740 if (ContainerName
!= NULL
)
742 /* Open the container key */
743 RtlInitUnicodeString(&KeyName
,
746 InitializeObjectAttributes(&ObjectAttributes
,
748 OBJ_CASE_INSENSITIVE
,
752 Status
= NtOpenKey(&ContainerKeyHandle
,
755 if (!NT_SUCCESS(Status
))
760 /* Open the object key */
761 RtlInitUnicodeString(&KeyName
,
764 InitializeObjectAttributes(&ObjectAttributes
,
766 OBJ_CASE_INSENSITIVE
,
770 Status
= NtOpenKey(&ObjectKeyHandle
,
774 NtClose(ContainerKeyHandle
);
776 if (!NT_SUCCESS(Status
))
783 /* Open the object key */
784 RtlInitUnicodeString(&KeyName
,
787 InitializeObjectAttributes(&ObjectAttributes
,
789 OBJ_CASE_INSENSITIVE
,
793 Status
= NtOpenKey(&ObjectKeyHandle
,
796 if (!NT_SUCCESS(Status
))
802 NewObject
= RtlAllocateHeap(RtlGetProcessHeap(),
804 sizeof(LSA_DB_OBJECT
));
805 if (NewObject
== NULL
)
807 NtClose(ObjectKeyHandle
);
808 return STATUS_NO_MEMORY
;
811 NewObject
->Signature
= LSAP_DB_SIGNATURE
;
812 NewObject
->RefCount
= 1;
813 NewObject
->ObjectType
= ObjectType
;
814 NewObject
->Access
= DesiredAccess
;
815 NewObject
->KeyHandle
= ObjectKeyHandle
;
816 NewObject
->ParentObject
= ParentObject
;
817 NewObject
->Trusted
= Trusted
;
819 if (ParentObject
!= NULL
)
820 ParentObject
->RefCount
++;
822 *DbObject
= NewObject
;
824 return STATUS_SUCCESS
;
829 LsapValidateDbObject(LSAPR_HANDLE Handle
,
830 LSA_DB_OBJECT_TYPE ObjectType
,
831 ACCESS_MASK DesiredAccess
,
832 PLSA_DB_OBJECT
*DbObject
)
834 PLSA_DB_OBJECT LocalObject
= (PLSA_DB_OBJECT
)Handle
;
835 BOOLEAN bValid
= FALSE
;
839 if (LocalObject
->Signature
== LSAP_DB_SIGNATURE
)
841 if ((ObjectType
== LsaDbIgnoreObject
) ||
842 (LocalObject
->ObjectType
== ObjectType
))
846 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
853 return STATUS_INVALID_HANDLE
;
855 if (DesiredAccess
!= 0)
857 /* Check for granted access rights */
858 if ((LocalObject
->Access
& DesiredAccess
) != DesiredAccess
)
860 ERR("LsapValidateDbObject access check failed %08lx %08lx\n",
861 LocalObject
->Access
, DesiredAccess
);
862 return STATUS_ACCESS_DENIED
;
866 if (DbObject
!= NULL
)
867 *DbObject
= LocalObject
;
869 return STATUS_SUCCESS
;
874 LsapCloseDbObject(PLSA_DB_OBJECT DbObject
)
876 PLSA_DB_OBJECT ParentObject
= NULL
;
877 NTSTATUS Status
= STATUS_SUCCESS
;
879 DbObject
->RefCount
--;
881 if (DbObject
->RefCount
> 0)
882 return STATUS_SUCCESS
;
884 if (DbObject
->KeyHandle
!= NULL
)
885 NtClose(DbObject
->KeyHandle
);
887 if (DbObject
->ParentObject
!= NULL
)
888 ParentObject
= DbObject
->ParentObject
;
890 RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject
);
892 if (ParentObject
!= NULL
)
894 ParentObject
->RefCount
--;
896 if (ParentObject
->RefCount
== 0)
897 Status
= LsapCloseDbObject(ParentObject
);
905 LsapDeleteDbObject(IN PLSA_DB_OBJECT DbObject
)
907 PLSA_DB_OBJECT ParentObject
= NULL
;
910 NTSTATUS Status
= STATUS_SUCCESS
;
912 DbObject
->RefCount
--;
914 if (DbObject
->RefCount
> 0)
915 return STATUS_SUCCESS
;
917 if (DbObject
->KeyHandle
!= NULL
)
923 Status
= LsapRegEnumerateSubKey(DbObject
->KeyHandle
,
927 if (!NT_SUCCESS(Status
))
930 TRACE("Index: %lu\n", Index
);
931 TRACE("Key name: %S\n", KeyName
);
933 Status
= LsapRegDeleteSubKey(DbObject
->KeyHandle
,
935 if (!NT_SUCCESS(Status
))
939 if (Status
== STATUS_NO_MORE_ENTRIES
)
940 Status
= STATUS_SUCCESS
;
942 LsapRegDeleteKey(DbObject
->KeyHandle
);
944 NtClose(DbObject
->KeyHandle
);
947 if (DbObject
->ParentObject
!= NULL
)
948 ParentObject
= DbObject
->ParentObject
;
950 RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject
);
952 if (ParentObject
!= NULL
)
954 ParentObject
->RefCount
--;
956 if (ParentObject
->RefCount
== 0)
957 Status
= LsapCloseDbObject(ParentObject
);
965 LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject
,
966 LPWSTR AttributeName
,
967 LPVOID AttributeData
,
970 OBJECT_ATTRIBUTES ObjectAttributes
;
971 UNICODE_STRING KeyName
;
975 RtlInitUnicodeString(&KeyName
,
978 InitializeObjectAttributes(&ObjectAttributes
,
980 OBJ_CASE_INSENSITIVE
,
984 Status
= NtCreateKey(&AttributeKey
,
989 REG_OPTION_NON_VOLATILE
,
991 if (!NT_SUCCESS(Status
))
997 Status
= RtlpNtSetValueKey(AttributeKey
,
1002 NtClose(AttributeKey
);
1009 LsapGetObjectAttribute(PLSA_DB_OBJECT DbObject
,
1010 LPWSTR AttributeName
,
1011 LPVOID AttributeData
,
1012 PULONG AttributeSize
)
1014 OBJECT_ATTRIBUTES ObjectAttributes
;
1015 UNICODE_STRING KeyName
;
1016 HANDLE AttributeKey
;
1020 RtlInitUnicodeString(&KeyName
,
1023 InitializeObjectAttributes(&ObjectAttributes
,
1025 OBJ_CASE_INSENSITIVE
,
1026 DbObject
->KeyHandle
,
1029 Status
= NtOpenKey(&AttributeKey
,
1032 if (!NT_SUCCESS(Status
))
1037 ValueSize
= *AttributeSize
;
1038 Status
= RtlpNtQueryValueKey(AttributeKey
,
1043 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
1048 if (AttributeData
== NULL
|| *AttributeSize
== 0)
1050 *AttributeSize
= ValueSize
;
1051 Status
= STATUS_SUCCESS
;
1054 else if (*AttributeSize
< ValueSize
)
1056 *AttributeSize
= ValueSize
;
1057 Status
= STATUS_BUFFER_OVERFLOW
;
1061 Status
= RtlpNtQueryValueKey(AttributeKey
,
1066 if (NT_SUCCESS(Status
))
1068 *AttributeSize
= ValueSize
;
1072 NtClose(AttributeKey
);