windows-nt/Source/XPSP1/NT/ds/security/services/scerpc/client/infget.cpp
2020-09-26 16:20:57 +08:00

2884 lines
90 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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);
}