windows-nt/Source/XPSP1/NT/sdktools/tweakui/secret.cpp
2020-09-26 16:20:57 +08:00

187 lines
4.4 KiB
C++

#include "tweakui.h"
/*
* Win9x doesn't have ntdll.dll, but since we only need one function from
* it, let's just define it ourselves.
*/
void _RtlInitUnicodeString(
OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString)
{
ULONG Length;
DestinationString->Buffer = (PWSTR)SourceString;
Length = lstrlenW(SourceString) * sizeof(WCHAR);
DestinationString->Length = (USHORT)Length;
DestinationString->MaximumLength = (USHORT)(Length + sizeof(UNICODE_NULL));
}
/*
* Win9x also doesn't have the Lsa functions in advapi32, so we need to
* GetProcAddress them on the fly.
*/
FARPROC GetAdvapi32Proc(LPCSTR pszName)
{
return GetProcAddress(GetModuleHandle("ADVAPI32"), pszName);
}
#define DELAYLOAD_FUNCTION(fn, args, nargs) \
\
NTSTATUS _##fn args \
{ \
NTSTATUS (NTAPI *fn) args = \
(NTSTATUS (NTAPI*)args)GetAdvapi32Proc(#fn); \
if (fn) return fn nargs; \
return STATUS_NOT_IMPLEMENTED; \
}
DELAYLOAD_FUNCTION(LsaOpenPolicy, (
IN PLSA_UNICODE_STRING SystemName OPTIONAL,
IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
IN ACCESS_MASK DesiredAccess,
IN OUT PLSA_HANDLE PolicyHandle),
(SystemName, ObjectAttributes, DesiredAccess, PolicyHandle))
DELAYLOAD_FUNCTION(LsaRetrievePrivateData, (
IN LSA_HANDLE PolicyHandle,
IN PLSA_UNICODE_STRING KeyName,
OUT PLSA_UNICODE_STRING * PrivateData),
(PolicyHandle, KeyName, PrivateData))
DELAYLOAD_FUNCTION(LsaStorePrivateData, (
IN LSA_HANDLE PolicyHandle,
IN PLSA_UNICODE_STRING KeyName,
IN PLSA_UNICODE_STRING PrivateData),
(PolicyHandle, KeyName, PrivateData))
DELAYLOAD_FUNCTION(LsaClose, (
IN LSA_HANDLE ObjectHandle),
(ObjectHandle))
DELAYLOAD_FUNCTION(LsaFreeMemory, (
IN PVOID Buffer),
(Buffer))
/****************************************************************************/
#define DEFAULT_PASSWORD_KEY L"DefaultPassword"
NTSTATUS
GetSecretDefaultPassword(
LPWSTR PasswordBuffer, DWORD cchBuf
)
{
NTSTATUS Status = STATUS_SUCCESS;
OBJECT_ATTRIBUTES ObjectAttributes;
LSA_HANDLE LsaHandle = NULL;
UNICODE_STRING SecretName;
PUNICODE_STRING SecretValue = NULL;
InitializeObjectAttributes(
&ObjectAttributes,
NULL,
0L,
(HANDLE)NULL,
NULL
);
Status = _LsaOpenPolicy(
NULL,
&ObjectAttributes,
POLICY_VIEW_LOCAL_INFORMATION,
&LsaHandle
);
if (!NT_SUCCESS(Status)) {
return Status;
}
_RtlInitUnicodeString(
&SecretName,
DEFAULT_PASSWORD_KEY
);
Status = _LsaRetrievePrivateData(
LsaHandle,
&SecretName,
&SecretValue
);
if (!NT_SUCCESS(Status)) {
_LsaClose(LsaHandle);
return Status;
}
DWORD cchSecret = SecretValue->Length / sizeof(WCHAR); // does not include terminator
lstrcpynW(PasswordBuffer, SecretValue->Buffer, min(cchBuf, cchSecret+1));
if (SecretValue->Buffer != NULL) {
_LsaFreeMemory(SecretValue->Buffer);
}
_LsaFreeMemory(SecretValue);
_LsaClose(LsaHandle);
return STATUS_SUCCESS;
}
NTSTATUS
SetSecretDefaultPassword(
LPWSTR PasswordBuffer
)
{
NTSTATUS Status = STATUS_SUCCESS;
OBJECT_ATTRIBUTES ObjectAttributes;
LSA_HANDLE LsaHandle = NULL;
UNICODE_STRING SecretName;
UNICODE_STRING SecretValue;
InitializeObjectAttributes(
&ObjectAttributes,
NULL,
0L,
(HANDLE)NULL,
NULL
);
Status = _LsaOpenPolicy(
NULL,
&ObjectAttributes,
POLICY_CREATE_SECRET,
&LsaHandle
);
if (!NT_SUCCESS(Status)) {
return Status;
}
_RtlInitUnicodeString(
&SecretName,
DEFAULT_PASSWORD_KEY
);
_RtlInitUnicodeString(
&SecretValue,
PasswordBuffer
);
Status = _LsaStorePrivateData(
LsaHandle,
&SecretName,
&SecretValue
);
if (!NT_SUCCESS(Status)) {
_LsaClose(LsaHandle);
return Status;
}
_LsaClose(LsaHandle);
return STATUS_SUCCESS;
}