Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1190 lines
29 KiB

/********************************************************************/
/** Copyright(c) 1989 Microsoft Corporation. **/
/********************************************************************/
//***
//
// Filename: registry.c
//
// Description: This module contains routines to manupilate information
// in the registry.
//
// History:
// May 11,1992. NarenG Created original version.
//
#include "afpsvcp.h"
// AFP Server Service registry parameter structure
//
typedef struct _AFP_SERVER_REG_PARAMS {
LPWSTR lpwValueName;
PVOID pValue;
DWORD dwDataType;
DWORD dwErrorLogId;
BOOL (*pfuncIsValid)( LPVOID );
} AFP_SERVER_REG_PARAMS, *PAFP_SERVER_REG_PARAMS;
AFP_SERVER_REG_PARAMS AfpServerRegParams[] = {
AFPREG_VALNAME_SVRNAME,
AfpGlobals.wchServerName,
REG_SZ,
AFPLOG_INVALID_SERVERNAME,
IsAfpServerNameValid,
AFPREG_VALNAME_SRVOPTIONS,
&(AfpGlobals.dwServerOptions),
REG_DWORD,
AFPLOG_INVALID_SRVOPTION,
IsAfpServerOptionsValid,
AFPREG_VALNAME_MAXSESSIONS,
&(AfpGlobals.dwMaxSessions),
REG_DWORD,
AFPLOG_INVALID_MAXSESSIONS,
IsAfpMaxSessionsValid,
AFPREG_VALNAME_LOGINMSG,
AfpGlobals.wchLoginMsg,
REG_SZ,
AFPLOG_INVALID_LOGINMSG,
IsAfpMsgValid,
AFPREG_VALNAME_MAXPAGEDMEM,
&(AfpGlobals.dwMaxPagedMem),
REG_DWORD,
AFPLOG_INVALID_MAXPAGEDMEM,
IsAfpMaxPagedMemValid,
AFPREG_VALNAME_MAXNONPAGEDMEM,
&(AfpGlobals.dwMaxNonPagedMem),
REG_DWORD,
AFPLOG_INVALID_MAXNONPAGEDMEM,
IsAfpMaxNonPagedMemValid,
NULL, NULL, 0, 0, FALSE
};
//**
//
// Call: AfpRegOpen
//
// Returns: NO_ERROR - success
// non-zero returns from registry API's
//
// Description: Will simply open and handles to keys in the registry
// where the server parameters, volumes list and ETC list
// are stored. These open handles will be stored in global
// variables.
//
DWORD
AfpRegOpen(
VOID
)
{
DWORD dwRetCode;
AfpGlobals.hkeyServerParams = NULL;
AfpGlobals.hkeyVolumesList = NULL;
AfpGlobals.hkeyIcons = NULL;
AfpGlobals.hkeyTypeCreators = NULL;
AfpGlobals.hkeyExtensions = NULL;
// The do - while( FALSE ) loop is used here to avoid using a goto to
// do a cleanup and exit.
//
do {
// Obtain handle to the ..\PARAMETERS key.
//
if ( dwRetCode = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
AFP_KEYPATH_SERVER_PARAMS,
0,
KEY_ALL_ACCESS,
&AfpGlobals.hkeyServerParams
))
break;
// Obtain handle to the ..\PARAMETERS\VOLUMES volume list key
//
if ( dwRetCode = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
AFP_KEYPATH_VOLUMES,
0,
KEY_ALL_ACCESS,
&AfpGlobals.hkeyVolumesList
))
break;
// Obtain handle to the ..\PARAMETERS\TYPE_CREATORS key
//
if ( dwRetCode = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
AFP_KEYPATH_TYPE_CREATORS,
0,
KEY_ALL_ACCESS,
&AfpGlobals.hkeyTypeCreators
))
break;
// Obtain handle to the ..\PARAMETERS\EXTENSIONS key
//
if ( dwRetCode = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
AFP_KEYPATH_EXTENSIONS,
0,
KEY_ALL_ACCESS,
&AfpGlobals.hkeyExtensions
))
break;
// Obtain handle to the ..\PARAMETERS\ICONS key
//
if ( dwRetCode = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
AFP_KEYPATH_ICONS,
0,
KEY_ALL_ACCESS,
&AfpGlobals.hkeyIcons
))
break;
} while( FALSE );
return( dwRetCode );
}
//**
//
// Call: AfpRegClose
//
// Returns: none
//
// Description: Simply closes all handles opened by AfpRegOpen
//
VOID
AfpRegClose(
VOID
)
{
if ( AfpGlobals.hkeyServerParams )
RegCloseKey( AfpGlobals.hkeyServerParams );
if ( AfpGlobals.hkeyVolumesList )
RegCloseKey( AfpGlobals.hkeyVolumesList );
if ( AfpGlobals.hkeyTypeCreators )
RegCloseKey( AfpGlobals.hkeyTypeCreators );
if ( AfpGlobals.hkeyExtensions )
RegCloseKey( AfpGlobals.hkeyExtensions );
if ( AfpGlobals.hkeyIcons )
RegCloseKey( AfpGlobals.hkeyIcons );
return;
}
//**
//
// Call: AfpRegServerGetInfo
//
// Returns: NO_ERROR - success
// non-zero returns from registry calls.
// ERROR_NOT_ENOUGH_MEMORY
//
// Description: This procedure is called to obtain server parameters.
// It is assumed that before this procedure is called the
// default values for these parameters are already set.
// If the parameter is not in the registry the default will
// be used ie. this procedure will not change it.
// If a parameter exists in the registry, it will be retrieved.
// If the retrieved parameter is invalid, an error event will
// be logged and the default value will be used.
//
//
DWORD
AfpRegServerGetInfo(
VOID
)
{
DWORD dwRetCode;
DWORD dwTitle = 0;
DWORD dwType;
LPBYTE lpbValueBuf;
DWORD dwMaxValNameLen;
DWORD dwNumValues;
DWORD dwMaxValueDataSize;
DWORD dwBufSize;
DWORD dwIndex;
// First find out the number of values and the max. size of them.
//
if ( dwRetCode = AfpRegGetKeyInfo( AfpGlobals.hkeyServerParams,
&dwMaxValNameLen,
&dwNumValues,
&dwMaxValueDataSize
))
return( dwRetCode );
// Allocate enough memory to hold the max. variable length data.
//
if ( ( lpbValueBuf = (LPBYTE)LocalAlloc(LPTR, dwMaxValueDataSize)) == NULL )
return( ERROR_NOT_ENOUGH_MEMORY );
// Run through ad get all the server parameters.
//
for ( dwIndex = 0,
dwBufSize = dwMaxValueDataSize;
AfpServerRegParams[dwIndex].lpwValueName != NULL;
dwIndex++,
dwBufSize = dwMaxValueDataSize ) {
ZeroMemory( lpbValueBuf, dwMaxValueDataSize );
// Get the server parameter.
//
dwRetCode = RegQueryValueEx( AfpGlobals.hkeyServerParams,
AfpServerRegParams[dwIndex].lpwValueName,
NULL,
&dwType,
lpbValueBuf,
&dwBufSize );
// If the parameter was present then read it in otherwise just
// skip it and let the default value stand.
//
if ( dwRetCode == NO_ERROR ) {
// If the parameter was valid we use it
//
if ( (*(AfpServerRegParams[dwIndex].pfuncIsValid))(lpbValueBuf) ){
switch( AfpServerRegParams[dwIndex].dwDataType ) {
case REG_SZ:
if ( STRLEN( (LPWSTR)lpbValueBuf ) > 0 )
STRCPY( (LPWSTR)(AfpServerRegParams[dwIndex].pValue),
(LPWSTR)lpbValueBuf );
else
((LPWSTR)(AfpServerRegParams[dwIndex].pValue))[0] =
TEXT('\0');
break;
case REG_DWORD:
*(LPDWORD)(AfpServerRegParams[dwIndex].pValue) =
*(LPDWORD)lpbValueBuf;
break;
default:
AFP_ASSERT( FALSE );
break;
}
}
else {
// Otherwise we log this error
//
AfpLogEvent( AfpServerRegParams[dwIndex].dwErrorLogId,
0, NULL, dwRetCode, EVENTLOG_WARNING_TYPE );
}
}
else if ( dwRetCode == ERROR_FILE_NOT_FOUND )
dwRetCode = NO_ERROR;
else
break;
}
LocalFree( lpbValueBuf );
return( dwRetCode );
}
//**
//
// Call: AfpRegVolumeAdd
//
// Returns: NO_ERROR - success
// non-zero returns from registry API's
//
// Description: This routine takes a AFP_VOLUME_INFO, creates a REG_MULTI_SZ
// from it and stores it in the registry.
//
DWORD
AfpRegVolumeAdd(
IN PAFP_VOLUME_INFO pVolumeInfo
)
{
DWORD dwRetCode;
DWORD cbMultiSzSize;
LPBYTE lpbMultiSz;
DWORD dwLength;
DWORD dwIndex;
WCHAR wchEncryptedPass[AFP_VOLPASS_LEN+1];
// Before we add the volume we encrypt the password if there is one
//
if ( ( pVolumeInfo->afpvol_password != (LPWSTR)NULL ) &&
( STRLEN( pVolumeInfo->afpvol_password ) > 0 ) ) {
ZeroMemory( wchEncryptedPass, sizeof( wchEncryptedPass ) );
dwLength = STRLEN( pVolumeInfo->afpvol_password );
for ( dwIndex = 0; dwIndex < AFP_VOLPASS_LEN; dwIndex++ ) {
wchEncryptedPass[dwIndex] = ( dwIndex < dwLength )
? pVolumeInfo->afpvol_password[dwIndex] ^ 0xF000
: (wchEncryptedPass[dwIndex] ^= 0xF000);
}
pVolumeInfo->afpvol_password = wchEncryptedPass;
}
if ( dwRetCode = AfpBufMakeMultiSz( AFP_VOLUME_STRUCT,
(LPBYTE)pVolumeInfo,
&lpbMultiSz,
&cbMultiSzSize ))
return( dwRetCode );
// Set the data.
//
dwRetCode = RegSetValueEx( AfpGlobals.hkeyVolumesList,
pVolumeInfo->afpvol_name,
0,
REG_MULTI_SZ,
lpbMultiSz,
cbMultiSzSize
);
LocalFree( lpbMultiSz );
return( dwRetCode );
}
//**
//
// Call: AfpRegVolumeDelete
//
// Returns: NO_ERROR - success
// non-zero returns from registry calls.
//
// Description: Will delete a volume from the Volume list in the registry.
//
DWORD
AfpRegVolumeDelete(
IN LPWSTR lpwsVolumeName
)
{
return( RegDeleteValue( AfpGlobals.hkeyVolumesList, lpwsVolumeName ) );
}
//**
//
// Call: AfpRegVolumeSetInfo
//
// Returns: NO_ERROR - success
// non-zero returns from registry API's
//
// Description:
//
//
DWORD
AfpRegVolumeSetInfo(
IN PAFP_VOLUME_INFO pVolumeInfo
)
{
return( AfpRegVolumeAdd( pVolumeInfo ) );
}
//**
//
// Call: AfpRegTypeCreatorEnum
//
// Returns: NO_ERROR - success
// ERROR_NOT_ENOUGH_MEMORY
// non-zero returns from registry APIs.
//
// Description: This procedure will read in type/creator/comment information
// from the registry and store it in memory in the
// AfpGlobals.AfpETCMapInfo structure. Only fatal errors will
// be returned. Non-fatal errors will be errorlogged.
//
DWORD
AfpRegTypeCreatorEnum(
VOID
)
{
DWORD dwRetCode;
DWORD cbMaxValNameLen;
DWORD cbValNameBufSize;
DWORD dwNumValues;
DWORD cbMaxValueDataSize;
DWORD dwValueIndex;
DWORD cbBufSize;
DWORD dwType;
PAFP_TYPE_CREATOR pTypeCreatorWalker;
PAFP_TYPE_CREATOR pTypeCreator;
LPWSTR lpwsValName;
LPBYTE lpbMultiSz;
CHAR chAnsiBuf[10];
// Read in the type/creators
//
if ( dwRetCode = AfpRegGetKeyInfo( AfpGlobals.hkeyTypeCreators,
&cbMaxValNameLen,
&dwNumValues,
&cbMaxValueDataSize
))
return( dwRetCode );
// Allocate space for the number of values in this key.
//
AfpGlobals.AfpETCMapInfo.afpetc_type_creator=(PAFP_TYPE_CREATOR)LocalAlloc(
LPTR,
sizeof(AFP_TYPE_CREATOR) * dwNumValues);
if ( AfpGlobals.AfpETCMapInfo.afpetc_type_creator == NULL )
return( ERROR_NOT_ENOUGH_MEMORY );
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators = 0;
if ( dwNumValues == 0 )
return( NO_ERROR );
if (( lpwsValName = (LPWSTR)LocalAlloc( LPTR, cbMaxValNameLen )) == NULL){
LocalFree(AfpGlobals.AfpETCMapInfo.afpetc_type_creator );
return( ERROR_NOT_ENOUGH_MEMORY );
}
if (( lpbMultiSz = (LPBYTE)LocalAlloc( LPTR, cbMaxValueDataSize )) == NULL){
LocalFree(AfpGlobals.AfpETCMapInfo.afpetc_type_creator );
LocalFree( lpwsValName );
return( ERROR_NOT_ENOUGH_MEMORY );
}
// Read in the type/creator/comment tuples
//
for ( dwValueIndex = 0,
AfpGlobals.dwCurrentTCId = AFP_DEF_TCID + 1,
cbBufSize = cbMaxValueDataSize,
cbValNameBufSize = cbMaxValNameLen,
pTypeCreatorWalker = AfpGlobals.AfpETCMapInfo.afpetc_type_creator;
dwValueIndex < dwNumValues;
dwValueIndex++,
cbBufSize = cbMaxValueDataSize,
cbValNameBufSize = cbMaxValNameLen
) {
if ( dwRetCode = RegEnumValue( AfpGlobals.hkeyTypeCreators,
dwValueIndex,
lpwsValName,
&cbValNameBufSize,
NULL,
&dwType,
lpbMultiSz,
&cbBufSize
))
break;
// Parse the mult sz and extract info into volume info structure
//
if ( dwRetCode = AfpBufParseMultiSz(
AFP_TYPECREATOR_STRUCT,
lpbMultiSz,
(LPBYTE)pTypeCreatorWalker
)) {
LPWSTR lpwsNames[2];
lpwsNames[0] = pTypeCreatorWalker->afptc_type;
lpwsNames[1] = pTypeCreatorWalker->afptc_creator;
AfpLogEvent( AFPLOG_INVALID_TYPE_CREATOR,
2,
lpwsNames,
(DWORD)AFPERR_InvalidTypeCreator,
EVENTLOG_WARNING_TYPE );
dwRetCode = NO_ERROR;
continue;
}
// Id is value name, so copy it in
//
wcstombs( chAnsiBuf, lpwsValName, sizeof( chAnsiBuf ) );
pTypeCreatorWalker->afptc_id = atoi( chAnsiBuf );
if ( !IsAfpTypeCreatorValid( pTypeCreatorWalker ) ) {
LPWSTR lpwsNames[2];
lpwsNames[0] = pTypeCreatorWalker->afptc_type;
lpwsNames[1] = pTypeCreatorWalker->afptc_creator;
AfpLogEvent( AFPLOG_INVALID_TYPE_CREATOR,
2,
lpwsNames,
(DWORD)AFPERR_InvalidTypeCreator,
EVENTLOG_WARNING_TYPE );
dwRetCode = NO_ERROR;
continue;
}
// Check to see if this is a duplicate.
//
pTypeCreator = AfpBinarySearch(
pTypeCreatorWalker,
AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
sizeof(AFP_TYPE_CREATOR),
AfpBCompareTypeCreator );
if ( pTypeCreator != NULL ) {
LPWSTR lpwsNames[2];
lpwsNames[0] = pTypeCreatorWalker->afptc_type;
lpwsNames[1] = pTypeCreatorWalker->afptc_creator;
AfpLogEvent( AFPLOG_INVALID_TYPE_CREATOR,
2,
lpwsNames,
(DWORD)AFPERR_InvalidTypeCreator,
EVENTLOG_WARNING_TYPE );
dwRetCode = NO_ERROR;
continue;
}
// Keep the Current id the max of all ids
//
AfpGlobals.dwCurrentTCId =
( AfpGlobals.dwCurrentTCId < pTypeCreatorWalker->afptc_id ) ?
pTypeCreatorWalker->afptc_id : AfpGlobals.dwCurrentTCId;
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators++;
pTypeCreatorWalker++;
}
LocalFree( lpwsValName );
LocalFree( lpbMultiSz );
if ( dwRetCode ) {
LocalFree( AfpGlobals.AfpETCMapInfo.afpetc_type_creator );
return( dwRetCode );
}
// Sort the type/creator table
//
qsort( AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
sizeof(AFP_TYPE_CREATOR),
AfpBCompareTypeCreator );
return( NO_ERROR );
}
//**
//
// Call: AfpRegExtensionEnum
//
// Returns: NO_ERROR - success
// ERROR_NOT_ENOUGH_MEMORY
// non-zero returns from registry APIs.
//
// Description: This procedure will read in extension information
// from the registry and store it in memory in the
// AfpGlobals.AfpETCMapInfo structure. Only fatal errors will
// be returned. Non-fatal errors will be errorlogged.
//
DWORD
AfpRegExtensionEnum(
VOID
)
{
DWORD dwRetCode;
DWORD cbMaxValNameLen;
DWORD cbValNameBufSize;
DWORD dwNumValues;
DWORD cbMaxValueDataSize;
DWORD dwValueIndex;
DWORD cbBufSize;
DWORD dwType;
PAFP_EXTENSION pExtensionWalker;
PAFP_EXTENSION pExtension;
LPWSTR lpwsValName;
LPBYTE lpbMultiSz;
DWORD dwNumExtensions;
PAFP_TYPE_CREATOR pTypeCreator;
AFP_TYPE_CREATOR AfpTypeCreator;
DWORD dwNumTypeCreators;
// Read in the extensions
//
if ( dwRetCode = AfpRegGetKeyInfo( AfpGlobals.hkeyExtensions,
&cbMaxValNameLen,
&dwNumValues,
&cbMaxValueDataSize
))
return( dwRetCode );
AfpGlobals.AfpETCMapInfo.afpetc_extension = (PAFP_EXTENSION)LocalAlloc(
LPTR,
sizeof(AFP_EXTENSION) *dwNumValues );
if ( AfpGlobals.AfpETCMapInfo.afpetc_extension == NULL )
return( ERROR_NOT_ENOUGH_MEMORY );
AfpGlobals.AfpETCMapInfo.afpetc_num_extensions = 0;
if ( dwNumValues == 0 )
return( NO_ERROR );
// Read in the extensions
//
if (( lpwsValName = (LPWSTR)LocalAlloc( LPTR, cbMaxValNameLen )) == NULL) {
LocalFree( AfpGlobals.AfpETCMapInfo.afpetc_extension );
return( ERROR_NOT_ENOUGH_MEMORY );
}
if (( lpbMultiSz = (LPBYTE)LocalAlloc( LPTR, cbMaxValueDataSize )) == NULL){
LocalFree( AfpGlobals.AfpETCMapInfo.afpetc_extension );
LocalFree( lpwsValName );
return( ERROR_NOT_ENOUGH_MEMORY );
}
for ( dwValueIndex = 0,
pExtensionWalker = AfpGlobals.AfpETCMapInfo.afpetc_extension,
cbBufSize = cbMaxValueDataSize,
cbValNameBufSize = cbMaxValNameLen;
dwValueIndex < dwNumValues;
dwValueIndex++,
cbBufSize = cbMaxValueDataSize,
cbValNameBufSize = cbMaxValNameLen
) {
if ( dwRetCode = RegEnumValue( AfpGlobals.hkeyExtensions,
dwValueIndex,
lpwsValName,
&cbValNameBufSize,
NULL,
&dwType,
lpbMultiSz,
&cbBufSize
))
break;
// Parse the mult sz and extract info into volume info structure
//
if ( dwRetCode = AfpBufParseMultiSz(
AFP_EXTENSION_STRUCT,
lpbMultiSz,
(LPBYTE)pExtensionWalker
)) {
LPWSTR lpwsName = pExtensionWalker->afpe_extension;
AfpLogEvent( AFPLOG_INVALID_EXTENSION,
1,
&lpwsName,
(DWORD)AFPERR_InvalidExtension,
EVENTLOG_WARNING_TYPE );
dwRetCode = NO_ERROR;
continue;
}
// Value name is extension, so copy it in
//
STRCPY( pExtensionWalker->afpe_extension, lpwsValName );
if ( !IsAfpExtensionValid( pExtensionWalker ) ) {
LPWSTR lpwsName = pExtensionWalker->afpe_extension;
AfpLogEvent( AFPLOG_INVALID_EXTENSION,
1,
&lpwsName,
(DWORD)AFPERR_InvalidExtension,
EVENTLOG_WARNING_TYPE );
dwRetCode = NO_ERROR;
continue;
}
// Check to see if this extension is associated with a vaid type/creator
// pair
//
dwNumTypeCreators = AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators;
AfpTypeCreator.afptc_id = pExtensionWalker->afpe_tcid;
pTypeCreator = _lfind( &AfpTypeCreator,
AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
(unsigned int *)&dwNumTypeCreators,
sizeof(AFP_TYPE_CREATOR),
AfpLCompareTypeCreator );
if ( pTypeCreator == NULL ) {
LPWSTR lpwsName = pExtensionWalker->afpe_extension;
AfpLogEvent( AFPLOG_INVALID_EXTENSION,
1,
&lpwsName,
(DWORD)AFPERR_InvalidExtension,
EVENTLOG_WARNING_TYPE );
dwRetCode = NO_ERROR;
continue;
}
// Check to see if this extension is a duplicate
//
dwNumExtensions = AfpGlobals.AfpETCMapInfo.afpetc_num_extensions;
pExtension = _lfind( pExtensionWalker,
AfpGlobals.AfpETCMapInfo.afpetc_extension,
(unsigned int *)&dwNumExtensions,
sizeof(AFP_EXTENSION),
AfpLCompareExtension );
if ( pExtension != NULL ) {
LPWSTR lpwsName = pExtensionWalker->afpe_extension;
AfpLogEvent( AFPLOG_INVALID_EXTENSION,
1,
&lpwsName,
(DWORD)AFPERR_DuplicateExtension,
EVENTLOG_WARNING_TYPE );
dwRetCode = NO_ERROR;
continue;
}
AfpGlobals.AfpETCMapInfo.afpetc_num_extensions++;
pExtensionWalker++;
}
LocalFree( lpwsValName );
LocalFree( lpbMultiSz );
if ( dwRetCode ) {
LocalFree( AfpGlobals.AfpETCMapInfo.afpetc_extension );
return( dwRetCode );
}
// Sort the extension table
//
qsort( AfpGlobals.AfpETCMapInfo.afpetc_extension,
AfpGlobals.AfpETCMapInfo.afpetc_num_extensions,
sizeof(AFP_EXTENSION),
AfpBCompareExtension );
return( NO_ERROR );
}
//**
//
// Call: AfpRegTypeCreatorAdd
//
// Returns: NO_ERROR - success
// non-zero returns from the registry
//
// Description: This routine will add a tupple to the registry. The value
// name for the tupple will be id of the type creator.
//
DWORD
AfpRegTypeCreatorAdd(
IN PAFP_TYPE_CREATOR pAfpTypeCreator
)
{
DWORD cbMultiSzSize;
LPBYTE lpbMultiSz;
DWORD dwRetCode;
WCHAR wchValueName[10];
CHAR chValueName[10];
_itoa( pAfpTypeCreator->afptc_id, chValueName, 10 );
mbstowcs( wchValueName, chValueName, sizeof(wchValueName)/sizeof(WCHAR) );
if ( dwRetCode = AfpBufMakeMultiSz( AFP_TYPECREATOR_STRUCT,
(LPBYTE)pAfpTypeCreator,
&lpbMultiSz,
&cbMultiSzSize ))
return( dwRetCode );
dwRetCode = RegSetValueEx( AfpGlobals.hkeyTypeCreators,
wchValueName,
0,
REG_MULTI_SZ,
lpbMultiSz,
cbMultiSzSize
);
LocalFree( lpbMultiSz );
return( dwRetCode );
}
//**
//
// Call: AfpRegTypeCreatorSetInfo
//
// Returns: NO_ERROR - success
// non-zero returns from the registry
//
// Description: Will change the value of a particular tupple.
//
DWORD
AfpRegTypeCreatorSetInfo(
IN PAFP_TYPE_CREATOR pAfpTypeCreator
)
{
return( AfpRegTypeCreatorAdd( pAfpTypeCreator ) );
}
//**
//
// Call: AfpRegTypeCreatorDelete
//
// Returns: NO_ERROR - success
// non-zero returns from the registry apis
//
// Description: Will delete a type creator entry from the registry key.
//
DWORD
AfpRegTypeCreatorDelete(
IN PAFP_TYPE_CREATOR pAfpTypeCreator
)
{
WCHAR wchValueName[10];
CHAR chValueName[10];
_itoa( pAfpTypeCreator->afptc_id, chValueName, 10 );
mbstowcs( wchValueName, chValueName, sizeof(wchValueName)/sizeof(WCHAR) );
return( RegDeleteValue( AfpGlobals.hkeyTypeCreators, wchValueName ));
}
//**
//
// Call: AfpRegExtensionAdd
//
// Returns: NO_ERROR - success
// non-zero returns from the registry
//
// Description: This routine will add a tupple to the registry. The value
// name for the tupple will be the concatenation of the
// type, creator and the extension. This is done to keep the
// value name unique so that it may be accessed directly.
//
DWORD
AfpRegExtensionAdd(
IN PAFP_EXTENSION pAfpExtension
)
{
DWORD cbMultiSzSize;
LPBYTE lpbMultiSz;
DWORD dwRetCode;
if ( dwRetCode = AfpBufMakeMultiSz( AFP_EXTENSION_STRUCT,
(LPBYTE)pAfpExtension,
&lpbMultiSz,
&cbMultiSzSize ))
return( dwRetCode );
dwRetCode = RegSetValueEx( AfpGlobals.hkeyExtensions,
pAfpExtension->afpe_extension,
0,
REG_MULTI_SZ,
lpbMultiSz,
cbMultiSzSize );
LocalFree( lpbMultiSz );
return( dwRetCode );
}
//**
//
// Call: AfpRegExtensionSetInfo
//
// Returns: NO_ERROR - success
// non-zero returns from the registry
//
// Description: Will change the value of a particular tupple.
//
DWORD
AfpRegExtensionSetInfo(
IN PAFP_EXTENSION pAfpExtension
)
{
// Make a Mult-sz of this and add it to the registry
//
return( AfpRegExtensionAdd( pAfpExtension ) );
}
//**
//
// Call: AfpRegExtensionDelete
//
// Returns: NO_ERROR - success
// non-zero returns from the registry
//
// Description: Deletes an extension from the registry.
//
DWORD
AfpRegExtensionDelete(
IN PAFP_EXTENSION pAfpExtension
)
{
return( RegDeleteValue( AfpGlobals.hkeyExtensions,
pAfpExtension->afpe_extension ));
}
//**
//
// Call: AfpRegGetKeyInfo
//
// Returns: NO_ERROR - success
// non-zero returns from registry API's
//
// Description: Will retrieve the number of values in this key and the
// maximum size of the value data. It will also return the
// length IN BYTES of the largest value name (including the
// NULL character ).
//
DWORD
AfpRegGetKeyInfo(
IN HKEY hKey,
OUT LPDWORD lpdwMaxValNameLen, // Longest valuename in this key
OUT LPDWORD lpdwNumValues, // Number of values in this key
OUT LPDWORD lpdwMaxValueDataSize // Max. size of value data.
)
{
WCHAR wchClassName[256];// This should be large enough to hold the
// class name for this key.
DWORD dwClassSize = sizeof( wchClassName ) / sizeof( wchClassName[0] );
DWORD dwNumSubKeys;
DWORD dwMaxSubKeySize;
DWORD dwMaxClassSize;
DWORD dwSecDescLen;
FILETIME LastWrite;
DWORD dwRetCode;
dwRetCode = RegQueryInfoKey(hKey,
wchClassName,
&dwClassSize,
NULL,
&dwNumSubKeys,
&dwMaxSubKeySize,
&dwMaxClassSize,
lpdwNumValues,
lpdwMaxValNameLen,
lpdwMaxValueDataSize,
&dwSecDescLen,
&LastWrite
);
if ( dwRetCode == NO_ERROR ) {
if ( *lpdwMaxValNameLen > 0 )
*lpdwMaxValNameLen = (*lpdwMaxValNameLen + 1) * sizeof(WCHAR);
}
return( dwRetCode );
}
//**
//
// Call: AfpRegServerGetCodePagePath
//
// Returns: NO_ERROR
// ERROR_PATH_NOT_FOUND
// other errors returned from registry APIs
//
// Description: Will get the path to the Mac codepage and store it in
// AfpGlobals.wchCodePagePath.
// It will first get the system directory. It will then get
// the codepage filename and concatenate it to the system
// directory.
//
DWORD
AfpRegServerGetCodePagePath(
VOID
)
{
DWORD dwRetCode;
HKEY hkeyCodepagePath;
DWORD dwType;
DWORD dwBufSize;
WCHAR wchCodepageNum[20];
WCHAR wchCodePageFile[MAX_PATH];
// Open the key
//
if ( dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
AFP_KEYPATH_CODEPAGE,
0,
KEY_QUERY_VALUE,
&hkeyCodepagePath
))
return( dwRetCode );
// This is not a loop
//
do {
// First get the system directory path
//
if ( !GetSystemDirectory( AfpGlobals.wchCodePagePath,
sizeof( AfpGlobals.wchCodePagePath ) / sizeof( AfpGlobals.wchCodePagePath[0] ))) {
dwRetCode = ERROR_PATH_NOT_FOUND;
break;
}
// Get the Code page number value for the Mac
//
dwBufSize = sizeof( wchCodepageNum );
if ( dwRetCode = RegQueryValueEx( hkeyCodepagePath,
AFPREG_VALNAME_CODEPAGE,
NULL,
&dwType,
(LPBYTE)wchCodepageNum,
&dwBufSize ))
break;
// Finally get the codepage filename
//
dwBufSize = sizeof( wchCodePageFile );
if ( dwRetCode = RegQueryValueEx( hkeyCodepagePath,
wchCodepageNum,
NULL,
&dwType,
(LPBYTE)wchCodePageFile,
&dwBufSize ))
break;
// Concatenate the filename to the system directory path
//
wcscat( AfpGlobals.wchCodePagePath, (LPWSTR)TEXT("\\") );
wcscat( AfpGlobals.wchCodePagePath, wchCodePageFile );
} while( FALSE );
// Close the key
//
RegCloseKey( hkeyCodepagePath );
return( dwRetCode );
}
//**
//
// Call: AfpRegServerSetInfo
//
// Returns: NO_ERROR - success
// non-zero returns from registry APIs.
//
// Description: This procedure will set specific server parameters in the
// registy depending on what bit is set the the dwParmnum
// parameter. The input will be a AFP_SERVER_INFO self relative
// structure that contains the parameter to set.
//
DWORD
AfpRegServerSetInfo(
IN PAFP_SERVER_INFO pServerInfo,
IN DWORD dwParmnum
)
{
DWORD dwRetCode;
LPWSTR lpwsPtr;
// Set the server name
//
if ( dwParmnum & AFP_SERVER_PARMNUM_NAME ) {
DWORD Length = 0;
lpwsPtr = pServerInfo->afpsrv_name;
if ( lpwsPtr != NULL ) {
OFFSET_TO_POINTER( lpwsPtr, pServerInfo );
Length = STRLEN(lpwsPtr)+1;
}
if ( dwRetCode=RegSetValueEx(
AfpGlobals.hkeyServerParams,
AFPREG_VALNAME_SVRNAME,
0,
REG_SZ,
(LPBYTE)lpwsPtr,
Length * sizeof(WCHAR)))
return( dwRetCode );
}
// Set Max sessions
//
if ( dwParmnum & AFP_SERVER_PARMNUM_MAX_SESSIONS ) {
if ( dwRetCode=RegSetValueEx(
AfpGlobals.hkeyServerParams,
AFPREG_VALNAME_MAXSESSIONS,
0,
REG_DWORD,
(LPBYTE)&(pServerInfo->afpsrv_max_sessions),
sizeof( DWORD )))
return( dwRetCode );
}
// Set server options
//
if ( dwParmnum & AFP_SERVER_PARMNUM_OPTIONS ) {
if ( dwRetCode = RegSetValueEx(
AfpGlobals.hkeyServerParams,
AFPREG_VALNAME_SRVOPTIONS,
0,
REG_DWORD,
(LPBYTE)&(pServerInfo->afpsrv_options),
sizeof( DWORD )
))
return( dwRetCode );
}
// Set Login message
//
if ( dwParmnum & AFP_SERVER_PARMNUM_LOGINMSG ) {
DWORD Length = 0;
lpwsPtr = pServerInfo->afpsrv_login_msg;
if ( lpwsPtr != NULL ) {
OFFSET_TO_POINTER( lpwsPtr, pServerInfo );
Length = STRLEN(lpwsPtr)+1;
}
if ( dwRetCode = RegSetValueEx(
AfpGlobals.hkeyServerParams,
AFPREG_VALNAME_LOGINMSG,
0,
REG_SZ,
(LPBYTE)lpwsPtr,
Length * sizeof(WCHAR)))
return( dwRetCode );
}
return( NO_ERROR );
}