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