You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
650 lines
22 KiB
650 lines
22 KiB
|
|
extern "C"
|
|
{
|
|
// include NT and SAM headers here,
|
|
// order of these files DOES matter
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <rpc.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <samrpc.h>
|
|
#include <ntlsa.h>
|
|
#define SECURITY_WIN32
|
|
#define SECURITY_PACKAGE
|
|
#include <security.h>
|
|
#include <secint.h>
|
|
#include <samisrv.h>
|
|
#include <lsarpc.h>
|
|
#include <lsaisrv.h>
|
|
#include <ntsam.h>
|
|
#include <ntsamp.h>
|
|
#include <netlib.h>
|
|
#include <windows.h>
|
|
#include <lmerr.h>
|
|
#include <lmcons.h>
|
|
#include <netlib.h>
|
|
#include <ntdef.h>
|
|
}
|
|
|
|
|
|
#ifndef OEM_STRING
|
|
typedef STRING OEM_STRING;
|
|
#endif
|
|
|
|
|
|
|
|
#include "main.h"
|
|
#include "Clogger.h"
|
|
|
|
#include "DSREvents.h"
|
|
|
|
static WCHAR g_wszLSAKey[] = L"SYSTEM\\CurrentControlSet\\Control\\Lsa";
|
|
static WCHAR g_wszNotPac[] = L"Notification Packages";
|
|
static WCHAR g_wszName[] = L"dsrestor";
|
|
static WCHAR g_wszEventLog[] = L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application";
|
|
static WCHAR g_wszEventFileName[] = L"EventMessageFile";
|
|
static WCHAR g_wszTypesSupported[] = L"TypesSupported";
|
|
static WCHAR g_wszEventFilePath[] = L"%SystemRoot%\\System32\\DSREvt.dll";
|
|
static DWORD g_dwTypesSupported = 0x7;
|
|
|
|
//For comparison of OLD_LARGE_INTEGER
|
|
BOOL operator > ( OLD_LARGE_INTEGER li1, OLD_LARGE_INTEGER li2 )
|
|
{
|
|
return( li1.HighPart > li2.HighPart ||
|
|
( li1.HighPart ==li2.HighPart && li1.LowPart > li2.LowPart ) );
|
|
}
|
|
|
|
|
|
|
|
//Generate Domain Admin Sid based on Domain Sid
|
|
NTSTATUS CreateDomainAdminSid(PSID *ppDomainAdminSid, //[Out] return Domain Admin Sid
|
|
PSID pDomainSid) //[in] Domain Sid
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SUCCESS;
|
|
UCHAR AccountSubAuthorityCount;
|
|
ULONG AccountSidLength;
|
|
PULONG RidLocation;
|
|
|
|
if (!ppDomainAdminSid || !pDomainSid)
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
// Calculate the size of the new sid
|
|
|
|
AccountSubAuthorityCount = *RtlSubAuthorityCountSid(pDomainSid) + (UCHAR)1;
|
|
AccountSidLength = RtlLengthRequiredSid(AccountSubAuthorityCount);
|
|
|
|
// Allocate space for the account sid
|
|
|
|
*ppDomainAdminSid = RtlAllocateHeap(RtlProcessHeap(), 0, AccountSidLength);
|
|
|
|
if (*ppDomainAdminSid == NULL)
|
|
{
|
|
|
|
NtStatus = STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
else
|
|
{
|
|
// Copy the domain sid into the first part of the account sid
|
|
|
|
NTSTATUS IgnoreStatus = RtlCopySid(AccountSidLength, *ppDomainAdminSid, pDomainSid);
|
|
|
|
// Increment the account sid sub-authority count
|
|
|
|
if (RtlSubAuthorityCountSid(*ppDomainAdminSid))
|
|
*RtlSubAuthorityCountSid(*ppDomainAdminSid) = AccountSubAuthorityCount;
|
|
|
|
// Add the rid as the final sub-authority
|
|
|
|
RidLocation = RtlSubAuthoritySid(*ppDomainAdminSid, AccountSubAuthorityCount-1);
|
|
if (RidLocation)
|
|
*RidLocation = DOMAIN_USER_RID_ADMIN;
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return NtStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a thread to run PassCheck()
|
|
BOOL NTAPI InitializeChangeNotify( void )
|
|
{
|
|
ULONG ulID = 0;
|
|
HANDLE hThread = CreateThread( NULL, 0, PassCheck, NULL, 0, &ulID );
|
|
if (hThread && (hThread != INVALID_HANDLE_VALUE))
|
|
CloseHandle( hThread );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS NTAPI PasswordChangeNotify( PUNICODE_STRING UserName,
|
|
ULONG RelativeId,
|
|
PUNICODE_STRING NewPassword )
|
|
{
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
BOOL NTAPI PasswordFilter( PUNICODE_STRING AccountName,
|
|
PUNICODE_STRING FullName,
|
|
PUNICODE_STRING Password,
|
|
BOOLEAN SetOperation )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get Password for DSRestoreMode and DomainAdmin and set to same if not already
|
|
// then sleep for 30 minutes
|
|
DWORD WINAPI PassCheck( LPVOID lpParameter )
|
|
{
|
|
CEventLogger EventLogger;
|
|
DWORD dwRt=0; //Return Value
|
|
DWORD dwSleepTime = 30*60*1000;
|
|
// 30 min * 60 sec * 1000 msec
|
|
NTSTATUS RtVal = STATUS_SUCCESS;
|
|
OLD_LARGE_INTEGER liPasswordLastSet = {0,0};
|
|
SAMPR_HANDLE hSAMPR = NULL;
|
|
PSAMPR_SERVER_NAME pSvrName = NULL;
|
|
SAMPR_HANDLE hServerHandle = NULL;
|
|
SAMPR_HANDLE hDomainHandle = NULL;
|
|
PSAMPR_USER_INFO_BUFFER pUserBuffer = NULL;
|
|
LSA_HANDLE hPolicyHd = NULL;
|
|
LSA_OBJECT_ATTRIBUTES ObjAttr;
|
|
PPOLICY_PRIMARY_DOMAIN_INFO pDomainInfo=NULL;
|
|
WCHAR szSvrName[MAX_COMPUTERNAME_LENGTH + 1];
|
|
DWORD dwSvrName = MAX_COMPUTERNAME_LENGTH + 1;
|
|
LSA_UNICODE_STRING ServerName;
|
|
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
|
|
PSID pDomainAdminSid = NULL;
|
|
NT_OWF_PASSWORD Password;
|
|
SID_AND_ATTRIBUTES_LIST GroupMembership;
|
|
SAMPR_HANDLE UserHandle = NULL;
|
|
UNICODE_STRING PsudoUserName;
|
|
|
|
|
|
//Get ready for event logging
|
|
EventLogger.InitEventLog(g_wszName ,0, LOGGING_LEVEL_3);
|
|
EventLogger.LogEvent(LOGTYPE_INFORMATION,
|
|
EVENTDSR_FILTER_STARTED);
|
|
|
|
//Required by LsaOpenPolicy
|
|
ZeroMemory(&ObjAttr,sizeof(LSA_OBJECT_ATTRIBUTES));
|
|
ServerName.MaximumLength=sizeof(WCHAR)*(MAX_COMPUTERNAME_LENGTH + 1);
|
|
GroupMembership.Count = 0;
|
|
GroupMembership.SidAndAttributes = NULL;
|
|
|
|
|
|
// First get the local server name
|
|
if( !GetComputerName(szSvrName, &dwSvrName))
|
|
{
|
|
dwRt = GetLastError();
|
|
EventLogger.LogEvent(LOGTYPE_FORCE_ERROR,
|
|
EVENTDSR_FILTER_NO_HOST_NAME,
|
|
dwRt);
|
|
goto EXIT;
|
|
}
|
|
|
|
ServerName.Buffer=szSvrName;
|
|
ServerName.Length=(USHORT)(sizeof(WCHAR)*dwSvrName);
|
|
|
|
// To get the Policy Handle
|
|
if( STATUS_SUCCESS != (RtVal=LsaOpenPolicy(
|
|
&ServerName,
|
|
&ObjAttr,
|
|
POLICY_VIEW_LOCAL_INFORMATION,
|
|
&hPolicyHd
|
|
)) )
|
|
{
|
|
//Error output RtVal
|
|
dwRt = GetLastError();
|
|
EventLogger.LogEvent(LOGTYPE_FORCE_ERROR,
|
|
EVENTDSR_FILTER_NO_LOCAL_POLICY,
|
|
dwRt);
|
|
|
|
goto EXIT;
|
|
}
|
|
|
|
// Get the Primary Domain information
|
|
if( STATUS_SUCCESS != (RtVal=LsaQueryInformationPolicy(
|
|
hPolicyHd,
|
|
PolicyPrimaryDomainInformation,
|
|
reinterpret_cast<PVOID *> (&pDomainInfo) ) ))
|
|
{
|
|
//Error, log return value RtVal
|
|
EventLogger.LogEvent(LOGTYPE_FORCE_ERROR,
|
|
EVENTDSR_FILTER_NO_DOMAIN_INFO,
|
|
RtVal);
|
|
goto EXIT;
|
|
}
|
|
|
|
if( NULL == pDomainInfo->Sid )
|
|
{
|
|
// If we are running in the DS Restore mode, the Domain sid will be NULL
|
|
// No need to run in this case.
|
|
goto EXIT;
|
|
}
|
|
|
|
//Build the sid for domain admin
|
|
if( STATUS_SUCCESS != CreateDomainAdminSid(&pDomainAdminSid, pDomainInfo->Sid) )
|
|
{
|
|
//Error output RtVal
|
|
dwRt = GetLastError();
|
|
EventLogger.LogEvent(LOGTYPE_FORCE_ERROR,
|
|
EVENTDSR_FILTER_NO_ADMIN_SID,
|
|
dwRt);
|
|
goto EXIT;
|
|
}
|
|
|
|
//Check if the domain admin Sid just generated is valid
|
|
if(! IsValidSid( pDomainAdminSid ))
|
|
{
|
|
dwRt = GetLastError();
|
|
EventLogger.LogEvent(LOGTYPE_FORCE_ERROR,
|
|
EVENTDSR_FILTER_NO_ADMIN_SID,
|
|
dwRt);
|
|
goto EXIT;
|
|
}
|
|
|
|
// Starting the loop of polling domain admin password
|
|
while( TRUE )
|
|
{
|
|
|
|
//Get the server handle
|
|
if(STATUS_SUCCESS != SamIConnect(
|
|
pSvrName,
|
|
&hServerHandle,
|
|
POLICY_ALL_ACCESS,
|
|
TRUE) )
|
|
{
|
|
dwRt = GetLastError();
|
|
EventLogger.LogEvent(LOGTYPE_FORCE_ERROR,
|
|
EVENTDSR_FILTER_CONNECT_SAM_FAIL,
|
|
dwRt);
|
|
break;
|
|
}
|
|
|
|
|
|
// Get the domain handle
|
|
if(STATUS_SUCCESS != SamrOpenDomain(
|
|
hServerHandle,
|
|
POLICY_ALL_ACCESS,
|
|
(PRPC_SID)(pDomainInfo->Sid),
|
|
//PSID and PRPC_SID are basically the same
|
|
&hDomainHandle) )
|
|
{
|
|
dwRt = GetLastError();
|
|
EventLogger.LogEvent(LOGTYPE_FORCE_ERROR,
|
|
EVENTDSR_FILTER_CONNECT_DOMAIN_FAIL,
|
|
dwRt);
|
|
break;
|
|
}
|
|
|
|
PsudoUserName.Buffer = reinterpret_cast<PWSTR> (pDomainAdminSid);
|
|
PsudoUserName.Length = (USHORT)GetLengthSid(pDomainAdminSid);
|
|
PsudoUserName.MaximumLength = PsudoUserName.Length;
|
|
|
|
//Get accout info for Domain Admin
|
|
if(STATUS_SUCCESS != ( RtVal= SamIGetUserLogonInformation(
|
|
hDomainHandle,
|
|
SAM_OPEN_BY_SID,
|
|
&PsudoUserName,
|
|
&pUserBuffer,
|
|
&GroupMembership,
|
|
&UserHandle) ) )
|
|
{
|
|
dwRt = GetLastError();
|
|
EventLogger.LogEvent(LOGTYPE_FORCE_ERROR,
|
|
EVENTDSR_FILTER_NO_DOMAIN_ADMIN_INFO,
|
|
dwRt);
|
|
break;
|
|
}
|
|
|
|
|
|
// Check if the password of the Domain Admin was changed in
|
|
// the last sleep period.
|
|
// The first time, always set the password.
|
|
if( pUserBuffer->All.PasswordLastSet > liPasswordLastSet )
|
|
{
|
|
RtlCopyMemory(
|
|
&Password,
|
|
pUserBuffer->All.NtOwfPassword.Buffer,
|
|
NT_OWF_PASSWORD_LENGTH);
|
|
|
|
if(STATUS_SUCCESS != SamiSetDSRMPasswordOWF(
|
|
&ServerName,
|
|
DOMAIN_USER_RID_ADMIN,
|
|
&Password
|
|
) )
|
|
{
|
|
dwRt = GetLastError();
|
|
EventLogger.LogEvent(LOGTYPE_FORCE_ERROR,
|
|
EVENTDSR_FILTER_SET_PAWD_FAIL,
|
|
dwRt);
|
|
break;
|
|
}
|
|
|
|
liPasswordLastSet=pUserBuffer->All.PasswordLastSet;
|
|
}
|
|
|
|
// Clean up for next loop
|
|
SamIFree_SAMPR_USER_INFO_BUFFER(pUserBuffer, UserAllInformation);
|
|
RtlZeroMemory(&Password, NT_OWF_PASSWORD_LENGTH);
|
|
SamrCloseHandle(&hServerHandle);
|
|
SamrCloseHandle(&hDomainHandle);
|
|
pUserBuffer = NULL;
|
|
hServerHandle=NULL;
|
|
hDomainHandle=NULL;
|
|
|
|
// Sleep 30 minutes
|
|
Sleep( dwSleepTime );
|
|
}
|
|
|
|
EXIT:
|
|
//Clean up
|
|
|
|
if( NULL != pUserBuffer )
|
|
{
|
|
SamIFree_SAMPR_USER_INFO_BUFFER(
|
|
pUserBuffer, UserAllInformation);
|
|
}
|
|
if( NULL != hServerHandle )
|
|
{
|
|
SamrCloseHandle(&hServerHandle);
|
|
}
|
|
if( NULL != hDomainHandle )
|
|
{
|
|
SamrCloseHandle(&hDomainHandle);
|
|
}
|
|
|
|
if( NULL != pDomainAdminSid )
|
|
{
|
|
RtlFreeHeap( RtlProcessHeap(), 0, (PVOID)pDomainAdminSid);
|
|
}
|
|
if( NULL != pDomainInfo )
|
|
{
|
|
LsaFreeMemory(pDomainInfo);
|
|
}
|
|
if( NULL != hPolicyHd )
|
|
{
|
|
LsaClose(hPolicyHd);
|
|
}
|
|
|
|
return dwRt;
|
|
}
|
|
|
|
|
|
HRESULT NTAPI RegisterFilter( void )
|
|
{
|
|
DWORD dwType = 0;
|
|
DWORD dwcbSize = 0;
|
|
HKEY hLSAKey = NULL;
|
|
HKEY hEventLogKey = NULL;
|
|
HKEY hDSEvtKey = NULL;
|
|
BOOL bSuccess = FALSE;
|
|
BOOL bRegistered = FALSE;
|
|
|
|
LONG lRetVal = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
g_wszLSAKey,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hLSAKey );
|
|
if (ERROR_SUCCESS == lRetVal)
|
|
{
|
|
ULONG ulStrLen = wcslen( g_wszName );
|
|
lRetVal = RegQueryValueEx( hLSAKey,
|
|
g_wszNotPac,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&dwcbSize );
|
|
if (ERROR_SUCCESS == lRetVal) // Key exists, must add my value to the end
|
|
{
|
|
WCHAR *pwsz = NULL;
|
|
DWORD dwBufSize = dwcbSize + (ulStrLen+1)*sizeof(WCHAR);
|
|
BYTE *pbyVal = new BYTE[dwBufSize];
|
|
if (NULL != pbyVal)
|
|
{
|
|
lRetVal = RegQueryValueEx( hLSAKey,
|
|
g_wszNotPac,
|
|
NULL,
|
|
&dwType,
|
|
pbyVal,
|
|
&dwcbSize );
|
|
if (ERROR_SUCCESS == lRetVal)
|
|
{
|
|
//First, check if we have already registered
|
|
pwsz = (WCHAR *)pbyVal;
|
|
while( *pwsz != 0 )
|
|
{
|
|
if (0 == wcscmp( pwsz, g_wszName ))
|
|
{
|
|
//It is already registered
|
|
bRegistered = TRUE;
|
|
bSuccess = TRUE;
|
|
break;
|
|
}
|
|
pwsz += (wcslen( pwsz ) + 1);
|
|
}
|
|
|
|
if(! bRegistered)
|
|
{
|
|
// Got the value, now I need to add myself to the end
|
|
pwsz = (WCHAR *)&(pbyVal[dwcbSize - 2]);
|
|
wcscpy( pwsz, g_wszName );
|
|
// Make sure we're termintate by 2 UNICODE NULLs (REG_MULTI_SZ)
|
|
pwsz += ulStrLen + 1;
|
|
*pwsz = 0;
|
|
lRetVal = RegSetValueEx( hLSAKey,
|
|
g_wszNotPac,
|
|
0,
|
|
(DWORD)REG_MULTI_SZ,
|
|
pbyVal,
|
|
dwBufSize );
|
|
if (ERROR_SUCCESS == lRetVal)
|
|
bSuccess = TRUE;
|
|
}
|
|
}
|
|
delete[] pbyVal;
|
|
}
|
|
}
|
|
else // Key doesn't exist. Have to create it
|
|
{
|
|
DWORD dwBufSize=(ulStrLen+2)*sizeof(WCHAR);
|
|
BYTE *rgbyVal= new BYTE[dwBufSize];
|
|
if( NULL != rgbyVal )
|
|
{
|
|
WCHAR *pwsz = (WCHAR *)rgbyVal;
|
|
wcscpy( pwsz, g_wszName );
|
|
|
|
// Make sure we're terminated by two UNICODE NULLs (REG_MULTI_SZ)
|
|
pwsz += ulStrLen + 1;
|
|
*pwsz = 0;
|
|
|
|
lRetVal = RegSetValueEx( hLSAKey,
|
|
g_wszNotPac,
|
|
0,
|
|
(DWORD)REG_MULTI_SZ,
|
|
rgbyVal,
|
|
dwBufSize );
|
|
if (ERROR_SUCCESS == lRetVal)
|
|
bSuccess = TRUE;
|
|
delete[] rgbyVal;
|
|
}
|
|
}
|
|
|
|
RegCloseKey( hLSAKey );
|
|
}
|
|
|
|
if( bSuccess )
|
|
{
|
|
|
|
lRetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
g_wszEventLog,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hEventLogKey);
|
|
if ( ERROR_SUCCESS == lRetVal )
|
|
{
|
|
//Create the Reg Key for eventlogging
|
|
lRetVal = RegCreateKeyEx(hEventLogKey,
|
|
g_wszName,
|
|
0,
|
|
NULL,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hDSEvtKey,
|
|
NULL);
|
|
if ( ERROR_SUCCESS == lRetVal )
|
|
{
|
|
lRetVal = RegSetValueEx(hDSEvtKey,
|
|
g_wszEventFileName,
|
|
0,
|
|
REG_SZ,
|
|
reinterpret_cast<CONST BYTE*>(g_wszEventFilePath),
|
|
sizeof(WCHAR)*wcslen(g_wszEventFilePath));
|
|
if (ERROR_SUCCESS == lRetVal )
|
|
{
|
|
lRetVal = RegSetValueEx(hDSEvtKey,
|
|
g_wszTypesSupported,
|
|
0,
|
|
REG_DWORD,
|
|
reinterpret_cast<CONST BYTE*>(&g_dwTypesSupported),
|
|
sizeof(DWORD));
|
|
}
|
|
RegCloseKey(hDSEvtKey);
|
|
}
|
|
|
|
if (ERROR_SUCCESS != lRetVal)
|
|
{
|
|
bSuccess = FALSE;
|
|
}
|
|
}
|
|
RegCloseKey(hEventLogKey);
|
|
}
|
|
|
|
|
|
return bSuccess ? (bRegistered ? S_FALSE : S_OK ) : E_FAIL;
|
|
}
|
|
|
|
|
|
HRESULT NTAPI UnRegisterFilter( void )
|
|
{
|
|
DWORD dwType = 0;
|
|
DWORD dwcbSize = 0;
|
|
HKEY hLSAKey = NULL;
|
|
HKEY hEventLogKey =NULL;
|
|
BOOL bSuccess = FALSE;
|
|
|
|
LONG lRetVal = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
g_wszLSAKey,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hLSAKey );
|
|
if (ERROR_SUCCESS == lRetVal)
|
|
{
|
|
lRetVal = RegQueryValueEx( hLSAKey,
|
|
g_wszNotPac,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&dwcbSize );
|
|
// Key exists, must delete my value from the end
|
|
if (ERROR_SUCCESS == lRetVal)
|
|
{
|
|
ULONG ulStrLen = wcslen( g_wszName );
|
|
BYTE *pbyVal = new BYTE[dwcbSize];
|
|
if (pbyVal)
|
|
{
|
|
lRetVal = RegQueryValueEx( hLSAKey,
|
|
g_wszNotPac,
|
|
NULL,
|
|
&dwType,
|
|
pbyVal,
|
|
&dwcbSize );
|
|
|
|
if (ERROR_SUCCESS == lRetVal)
|
|
{
|
|
// Got the old key,
|
|
// now step through and remove my part of the key
|
|
WCHAR *pwsz = (WCHAR *)pbyVal;
|
|
WCHAR *wszNewRegVal = new WCHAR[dwcbSize];
|
|
WCHAR *pwszNewVal = wszNewRegVal;
|
|
DWORD dwLen = 0;
|
|
|
|
if (wszNewRegVal)
|
|
{
|
|
*pwszNewVal = 0;
|
|
while( *pwsz != 0 )
|
|
{
|
|
if (wcscmp( pwsz, g_wszName ))
|
|
{
|
|
wcscpy( pwszNewVal, pwsz );
|
|
dwLen += wcslen( pwsz ) + 1;
|
|
pwszNewVal += (wcslen( pwsz ) + 1);
|
|
}
|
|
pwsz += (wcslen( pwsz ) + 1);
|
|
}
|
|
|
|
// if we got here and there's nothing in the buffer,
|
|
// we were the only one installed,
|
|
// now we must delete the key, else set it to the old value
|
|
wszNewRegVal[dwLen] = 0; // add the last NULL
|
|
dwLen++; // account for that last NULL
|
|
lRetVal = RegSetValueEx(hLSAKey,
|
|
g_wszNotPac,
|
|
0,
|
|
(DWORD)REG_MULTI_SZ,
|
|
reinterpret_cast<CONST BYTE*>(wszNewRegVal),
|
|
dwLen*sizeof(WCHAR));
|
|
if (ERROR_SUCCESS == lRetVal)
|
|
bSuccess = TRUE;
|
|
delete[] wszNewRegVal;
|
|
}
|
|
}
|
|
delete[] pbyVal;
|
|
}
|
|
// NTRAID#NTBUG9-655545-2002/07/05-artm
|
|
RegCloseKey( hLSAKey );
|
|
}
|
|
}
|
|
|
|
if( bSuccess )
|
|
{
|
|
//Delete the Reg Key for eventlogging
|
|
lRetVal=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
g_wszEventLog,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hEventLogKey);
|
|
if (ERROR_SUCCESS == lRetVal)
|
|
{
|
|
RegDeleteKey(hEventLogKey, g_wszName );
|
|
if( ERROR_SUCCESS != lRetVal &&
|
|
ERROR_FILE_NOT_FOUND != lRetVal )
|
|
// If the key does not exist, ERROR_FILE_NOT_FOUND wii be returened
|
|
{
|
|
bSuccess = FALSE;
|
|
}
|
|
RegCloseKey( hEventLogKey );
|
|
}
|
|
else
|
|
{
|
|
bSuccess = FALSE;
|
|
}
|
|
}
|
|
|
|
return bSuccess ? S_OK : E_FAIL;
|
|
}
|