2884 lines
90 KiB
C++
2884 lines
90 KiB
C++
/*++
|
||
Copyright (c) 1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
infget.c
|
||
|
||
Abstract:
|
||
|
||
Routines to get information from security profiles (INF layout).
|
||
Functions from setupapi.lib (setupapi.h), syssetup.lib (syssetup.h),
|
||
netlib.lib (netlib.h) for parsing the INF layout are referenced
|
||
besides ntdll, ntrtl, and etc.
|
||
|
||
Author:
|
||
|
||
Jin Huang (jinhuang) 28-Oct-1996
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "headers.h"
|
||
#include "scedllrc.h"
|
||
#include "infp.h"
|
||
#include "sceutil.h"
|
||
#include <sddl.h>
|
||
|
||
#pragma hdrstop
|
||
|
||
//#define INF_DBG 1
|
||
|
||
#define SCEINF_OBJECT_FLAG_DSOBJECT 1
|
||
#define SCEINF_OBJECT_FLAG_OLDSDDL 2
|
||
#define SCEINF_OBJECT_FLAG_UNKNOWN_VERSION 4
|
||
|
||
|
||
//
|
||
// Forward references
|
||
//
|
||
SCESTATUS
|
||
SceInfpGetSystemAccess(
|
||
IN HINF hInf,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_PROFILE_INFO pSCEinfo,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SceInfpGetUserSettings(
|
||
IN HINF hInf,
|
||
OUT PSCE_NAME_LIST *pProfileList,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SceInfpGetGroupMembership(
|
||
IN HINF hInf,
|
||
OUT PSCE_GROUP_MEMBERSHIP *pGroupMembership,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SceInfpGetObjects(
|
||
IN HINF hInf,
|
||
IN PCWSTR SectionName,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_OBJECT_ARRAY *pAllNodes,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SceInfpGetOneObjectSecurity(
|
||
IN PINFCONTEXT pInfLine,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_OBJECT_SECURITY *pObject,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SceInfpGetAuditLogSetting(
|
||
IN HINF hInf,
|
||
IN PCWSTR SectionName,
|
||
IN DWORD ObjectFlag,
|
||
OUT PDWORD LogSize,
|
||
OUT PDWORD Periods,
|
||
OUT PDWORD RetentionDays,
|
||
OUT PDWORD RestrictGuest,
|
||
IN OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SceInfpGetAuditing(
|
||
IN HINF hInf,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_PROFILE_INFO pSCEinfo,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SceInfpGetKerberosPolicy(
|
||
IN HINF hInf,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_KERBEROS_TICKET_INFO * ppKerberosInfo,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SceInfpGetRegistryValues(
|
||
IN HINF hInf,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_REGISTRY_VALUE_INFO * ppRegValues,
|
||
OUT LPDWORD pValueCount,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SceInfpGetOneRegistryValue(
|
||
IN PINFCONTEXT pInfLine,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_REGISTRY_VALUE_INFO pValues,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
);
|
||
|
||
SCESTATUS
|
||
SceInfpGetSystemServices(
|
||
IN HINF hInf,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_SERVICES *pServiceList,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
);
|
||
|
||
//
|
||
// function definitions
|
||
//
|
||
|
||
SCESTATUS
|
||
SceInfpGetSecurityProfileInfo(
|
||
IN HINF hInf,
|
||
IN AREA_INFORMATION Area,
|
||
OUT PSCE_PROFILE_INFO *ppInfoBuffer,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/**++
|
||
|
||
Function Description:
|
||
|
||
This function reads all or part of information from a SCP file in INF
|
||
format into the InfoBuffer.
|
||
|
||
The memory related to the area(s) will be reset/freed before loading
|
||
information from the INF file. If the return code is SCESTATUS_SUCCESS,
|
||
then the output InfoBuffer contains the requested information. Otherwise,
|
||
InfoBuffer contains nothing for the area(s) specified.
|
||
|
||
Arguments:
|
||
|
||
hInf - The INF handle to read from.
|
||
|
||
Area - area(s) for which to get information from
|
||
AREA_SECURITY_POLICY
|
||
AREA_PRIVILEGES
|
||
AREA_USER_SETTINGS
|
||
AREA_GROUP_MEMBERSHIP
|
||
AREA_REGISTRY_SECURITY
|
||
AREA_SYSTEM_SERVICE
|
||
AREA_FILE_SECURITY
|
||
|
||
ppInfoBuffer - The address of SCP profile buffers. If it is NULL, a buffer
|
||
will be created which must be freed by SceFreeMemory. The
|
||
output is the information requested if successful, or nothing
|
||
if fail.
|
||
|
||
Errlog - A buffer to hold all error codes/text encountered when
|
||
parsing the INF file. If Errlog is NULL, no further error
|
||
information is returned except the return DWORD
|
||
|
||
Return Value:
|
||
|
||
SCESTATUS_SUCCESS
|
||
SCESTATUS_PROFILE_NOT_FOUND
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_BAD_FORMAT
|
||
SCESTATUS_INVALID_DATA
|
||
|
||
-- **/
|
||
{
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
UINT Len;
|
||
BOOL bFreeMem=FALSE;
|
||
DWORD ObjectFlag=0;
|
||
|
||
//
|
||
// if the INF file is not loaded (hInf = 0), then return
|
||
//
|
||
|
||
if ( !hInf ) {
|
||
|
||
return( SCESTATUS_INVALID_PARAMETER );
|
||
}
|
||
|
||
//
|
||
// address for InfoBuffer cannot be NULL
|
||
//
|
||
if ( ppInfoBuffer == NULL ) {
|
||
return( SCESTATUS_INVALID_PARAMETER );
|
||
}
|
||
|
||
//
|
||
// if the Area is not valid, then return
|
||
//
|
||
if ( Area & ~AREA_ALL) {
|
||
|
||
return( SCESTATUS_INVALID_PARAMETER );
|
||
}
|
||
|
||
if ( *ppInfoBuffer == NULL) {
|
||
//
|
||
// allocate memory
|
||
//
|
||
Len = sizeof(SCE_PROFILE_INFO);
|
||
|
||
*ppInfoBuffer = (PSCE_PROFILE_INFO)ScepAlloc( (UINT)0, Len );
|
||
if ( *ppInfoBuffer == NULL ) {
|
||
|
||
return( SCESTATUS_NOT_ENOUGH_RESOURCE );
|
||
}
|
||
memset(*ppInfoBuffer, '\0', Len);
|
||
(*ppInfoBuffer)->Type = SCE_STRUCT_INF;
|
||
|
||
ScepResetSecurityPolicyArea(*ppInfoBuffer);
|
||
|
||
bFreeMem = TRUE;
|
||
}
|
||
|
||
|
||
//
|
||
// Free related memory and reset the buffer before parsing
|
||
// there is a problem here for now. it clears the handle and
|
||
// filename too. So comment it out.
|
||
|
||
SceFreeMemory( (PVOID)(*ppInfoBuffer), Area );
|
||
|
||
//
|
||
// system access
|
||
//
|
||
|
||
INT Revision = 0;
|
||
INFCONTEXT InfLine;
|
||
|
||
if ( SetupFindFirstLine(hInf,L"Version",L"Revision",&InfLine) ) {
|
||
if ( !SetupGetIntField(&InfLine, 1, (INT *)&Revision) ) {
|
||
Revision = 0;
|
||
}
|
||
}
|
||
|
||
if ( Revision == 0) {
|
||
ObjectFlag = SCEINF_OBJECT_FLAG_OLDSDDL;
|
||
}
|
||
|
||
if ( Revision > SCE_TEMPLATE_MAX_SUPPORTED_VERSION ) {
|
||
ObjectFlag |= SCEINF_OBJECT_FLAG_UNKNOWN_VERSION;
|
||
}
|
||
|
||
if ( Area & AREA_SECURITY_POLICY ) {
|
||
|
||
rc = SceInfpGetSystemAccess(
|
||
hInf,
|
||
ObjectFlag,
|
||
*ppInfoBuffer,
|
||
Errlog
|
||
);
|
||
|
||
if( rc != SCESTATUS_SUCCESS )
|
||
goto Done;
|
||
|
||
//
|
||
// system auditing
|
||
//
|
||
rc = SceInfpGetAuditing(
|
||
hInf,
|
||
ObjectFlag,
|
||
*ppInfoBuffer,
|
||
Errlog
|
||
);
|
||
|
||
if( rc != SCESTATUS_SUCCESS )
|
||
goto Done;
|
||
|
||
//
|
||
// kerberos policy
|
||
//
|
||
rc = SceInfpGetKerberosPolicy(
|
||
hInf,
|
||
ObjectFlag,
|
||
&((*ppInfoBuffer)->pKerberosInfo),
|
||
Errlog
|
||
);
|
||
|
||
if( rc != SCESTATUS_SUCCESS )
|
||
goto Done;
|
||
|
||
//
|
||
// registry values
|
||
//
|
||
rc = SceInfpGetRegistryValues(
|
||
hInf,
|
||
ObjectFlag,
|
||
&((*ppInfoBuffer)->aRegValues),
|
||
&((*ppInfoBuffer)->RegValueCount),
|
||
Errlog
|
||
);
|
||
|
||
if( rc != SCESTATUS_SUCCESS )
|
||
goto Done;
|
||
}
|
||
|
||
//
|
||
// privilege/rights
|
||
//
|
||
if ( Area & AREA_PRIVILEGES ) {
|
||
|
||
rc = SceInfpGetPrivileges(
|
||
hInf,
|
||
TRUE,
|
||
&( (*ppInfoBuffer)->OtherInfo.scp.u.pInfPrivilegeAssignedTo ),
|
||
Errlog
|
||
);
|
||
|
||
if( rc != SCESTATUS_SUCCESS )
|
||
goto Done;
|
||
}
|
||
|
||
//
|
||
// account profiles list
|
||
//
|
||
|
||
if ( Area & AREA_USER_SETTINGS ) {
|
||
|
||
rc = SceInfpGetUserSettings(
|
||
hInf,
|
||
&( (*ppInfoBuffer)->OtherInfo.scp.pAccountProfiles ),
|
||
Errlog
|
||
);
|
||
|
||
if( rc != SCESTATUS_SUCCESS )
|
||
goto Done;
|
||
}
|
||
|
||
//
|
||
// group memberships
|
||
//
|
||
|
||
if ( Area & AREA_GROUP_MEMBERSHIP ) {
|
||
|
||
rc = SceInfpGetGroupMembership(
|
||
hInf,
|
||
&((*ppInfoBuffer)->pGroupMembership),
|
||
Errlog
|
||
);
|
||
|
||
if( rc != SCESTATUS_SUCCESS )
|
||
goto Done;
|
||
}
|
||
|
||
//
|
||
// registry keys security
|
||
//
|
||
|
||
if ( Area & AREA_REGISTRY_SECURITY ) {
|
||
|
||
rc = SceInfpGetObjects(
|
||
hInf,
|
||
szRegistryKeys,
|
||
ObjectFlag,
|
||
&((*ppInfoBuffer)->pRegistryKeys.pAllNodes),
|
||
Errlog
|
||
);
|
||
if ( rc != SCESTATUS_SUCCESS )
|
||
goto Done;
|
||
|
||
}
|
||
//
|
||
// system services
|
||
//
|
||
|
||
if ( Area & AREA_SYSTEM_SERVICE ) {
|
||
|
||
|
||
rc = SceInfpGetSystemServices(
|
||
hInf,
|
||
ObjectFlag,
|
||
&((*ppInfoBuffer)->pServices),
|
||
Errlog
|
||
);
|
||
|
||
if( rc != SCESTATUS_SUCCESS )
|
||
goto Done;
|
||
}
|
||
|
||
//
|
||
// file security
|
||
//
|
||
|
||
if ( Area & AREA_FILE_SECURITY ) {
|
||
|
||
rc = SceInfpGetObjects(
|
||
hInf,
|
||
szFileSecurity,
|
||
ObjectFlag,
|
||
&((*ppInfoBuffer)->pFiles.pAllNodes),
|
||
Errlog
|
||
);
|
||
if ( rc != SCESTATUS_SUCCESS )
|
||
goto Done;
|
||
|
||
}
|
||
#if 0
|
||
if ( Area & AREA_DS_OBJECTS ) {
|
||
|
||
rc = SceInfpGetObjects(
|
||
hInf,
|
||
szDSSecurity,
|
||
ObjectFlag | SCEINF_OBJECT_FLAG_DSOBJECT,
|
||
&((*ppInfoBuffer)->pDsObjects.pAllNodes),
|
||
Errlog
|
||
);
|
||
if ( rc != SCESTATUS_SUCCESS )
|
||
goto Done;
|
||
}
|
||
#endif
|
||
|
||
Done:
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
|
||
//
|
||
// need free memory because some fatal error happened
|
||
//
|
||
|
||
SceFreeMemory( (PVOID)(*ppInfoBuffer), Area );
|
||
if ( bFreeMem ) {
|
||
ScepFree(*ppInfoBuffer);
|
||
*ppInfoBuffer = NULL;
|
||
}
|
||
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetSystemAccess(
|
||
IN HINF hInf,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_PROFILE_INFO pSCEinfo,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/*++
|
||
Routine Description:
|
||
|
||
This routine retrieves system access area information from the SCP INF
|
||
file and stores in the output buffer pSCEinfo. System access information
|
||
includes information in [System Access] section.
|
||
|
||
Arguments:
|
||
|
||
hInf - INF handle to the profile
|
||
|
||
pSCEinfo - the output buffer to hold profile info.
|
||
|
||
Errlog - A buffer to hold all error codes/text encountered when
|
||
parsing the INF file. If Errlog is NULL, no further error
|
||
information is returned except the return DWORD
|
||
|
||
Return value:
|
||
|
||
SCESTATUS - SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_BAD_FORMAT
|
||
SCESTATUS_INVALID_DATA
|
||
|
||
--*/
|
||
|
||
{
|
||
INFCONTEXT InfLine;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
DWORD Keyvalue=0;
|
||
DWORD DataSize=0;
|
||
PWSTR Strvalue=NULL;
|
||
|
||
SCE_KEY_LOOKUP AccessSCPLookup[] = {
|
||
{(PWSTR)TEXT("MinimumPasswordAge"), offsetof(struct _SCE_PROFILE_INFO, MinimumPasswordAge), 'D'},
|
||
{(PWSTR)TEXT("MaximumPasswordAge"), offsetof(struct _SCE_PROFILE_INFO, MaximumPasswordAge), 'D'},
|
||
{(PWSTR)TEXT("MinimumPasswordLength"), offsetof(struct _SCE_PROFILE_INFO, MinimumPasswordLength), 'D'},
|
||
{(PWSTR)TEXT("PasswordComplexity"), offsetof(struct _SCE_PROFILE_INFO, PasswordComplexity), 'D'},
|
||
{(PWSTR)TEXT("PasswordHistorySize"), offsetof(struct _SCE_PROFILE_INFO, PasswordHistorySize), 'D'},
|
||
{(PWSTR)TEXT("LockoutBadCount"), offsetof(struct _SCE_PROFILE_INFO, LockoutBadCount), 'D'},
|
||
{(PWSTR)TEXT("ResetLockoutCount"), offsetof(struct _SCE_PROFILE_INFO, ResetLockoutCount), 'D'},
|
||
{(PWSTR)TEXT("LockoutDuration"), offsetof(struct _SCE_PROFILE_INFO, LockoutDuration), 'D'},
|
||
{(PWSTR)TEXT("RequireLogonToChangePassword"), offsetof(struct _SCE_PROFILE_INFO, RequireLogonToChangePassword), 'D'},
|
||
{(PWSTR)TEXT("ForceLogoffWhenHourExpire"), offsetof(struct _SCE_PROFILE_INFO, ForceLogoffWhenHourExpire), 'D'},
|
||
{(PWSTR)TEXT("NewAdministratorName"), 0, 'A'},
|
||
{(PWSTR)TEXT("NewGuestName"), 0, 'G'},
|
||
{(PWSTR)TEXT("SecureSystemPartition"), offsetof(struct _SCE_PROFILE_INFO, SecureSystemPartition), 'D'},
|
||
{(PWSTR)TEXT("ClearTextPassword"), offsetof(struct _SCE_PROFILE_INFO, ClearTextPassword), 'D'},
|
||
{(PWSTR)TEXT("LSAAnonymousNameLookup"), offsetof(struct _SCE_PROFILE_INFO, LSAAnonymousNameLookup), 'D'},
|
||
{(PWSTR)TEXT("EnableAdminAccount"), offsetof(struct _SCE_PROFILE_INFO, EnableAdminAccount), 'D'},
|
||
{(PWSTR)TEXT("EnableGuestAccount"), offsetof(struct _SCE_PROFILE_INFO, EnableGuestAccount), 'D'}
|
||
};
|
||
|
||
DWORD cAccess = sizeof(AccessSCPLookup) / sizeof(SCE_KEY_LOOKUP);
|
||
|
||
DWORD i;
|
||
UINT Offset;
|
||
WCHAR Keyname[SCE_KEY_MAX_LENGTH];
|
||
|
||
//
|
||
// Initialize to SCE_NO_VALUE
|
||
//
|
||
for ( i=0; i<cAccess; i++) {
|
||
if ( AccessSCPLookup[i].BufferType == 'D' )
|
||
*((DWORD *)((CHAR *)pSCEinfo+AccessSCPLookup[i].Offset)) = SCE_NO_VALUE;
|
||
|
||
}
|
||
//
|
||
// Locate the [System Access] section.
|
||
//
|
||
|
||
if(SetupFindFirstLine(hInf,szSystemAccess,NULL,&InfLine)) {
|
||
|
||
do {
|
||
|
||
//
|
||
// Get key names and its setting.
|
||
//
|
||
|
||
rc = SCESTATUS_SUCCESS;
|
||
memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
|
||
|
||
if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) ) {
|
||
|
||
for ( i=0; i<cAccess; i++) {
|
||
|
||
//
|
||
// get settings in AccessLookup table
|
||
//
|
||
Offset = AccessSCPLookup[i].Offset;
|
||
|
||
if (_wcsicmp(Keyname, AccessSCPLookup[i].KeyString ) == 0) {
|
||
|
||
switch ( AccessSCPLookup[i].BufferType ) {
|
||
case 'B':
|
||
|
||
//
|
||
// Int Field
|
||
//
|
||
Keyvalue = 0;
|
||
SetupGetIntField( &InfLine, 1, (INT *)&Keyvalue );
|
||
*((BOOL *)((CHAR *)pSCEinfo+Offset)) = Keyvalue ? TRUE : FALSE;
|
||
|
||
break;
|
||
case 'D':
|
||
|
||
//
|
||
// Int Field
|
||
//
|
||
|
||
if (SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue ) )
|
||
*((DWORD *)((CHAR *)pSCEinfo+Offset)) = (DWORD)Keyvalue;
|
||
|
||
break;
|
||
default:
|
||
|
||
//
|
||
// String Field - NewAdministratorName, or NewGuestName
|
||
//
|
||
|
||
if(SetupGetStringField(&InfLine,1,NULL,0,&DataSize) && DataSize > 0) {
|
||
|
||
Strvalue = (PWSTR)ScepAlloc( 0, (DataSize+1)*sizeof(WCHAR));
|
||
|
||
if( Strvalue == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
|
||
} else {
|
||
Strvalue[DataSize] = L'\0';
|
||
|
||
if(SetupGetStringField(&InfLine,1,Strvalue,DataSize, NULL)) {
|
||
if ( Strvalue[0] != L'\0' && Strvalue[0] != L' ') {
|
||
if (AccessSCPLookup[i].BufferType == 'A') // administrator
|
||
pSCEinfo->NewAdministratorName = Strvalue;
|
||
else // guest
|
||
pSCEinfo->NewGuestName = Strvalue;
|
||
} else
|
||
ScepFree(Strvalue);
|
||
Strvalue = NULL;
|
||
} else {
|
||
ScepFree( Strvalue );
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
}
|
||
}
|
||
} else
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
break;
|
||
}
|
||
|
||
break; // for loop
|
||
|
||
}
|
||
}
|
||
|
||
if ( i >= cAccess &&
|
||
!(ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION) ) {
|
||
|
||
//
|
||
// Did not find a match in the lookup table
|
||
//
|
||
|
||
ScepBuildErrorLogInfo( NO_ERROR,
|
||
Errlog,
|
||
SCEERR_NOT_EXPECTED,
|
||
Keyname,szSystemAccess );
|
||
|
||
}
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc),
|
||
Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
Keyname );
|
||
}
|
||
|
||
} else {
|
||
rc = SCESTATUS_INVALID_DATA;
|
||
ScepBuildErrorLogInfo( ERROR_INVALID_DATA, Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
szSystemAccess);
|
||
}
|
||
|
||
//
|
||
// if error happens, get out
|
||
//
|
||
if ( rc != SCESTATUS_SUCCESS )
|
||
return(rc);
|
||
|
||
} while(SetupFindNextLine(&InfLine,&InfLine));
|
||
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetUserSettings(
|
||
IN HINF hInf,
|
||
OUT PSCE_NAME_LIST *pProfileList,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine retrieves account profile list from the INF file (SCP) and
|
||
stores in the output buffer pProfileList.
|
||
|
||
Arguments:
|
||
|
||
hInf - INF handle to the profile
|
||
|
||
pProfileList - the output buffer to hold account profile list.
|
||
|
||
Errlog - The error list encountered inside inf processing.
|
||
|
||
Return value:
|
||
|
||
SCESTATUS - SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_BAD_FORMAT
|
||
SCESTATUS_INVALID_DATA
|
||
-- */
|
||
|
||
{
|
||
INFCONTEXT InfLine;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
WCHAR Keyname[SCE_KEY_MAX_LENGTH];
|
||
|
||
//
|
||
// [Account Profiles] section
|
||
//
|
||
|
||
if(SetupFindFirstLine(hInf,szAccountProfiles,NULL,&InfLine)) {
|
||
|
||
do {
|
||
|
||
memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
|
||
|
||
if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) ) {
|
||
|
||
//
|
||
// find a key name which is a profile name.
|
||
//
|
||
rc = ScepAddToNameList(pProfileList, Keyname, 0);
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo(ERROR_INVALID_DATA,
|
||
Errlog,
|
||
SCEERR_ADD,
|
||
Keyname );
|
||
}
|
||
} else {
|
||
ScepBuildErrorLogInfo(ERROR_BAD_FORMAT,
|
||
Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
L"profile name"
|
||
);
|
||
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
}
|
||
|
||
} while( rc == SCESTATUS_SUCCESS &&
|
||
SetupFindNextLine(&InfLine,&InfLine));
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetGroupMembership(
|
||
IN HINF hInf,
|
||
OUT PSCE_GROUP_MEMBERSHIP *pGroupMembership,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine retrieves group membership information from the SCP INF file
|
||
and stores in the output buffer pGroupMembership. Group membership info is
|
||
in [Group Membership] section.
|
||
|
||
Arguments:
|
||
|
||
hInf - INF handle to the profile
|
||
|
||
pGroupMembership - the output buffer to hold group membersip information.
|
||
|
||
Errlog - the error list for errors encountered in this routine.
|
||
|
||
Return value:
|
||
|
||
SCESTATUS - SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_BAD_FORMAT
|
||
SCESTATUS_INVALID_DATA
|
||
|
||
-- */
|
||
{
|
||
INFCONTEXT InfLine;
|
||
PSCE_NAME_LIST pMembers=NULL;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
PWSTR Keyname=NULL;
|
||
DWORD KeyLen;
|
||
DWORD ValueType;
|
||
PWSTR pTemp;
|
||
DWORD i;
|
||
DWORD cFields;
|
||
DWORD DataSize;
|
||
PWSTR Strvalue=NULL;
|
||
PWSTR GroupName=NULL;
|
||
DWORD GroupLen;
|
||
|
||
|
||
if ( pGroupMembership == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
LSA_HANDLE LsaHandle=NULL;
|
||
|
||
//
|
||
// Locate the [Group MemberShip] section.
|
||
//
|
||
|
||
if ( SetupFindFirstLine(hInf,szGroupMembership,NULL,&InfLine) ) {
|
||
|
||
//
|
||
// open lsa policy handle for sid/name lookup
|
||
//
|
||
|
||
rc = RtlNtStatusToDosError(
|
||
ScepOpenLsaPolicy(
|
||
POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION,
|
||
&LsaHandle,
|
||
TRUE
|
||
));
|
||
|
||
if ( ERROR_SUCCESS != rc ) {
|
||
ScepBuildErrorLogInfo(
|
||
rc,
|
||
Errlog,
|
||
SCEERR_ADD,
|
||
TEXT("LSA")
|
||
);
|
||
return(ScepDosErrorToSceStatus(rc));
|
||
}
|
||
|
||
PSID pSid=NULL;
|
||
|
||
do {
|
||
//
|
||
// Get group names.
|
||
//
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
|
||
if ( SetupGetStringField(&InfLine, 0, NULL, 0, &KeyLen) ) {
|
||
|
||
Keyname = (PWSTR)ScepAlloc( 0, (KeyLen+1)*sizeof(WCHAR));
|
||
if ( Keyname == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
goto Done;
|
||
}
|
||
Keyname[KeyLen] = L'\0';
|
||
|
||
if ( SetupGetStringField(&InfLine, 0, Keyname, KeyLen, NULL) ) {
|
||
//
|
||
// look for what kind of value this line is
|
||
//
|
||
pTemp = ScepWcstrr(Keyname, szMembers);
|
||
ValueType = 0;
|
||
|
||
if ( pTemp == NULL ) {
|
||
pTemp = ScepWcstrr(Keyname, szMemberof);
|
||
ValueType = 1;
|
||
}
|
||
|
||
if ( pTemp == NULL ) {
|
||
ScepBuildErrorLogInfo( ERROR_INVALID_DATA,
|
||
Errlog,
|
||
SCEERR_CANT_FIND_KEYWORD,
|
||
Keyname
|
||
);
|
||
rc = SCESTATUS_SUCCESS;
|
||
goto NextLine;
|
||
}
|
||
|
||
// terminiate Keyname for the group name only
|
||
*pTemp = L'\0';
|
||
|
||
if ( Keyname[0] == L'*' ) {
|
||
//
|
||
// *SID format, convert it into group name
|
||
//
|
||
if ( ConvertStringSidToSid( Keyname+1, &pSid) ) {
|
||
//
|
||
// if failed to convert from sid string to sid,
|
||
// treat it as any name
|
||
//
|
||
|
||
ScepConvertSidToName(
|
||
LsaHandle,
|
||
pSid,
|
||
TRUE,
|
||
&GroupName,
|
||
&GroupLen
|
||
);
|
||
LocalFree(pSid);
|
||
pSid = NULL;
|
||
}
|
||
}
|
||
|
||
if ( GroupName == NULL ) {
|
||
GroupLen = (DWORD) (pTemp - Keyname);
|
||
}
|
||
|
||
//
|
||
// String fields. Each string respresents a member or memberof name.
|
||
//
|
||
|
||
cFields = SetupGetFieldCount( &InfLine );
|
||
|
||
for ( i=0; i<cFields; i++) {
|
||
if(SetupGetStringField(&InfLine,i+1,NULL,0,&DataSize) && DataSize > 0 ) {
|
||
|
||
Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
|
||
(DataSize+1)*sizeof(WCHAR) );
|
||
|
||
if( Strvalue == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
} else {
|
||
if(SetupGetStringField(&InfLine,i+1,Strvalue,DataSize,NULL)) {
|
||
|
||
//
|
||
// Get a member name and save in the list
|
||
//
|
||
|
||
if ( Strvalue[0] == L'*' && DataSize > 0 ) {
|
||
//
|
||
// this is a SID format, should look it up
|
||
//
|
||
rc = ScepLookupSidStringAndAddToNameList(
|
||
LsaHandle,
|
||
&pMembers,
|
||
Strvalue, // +1,
|
||
DataSize // -1
|
||
);
|
||
|
||
} else {
|
||
|
||
rc = ScepAddToNameList(&pMembers,
|
||
Strvalue,
|
||
DataSize+1
|
||
);
|
||
}
|
||
}
|
||
|
||
ScepFree( Strvalue );
|
||
Strvalue = NULL;
|
||
}
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS)
|
||
break; // for loop
|
||
|
||
} // end of for loop
|
||
|
||
if ( rc == SCESTATUS_SUCCESS ) { // && pMembers != NULL ) {
|
||
//
|
||
// add this list to the group
|
||
//
|
||
rc = ScepAddToGroupMembership(
|
||
pGroupMembership,
|
||
GroupName ? GroupName : Keyname,
|
||
GroupLen, // wcslen(Keyname),
|
||
pMembers,
|
||
ValueType,
|
||
TRUE,
|
||
TRUE
|
||
);
|
||
if ( rc == SCESTATUS_SUCCESS )
|
||
pMembers = NULL;
|
||
|
||
}
|
||
// restore the character
|
||
*pTemp = L'_';
|
||
|
||
}
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
|
||
ScepBuildErrorLogInfo( ERROR_BAD_FORMAT,
|
||
Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
szGroupMembership
|
||
);
|
||
goto Done;
|
||
|
||
}
|
||
|
||
NextLine:
|
||
//
|
||
// Free pMembers, Keyname
|
||
//
|
||
ScepFreeNameList(pMembers);
|
||
pMembers = NULL;
|
||
|
||
ScepFree(Keyname);
|
||
Keyname = NULL;
|
||
|
||
if ( GroupName ) {
|
||
LocalFree(GroupName);
|
||
GroupName = NULL;
|
||
}
|
||
|
||
} while(SetupFindNextLine(&InfLine,&InfLine));
|
||
}
|
||
|
||
Done:
|
||
//
|
||
// Free pMembers, Keyname
|
||
//
|
||
ScepFreeNameList(pMembers);
|
||
|
||
if ( Keyname != NULL )
|
||
ScepFree(Keyname);
|
||
|
||
if ( Strvalue != NULL )
|
||
ScepFree( Strvalue );
|
||
|
||
if ( LsaHandle ) {
|
||
LsaClose(LsaHandle);
|
||
}
|
||
|
||
if ( GroupName ) {
|
||
LocalFree(GroupName);
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetObjects(
|
||
IN HINF hInf,
|
||
IN PCWSTR SectionName,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_OBJECT_ARRAY *pAllNodes,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine retrieves registry or files security information (names and
|
||
security descriptors) from the INF file (SCP and SAP) and stores in the
|
||
output buffer pSCEinfo. Registry information is in [SCRegistryKeysSecurity]
|
||
section. Files information is in [SSFileSecurity], [SCIntel86Only], and
|
||
[SCRISCOnly] sections. These sections have the same format, namely, 3 fields
|
||
on each line - name, workstaiton setting, and server setting.
|
||
|
||
Arguments:
|
||
|
||
hInf - INF handle to the profile
|
||
|
||
SectionName - the section name to retrieve.
|
||
|
||
pAllNodes - the output buffer to hold all objects in the section.
|
||
|
||
Errlog - the cummulative error list to hold errors encountered in this routine.
|
||
|
||
Return value:
|
||
|
||
SCESTATUS - SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_BAD_FORMAT
|
||
SCESTATUS_INVALID_DATA
|
||
-- */
|
||
{
|
||
INFCONTEXT InfLine;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
LONG i;
|
||
LONG nLines;
|
||
DWORD cFields;
|
||
|
||
if ( pAllNodes == NULL || SectionName == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
//
|
||
// count how many objects
|
||
//
|
||
nLines = SetupGetLineCount(hInf, SectionName );
|
||
if ( nLines == -1 ) {
|
||
// section not found
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
*pAllNodes = (PSCE_OBJECT_ARRAY)ScepAlloc(0, sizeof(SCE_OBJECT_ARRAY));
|
||
if ( *pAllNodes == NULL )
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
|
||
(*pAllNodes)->Count = nLines;
|
||
(*pAllNodes)->pObjectArray = NULL;
|
||
|
||
if ( nLines == 0 )
|
||
return(SCESTATUS_SUCCESS);
|
||
|
||
//
|
||
// allocate memory for all objects
|
||
//
|
||
(*pAllNodes)->pObjectArray = (PSCE_OBJECT_SECURITY *)ScepAlloc( LMEM_ZEROINIT,
|
||
nLines*sizeof(PSCE_OBJECT_SECURITY) );
|
||
if ( (*pAllNodes)->pObjectArray == NULL ) {
|
||
ScepFree(*pAllNodes);
|
||
*pAllNodes = NULL;
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
}
|
||
|
||
//
|
||
// Locate the section.
|
||
//
|
||
if ( SetupFindFirstLine(hInf,SectionName,NULL,&InfLine) ) {
|
||
i = 0;
|
||
TCHAR tmpBuf[MAX_PATH];
|
||
|
||
do {
|
||
//
|
||
// Get string fields. Don't care the key name or if it exist.
|
||
// Must have 3 fields each line for supported versions.
|
||
//
|
||
cFields = SetupGetFieldCount( &InfLine );
|
||
|
||
if ( cFields < 3 ) {
|
||
|
||
tmpBuf[0] = L'\0';
|
||
SetupGetStringField(&InfLine,1,tmpBuf,MAX_PATH,NULL);
|
||
|
||
ScepBuildErrorLogInfo( ERROR_INVALID_DATA,
|
||
Errlog,
|
||
SCEERR_OBJECT_FIELDS,
|
||
tmpBuf);
|
||
|
||
if (ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION) {
|
||
//
|
||
// maybe a new format for object,
|
||
// ignore this line
|
||
//
|
||
rc = SCESTATUS_SUCCESS;
|
||
goto NextLine;
|
||
|
||
} else {
|
||
rc = SCESTATUS_INVALID_DATA;
|
||
}
|
||
}
|
||
|
||
if ( SCESTATUS_SUCCESS == rc ) {
|
||
|
||
rc = SceInfpGetOneObjectSecurity(
|
||
&InfLine,
|
||
ObjectFlag,
|
||
( (*pAllNodes)->pObjectArray + i ),
|
||
Errlog
|
||
);
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
|
||
if ( rc == SCESTATUS_BAD_FORMAT ) {
|
||
|
||
ScepBuildErrorLogInfo( ERROR_BAD_FORMAT,
|
||
Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
SectionName);
|
||
}
|
||
|
||
break; // do..while loop
|
||
}
|
||
|
||
i++;
|
||
|
||
NextLine:
|
||
if ( i > nLines ) {
|
||
// more lines than allocated
|
||
rc = SCESTATUS_INVALID_DATA;
|
||
ScepBuildErrorLogInfo(ERROR_INVALID_DATA,
|
||
Errlog,
|
||
SCEERR_MORE_OBJECTS,
|
||
nLines
|
||
);
|
||
break;
|
||
}
|
||
|
||
} while(SetupFindNextLine(&InfLine,&InfLine));
|
||
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
// free memory
|
||
ScepFreeObjectSecurity( *pAllNodes );
|
||
// ScepFree( *pAllNodes );
|
||
*pAllNodes = NULL;
|
||
|
||
} else if ( ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION ) {
|
||
|
||
//
|
||
// reset the count because some lines may be skipped
|
||
//
|
||
(*pAllNodes)->Count = i;
|
||
}
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetOneObjectSecurity(
|
||
IN PINFCONTEXT pInfLine,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_OBJECT_SECURITY *ppObject,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine retrieves security setting for one object (a registry key,
|
||
or a file) from the INF file (SCP type). Each object in these sections
|
||
is represented by one line. Each object has 3 fields, a name, a status
|
||
flag, and security setting. This routine stores the output in buffer
|
||
ppObject.
|
||
|
||
Arguments:
|
||
|
||
pInfLine - Current line context from the INF file for one object
|
||
|
||
ppObject - Output buffer (tree root ) to hold the security settings for this line
|
||
|
||
Errlog - The cummulative error list for errors encountered in this routine
|
||
|
||
Return value:
|
||
|
||
SCESTATUS - SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_BAD_FORMAT
|
||
SCESTATUS_INVALID_DATA
|
||
-- */
|
||
{
|
||
DWORD cFields;
|
||
DWORD DataSize;
|
||
PWSTR Strvalue=NULL;
|
||
PWSTR SDspec=NULL;
|
||
DWORD SDsize;
|
||
DWORD Status=0;
|
||
PSECURITY_DESCRIPTOR pTempSD=NULL;
|
||
SECURITY_INFORMATION SeInfo;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
|
||
//
|
||
// The Registry/File INF layout must have 3 fields for each line.
|
||
// The first field is the key/file name, the 2nd field is status flag -
|
||
// ignore, or check, and the 3rd field is the security descriptor text
|
||
//
|
||
|
||
if ( ppObject == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
cFields = SetupGetFieldCount( pInfLine );
|
||
|
||
if ( cFields < 3 ) {
|
||
|
||
return(SCESTATUS_INVALID_DATA);
|
||
|
||
} else if(SetupGetStringField(pInfLine,1,NULL,0,&DataSize) && DataSize > 0 ) {
|
||
|
||
Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
|
||
(DataSize+1)*sizeof(WCHAR) );
|
||
if( Strvalue == NULL ) {
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
} else {
|
||
|
||
//
|
||
// the first field is the key/file name.
|
||
// The 2nd is a status flag.
|
||
// The 3rd field is the security descriptor text
|
||
//
|
||
|
||
if( SetupGetStringField(pInfLine,1,Strvalue,DataSize,NULL) &&
|
||
SetupGetIntField( pInfLine, 2, (INT *)&Status ) &&
|
||
// SetupGetStringField(pInfLine,3,NULL,0,&SDsize) ) {
|
||
SetupGetMultiSzField(pInfLine,3,NULL,0,&SDsize) ) {
|
||
|
||
SDspec = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
|
||
(SDsize+1)*sizeof(WCHAR)
|
||
);
|
||
if( SDspec == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
goto Done;
|
||
}
|
||
|
||
// if(SetupGetStringField(pInfLine,3,SDspec,SDsize,NULL)) {
|
||
if(SetupGetMultiSzField(pInfLine,3,SDspec,SDsize,NULL)) {
|
||
|
||
//
|
||
// convert the multi-sz delimiter to space, if there is any
|
||
//
|
||
if ( cFields > 3 ) {
|
||
ScepConvertMultiSzToDelim(SDspec, SDsize, L'\0', L' ');
|
||
}
|
||
|
||
if ( ObjectFlag & SCEINF_OBJECT_FLAG_OLDSDDL ) {
|
||
|
||
ScepConvertToSDDLFormat(SDspec, SDsize);
|
||
}
|
||
|
||
//
|
||
// Convert the text to real security descriptors
|
||
//
|
||
|
||
rc = ConvertTextSecurityDescriptor(
|
||
SDspec,
|
||
&pTempSD,
|
||
&SDsize,
|
||
&SeInfo
|
||
);
|
||
|
||
if (rc == NO_ERROR) {
|
||
// create a new object node to hold these info.
|
||
|
||
if ( !(ObjectFlag & SCEINF_OBJECT_FLAG_DSOBJECT) ) {
|
||
ScepChangeAclRevision(pTempSD, ACL_REVISION);
|
||
}
|
||
|
||
*ppObject = (PSCE_OBJECT_SECURITY)ScepAlloc(0, sizeof(SCE_OBJECT_SECURITY));
|
||
if ( *ppObject == NULL )
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
else {
|
||
(*ppObject)->Name = Strvalue;
|
||
(*ppObject)->Status = (BYTE)Status;
|
||
(*ppObject)->IsContainer = TRUE; // always default to TRUE
|
||
(*ppObject)->pSecurityDescriptor = pTempSD;
|
||
(*ppObject)->SeInfo = SeInfo;
|
||
pTempSD = NULL;
|
||
// (*ppObject)->SDspec = SDspec;
|
||
// (*ppObject)->SDsize = SDsize;
|
||
Strvalue = NULL;
|
||
// SDspec = NULL;
|
||
|
||
rc = SCESTATUS_SUCCESS;
|
||
}
|
||
} else {
|
||
ScepBuildErrorLogInfo(rc,
|
||
Errlog,
|
||
SCEERR_BUILD_SD,
|
||
Strvalue);
|
||
|
||
rc = ScepDosErrorToSceStatus(rc);
|
||
}
|
||
|
||
} else
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
} else
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
}
|
||
} else
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
|
||
Done:
|
||
if ( Strvalue != NULL )
|
||
ScepFree( Strvalue );
|
||
|
||
if ( SDspec != NULL )
|
||
ScepFree( SDspec );
|
||
|
||
if ( pTempSD != NULL )
|
||
ScepFree( pTempSD );
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetAuditing(
|
||
IN HINF hInf,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_PROFILE_INFO pSCEinfo,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine retrieves system auditing information from the INF file and
|
||
storesin the output buffer pSCEinfo. The auditing information is stored in
|
||
[System Log], [Security Log], [Application Log], [Event Audit],
|
||
[Registry Audit], and [File Audit] sections.
|
||
|
||
Arguments:
|
||
|
||
hInf - INF handle to the profile
|
||
|
||
pSCEinfo - the output buffer to hold SCP profile info.
|
||
|
||
Errlog - The cummulative error list to hold errors encountered in this routine.
|
||
|
||
Return value:
|
||
|
||
SCESTATUS - SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_BAD_FORMAT
|
||
SCESTATUS_INVALID_DATA
|
||
-- */
|
||
{
|
||
|
||
INFCONTEXT InfLine;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
DWORD Keyvalue;
|
||
WCHAR Keyname[SCE_KEY_MAX_LENGTH];
|
||
DWORD LogSize;
|
||
DWORD Periods;
|
||
DWORD RetentionDays;
|
||
DWORD RestrictGuest;
|
||
PCWSTR szAuditLog;
|
||
DWORD i;
|
||
|
||
|
||
for ( i=0; i<3; i++ ) {
|
||
|
||
//
|
||
// Get Event Log setting for system log, security log and application log
|
||
//
|
||
|
||
switch (i) {
|
||
case 0:
|
||
szAuditLog = szAuditSystemLog;
|
||
break;
|
||
case 1:
|
||
szAuditLog = szAuditSecurityLog;
|
||
break;
|
||
default:
|
||
szAuditLog = szAuditApplicationLog;
|
||
break;
|
||
}
|
||
|
||
LogSize=SCE_NO_VALUE;
|
||
Periods=SCE_NO_VALUE;
|
||
RetentionDays=SCE_NO_VALUE;
|
||
RestrictGuest=SCE_NO_VALUE;
|
||
|
||
rc = SceInfpGetAuditLogSetting(
|
||
hInf,
|
||
szAuditLog,
|
||
ObjectFlag,
|
||
&LogSize,
|
||
&Periods,
|
||
&RetentionDays,
|
||
&RestrictGuest,
|
||
Errlog
|
||
);
|
||
|
||
if ( rc != SCESTATUS_SUCCESS )
|
||
return(rc);
|
||
|
||
pSCEinfo->MaximumLogSize[i] = LogSize;
|
||
pSCEinfo->AuditLogRetentionPeriod[i] = Periods;
|
||
pSCEinfo->RetentionDays[i] = RetentionDays;
|
||
pSCEinfo->RestrictGuestAccess[i] = RestrictGuest;
|
||
}
|
||
|
||
//
|
||
// Get Audit Event info
|
||
//
|
||
if ( SetupFindFirstLine(hInf,szAuditEvent,NULL,&InfLine) ) {
|
||
|
||
do {
|
||
|
||
memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
|
||
|
||
if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) &&
|
||
SetupGetIntField( &InfLine, 1, (INT *)&Keyvalue )
|
||
) {
|
||
|
||
if ( _wcsicmp(Keyname, TEXT("AuditSystemEvents")) == 0 ) {
|
||
|
||
pSCEinfo->AuditSystemEvents = Keyvalue;
|
||
|
||
} else if ( _wcsicmp(Keyname, TEXT("AuditLogonEvents")) == 0 ) {
|
||
|
||
pSCEinfo->AuditLogonEvents = Keyvalue;
|
||
|
||
} else if ( _wcsicmp(Keyname, TEXT("AuditObjectAccess")) == 0 ) {
|
||
|
||
pSCEinfo->AuditObjectAccess = Keyvalue;
|
||
|
||
} else if ( _wcsicmp(Keyname, TEXT("AuditPrivilegeUse")) == 0 ) {
|
||
|
||
pSCEinfo->AuditPrivilegeUse = Keyvalue;
|
||
|
||
} else if ( _wcsicmp(Keyname, TEXT("AuditPolicyChange")) == 0 ) {
|
||
|
||
pSCEinfo->AuditPolicyChange = Keyvalue;
|
||
|
||
} else if ( _wcsicmp(Keyname, TEXT("AuditAccountManage")) == 0 ) {
|
||
|
||
pSCEinfo->AuditAccountManage = Keyvalue;
|
||
|
||
} else if ( _wcsicmp(Keyname, TEXT("AuditProcessTracking")) == 0 ) {
|
||
|
||
pSCEinfo->AuditProcessTracking = Keyvalue;
|
||
|
||
} else if ( _wcsicmp(Keyname, TEXT("AuditDSAccess")) == 0 ) {
|
||
|
||
pSCEinfo->AuditDSAccess = Keyvalue;
|
||
|
||
} else if ( _wcsicmp(Keyname, TEXT("AuditAccountLogon")) == 0 ) {
|
||
|
||
pSCEinfo->AuditAccountLogon = Keyvalue;
|
||
|
||
} else if ( _wcsicmp(Keyname, TEXT("CrashOnAuditFull")) == 0 ) {
|
||
|
||
pSCEinfo->CrashOnAuditFull = Keyvalue;
|
||
|
||
} else if ( !(ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION) ) {
|
||
|
||
ScepBuildErrorLogInfo(0, Errlog,
|
||
SCEERR_NOT_EXPECTED,
|
||
Keyname, szAuditEvent);
|
||
}
|
||
|
||
} else {
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
ScepBuildErrorLogInfo( ERROR_BAD_FORMAT,
|
||
Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
szAuditEvent
|
||
);
|
||
return(rc);
|
||
}
|
||
} while(SetupFindNextLine(&InfLine, &InfLine));
|
||
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetAuditLogSetting(
|
||
IN HINF hInf,
|
||
IN PCWSTR SectionName,
|
||
IN DWORD ObjectFlag,
|
||
OUT PDWORD LogSize,
|
||
OUT PDWORD Periods,
|
||
OUT PDWORD RetentionDays,
|
||
OUT PDWORD RestrictGuest,
|
||
IN OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine retrieves audit log setting from the INF file based on the
|
||
SectionName passed in. The audit log settings include MaximumSize,
|
||
RetentionPeriod and RetentionDays. There are 3 different logs (system,
|
||
security, and application) which all have the same setting. The information
|
||
returned in in LogSize, Periods, RetentionDays. These 3 output arguments will
|
||
be reset to SCE_NO_VALUE at the begining of the routine. So if error
|
||
occurs after the reset, the original values won't be set back.
|
||
|
||
Arguments:
|
||
|
||
hInf - INF handle to the profile
|
||
|
||
SectionName - Log section name (SAdtSystemLog, SAdtSecurityLog, SAdtApplicationLog)
|
||
|
||
LogSize - The maximum size of the log
|
||
|
||
Periods - The retention period of the log
|
||
|
||
RetentionDays - The number of days for log retention
|
||
|
||
Return value:
|
||
|
||
SCESTATUS - SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_BAD_FORMAT
|
||
SCESTATUS_INVALID_DATA
|
||
-- */
|
||
{
|
||
|
||
INFCONTEXT InfLine;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
DWORD Keyvalue;
|
||
WCHAR Keyname[SCE_KEY_MAX_LENGTH];
|
||
|
||
*LogSize = SCE_NO_VALUE;
|
||
*Periods = SCE_NO_VALUE;
|
||
*RetentionDays = SCE_NO_VALUE;
|
||
|
||
if ( SetupFindFirstLine(hInf,SectionName,NULL,&InfLine) ) {
|
||
|
||
do {
|
||
|
||
memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
|
||
|
||
if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) &&
|
||
SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue)
|
||
) {
|
||
|
||
if ( _wcsicmp(Keyname, TEXT("MaximumLogSize")) == 0 )
|
||
*LogSize = Keyvalue;
|
||
else if (_wcsicmp(Keyname, TEXT("AuditLogRetentionPeriod")) == 0 )
|
||
*Periods = Keyvalue;
|
||
else if (_wcsicmp(Keyname, TEXT("RetentionDays")) == 0 )
|
||
*RetentionDays = Keyvalue;
|
||
else if (_wcsicmp(Keyname, TEXT("RestrictGuestAccess")) == 0 )
|
||
*RestrictGuest = Keyvalue;
|
||
else if ( !(ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION) ) {
|
||
ScepBuildErrorLogInfo(0, Errlog,
|
||
SCEERR_NOT_EXPECTED,
|
||
Keyname, SectionName);
|
||
}
|
||
|
||
} else {
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
ScepBuildErrorLogInfo( ERROR_BAD_FORMAT, Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
SectionName
|
||
);
|
||
}
|
||
if ( rc != SCESTATUS_SUCCESS )
|
||
break;
|
||
|
||
} while(SetupFindNextLine(&InfLine, &InfLine));
|
||
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetUserSection(
|
||
IN HINF hInf,
|
||
IN PWSTR Name,
|
||
OUT PSCE_USER_PROFILE *pOneProfile,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
{
|
||
INFCONTEXT InfLine;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
PSCE_LOGON_HOUR pLogonHour=NULL;
|
||
PWSTR SectionName=NULL;
|
||
WCHAR Keyname[SCE_KEY_MAX_LENGTH];
|
||
DWORD Keyvalue;
|
||
DWORD Keyvalue2;
|
||
PWSTR Strvalue=NULL;
|
||
DWORD DataSize;
|
||
DWORD i, cFields;
|
||
LONG i1,i2;
|
||
PSECURITY_DESCRIPTOR pTempSD=NULL;
|
||
SECURITY_INFORMATION SeInfo;
|
||
|
||
|
||
|
||
if ( hInf == NULL || Name == NULL || pOneProfile == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
SectionName = (PWSTR)ScepAlloc( LMEM_ZEROINIT, (wcslen(Name)+9)*sizeof(WCHAR));
|
||
if ( SectionName == NULL )
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
|
||
swprintf(SectionName, L"UserProfile %s", Name );
|
||
|
||
if ( SetupFindFirstLine(hInf, SectionName, NULL, &InfLine) ) {
|
||
|
||
//
|
||
// find the detail profile section. Allocate memory
|
||
//
|
||
*pOneProfile = (PSCE_USER_PROFILE)ScepAlloc( 0, sizeof(SCE_USER_PROFILE));
|
||
if ( *pOneProfile == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
goto Done;
|
||
}
|
||
//
|
||
// initialize
|
||
//
|
||
(*pOneProfile)->Type = SCE_STRUCT_PROFILE;
|
||
(*pOneProfile)->ForcePasswordChange = SCE_NO_VALUE;
|
||
(*pOneProfile)->DisallowPasswordChange = SCE_NO_VALUE;
|
||
(*pOneProfile)->NeverExpirePassword = SCE_NO_VALUE;
|
||
(*pOneProfile)->AccountDisabled = SCE_NO_VALUE;
|
||
(*pOneProfile)->UserProfile = NULL;
|
||
(*pOneProfile)->LogonScript = NULL;
|
||
(*pOneProfile)->HomeDir = NULL;
|
||
(*pOneProfile)->pLogonHours = NULL;
|
||
(*pOneProfile)->pWorkstations.Length = 0;
|
||
(*pOneProfile)->pWorkstations.MaximumLength = 0;
|
||
(*pOneProfile)->pWorkstations.Buffer = NULL;
|
||
(*pOneProfile)->pGroupsBelongsTo = NULL;
|
||
(*pOneProfile)->pAssignToUsers = NULL;
|
||
(*pOneProfile)->pHomeDirSecurity = NULL;
|
||
(*pOneProfile)->HomeSeInfo = 0;
|
||
(*pOneProfile)->pTempDirSecurity = NULL;
|
||
(*pOneProfile)->TempSeInfo = 0;
|
||
|
||
|
||
do {
|
||
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
|
||
|
||
if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) ) {
|
||
|
||
if ( _wcsicmp(Keyname, TEXT("DisallowPasswordChange")) == 0 ) {
|
||
//
|
||
// Int Field
|
||
//
|
||
if ( SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue ) ) {
|
||
|
||
(*pOneProfile)->DisallowPasswordChange = Keyvalue;
|
||
rc = SCESTATUS_SUCCESS;
|
||
}
|
||
goto NextLine;
|
||
|
||
}
|
||
if ( _wcsicmp(Keyname, TEXT("PasswordChangeStyle")) == 0 ) {
|
||
//
|
||
// Int Field
|
||
//
|
||
if ( SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue ) ) {
|
||
|
||
rc = SCESTATUS_SUCCESS;
|
||
switch (Keyvalue ) {
|
||
case 1:
|
||
(*pOneProfile)->NeverExpirePassword = 1;
|
||
(*pOneProfile)->ForcePasswordChange = 0;
|
||
break;
|
||
case 2:
|
||
(*pOneProfile)->NeverExpirePassword = 0;
|
||
(*pOneProfile)->ForcePasswordChange = 1;
|
||
break;
|
||
case 0:
|
||
// SCE_NO_VALUE for both. same as initialization
|
||
break;
|
||
default:
|
||
rc = SCESTATUS_INVALID_DATA;
|
||
break;
|
||
}
|
||
}
|
||
goto NextLine;
|
||
|
||
}
|
||
if ( _wcsicmp(Keyname, TEXT("AccountDisabled")) == 0 ) {
|
||
//
|
||
// Int Field
|
||
//
|
||
if ( SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue ) ) {
|
||
|
||
(*pOneProfile)->AccountDisabled = Keyvalue == 0 ? 0 : 1;
|
||
rc = SCESTATUS_SUCCESS;
|
||
}
|
||
goto NextLine;
|
||
|
||
}
|
||
if ( _wcsicmp(Keyname, TEXT("UserProfile")) == 0 ) {
|
||
//
|
||
// String Field
|
||
//
|
||
if( SetupGetStringField(&InfLine,1,NULL,0,&DataSize) ) {
|
||
|
||
Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
|
||
(DataSize+1)*sizeof(WCHAR));
|
||
|
||
if( Strvalue == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
} else {
|
||
if(SetupGetStringField(&InfLine,1,Strvalue,DataSize,NULL)) {
|
||
|
||
(*pOneProfile)->UserProfile = Strvalue;
|
||
rc = SCESTATUS_SUCCESS;
|
||
|
||
} else
|
||
ScepFree( Strvalue );
|
||
}
|
||
}
|
||
goto NextLine;
|
||
}
|
||
if ( _wcsicmp(Keyname, TEXT("LogonScript")) == 0 ) {
|
||
//
|
||
// String Field
|
||
//
|
||
if(SetupGetStringField(&InfLine,1,NULL,0,&DataSize) ) {
|
||
|
||
Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
|
||
(DataSize+1)*sizeof(WCHAR));
|
||
|
||
if( Strvalue == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
} else {
|
||
if(SetupGetStringField(&InfLine,1,Strvalue,DataSize,NULL)) {
|
||
|
||
(*pOneProfile)->LogonScript = Strvalue;
|
||
rc = SCESTATUS_SUCCESS;
|
||
} else
|
||
ScepFree( Strvalue );
|
||
}
|
||
}
|
||
goto NextLine;
|
||
}
|
||
if ( _wcsicmp(Keyname, TEXT("HomeDir")) == 0 ) {
|
||
//
|
||
// String Field
|
||
//
|
||
if(SetupGetStringField(&InfLine,1,NULL,0,&DataSize) ) {
|
||
|
||
Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
|
||
(DataSize+1)*sizeof(WCHAR));
|
||
|
||
if( Strvalue == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
} else {
|
||
if(SetupGetStringField(&InfLine,1,Strvalue,DataSize,NULL)) {
|
||
(*pOneProfile)->HomeDir = Strvalue;
|
||
rc = SCESTATUS_SUCCESS;
|
||
} else
|
||
ScepFree( Strvalue );
|
||
}
|
||
}
|
||
goto NextLine;
|
||
}
|
||
if ( _wcsicmp(Keyname, TEXT("LogonHours")) == 0 ) {
|
||
|
||
//
|
||
// Int fields (in pairs). Each pair represents a logon hour range
|
||
//
|
||
|
||
cFields = SetupGetFieldCount( &InfLine );
|
||
|
||
//
|
||
// The first field is the key. Logon hour ranges must be in pairs
|
||
//
|
||
|
||
if ( cFields < 2 ) {
|
||
pLogonHour = (PSCE_LOGON_HOUR)ScepAlloc( LMEM_ZEROINIT,
|
||
sizeof(SCE_LOGON_HOUR) );
|
||
if ( pLogonHour == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
goto NextLine;
|
||
}
|
||
pLogonHour->Start = SCE_NO_VALUE;
|
||
pLogonHour->End = SCE_NO_VALUE;
|
||
pLogonHour->Next = (*pOneProfile)->pLogonHours;
|
||
(*pOneProfile)->pLogonHours = pLogonHour;
|
||
|
||
rc = SCESTATUS_SUCCESS;
|
||
goto NextLine;
|
||
}
|
||
for ( i=0; i<cFields; i+=2) {
|
||
|
||
if ( SetupGetIntField( &InfLine, i+1, (INT *)&Keyvalue ) &&
|
||
SetupGetIntField( &InfLine, i+2, (INT *)&Keyvalue2 ) ) {
|
||
//
|
||
// find a pair of logon hours.
|
||
//
|
||
pLogonHour = (PSCE_LOGON_HOUR)ScepAlloc( LMEM_ZEROINIT,
|
||
sizeof(SCE_LOGON_HOUR) );
|
||
if ( pLogonHour == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
goto NextLine;
|
||
}
|
||
pLogonHour->Start = Keyvalue;
|
||
pLogonHour->End = Keyvalue2;
|
||
pLogonHour->Next = (*pOneProfile)->pLogonHours;
|
||
|
||
(*pOneProfile)->pLogonHours = pLogonHour;
|
||
rc = SCESTATUS_SUCCESS;
|
||
|
||
} else
|
||
rc = SCESTATUS_INVALID_DATA;
|
||
}
|
||
goto NextLine;
|
||
}
|
||
|
||
if ( _wcsicmp(Keyname, TEXT("Workstations")) == 0 ) {
|
||
|
||
if( SetupGetMultiSzField(&InfLine,1,NULL,0,&DataSize) ) {
|
||
|
||
Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
|
||
(DataSize+1)*sizeof(WCHAR));
|
||
|
||
if( Strvalue == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
} else {
|
||
if(SetupGetMultiSzField(&InfLine,1,Strvalue,DataSize,NULL)) {
|
||
(*pOneProfile)->pWorkstations.Length = (USHORT)(DataSize*sizeof(WCHAR));
|
||
(*pOneProfile)->pWorkstations.Buffer = Strvalue;
|
||
Strvalue = NULL;
|
||
rc = SCESTATUS_SUCCESS;
|
||
} else {
|
||
rc = SCESTATUS_INVALID_DATA;
|
||
ScepFree(Strvalue);
|
||
}
|
||
}
|
||
}
|
||
goto NextLine;
|
||
}
|
||
|
||
i1 = i2 = 0;
|
||
|
||
if ( (i1=_wcsicmp(Keyname, TEXT("GroupsBelongsTo"))) == 0 ||
|
||
(i2=_wcsicmp(Keyname, TEXT("AssignToUsers"))) == 0 ) {
|
||
|
||
//
|
||
// String fields. Each string respresents a workstation name,
|
||
// a group name, or a user name. These names are saved in PSCE_NAME_LIST
|
||
//
|
||
|
||
cFields = SetupGetFieldCount( &InfLine );
|
||
|
||
for ( i=0; i<cFields; i++) {
|
||
|
||
if( SetupGetStringField(&InfLine,i+1,NULL,0,&DataSize) && DataSize > 0 ) {
|
||
|
||
if ( DataSize <= 1) {
|
||
rc = SCESTATUS_SUCCESS;
|
||
continue;
|
||
}
|
||
|
||
Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
|
||
(DataSize+1)*sizeof(WCHAR));
|
||
|
||
if( Strvalue == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
} else {
|
||
if(SetupGetStringField(&InfLine,i+1,Strvalue,DataSize,NULL)) {
|
||
//
|
||
// Save information in a name list
|
||
//
|
||
if ( i1 == 0) {
|
||
rc = ScepAddToNameList(&((*pOneProfile)->pGroupsBelongsTo),
|
||
Strvalue,
|
||
DataSize+1
|
||
);
|
||
} else {
|
||
rc = ScepAddToNameList(&((*pOneProfile)->pAssignToUsers),
|
||
Strvalue,
|
||
DataSize+1
|
||
);
|
||
}
|
||
if ( rc != NO_ERROR )
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
}
|
||
ScepFree( Strvalue );
|
||
}
|
||
}
|
||
if ( rc != SCESTATUS_SUCCESS)
|
||
break; // for loop
|
||
}
|
||
goto NextLine;
|
||
}
|
||
|
||
i1 = i2 = 0;
|
||
|
||
if ( (i1=_wcsicmp(Keyname, TEXT("HomeDirSecurity"))) == 0 ||
|
||
(i2=_wcsicmp(Keyname, TEXT("TempDirSecurity"))) == 0 ) {
|
||
|
||
// if(SetupGetStringField(&InfLine,1,NULL,0,&DataSize) && DataSize > 0 ) {
|
||
if(SetupGetMultiSzField(&InfLine,1,NULL,0,&DataSize) && DataSize > 0 ) {
|
||
|
||
Strvalue = (PWSTR)ScepAlloc( 0, (DataSize+1)*sizeof(WCHAR));
|
||
if ( Strvalue == NULL )
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
else {
|
||
// if(SetupGetStringField(&InfLine,1,Strvalue,DataSize,NULL)) {
|
||
if(SetupGetMultiSzField(&InfLine,1,Strvalue,DataSize,NULL)) {
|
||
//
|
||
// convert multi-sz to space
|
||
//
|
||
if ( SetupGetFieldCount( &InfLine ) > 1 ) {
|
||
ScepConvertMultiSzToDelim(Strvalue, DataSize, L'\0', L' ');
|
||
}
|
||
//
|
||
// Convert the text to real security descriptors
|
||
//
|
||
rc = ConvertTextSecurityDescriptor(
|
||
Strvalue,
|
||
&pTempSD,
|
||
&Keyvalue2,
|
||
&SeInfo
|
||
);
|
||
|
||
if (rc == NO_ERROR) {
|
||
|
||
ScepChangeAclRevision(pTempSD, ACL_REVISION);
|
||
|
||
if ( i1 == 0 ) {
|
||
(*pOneProfile)->pHomeDirSecurity = pTempSD;
|
||
(*pOneProfile)->HomeSeInfo = SeInfo;
|
||
} else {
|
||
(*pOneProfile)->pTempDirSecurity = pTempSD;
|
||
(*pOneProfile)->TempSeInfo = SeInfo;
|
||
}
|
||
pTempSD = NULL;
|
||
} else {
|
||
ScepBuildErrorLogInfo(
|
||
rc,
|
||
Errlog,
|
||
SCEERR_BUILD_SD,
|
||
Keyname //Strvalue
|
||
);
|
||
rc = ScepDosErrorToSceStatus(rc);
|
||
}
|
||
|
||
} else
|
||
rc = SCESTATUS_INVALID_DATA;
|
||
|
||
ScepFree(Strvalue);
|
||
}
|
||
}
|
||
goto NextLine;
|
||
}
|
||
|
||
//
|
||
// no string matched. ignore
|
||
//
|
||
|
||
ScepBuildErrorLogInfo(
|
||
NO_ERROR,
|
||
Errlog,
|
||
SCEERR_NOT_EXPECTED,
|
||
Keyname, SectionName);
|
||
rc = SCESTATUS_SUCCESS;
|
||
|
||
}
|
||
NextLine:
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
|
||
ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc),
|
||
Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
SectionName
|
||
);
|
||
goto Done;
|
||
}
|
||
|
||
} while(SetupFindNextLine(&InfLine,&InfLine));
|
||
}
|
||
|
||
Done:
|
||
|
||
// free memory
|
||
|
||
if ( SectionName != NULL )
|
||
ScepFree(SectionName);
|
||
|
||
if ( pTempSD != NULL )
|
||
ScepFree( pTempSD );
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
// free pOneProfile memory
|
||
SceFreeMemory( *pOneProfile, 0 );
|
||
*pOneProfile = NULL;
|
||
}
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
SCESTATUS
|
||
SceInfpGetDescription(
|
||
IN HINF hInf,
|
||
OUT PWSTR *Description
|
||
)
|
||
{
|
||
INFCONTEXT InfLine;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
DWORD LineLen, Len;
|
||
DWORD TotalLen=0;
|
||
DWORD i, cFields;
|
||
|
||
if(SetupFindFirstLine(hInf,szDescription,NULL,&InfLine)) {
|
||
|
||
do {
|
||
|
||
cFields = SetupGetFieldCount( &InfLine );
|
||
|
||
for ( i=0; i<cFields && rc==SCESTATUS_SUCCESS; i++) {
|
||
//
|
||
// count the total length of the description.
|
||
//
|
||
if ( !SetupGetStringField(&InfLine, i+1, NULL, 0, &LineLen) ) {
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
}
|
||
TotalLen += LineLen+1;
|
||
LineLen = 0;
|
||
}
|
||
if ( rc != SCESTATUS_SUCCESS )
|
||
break;
|
||
} while ( SetupFindNextLine(&InfLine,&InfLine) );
|
||
|
||
if ( rc == SCESTATUS_SUCCESS && TotalLen > 0 ) {
|
||
//
|
||
// allocate memory for the return buffer
|
||
//
|
||
*Description = (PWSTR)ScepAlloc( LMEM_ZEROINIT, (TotalLen+1)*sizeof(WCHAR));
|
||
if ( *Description == NULL )
|
||
return( SCESTATUS_NOT_ENOUGH_RESOURCE );
|
||
|
||
// re-position to the first line
|
||
SetupFindFirstLine(hInf,szDescription,NULL,&InfLine);
|
||
|
||
Len = 0;
|
||
LineLen = 0;
|
||
|
||
do {
|
||
//
|
||
// read each line in the section and append to the end of the buffer
|
||
// note: the required size returned from SetupGetStringField already
|
||
// has one more character space.
|
||
//
|
||
cFields = SetupGetFieldCount( &InfLine );
|
||
|
||
for ( i=0; i<cFields && rc==SCESTATUS_SUCCESS; i++) {
|
||
if ( !SetupGetStringField(&InfLine, i+1,
|
||
*Description+Len, TotalLen-Len, &LineLen) ) {
|
||
rc = SCESTATUS_INVALID_DATA;
|
||
}
|
||
if ( i == cFields-1)
|
||
*(*Description+Len+LineLen-1) = L' ';
|
||
else
|
||
*(*Description+Len+LineLen-1) = L',';
|
||
Len += LineLen;
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS )
|
||
break;
|
||
} while ( SetupFindNextLine(&InfLine,&InfLine) );
|
||
|
||
}
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
// if error occurs, free memory
|
||
ScepFree(*Description);
|
||
*Description = NULL;
|
||
}
|
||
|
||
} else {
|
||
rc = SCESTATUS_RECORD_NOT_FOUND;
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetSystemServices(
|
||
IN HINF hInf,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_SERVICES *pServiceList,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/*
|
||
Routine Description:
|
||
|
||
Get the list of services with startup status and security descriptors
|
||
in the inf file
|
||
|
||
Arguments:
|
||
|
||
Return Value:
|
||
|
||
*/
|
||
{
|
||
INFCONTEXT InfLine;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
PWSTR Keyname=NULL;
|
||
DWORD KeyLen;
|
||
DWORD Status;
|
||
|
||
DWORD DataSize;
|
||
PWSTR Strvalue=NULL;
|
||
SECURITY_INFORMATION SeInfo;
|
||
PSECURITY_DESCRIPTOR pSecurityDescriptor=NULL;
|
||
DWORD cFields=0;
|
||
|
||
if ( pServiceList == NULL )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
//
|
||
// Locate the [Service General Setting] section.
|
||
//
|
||
|
||
if ( SetupFindFirstLine(hInf,szServiceGeneral,NULL,&InfLine) ) {
|
||
|
||
TCHAR tmpBuf[MAX_PATH];
|
||
do {
|
||
//
|
||
// Get service names.
|
||
//
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
|
||
cFields = SetupGetFieldCount( &InfLine );
|
||
|
||
if ( cFields < 3 ) {
|
||
|
||
tmpBuf[0] = L'\0';
|
||
SetupGetStringField(&InfLine,1,tmpBuf,MAX_PATH,NULL);
|
||
|
||
ScepBuildErrorLogInfo( ERROR_INVALID_DATA,
|
||
Errlog,
|
||
SCEERR_OBJECT_FIELDS,
|
||
tmpBuf);
|
||
|
||
if ( ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION ) {
|
||
//
|
||
// a newer version of template, ignore this line
|
||
//
|
||
rc = SCESTATUS_SUCCESS;
|
||
goto NextLine;
|
||
} else {
|
||
//
|
||
// bad format, quit
|
||
//
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
if ( SetupGetStringField(&InfLine, 1, NULL, 0, &KeyLen) ) {
|
||
|
||
Keyname = (PWSTR)ScepAlloc( 0, (KeyLen+1)*sizeof(WCHAR));
|
||
if ( Keyname != NULL ) {
|
||
Keyname[KeyLen] = L'\0';
|
||
|
||
if ( SetupGetStringField(&InfLine, 1, Keyname, KeyLen, NULL) ) {
|
||
//
|
||
// Get value (startup status, security descriptor SDDL)
|
||
//
|
||
if ( SetupGetIntField(&InfLine, 2, (INT *)&Status) &&
|
||
// SetupGetStringField(&InfLine,3,NULL,0,&DataSize) && DataSize > 0 ) {
|
||
SetupGetMultiSzField(&InfLine,3,NULL,0,&DataSize) && DataSize > 0 ) {
|
||
|
||
Strvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
|
||
(DataSize+1)*sizeof(WCHAR) );
|
||
|
||
if( Strvalue != NULL ) {
|
||
// if(SetupGetStringField(&InfLine,3,Strvalue,DataSize,NULL)) {
|
||
if(SetupGetMultiSzField(&InfLine,3,Strvalue,DataSize,NULL)) {
|
||
//
|
||
// convert multi-sz to space
|
||
//
|
||
if ( cFields > 3 ) {
|
||
ScepConvertMultiSzToDelim(Strvalue, DataSize, L'\0', L' ');
|
||
}
|
||
|
||
if ( ObjectFlag & SCEINF_OBJECT_FLAG_OLDSDDL ) {
|
||
|
||
ScepConvertToSDDLFormat(Strvalue, DataSize);
|
||
}
|
||
|
||
//
|
||
// Convert to security descriptor
|
||
//
|
||
rc = ConvertTextSecurityDescriptor(
|
||
Strvalue,
|
||
&pSecurityDescriptor,
|
||
&DataSize,
|
||
&SeInfo
|
||
);
|
||
if ( rc == SCESTATUS_SUCCESS ) {
|
||
|
||
ScepChangeAclRevision(pSecurityDescriptor, ACL_REVISION);
|
||
|
||
//
|
||
// add to the service list
|
||
//
|
||
rc = ScepAddOneServiceToList(
|
||
Keyname,
|
||
NULL,
|
||
Status,
|
||
(PVOID)pSecurityDescriptor,
|
||
SeInfo,
|
||
TRUE,
|
||
pServiceList
|
||
);
|
||
if ( rc != ERROR_SUCCESS) {
|
||
LocalFree(pSecurityDescriptor);
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
}
|
||
}
|
||
}
|
||
|
||
ScepFree( Strvalue );
|
||
Strvalue = NULL;
|
||
} else
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
}
|
||
}
|
||
//
|
||
// Free Keyname
|
||
//
|
||
ScepFree(Keyname);
|
||
Keyname = NULL;
|
||
} else
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
|
||
ScepBuildErrorLogInfo( ERROR_BAD_FORMAT,
|
||
Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
szServiceGeneral
|
||
);
|
||
break;
|
||
}
|
||
NextLine:
|
||
;
|
||
|
||
} while(SetupFindNextLine(&InfLine,&InfLine));
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
//
|
||
// free the service list
|
||
//
|
||
SceFreePSCE_SERVICES(*pServiceList);
|
||
*pServiceList = NULL;
|
||
|
||
}
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetKerberosPolicy(
|
||
IN HINF hInf,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_KERBEROS_TICKET_INFO * ppKerberosInfo,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/*++
|
||
Routine Description:
|
||
|
||
This routine retrieves kerberos policy information from the SCP INF
|
||
file and stores in the output buffer ppKerberosInfo.
|
||
|
||
Arguments:
|
||
|
||
hInf - INF handle to the profile
|
||
|
||
ppKerberosInfo - the output buffer to hold kerberos info.
|
||
|
||
Errlog - A buffer to hold all error codes/text encountered when
|
||
parsing the INF file. If Errlog is NULL, no further error
|
||
information is returned except the return DWORD
|
||
|
||
Return value:
|
||
|
||
SCESTATUS - SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_BAD_FORMAT
|
||
SCESTATUS_INVALID_DATA
|
||
|
||
--*/
|
||
|
||
{
|
||
INFCONTEXT InfLine;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
|
||
SCE_KEY_LOOKUP AccessSCPLookup[] = {
|
||
{(PWSTR)TEXT("MaxTicketAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxTicketAge), 'D'},
|
||
{(PWSTR)TEXT("MaxRenewAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxRenewAge), 'D'},
|
||
{(PWSTR)TEXT("MaxServiceAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxServiceAge), 'D'},
|
||
{(PWSTR)TEXT("MaxClockSkew"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxClockSkew), 'D'},
|
||
{(PWSTR)TEXT("TicketValidateClient"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, TicketValidateClient), 'D'}
|
||
};
|
||
|
||
DWORD cAccess = sizeof(AccessSCPLookup) / sizeof(SCE_KEY_LOOKUP);
|
||
|
||
//
|
||
// check arguments
|
||
//
|
||
if ( !hInf || !ppKerberosInfo ) {
|
||
return (SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
BOOL bAllocated = FALSE;
|
||
//
|
||
// Locate the [Kerberos Policy] section.
|
||
//
|
||
if(SetupFindFirstLine(hInf,szKerberosPolicy,NULL,&InfLine)) {
|
||
|
||
//
|
||
// allocate the output buffer if it is NULL
|
||
//
|
||
if ( NULL == *ppKerberosInfo ) {
|
||
|
||
*ppKerberosInfo = (PSCE_KERBEROS_TICKET_INFO)ScepAlloc(0, sizeof(SCE_KERBEROS_TICKET_INFO));
|
||
|
||
if ( NULL == *ppKerberosInfo ) {
|
||
return (SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
}
|
||
bAllocated = TRUE;
|
||
}
|
||
//
|
||
// Initialize to SCE_NO_VALUE
|
||
//
|
||
for ( DWORD i=0; i<cAccess; i++) {
|
||
if ( AccessSCPLookup[i].BufferType == 'D' ) {
|
||
*((DWORD *)((CHAR *)(*ppKerberosInfo)+AccessSCPLookup[i].Offset)) = SCE_NO_VALUE;
|
||
}
|
||
}
|
||
|
||
UINT Offset;
|
||
WCHAR Keyname[SCE_KEY_MAX_LENGTH];
|
||
int Keyvalue=0;
|
||
|
||
do {
|
||
|
||
//
|
||
// Get key names and its setting.
|
||
//
|
||
|
||
rc = SCESTATUS_SUCCESS;
|
||
memset(Keyname, '\0', SCE_KEY_MAX_LENGTH*sizeof(WCHAR));
|
||
|
||
if ( SetupGetStringField(&InfLine, 0, Keyname, SCE_KEY_MAX_LENGTH, NULL) ) {
|
||
|
||
for ( i=0; i<cAccess; i++) {
|
||
|
||
//
|
||
// get settings in AccessLookup table
|
||
//
|
||
Offset = AccessSCPLookup[i].Offset;
|
||
|
||
if (_wcsicmp(Keyname, AccessSCPLookup[i].KeyString ) == 0) {
|
||
|
||
switch ( AccessSCPLookup[i].BufferType ) {
|
||
case 'D':
|
||
|
||
//
|
||
// Int Field
|
||
//
|
||
|
||
if (SetupGetIntField(&InfLine, 1, (INT *)&Keyvalue ) ) {
|
||
*((DWORD *)((CHAR *)(*ppKerberosInfo)+Offset)) = (DWORD)Keyvalue;
|
||
} else {
|
||
rc = SCESTATUS_INVALID_DATA;
|
||
}
|
||
|
||
break;
|
||
default:
|
||
//
|
||
// should not occur
|
||
//
|
||
break;
|
||
}
|
||
|
||
break; // for loop
|
||
|
||
}
|
||
}
|
||
|
||
if ( i >= cAccess &&
|
||
!(ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION) ) {
|
||
|
||
//
|
||
// Did not find a match in the lookup table
|
||
//
|
||
|
||
ScepBuildErrorLogInfo( NO_ERROR,
|
||
Errlog,
|
||
SCEERR_NOT_EXPECTED,
|
||
Keyname,szKerberosPolicy );
|
||
|
||
}
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc),
|
||
Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
Keyname );
|
||
}
|
||
|
||
} else {
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
ScepBuildErrorLogInfo( ERROR_BAD_FORMAT, Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
szKerberosPolicy);
|
||
}
|
||
|
||
//
|
||
// if error happens, get out
|
||
//
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
break;
|
||
}
|
||
|
||
} while(SetupFindNextLine(&InfLine,&InfLine));
|
||
|
||
}
|
||
|
||
if ( SCESTATUS_SUCCESS != rc && bAllocated && *ppKerberosInfo ) {
|
||
//
|
||
// free allocated memory if error occurs
|
||
//
|
||
ScepFree(*ppKerberosInfo);
|
||
*ppKerberosInfo = NULL;
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetRegistryValues(
|
||
IN HINF hInf,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_REGISTRY_VALUE_INFO * ppRegValues,
|
||
OUT LPDWORD pValueCount,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/*++
|
||
Routine Description:
|
||
|
||
This routine retrieves kerberos policy information from the SCP INF
|
||
file and stores in the output buffer ppKerberosInfo.
|
||
|
||
Arguments:
|
||
|
||
hInf - INF handle to the profile
|
||
|
||
ppRegValues - the output array to hold registry values.
|
||
|
||
pValueCount - the buffer to hold number of registry values in the array
|
||
|
||
Errlog - A buffer to hold all error codes/text encountered when
|
||
parsing the INF file. If Errlog is NULL, no further error
|
||
information is returned except the return DWORD
|
||
|
||
Return value:
|
||
|
||
SCESTATUS - SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_BAD_FORMAT
|
||
SCESTATUS_INVALID_DATA
|
||
|
||
--*/
|
||
|
||
{
|
||
INFCONTEXT InfLine;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
LONG i;
|
||
LONG nLines;
|
||
|
||
//
|
||
// check arguments
|
||
//
|
||
if ( !hInf || !ppRegValues || !pValueCount ) {
|
||
return (SCESTATUS_INVALID_PARAMETER);
|
||
}
|
||
|
||
//
|
||
// count how many objects
|
||
//
|
||
nLines = SetupGetLineCount(hInf, szRegistryValues );
|
||
if ( nLines == -1 ) {
|
||
//
|
||
// section not found
|
||
//
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
|
||
*pValueCount = nLines;
|
||
*ppRegValues = NULL;
|
||
|
||
if ( nLines == 0 ) {
|
||
//
|
||
// no value is to be secured
|
||
//
|
||
return(SCESTATUS_SUCCESS);
|
||
}
|
||
//
|
||
// allocate memory for all objects
|
||
//
|
||
*ppRegValues = (PSCE_REGISTRY_VALUE_INFO)ScepAlloc( LMEM_ZEROINIT,
|
||
nLines*sizeof(SCE_REGISTRY_VALUE_INFO) );
|
||
if ( *ppRegValues == NULL ) {
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
}
|
||
|
||
//
|
||
// Locate the section.
|
||
//
|
||
if ( SetupFindFirstLine(hInf,szRegistryValues,NULL,&InfLine) ) {
|
||
i = 0;
|
||
|
||
do {
|
||
//
|
||
// Get string key and a int value.
|
||
//
|
||
if ( i >= nLines ) {
|
||
//
|
||
// more lines than allocated
|
||
//
|
||
rc = SCESTATUS_INVALID_DATA;
|
||
ScepBuildErrorLogInfo(ERROR_INVALID_DATA,
|
||
Errlog,
|
||
SCEERR_MORE_OBJECTS,
|
||
nLines
|
||
);
|
||
break;
|
||
}
|
||
rc = SceInfpGetOneRegistryValue(
|
||
&InfLine,
|
||
ObjectFlag,
|
||
&((*ppRegValues)[i]),
|
||
Errlog
|
||
);
|
||
if ( SCESTATUS_SUCCESS == rc ) {
|
||
i++;
|
||
} else if ( ERROR_PRODUCT_VERSION == rc ) {
|
||
//
|
||
// a newer version, should ignore this line
|
||
//
|
||
rc = SCESTATUS_SUCCESS;
|
||
} else {
|
||
break; // do..while loop
|
||
}
|
||
|
||
} while(SetupFindNextLine(&InfLine,&InfLine));
|
||
|
||
}
|
||
|
||
if ( rc != SCESTATUS_SUCCESS ) {
|
||
//
|
||
// free memory
|
||
//
|
||
ScepFreeRegistryValues( ppRegValues, *pValueCount );
|
||
*ppRegValues = NULL;
|
||
|
||
} else {
|
||
|
||
*pValueCount = i;
|
||
}
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|
||
SCESTATUS
|
||
SceInfpGetOneRegistryValue(
|
||
IN PINFCONTEXT pInfLine,
|
||
IN DWORD ObjectFlag,
|
||
OUT PSCE_REGISTRY_VALUE_INFO pValues,
|
||
OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
|
||
)
|
||
/* ++
|
||
Routine Description:
|
||
|
||
This routine retrieves one registry value from the INF file (SCP type).
|
||
Each registry value in these sections is represented by one line.
|
||
|
||
Arguments:
|
||
|
||
pInfLine - Current line context from the INF file for one object
|
||
|
||
pValues- Output buffer to hold the regitry value name and value
|
||
|
||
Errlog - The cummulative error list for errors encountered in this routine
|
||
|
||
Return value:
|
||
|
||
SCESTATUS - SCESTATUS_SUCCESS
|
||
SCESTATUS_NOT_ENOUGH_RESOURCE
|
||
SCESTATUS_INVALID_PARAMETER
|
||
SCESTATUS_BAD_FORMAT
|
||
SCESTATUS_INVALID_DATA
|
||
-- */
|
||
{
|
||
DWORD KeySize;
|
||
PWSTR Keyvalue=NULL;
|
||
SCESTATUS rc=SCESTATUS_SUCCESS;
|
||
INT dType;
|
||
PWSTR pValueStr=NULL;
|
||
DWORD nLen;
|
||
|
||
|
||
if ( !pInfLine || !pValues )
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
nLen = SetupGetFieldCount( pInfLine );
|
||
|
||
if ( nLen < 2 ) {
|
||
|
||
TCHAR tmpBuf[MAX_PATH];
|
||
|
||
tmpBuf[0] = L'\0';
|
||
SetupGetStringField(pInfLine,0,tmpBuf,MAX_PATH,NULL);
|
||
|
||
ScepBuildErrorLogInfo( ERROR_INVALID_DATA,
|
||
Errlog,
|
||
SCEERR_REGVALUE_FIELDS,
|
||
tmpBuf);
|
||
|
||
//
|
||
// if it's a newer version template, should ignore this line
|
||
//
|
||
if ( ObjectFlag & SCEINF_OBJECT_FLAG_UNKNOWN_VERSION )
|
||
return(ERROR_PRODUCT_VERSION);
|
||
else
|
||
return(SCESTATUS_INVALID_DATA);
|
||
}
|
||
|
||
//
|
||
// get the key field (string)
|
||
//
|
||
if(SetupGetStringField(pInfLine,0,NULL,0,&KeySize) && KeySize > 0 ) {
|
||
|
||
Keyvalue = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
|
||
(KeySize+1)*sizeof(WCHAR) );
|
||
if( Keyvalue == NULL ) {
|
||
return(SCESTATUS_NOT_ENOUGH_RESOURCE);
|
||
} else {
|
||
//
|
||
// get key
|
||
//
|
||
if( SetupGetStringField(pInfLine,0,Keyvalue,KeySize,NULL) ) {
|
||
//
|
||
// get the data type, if error, assume REG_DWORD type
|
||
//
|
||
if ( !SetupGetIntField( pInfLine, 1, (INT *)&dType ) ) {
|
||
dType = REG_DWORD;
|
||
}
|
||
|
||
if ( SetupGetMultiSzField(pInfLine,2,NULL,0,&nLen) ) {
|
||
|
||
pValueStr = (PWSTR)ScepAlloc( LMEM_ZEROINIT,
|
||
(nLen+1)*sizeof(WCHAR)
|
||
);
|
||
if( pValueStr == NULL ) {
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
} else if ( !SetupGetMultiSzField(pInfLine,2,pValueStr,nLen,NULL) ) {
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
} else {
|
||
|
||
if ( dType == REG_MULTI_SZ &&
|
||
(0 == _wcsicmp( Keyvalue, szLegalNoticeTextKeyName))) {
|
||
|
||
//
|
||
// check for commas and escape them with "," so the UI etc.
|
||
// understands this, since, here, for lines such as
|
||
// k=7,a",",b,c
|
||
// pValueStr will be a,\0b\0c\0\0 which we should make
|
||
// a","\0b\0c\0\0
|
||
//
|
||
|
||
DWORD dwCommaCount = 0;
|
||
|
||
for ( DWORD dwIndex = 0; dwIndex < nLen; dwIndex++) {
|
||
if ( pValueStr[dwIndex] == L',' )
|
||
dwCommaCount++;
|
||
}
|
||
|
||
if ( dwCommaCount > 0 ) {
|
||
|
||
PWSTR pValueStrEscaped;
|
||
DWORD dwNumBytes;
|
||
|
||
dwNumBytes = (nLen + 1 + dwCommaCount * 2) * sizeof(WCHAR);
|
||
|
||
pValueStrEscaped = (PWSTR)ScepAlloc(LMEM_ZEROINIT, dwNumBytes);
|
||
|
||
if (pValueStrEscaped) {
|
||
|
||
memset(pValueStrEscaped, '\0', dwNumBytes);
|
||
|
||
nLen = ScepEscapeString(pValueStr,
|
||
nLen+1,
|
||
L',',
|
||
L'"',
|
||
pValueStrEscaped
|
||
);
|
||
|
||
ScepFree(pValueStr);
|
||
|
||
pValueStr = pValueStrEscaped;
|
||
}
|
||
|
||
else {
|
||
|
||
rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( SCESTATUS_SUCCESS == rc)
|
||
|
||
rc = ScepConvertMultiSzToDelim(pValueStr, nLen, L'\0', L',');
|
||
|
||
if ( SCESTATUS_SUCCESS == rc) {
|
||
|
||
//
|
||
// assign them to the output buffer
|
||
//
|
||
pValues->FullValueName = Keyvalue;
|
||
Keyvalue = NULL;
|
||
pValues->ValueType = (DWORD)dType;
|
||
|
||
pValues->Value = pValueStr;
|
||
pValueStr = NULL;
|
||
|
||
}
|
||
}
|
||
} else {
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
}
|
||
|
||
} else
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
}
|
||
} else
|
||
rc = SCESTATUS_BAD_FORMAT;
|
||
|
||
if ( rc == SCESTATUS_BAD_FORMAT ) {
|
||
|
||
ScepBuildErrorLogInfo( ERROR_BAD_FORMAT,
|
||
Errlog,
|
||
SCEERR_QUERY_INFO,
|
||
szRegistryValues);
|
||
}
|
||
|
||
if ( Keyvalue != NULL )
|
||
ScepFree( Keyvalue );
|
||
|
||
if ( pValueStr != NULL ) {
|
||
ScepFree(pValueStr);
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
|
||
SCESTATUS
|
||
WINAPI
|
||
SceSvcGetInformationTemplate(
|
||
IN PCWSTR TemplateName,
|
||
IN PCWSTR ServiceName,
|
||
IN PCWSTR Key OPTIONAL,
|
||
OUT PSCESVC_CONFIGURATION_INFO *ServiceInfo
|
||
)
|
||
/*
|
||
Routine Description:
|
||
|
||
Read information from the service's section in the template (inf format) into
|
||
the ServiceInfo buffer. If Key is specified, only one key's information is read.
|
||
|
||
Arguments:
|
||
|
||
Template - The template's name (inf format)
|
||
|
||
ServiceName - The service's name as used in service control manager, is also the
|
||
section name used in the template
|
||
|
||
Key - if specified, it is the key information to match in the template;
|
||
if it is NULL, all information from the section is read
|
||
|
||
ServiceInfo - output buffer of a array of Key/Value pairs
|
||
|
||
Return Value:
|
||
|
||
|
||
*/
|
||
{
|
||
HINF hInf;
|
||
SCESTATUS rc;
|
||
|
||
if ( TemplateName == NULL || ServiceName == NULL || ServiceInfo == NULL ) {
|
||
|
||
return(SCESTATUS_INVALID_PARAMETER);
|
||
|
||
}
|
||
|
||
//
|
||
// open the template
|
||
//
|
||
|
||
rc = SceInfpOpenProfile(
|
||
TemplateName,
|
||
&hInf
|
||
);
|
||
|
||
if ( rc != SCESTATUS_SUCCESS )
|
||
return(rc);
|
||
|
||
//
|
||
// call private API to read information.
|
||
//
|
||
|
||
rc = SceSvcpGetInformationTemplate(hInf,
|
||
ServiceName,
|
||
Key,
|
||
ServiceInfo );
|
||
|
||
//
|
||
// close the template
|
||
//
|
||
|
||
SceInfpCloseProfile(hInf);
|
||
|
||
return(rc);
|
||
|
||
}
|
||
|
||
|