mirror of https://github.com/tongzx/nt5src
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.
758 lines
21 KiB
758 lines
21 KiB
/********************************************************************/
|
|
/** Copyright(c) 1989 Microsoft Corporation. **/
|
|
/********************************************************************/
|
|
|
|
//***
|
|
//
|
|
// Filename: etcmap.c
|
|
//
|
|
// Description: This module contains support routines for the extension/
|
|
// type/creator mappings category API's for the AFP server
|
|
// service. These routines are called directly by the RPC
|
|
// runtime.
|
|
//
|
|
// History:
|
|
// June 11,1992. NarenG Created original version.
|
|
//
|
|
#include "afpsvcp.h"
|
|
|
|
//**
|
|
//
|
|
// Call: AfpAdminrETCMapGetInfo
|
|
//
|
|
// Returns: NO_ERROR
|
|
// ERROR_ACCESS_DENIED
|
|
// ERROR_NOT_ENOUGH_MEMORY
|
|
//
|
|
// Description: Will alllocate enough memory to contain all mappings, copy
|
|
// the information and return.
|
|
//
|
|
DWORD
|
|
AfpAdminrETCMapGetInfo(
|
|
IN AFP_SERVER_HANDLE hServer,
|
|
OUT PAFP_ETCMAP_INFO *ppAfpETCMapInfo
|
|
)
|
|
{
|
|
DWORD dwRetCode=0;
|
|
DWORD dwAccessStatus=0;
|
|
|
|
|
|
// Check if caller has access
|
|
//
|
|
if ( dwRetCode = AfpSecObjAccessCheck( AFPSVC_ALL_ACCESS, &dwAccessStatus))
|
|
{
|
|
AFP_PRINT(( "SFMSVC: AfpAdminrETCMapGetInfo, AfpSecObjAccessCheck failed %ld\n",dwRetCode));
|
|
AfpLogEvent( AFPLOG_CANT_CHECK_ACCESS, 0, NULL,
|
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|
return( ERROR_ACCESS_DENIED );
|
|
}
|
|
|
|
if ( dwAccessStatus )
|
|
{
|
|
AFP_PRINT(( "SFMSVC: AfpAdminrETCMapGetInfo, AfpSecObjAccessCheck returned %ld\n",dwAccessStatus));
|
|
return( ERROR_ACCESS_DENIED );
|
|
}
|
|
|
|
// MUTEX start
|
|
//
|
|
WaitForSingleObject( AfpGlobals.hmutexETCMap, INFINITE );
|
|
|
|
// This loop is used to allow break's instead of goto's to be used
|
|
// on an error condition.
|
|
//
|
|
do {
|
|
|
|
dwRetCode = NO_ERROR;
|
|
|
|
// Allocate memory and copy ETC mappings information
|
|
//
|
|
*ppAfpETCMapInfo = MIDL_user_allocate( sizeof(AFP_ETCMAP_INFO) );
|
|
|
|
if ( *ppAfpETCMapInfo == NULL ) {
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
(*ppAfpETCMapInfo)->afpetc_num_type_creators =
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators;
|
|
|
|
(*ppAfpETCMapInfo)->afpetc_type_creator = MIDL_user_allocate(
|
|
sizeof(AFP_TYPE_CREATOR)
|
|
*AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators);
|
|
|
|
if ( (*ppAfpETCMapInfo)->afpetc_type_creator == NULL ) {
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
(*ppAfpETCMapInfo)->afpetc_num_extensions =
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_extensions;
|
|
|
|
(*ppAfpETCMapInfo)->afpetc_extension = MIDL_user_allocate(
|
|
sizeof(AFP_EXTENSION)
|
|
*AfpGlobals.AfpETCMapInfo.afpetc_num_extensions);
|
|
|
|
if ( (*ppAfpETCMapInfo)->afpetc_extension == NULL ) {
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
CopyMemory( (LPBYTE)(*ppAfpETCMapInfo)->afpetc_type_creator,
|
|
(LPBYTE)(AfpGlobals.AfpETCMapInfo.afpetc_type_creator),
|
|
sizeof(AFP_TYPE_CREATOR)
|
|
* AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators);
|
|
|
|
CopyMemory( (LPBYTE)(*ppAfpETCMapInfo)->afpetc_extension,
|
|
(LPBYTE)(AfpGlobals.AfpETCMapInfo.afpetc_extension),
|
|
sizeof(AFP_EXTENSION)
|
|
* AfpGlobals.AfpETCMapInfo.afpetc_num_extensions);
|
|
|
|
} while( FALSE );
|
|
|
|
// MUTEX end
|
|
//
|
|
ReleaseMutex( AfpGlobals.hmutexETCMap );
|
|
|
|
if ( dwRetCode ) {
|
|
|
|
if ( *ppAfpETCMapInfo != NULL ) {
|
|
|
|
if ( (*ppAfpETCMapInfo)->afpetc_type_creator != NULL )
|
|
MIDL_user_free( (*ppAfpETCMapInfo)->afpetc_type_creator );
|
|
|
|
MIDL_user_free( *ppAfpETCMapInfo );
|
|
}
|
|
}
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: AfpAdminrETCMapAdd
|
|
//
|
|
// Returns: NO_ERROR
|
|
// ERROR_ACCESS_DENIED
|
|
// AFPERR_DuplicateTypeCreator;
|
|
// non-zero returns from the registry API's
|
|
//
|
|
// Description: This routine will add a type/creator/comment tupple to the
|
|
// registry and the cache.
|
|
//
|
|
DWORD
|
|
AfpAdminrETCMapAdd(
|
|
IN AFP_SERVER_HANDLE hServer,
|
|
IN PAFP_TYPE_CREATOR pAfpTypeCreator
|
|
)
|
|
{
|
|
DWORD dwRetCode=0;
|
|
DWORD dwAccessStatus=0;
|
|
PAFP_TYPE_CREATOR pTypeCreator;
|
|
DWORD dwNumTypeCreators;
|
|
|
|
|
|
// Check if caller has access
|
|
//
|
|
if ( dwRetCode = AfpSecObjAccessCheck( AFPSVC_ALL_ACCESS, &dwAccessStatus))
|
|
{
|
|
AFP_PRINT(( "SFMSVC: AfpAdminrETCMapAdd, AfpSecObjAccessCheck failed %ld\n",dwRetCode));
|
|
AfpLogEvent( AFPLOG_CANT_CHECK_ACCESS, 0, NULL,
|
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|
return( ERROR_ACCESS_DENIED );
|
|
}
|
|
|
|
if ( dwAccessStatus )
|
|
{
|
|
AFP_PRINT(( "SFMSVC: AfpAdminrETCMapAdd, AfpSecObjAccessCheck returned %ld\n",dwAccessStatus));
|
|
return( ERROR_ACCESS_DENIED );
|
|
}
|
|
|
|
// MUTEX start
|
|
//
|
|
WaitForSingleObject( AfpGlobals.hmutexETCMap, INFINITE );
|
|
|
|
// This loop is used to allow break's instead of goto's to be used
|
|
// on an error condition.
|
|
//
|
|
do {
|
|
|
|
dwRetCode = NO_ERROR;
|
|
|
|
// First check to see if the type already exists.
|
|
//
|
|
pTypeCreator = AfpBinarySearch(
|
|
pAfpTypeCreator,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
|
|
sizeof(AFP_TYPE_CREATOR),
|
|
AfpBCompareTypeCreator );
|
|
|
|
// It exists so return error
|
|
//
|
|
if ( pTypeCreator != NULL ) {
|
|
dwRetCode = (DWORD)AFPERR_DuplicateTypeCreator;
|
|
break;
|
|
}
|
|
|
|
// Set the ID for this type/creator
|
|
//
|
|
pAfpTypeCreator->afptc_id = ++AfpGlobals.dwCurrentTCId;
|
|
|
|
// It does not exist so add it to the registry and the cache.
|
|
//
|
|
if ( dwRetCode = AfpRegTypeCreatorAdd( pAfpTypeCreator ) )
|
|
break;
|
|
|
|
// Grow the cache size by one entry.
|
|
//
|
|
pTypeCreator = AfpGlobals.AfpETCMapInfo.afpetc_type_creator;
|
|
dwNumTypeCreators = AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators;
|
|
|
|
pTypeCreator = (PAFP_TYPE_CREATOR)LocalReAlloc(
|
|
pTypeCreator,
|
|
(dwNumTypeCreators+1)*sizeof(AFP_TYPE_CREATOR),
|
|
LMEM_MOVEABLE );
|
|
|
|
if ( pTypeCreator == NULL ) {
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
pTypeCreator[dwNumTypeCreators++] = *pAfpTypeCreator;
|
|
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators = dwNumTypeCreators;
|
|
AfpGlobals.AfpETCMapInfo.afpetc_type_creator = pTypeCreator;
|
|
|
|
// Sort the table
|
|
//
|
|
qsort( pTypeCreator,
|
|
dwNumTypeCreators,
|
|
sizeof(AFP_TYPE_CREATOR),
|
|
AfpBCompareTypeCreator );
|
|
|
|
} while( FALSE );
|
|
|
|
// MUTEX end
|
|
//
|
|
ReleaseMutex( AfpGlobals.hmutexETCMap );
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: AfpAdminrETCMapDelete
|
|
//
|
|
// Returns: NO_ERROR
|
|
// ERROR_ACCESS_DENIED
|
|
// AFPERR_TypeCreatorNotExistant
|
|
// non-zero returns from registry api's.
|
|
// non-zero returns from the FSD.
|
|
//
|
|
//
|
|
// Description: This routine will delete a type/creator tupple from the
|
|
// registry and the cache. If there are any extensions that map
|
|
// to this tupple, they are deleted.
|
|
// Shrinking by reallocating is not done. This will be done the
|
|
// next time an extension is added or if the server is restarted.
|
|
//
|
|
DWORD
|
|
AfpAdminrETCMapDelete(
|
|
IN AFP_SERVER_HANDLE hServer,
|
|
IN PAFP_TYPE_CREATOR pAfpTypeCreator
|
|
)
|
|
{
|
|
AFP_REQUEST_PACKET AfpSrp;
|
|
DWORD dwRetCode=0;
|
|
DWORD dwAccessStatus=0;
|
|
PAFP_TYPE_CREATOR pTypeCreator;
|
|
AFP_EXTENSION AfpExtensionKey;
|
|
PAFP_EXTENSION pExtension;
|
|
PAFP_EXTENSION pExtensionWalker;
|
|
DWORD cbSize;
|
|
DWORD dwIndex;
|
|
ETCMAPINFO2 ETCMapFSDBuf;
|
|
DWORD dwCount;
|
|
|
|
|
|
// Check if caller has access
|
|
//
|
|
if ( dwRetCode = AfpSecObjAccessCheck( AFPSVC_ALL_ACCESS, &dwAccessStatus))
|
|
{
|
|
AFP_PRINT(( "SFMSVC: AfpAdminrETCMapDelete, AfpSecObjAccessCheck failed %ld\n",dwRetCode));
|
|
AfpLogEvent( AFPLOG_CANT_CHECK_ACCESS, 0, NULL,
|
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|
return( ERROR_ACCESS_DENIED );
|
|
}
|
|
|
|
if ( dwAccessStatus )
|
|
{
|
|
AFP_PRINT(( "SFMSVC: AfpAdminrETCMapDelete, AfpSecObjAccessCheck returned %ld\n",dwAccessStatus));
|
|
return( ERROR_ACCESS_DENIED );
|
|
}
|
|
|
|
// MUTEX start
|
|
//
|
|
WaitForSingleObject( AfpGlobals.hmutexETCMap, INFINITE );
|
|
|
|
// This loop is used to allow break's instead of goto's to be used
|
|
// on an error condition.
|
|
//
|
|
do {
|
|
|
|
dwRetCode = NO_ERROR;
|
|
|
|
// First check to see if the type/creator exists.
|
|
//
|
|
pTypeCreator = AfpBinarySearch(
|
|
pAfpTypeCreator,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
|
|
sizeof(AFP_TYPE_CREATOR),
|
|
AfpBCompareTypeCreator );
|
|
|
|
// It does not exist so return error
|
|
//
|
|
if ( pTypeCreator == NULL ) {
|
|
dwRetCode = (DWORD)AFPERR_TypeCreatorNotExistant;
|
|
break;
|
|
}
|
|
|
|
// If this is the default type/creator
|
|
//
|
|
if ( pTypeCreator->afptc_id == AFP_DEF_TCID ) {
|
|
dwRetCode = (DWORD)AFPERR_CannotDeleteDefaultTC;
|
|
break;
|
|
}
|
|
|
|
// Store the id of this type/creator. All extensions with this
|
|
// id will have to be deleted.
|
|
//
|
|
AfpExtensionKey.afpe_tcid = pTypeCreator->afptc_id;
|
|
|
|
// Walk the list of extensions and delete all entries with
|
|
// the corresponding type/creator ID
|
|
//
|
|
pExtension = AfpBinarySearch(
|
|
&AfpExtensionKey,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_extension,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_extensions,
|
|
sizeof(AFP_EXTENSION),
|
|
AfpBCompareExtension );
|
|
|
|
if ( pExtension != NULL ) {
|
|
|
|
for ( dwIndex = (DWORD)(((ULONG_PTR)pExtension -
|
|
(ULONG_PTR)(AfpGlobals.AfpETCMapInfo.afpetc_extension)) / sizeof(AFP_EXTENSION)),
|
|
pExtensionWalker = pExtension,
|
|
dwCount = 0;
|
|
|
|
( dwIndex < AfpGlobals.AfpETCMapInfo.afpetc_num_extensions )
|
|
&&
|
|
( pExtensionWalker->afpe_tcid == AfpExtensionKey.afpe_tcid );
|
|
|
|
dwIndex++,
|
|
dwCount++,
|
|
pExtensionWalker++ )
|
|
{
|
|
|
|
// IOCTL the FSD to delete this tupple
|
|
//
|
|
AfpBufCopyFSDETCMapInfo( pAfpTypeCreator,
|
|
pExtensionWalker,
|
|
&ETCMapFSDBuf );
|
|
|
|
AfpSrp.dwRequestCode = OP_SERVER_DELETE_ETC;
|
|
AfpSrp.dwApiType = AFP_API_TYPE_DELETE;
|
|
AfpSrp.Type.Delete.pInputBuf = &ETCMapFSDBuf;
|
|
AfpSrp.Type.Delete.cbInputBufSize = sizeof(ETCMAPINFO2);
|
|
|
|
if ( dwRetCode = AfpServerIOCtrl( &AfpSrp ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Delete this extension from the registry
|
|
//
|
|
if ( dwRetCode = AfpRegExtensionDelete( pExtensionWalker ))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( dwRetCode )
|
|
break;
|
|
|
|
// Remove the extensions from the cache
|
|
//
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_extensions -= dwCount;
|
|
|
|
// Remove these extensions from the cache too
|
|
//
|
|
cbSize = AfpGlobals.AfpETCMapInfo.afpetc_num_extensions
|
|
* sizeof(AFP_EXTENSION);
|
|
|
|
cbSize -= (DWORD)((ULONG_PTR)pExtension -
|
|
(ULONG_PTR)(AfpGlobals.AfpETCMapInfo.afpetc_extension));
|
|
|
|
CopyMemory( (LPBYTE)pExtension, (LPBYTE)pExtensionWalker, cbSize );
|
|
|
|
}
|
|
|
|
// Delete the type/creator from the registry
|
|
//
|
|
if ( dwRetCode = AfpRegTypeCreatorDelete( pTypeCreator ) )
|
|
break;
|
|
|
|
// Delete the type/creator from the cache
|
|
//
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators--;
|
|
|
|
cbSize = AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators
|
|
* sizeof(AFP_TYPE_CREATOR);
|
|
|
|
cbSize -= (DWORD)((ULONG_PTR)pTypeCreator -
|
|
(ULONG_PTR)AfpGlobals.AfpETCMapInfo.afpetc_type_creator);
|
|
|
|
CopyMemory( (LPBYTE)pTypeCreator,
|
|
(LPBYTE)((ULONG_PTR)pTypeCreator+sizeof(AFP_TYPE_CREATOR)),
|
|
cbSize );
|
|
|
|
} while( FALSE );
|
|
|
|
// MUTEX end
|
|
//
|
|
ReleaseMutex( AfpGlobals.hmutexETCMap );
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: AfpAdminrETCMapSetInfo
|
|
//
|
|
// Returns: NO_ERROR
|
|
// ERROR_ACCESS_DENIED
|
|
// AFPERR_TypeCreatorNotExistant
|
|
// AFPERR_CannotEditDefaultTC;
|
|
// non-zero returns from registry api's.
|
|
//
|
|
// Description: This routine will simply change the comment for a type/creator
|
|
// tupple.
|
|
//
|
|
DWORD
|
|
AfpAdminrETCMapSetInfo(
|
|
IN AFP_SERVER_HANDLE hServer,
|
|
IN PAFP_TYPE_CREATOR pAfpTypeCreator
|
|
)
|
|
{
|
|
DWORD dwRetCode=0;
|
|
DWORD dwAccessStatus=0;
|
|
PAFP_TYPE_CREATOR pTypeCreator;
|
|
|
|
|
|
// Check if caller has access
|
|
//
|
|
if ( dwRetCode = AfpSecObjAccessCheck( AFPSVC_ALL_ACCESS, &dwAccessStatus))
|
|
{
|
|
AFP_PRINT(( "SFMSVC: AfpAdminrETCMapSetInfo, AfpSecObjAccessCheck failed %ld\n",dwRetCode));
|
|
AfpLogEvent( AFPLOG_CANT_CHECK_ACCESS, 0, NULL,
|
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|
return( ERROR_ACCESS_DENIED );
|
|
}
|
|
|
|
if ( dwAccessStatus )
|
|
{
|
|
AFP_PRINT(( "SFMSVC: AfpAdminrETCMapSetInfo, AfpSecObjAccessCheck returned %ld\n",dwAccessStatus));
|
|
return( ERROR_ACCESS_DENIED );
|
|
}
|
|
|
|
// MUTEX start
|
|
//
|
|
WaitForSingleObject( AfpGlobals.hmutexETCMap, INFINITE );
|
|
|
|
// This loop is used to allow break's instead of goto's to be used
|
|
// on an error condition.
|
|
//
|
|
do {
|
|
dwRetCode = NO_ERROR;
|
|
|
|
|
|
// First check to see if the type/creator exists.
|
|
//
|
|
pTypeCreator = AfpBinarySearch(
|
|
pAfpTypeCreator,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
|
|
sizeof(AFP_TYPE_CREATOR),
|
|
AfpBCompareTypeCreator );
|
|
|
|
// It does not exist so return error
|
|
//
|
|
if ( pTypeCreator == NULL ) {
|
|
dwRetCode = (DWORD)AFPERR_TypeCreatorNotExistant;
|
|
break;
|
|
}
|
|
|
|
// If this is the default type/creator
|
|
//
|
|
if ( pTypeCreator->afptc_id == AFP_DEF_TCID ) {
|
|
dwRetCode = (DWORD)AFPERR_CannotEditDefaultTC;
|
|
break;
|
|
}
|
|
|
|
// Copy the id.
|
|
//
|
|
pAfpTypeCreator->afptc_id = pTypeCreator->afptc_id;
|
|
|
|
// Set the comment in the registry
|
|
//
|
|
if ( dwRetCode = AfpRegTypeCreatorSetInfo( pAfpTypeCreator ) ) {
|
|
break;
|
|
}
|
|
|
|
// Set the comment in the cache.
|
|
//
|
|
STRCPY( pTypeCreator->afptc_comment, pAfpTypeCreator->afptc_comment );
|
|
|
|
} while( FALSE );
|
|
|
|
// MUTEX end
|
|
//
|
|
ReleaseMutex( AfpGlobals.hmutexETCMap );
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: AfpAdminrETCMapAssociate
|
|
//
|
|
// Returns: NO_ERROR
|
|
// ERROR_ACCESS_DENIED
|
|
// AFPERR_TypeCreatorNotExistant
|
|
// non-zero returns from registry api's.
|
|
// non-zero returns from the FSD
|
|
//
|
|
//
|
|
// Description: This routine will associate the given extension with the
|
|
// specified type/creator if it exists. If the extension is
|
|
// being mapped to the default type/creator, it will be
|
|
// deleted.
|
|
//
|
|
DWORD
|
|
AfpAdminrETCMapAssociate(
|
|
IN AFP_SERVER_HANDLE hServer,
|
|
IN PAFP_TYPE_CREATOR pAfpTypeCreator,
|
|
IN PAFP_EXTENSION pAfpExtension
|
|
)
|
|
{
|
|
AFP_REQUEST_PACKET AfpSrp;
|
|
DWORD dwRetCode=0;
|
|
DWORD dwAccessStatus=0;
|
|
PAFP_TYPE_CREATOR pTypeCreator;
|
|
PAFP_EXTENSION pExtension;
|
|
SRVETCPKT SrvETCPkt;
|
|
DWORD dwNumExtensions;
|
|
DWORD cbSize;
|
|
BYTE bETCMapFSDBuf[sizeof(ETCMAPINFO2)+sizeof(SETINFOREQPKT)];
|
|
|
|
|
|
// Check if caller has access
|
|
//
|
|
if ( dwRetCode = AfpSecObjAccessCheck( AFPSVC_ALL_ACCESS, &dwAccessStatus))
|
|
{
|
|
AFP_PRINT(( "SFMSVC: AfpAdminrETCMapAssociate, AfpSecObjAccessCheck failed %ld\n",dwRetCode));
|
|
AfpLogEvent( AFPLOG_CANT_CHECK_ACCESS, 0, NULL,
|
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|
return( ERROR_ACCESS_DENIED );
|
|
}
|
|
|
|
if ( dwAccessStatus )
|
|
{
|
|
AFP_PRINT(( "SFMSVC: AfpAdminrETCMapAssociate, AfpSecObjAccessCheck returned %ld\n",dwAccessStatus));
|
|
return( ERROR_ACCESS_DENIED );
|
|
}
|
|
|
|
// MUTEX start
|
|
//
|
|
WaitForSingleObject( AfpGlobals.hmutexETCMap, INFINITE );
|
|
|
|
// This loop is used to allow break's instead of goto's to be used
|
|
// on an error condition.
|
|
//
|
|
do {
|
|
dwRetCode = NO_ERROR;
|
|
|
|
// First check to see if the type/creator pair that the
|
|
// new extension is to be associated with, exists.
|
|
//
|
|
pTypeCreator = AfpBinarySearch(
|
|
pAfpTypeCreator,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
|
|
sizeof(AFP_TYPE_CREATOR),
|
|
AfpBCompareTypeCreator );
|
|
|
|
// It does not exist so return error
|
|
//
|
|
if ( pTypeCreator == NULL ) {
|
|
dwRetCode = (DWORD)AFPERR_TypeCreatorNotExistant;
|
|
break;
|
|
}
|
|
|
|
// Now check to see if the extension is already associated with
|
|
// a type/creator pair.
|
|
//
|
|
dwNumExtensions = AfpGlobals.AfpETCMapInfo.afpetc_num_extensions;
|
|
pExtension = _lfind( pAfpExtension,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_extension,
|
|
(unsigned int *)&dwNumExtensions,
|
|
sizeof(AFP_EXTENSION),
|
|
AfpLCompareExtension );
|
|
|
|
// Not currently associated so we need to add an entry
|
|
//
|
|
if ( pExtension == NULL ) {
|
|
|
|
// If this extension is being associated with the default
|
|
// then simply return.
|
|
//
|
|
if ( pTypeCreator->afptc_id == AFP_DEF_TCID ) {
|
|
dwRetCode = NO_ERROR;
|
|
break;
|
|
}
|
|
|
|
// Add mapping to FSD
|
|
//
|
|
AfpBufCopyFSDETCMapInfo( pAfpTypeCreator,
|
|
pAfpExtension,
|
|
&(SrvETCPkt.retc_EtcMaps[0]) );
|
|
|
|
SrvETCPkt.retc_NumEtcMaps = 1;
|
|
|
|
AfpSrp.dwRequestCode = OP_SERVER_ADD_ETC;
|
|
AfpSrp.dwApiType = AFP_API_TYPE_ADD;
|
|
AfpSrp.Type.Add.pInputBuf = &SrvETCPkt;
|
|
AfpSrp.Type.Add.cbInputBufSize = sizeof(SRVETCPKT);
|
|
|
|
if ( dwRetCode = AfpServerIOCtrl( &AfpSrp ) )
|
|
break;
|
|
|
|
// Add extension to registry.
|
|
//
|
|
pAfpExtension->afpe_tcid = pTypeCreator->afptc_id;
|
|
|
|
if ( dwRetCode = AfpRegExtensionSetInfo( pAfpExtension ) ) {
|
|
break;
|
|
}
|
|
|
|
// Add extension to cache.
|
|
//
|
|
pExtension = AfpGlobals.AfpETCMapInfo.afpetc_extension;
|
|
dwNumExtensions = AfpGlobals.AfpETCMapInfo.afpetc_num_extensions;
|
|
|
|
pExtension = (PAFP_EXTENSION)LocalReAlloc(
|
|
pExtension,
|
|
(dwNumExtensions+1)*sizeof(AFP_EXTENSION),
|
|
LMEM_MOVEABLE );
|
|
|
|
if ( pExtension == NULL ) {
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
pExtension[dwNumExtensions++] = *pAfpExtension;
|
|
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_extensions = dwNumExtensions;
|
|
AfpGlobals.AfpETCMapInfo.afpetc_extension = pExtension;
|
|
|
|
}
|
|
|
|
// Extension is already mapped.
|
|
//
|
|
else {
|
|
|
|
// If this extension is being associated with the default
|
|
// then delete this extension from the registry and cache and
|
|
// delete the mapping from the FSD
|
|
//
|
|
if ( pTypeCreator->afptc_id == AFP_DEF_TCID ) {
|
|
|
|
// IOCTL the FSD to delete this tupple
|
|
//
|
|
AfpBufCopyFSDETCMapInfo( pAfpTypeCreator,
|
|
pAfpExtension,
|
|
(PETCMAPINFO2)bETCMapFSDBuf );
|
|
|
|
AfpSrp.dwRequestCode = OP_SERVER_DELETE_ETC;
|
|
AfpSrp.dwApiType = AFP_API_TYPE_DELETE;
|
|
AfpSrp.Type.Delete.pInputBuf = bETCMapFSDBuf;
|
|
AfpSrp.Type.Delete.cbInputBufSize = sizeof(ETCMAPINFO2);
|
|
|
|
if ( dwRetCode = AfpServerIOCtrl( &AfpSrp ) )
|
|
break;
|
|
|
|
// Delete this extension from the registry
|
|
//
|
|
if ( dwRetCode = AfpRegExtensionDelete( pAfpExtension ) ) {
|
|
break;
|
|
}
|
|
|
|
// Remove this extensions from the cache too
|
|
//
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_extensions--;
|
|
|
|
cbSize = AfpGlobals.AfpETCMapInfo.afpetc_num_extensions
|
|
* sizeof(AFP_EXTENSION);
|
|
|
|
cbSize -= (DWORD)((ULONG_PTR)pExtension -
|
|
(ULONG_PTR)(AfpGlobals.AfpETCMapInfo.afpetc_extension));
|
|
|
|
CopyMemory( (LPBYTE)pExtension,
|
|
(LPBYTE)((ULONG_PTR)pExtension+sizeof(AFP_EXTENSION)),
|
|
cbSize );
|
|
|
|
}
|
|
else {
|
|
|
|
// Otherwise simply change the mapping in the FSD
|
|
//
|
|
pExtension->afpe_tcid = pTypeCreator->afptc_id;
|
|
|
|
AfpBufCopyFSDETCMapInfo(pTypeCreator,
|
|
pExtension,
|
|
(PETCMAPINFO2)(bETCMapFSDBuf+sizeof(SETINFOREQPKT)));
|
|
|
|
AfpSrp.dwRequestCode = OP_SERVER_SET_ETC;
|
|
AfpSrp.dwApiType = AFP_API_TYPE_SETINFO;
|
|
AfpSrp.Type.SetInfo.pInputBuf = bETCMapFSDBuf;
|
|
AfpSrp.Type.SetInfo.cbInputBufSize = sizeof(bETCMapFSDBuf);
|
|
|
|
if ( dwRetCode = AfpServerIOCtrl( &AfpSrp ) )
|
|
break;
|
|
|
|
// Change the registry
|
|
//
|
|
if ( dwRetCode = AfpRegExtensionSetInfo( pExtension ) ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// Sort the table
|
|
//
|
|
qsort( AfpGlobals.AfpETCMapInfo.afpetc_extension,
|
|
AfpGlobals.AfpETCMapInfo.afpetc_num_extensions,
|
|
sizeof(AFP_EXTENSION),
|
|
AfpBCompareExtension );
|
|
|
|
} while( FALSE );
|
|
|
|
// MUTEX end
|
|
//
|
|
ReleaseMutex( AfpGlobals.hmutexETCMap );
|
|
|
|
return( dwRetCode );
|
|
}
|