1300 lines
33 KiB
C
1300 lines
33 KiB
C
|
/********************************************************************/
|
|||
|
/** Copyright(c) 1989 Microsoft Corporation. **/
|
|||
|
/********************************************************************/
|
|||
|
|
|||
|
//***
|
|||
|
//
|
|||
|
// Filename: init.c
|
|||
|
//
|
|||
|
// Description: This module contains code to intialize and de-initialize
|
|||
|
// the AFP Server, RPC server, the security object and
|
|||
|
// other global vriables.
|
|||
|
//
|
|||
|
// History:
|
|||
|
// May 11,1992. NarenG Created original version.
|
|||
|
//
|
|||
|
//
|
|||
|
#include "afpsvcp.h"
|
|||
|
|
|||
|
// Prototypes of functions used only within this module.
|
|||
|
//
|
|||
|
DWORD
|
|||
|
AfpInitServerVolumes(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
AfpInitServerParameters(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
AfpInitServerIcons(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
AfpInitETCMaps(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
AfpInitRPC(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
AfpInitServerDomainOffsets(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
AfpTerminateRPC(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
AfpIniLsa(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
IsAfpGuestAccountEnabled(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: AfpInitialize
|
|||
|
//
|
|||
|
// Returns: NO_ERROR
|
|||
|
//
|
|||
|
// Description: Will do all server intialization.
|
|||
|
// 1) Create the security object.
|
|||
|
// 2) Set up the server for RPC.
|
|||
|
// 3) Open all the registry keys that store AFP data.
|
|||
|
// 4) Get the handle to the FSD.
|
|||
|
// 5) Get default server parameters
|
|||
|
// 6) It will initialize the AFP Server with volume, ETC, icon
|
|||
|
// and server parameter information.
|
|||
|
// 7) IOCTL the FSD to start the server.
|
|||
|
//
|
|||
|
DWORD
|
|||
|
AfpInitialize(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
AFP_REQUEST_PACKET AfpRequestPkt;
|
|||
|
DWORD dwRetCode;
|
|||
|
BOOL fFirstThread;
|
|||
|
DWORD nThreads;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// Load strings from resource file
|
|||
|
//
|
|||
|
if (( !LoadString( GetModuleHandle( NULL ), 1, AfpGlobals.wchUnknown, 100 ))
|
|||
|
||
|
|||
|
( !LoadString( GetModuleHandle( NULL ), 2, AfpGlobals.wchInvalid, 100 ))
|
|||
|
||
|
|||
|
( !LoadString( GetModuleHandle( NULL ), 3, AfpGlobals.wchDeleted, 100 ))
|
|||
|
||
|
|||
|
( !LoadString( GetModuleHandle( NULL ), 4, AfpGlobals.wchDefTCComment,
|
|||
|
AFP_ETC_COMMENT_LEN+1 )))
|
|||
|
AfpLogEvent( AFPLOG_CANT_LOAD_RESOURCE, 0, NULL,
|
|||
|
GetLastError(), EVENTLOG_WARNING_TYPE );
|
|||
|
|
|||
|
//
|
|||
|
// Create the security object
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpSecObjCreate() ) {
|
|||
|
AfpLogEvent( AFPLOG_CANT_CREATE_SECOBJ, 0, NULL,
|
|||
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
// Initialize the server to accept RPC calls
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpInitRPC() ) {
|
|||
|
AfpLogEvent( AFPLOG_CANT_INIT_RPC, 0, NULL,
|
|||
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
AfpGlobals.dwServerState |= AFPSTATE_RPC_STARTED;
|
|||
|
|
|||
|
// Open the registry keys where AFP Server information is stored
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpRegOpen() ) {
|
|||
|
AfpLogEvent( AFPLOG_CANT_OPEN_REGKEY, 0, NULL,
|
|||
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
AfpGlobals.ServiceStatus.dwCheckPoint++;
|
|||
|
AfpAnnounceServiceStatus();
|
|||
|
|
|||
|
// Open and load the AFP Server FSD and obtain a handle to it
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpFSDLoad() ) {
|
|||
|
AfpLogEvent( AFPLOG_CANT_LOAD_FSD, 0, NULL,
|
|||
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
AfpGlobals.dwServerState |= AFPSTATE_FSD_LOADED;
|
|||
|
|
|||
|
if ( dwRetCode = AfpFSDOpen( &(AfpGlobals.hFSD) ) ) {
|
|||
|
AfpLogEvent( AFPLOG_CANT_OPEN_FSD, 0, NULL,
|
|||
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
// Query the product type of server.
|
|||
|
//
|
|||
|
AfpGlobals.pSidNone = NULL;
|
|||
|
RtlGetNtProductType ( &(AfpGlobals.NtProductType) );
|
|||
|
|
|||
|
// Create the event object for the server helper thread.
|
|||
|
//
|
|||
|
if ( (AfpGlobals.heventSrvrHlprThread =
|
|||
|
CreateEvent( NULL, FALSE, FALSE, NULL ) ) == NULL){
|
|||
|
AfpLogEvent( AFPLOG_CANT_START, 0, NULL, GetLastError(),
|
|||
|
EVENTLOG_ERROR_TYPE );
|
|||
|
return( GetLastError() );
|
|||
|
}
|
|||
|
|
|||
|
// Create the event object for the server helper thread termination.
|
|||
|
//
|
|||
|
if ( (AfpGlobals.heventSrvrHlprThreadTerminate =
|
|||
|
CreateEvent( NULL, FALSE, FALSE, NULL ) ) == NULL){
|
|||
|
AfpLogEvent( AFPLOG_CANT_START, 0, NULL, GetLastError(),
|
|||
|
EVENTLOG_ERROR_TYPE );
|
|||
|
return( GetLastError() );
|
|||
|
}
|
|||
|
|
|||
|
// Create the event object for the "special case" unblocking of server helper thread
|
|||
|
//
|
|||
|
if ( (AfpGlobals.heventSrvrHlprSpecial =
|
|||
|
CreateEvent( NULL, FALSE, FALSE, NULL ) ) == NULL){
|
|||
|
AfpLogEvent( AFPLOG_CANT_START, 0, NULL, GetLastError(),
|
|||
|
EVENTLOG_ERROR_TYPE );
|
|||
|
return( GetLastError() );
|
|||
|
}
|
|||
|
|
|||
|
// Create server helper threads. The parameter indicates if this is the
|
|||
|
// first thread that is being created.
|
|||
|
//
|
|||
|
fFirstThread = TRUE;
|
|||
|
nThreads = 0;
|
|||
|
|
|||
|
do {
|
|||
|
|
|||
|
if ( ( dwRetCode = AfpCreateServerHelperThread( fFirstThread ) )
|
|||
|
!= NO_ERROR ) {
|
|||
|
AfpLogEvent( AFPLOG_CANT_CREATE_SRVRHLPR, 0, NULL,
|
|||
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|||
|
|
|||
|
if ( fFirstThread ) {
|
|||
|
AfpLogEvent( AFPLOG_CANT_START, 0, NULL,
|
|||
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Wait for the server helper thread to indicate if it successfully
|
|||
|
// initialized itself.
|
|||
|
//
|
|||
|
WaitForSingleObject( AfpGlobals.heventSrvrHlprThread, INFINITE );
|
|||
|
|
|||
|
if ( AfpGlobals.dwSrvrHlprCode != NO_ERROR ) {
|
|||
|
AfpLogEvent(AFPLOG_CANT_INIT_SRVRHLPR,
|
|||
|
0,
|
|||
|
NULL,
|
|||
|
AfpGlobals.dwSrvrHlprCode,
|
|||
|
EVENTLOG_ERROR_TYPE );
|
|||
|
|
|||
|
if ( fFirstThread )
|
|||
|
{
|
|||
|
AFP_PRINT( ( "SFMSVC: can't start macfile, first thread failed %ld\n",
|
|||
|
AfpGlobals.dwSrvrHlprCode));
|
|||
|
AfpLogEvent( AFPLOG_CANT_START, 0, NULL, dwRetCode,
|
|||
|
EVENTLOG_ERROR_TYPE );
|
|||
|
return( AfpGlobals.dwSrvrHlprCode );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
fFirstThread = FALSE;
|
|||
|
|
|||
|
}while( ++nThreads < NUM_SECURITY_UTILITY_THREADS );
|
|||
|
|
|||
|
// Read in server parameters from the registry and intialize the
|
|||
|
// server with them.
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpInitServerParameters())
|
|||
|
{
|
|||
|
AFP_PRINT( ( "SFMSVC: AfpInitServerParameters failed %ld\n",dwRetCode));
|
|||
|
AfpLogEvent( AFPLOG_CANT_INIT_SRVR_PARAMS, 0, NULL, dwRetCode,EVENTLOG_ERROR_TYPE );
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
AfpGlobals.ServiceStatus.dwCheckPoint++;
|
|||
|
AfpAnnounceServiceStatus();
|
|||
|
|
|||
|
|
|||
|
// Read in the ETC Mappings and initialize the AFP Server with them
|
|||
|
// Also create a private cache of this information.
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpInitETCMaps() )
|
|||
|
{
|
|||
|
AFP_PRINT( ( "SFMSVC: AfpInitETCMaps failed %ld\n",dwRetCode));
|
|||
|
AfpLogEvent( AFPLOG_CANT_INIT_ETCINFO, 0, NULL, dwRetCode,EVENTLOG_ERROR_TYPE );
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if ( dwRetCode = AfpInitServerIcons() )
|
|||
|
{
|
|||
|
AFP_PRINT( ( "SFMSVC: AfpInitServerIcons failed %ld\n",dwRetCode));
|
|||
|
AfpLogEvent( AFPLOG_CANT_INIT_ICONS, 0, NULL, dwRetCode ,EVENTLOG_ERROR_TYPE );
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
AfpGlobals.ServiceStatus.dwCheckPoint++;
|
|||
|
AfpAnnounceServiceStatus();
|
|||
|
|
|||
|
// Read in any volumes and initialize the server with them
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpInitServerVolumes() )
|
|||
|
{
|
|||
|
AFP_PRINT( ( "SFMSVC: AfpInitServerVolumes failed %ld\n",dwRetCode));
|
|||
|
AfpLogEvent( AFPLOG_CANT_INIT_VOLUMES, 0, NULL, dwRetCode,EVENTLOG_ERROR_TYPE );
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Create mutex objects around volume operations to avoid simultaneous
|
|||
|
// writing in the registry.
|
|||
|
//
|
|||
|
if ( (AfpGlobals.hmutexVolume = CreateMutex( NULL, FALSE, NULL ) ) == NULL)
|
|||
|
{
|
|||
|
AFP_PRINT( ( "SFMSVC: CreateMutex failed in AfpInitialize\n"));
|
|||
|
AfpLogEvent( AFPLOG_CANT_START, 0, NULL, dwRetCode,EVENTLOG_ERROR_TYPE );
|
|||
|
return( GetLastError() );
|
|||
|
}
|
|||
|
|
|||
|
// Create mutex objects around ETCMap operations.
|
|||
|
//
|
|||
|
if ( (AfpGlobals.hmutexETCMap = CreateMutex( NULL, FALSE, NULL ) ) == NULL)
|
|||
|
{
|
|||
|
AFP_PRINT( ( "SFMSVC: CreateMutex 2 failed in AfpInitialize\n"));
|
|||
|
AfpLogEvent( AFPLOG_CANT_START, 0, NULL, GetLastError(),EVENTLOG_ERROR_TYPE );
|
|||
|
return( GetLastError() );
|
|||
|
}
|
|||
|
|
|||
|
// OK we are all set to go so lets tell the AFP Server to start
|
|||
|
//
|
|||
|
AfpRequestPkt.dwRequestCode = OP_SERVICE_START;
|
|||
|
AfpRequestPkt.dwApiType = AFP_API_TYPE_COMMAND;
|
|||
|
|
|||
|
AFP_PRINT( ( "SFMSVC: ioctling sfmsrv to start\n"));
|
|||
|
|
|||
|
if ( dwRetCode = AfpServerIOCtrl( &AfpRequestPkt ) )
|
|||
|
{
|
|||
|
AFP_PRINT( ( "SFMSVC: AfpServerIOCtrl to start sfmsrv failed %ld\n",dwRetCode));
|
|||
|
AfpLogEvent( AFPLOG_CANT_START,0,NULL,dwRetCode,EVENTLOG_ERROR_TYPE);
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
AfpIniLsa();
|
|||
|
|
|||
|
return( NO_ERROR );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: AfpTerminate
|
|||
|
//
|
|||
|
// Returns: none.
|
|||
|
//
|
|||
|
// Description: This procedure will shut down the server, and do any
|
|||
|
// clean up if required.
|
|||
|
//
|
|||
|
VOID
|
|||
|
AfpTerminate(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
AFP_REQUEST_PACKET AfpRequestPkt;
|
|||
|
DWORD dwRetCode;
|
|||
|
|
|||
|
|
|||
|
// If the FSD was loaded
|
|||
|
//
|
|||
|
if ( AfpGlobals.dwServerState & AFPSTATE_FSD_LOADED ) {
|
|||
|
|
|||
|
// Tell the server to shut down
|
|||
|
//
|
|||
|
AfpRequestPkt.dwRequestCode = OP_SERVICE_STOP;
|
|||
|
AfpRequestPkt.dwApiType = AFP_API_TYPE_COMMAND;
|
|||
|
|
|||
|
if ( dwRetCode = AfpServerIOCtrl( &AfpRequestPkt ) )
|
|||
|
AfpLogEvent( AFPLOG_CANT_STOP, 0, NULL,
|
|||
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|||
|
}
|
|||
|
|
|||
|
AfpGlobals.ServiceStatus.dwCheckPoint++;
|
|||
|
AfpAnnounceServiceStatus();
|
|||
|
|
|||
|
// Try to close the FSD
|
|||
|
//
|
|||
|
if ( AfpGlobals.hFSD != NULL )
|
|||
|
{
|
|||
|
if ( dwRetCode = AfpFSDClose( AfpGlobals.hFSD ) )
|
|||
|
{
|
|||
|
AfpLogEvent( AFPLOG_CANT_STOP, 0, NULL,
|
|||
|
dwRetCode, EVENTLOG_ERROR_TYPE );
|
|||
|
}
|
|||
|
|
|||
|
// Try to unload the FSD
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpFSDUnload() )
|
|||
|
{
|
|||
|
AfpLogEvent( AFPLOG_CANT_STOP, 0, NULL,
|
|||
|
dwRetCode, EVENTLOG_ERROR_TYPE);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
AfpGlobals.ServiceStatus.dwCheckPoint++;
|
|||
|
AfpAnnounceServiceStatus();
|
|||
|
|
|||
|
// Delete the security object.
|
|||
|
//
|
|||
|
AfpSecObjDelete();
|
|||
|
|
|||
|
// De-initialize the RPC server
|
|||
|
//
|
|||
|
AfpTerminateRPC();
|
|||
|
|
|||
|
// Close the registry keys.
|
|||
|
//
|
|||
|
AfpRegClose();
|
|||
|
|
|||
|
// Free the pSidNone if we allocated it for standalone
|
|||
|
//
|
|||
|
if (AfpGlobals.pSidNone != NULL)
|
|||
|
{
|
|||
|
LocalFree(AfpGlobals.pSidNone);
|
|||
|
AfpGlobals.pSidNone = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if (SfmLsaHandle != NULL)
|
|||
|
{
|
|||
|
LsaDeregisterLogonProcess( SfmLsaHandle );
|
|||
|
SfmLsaHandle = NULL;
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: AfpInitServerParameters
|
|||
|
//
|
|||
|
// Returns: NO_ERROR
|
|||
|
// non-zero return codes from the IOCTL or other system calls.
|
|||
|
//
|
|||
|
// Description: This procedure will set default values for parameters. It
|
|||
|
// will then call AfpRegServerGetInfo to override these defaults
|
|||
|
// with any parameters that may be stored in the registry. It
|
|||
|
// will then initialize the FSD with these parameters.
|
|||
|
//
|
|||
|
DWORD
|
|||
|
AfpInitServerParameters(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
AFP_SERVER_INFO AfpServerInfo;
|
|||
|
DWORD cbServerNameSize;
|
|||
|
DWORD dwRetCode;
|
|||
|
AFP_REQUEST_PACKET AfpRequestPkt;
|
|||
|
|
|||
|
|
|||
|
// Initialize all the server parameters with defaults
|
|||
|
//
|
|||
|
cbServerNameSize = sizeof( AfpGlobals.wchServerName );
|
|||
|
if ( !GetComputerName( AfpGlobals.wchServerName, &cbServerNameSize ) )
|
|||
|
return( GetLastError() );
|
|||
|
|
|||
|
AfpGlobals.dwMaxSessions = AFP_DEF_MAXSESSIONS;
|
|||
|
AfpGlobals.dwServerOptions = AFP_DEF_SRVOPTIONS;
|
|||
|
AfpGlobals.wchLoginMsg[0] = TEXT('\0');
|
|||
|
AfpGlobals.dwMaxPagedMem = AFP_DEF_MAXPAGEDMEM;
|
|||
|
AfpGlobals.dwMaxNonPagedMem = AFP_DEF_MAXNONPAGEDMEM;
|
|||
|
|
|||
|
// Read in any server parameters in the registry. Registry parameters
|
|||
|
// will override the defaults set above.
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpRegServerGetInfo() )
|
|||
|
return( dwRetCode );
|
|||
|
|
|||
|
if (IsAfpGuestAccountEnabled())
|
|||
|
{
|
|||
|
AfpGlobals.dwServerOptions |= AFP_SRVROPT_GUESTLOGONALLOWED;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
AfpGlobals.dwServerOptions &= ~AFP_SRVROPT_GUESTLOGONALLOWED;
|
|||
|
}
|
|||
|
|
|||
|
// Get the path to the codepage
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpRegServerGetCodePagePath() )
|
|||
|
return( dwRetCode );
|
|||
|
|
|||
|
// Set up server info structure
|
|||
|
//
|
|||
|
AfpServerInfo.afpsrv_name = AfpGlobals.wchServerName;
|
|||
|
AfpServerInfo.afpsrv_max_sessions = AfpGlobals.dwMaxSessions;
|
|||
|
AfpServerInfo.afpsrv_options = AfpGlobals.dwServerOptions;
|
|||
|
if (AfpGlobals.NtProductType != NtProductLanManNt)
|
|||
|
{
|
|||
|
AfpServerInfo.afpsrv_options |= AFP_SRVROPT_STANDALONE;
|
|||
|
}
|
|||
|
AfpServerInfo.afpsrv_login_msg = AfpGlobals.wchLoginMsg;
|
|||
|
AfpServerInfo.afpsrv_max_paged_mem = AfpGlobals.dwMaxPagedMem;
|
|||
|
AfpServerInfo.afpsrv_max_nonpaged_mem = AfpGlobals.dwMaxNonPagedMem;
|
|||
|
AfpServerInfo.afpsrv_codepage = AfpGlobals.wchCodePagePath;
|
|||
|
|
|||
|
// Make this buffer self-relative.
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpBufMakeFSDRequest(
|
|||
|
(LPBYTE)&AfpServerInfo,
|
|||
|
sizeof(SETINFOREQPKT),
|
|||
|
AFP_SERVER_STRUCT,
|
|||
|
(LPBYTE*)&(AfpRequestPkt.Type.SetInfo.pInputBuf),
|
|||
|
&(AfpRequestPkt.Type.SetInfo.cbInputBufSize)))
|
|||
|
{
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
// IOCTL the FSD to set the server parameters
|
|||
|
//
|
|||
|
AfpRequestPkt.dwRequestCode = OP_SERVER_SET_INFO;
|
|||
|
AfpRequestPkt.dwApiType = AFP_API_TYPE_SETINFO;
|
|||
|
AfpRequestPkt.Type.SetInfo.dwParmNum = AFP_SERVER_PARMNUM_ALL;
|
|||
|
|
|||
|
dwRetCode = AfpServerIOCtrl( &AfpRequestPkt );
|
|||
|
|
|||
|
LocalFree( AfpRequestPkt.Type.SetInfo.pInputBuf );
|
|||
|
|
|||
|
return( dwRetCode );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: AfpInitServerVolumes
|
|||
|
//
|
|||
|
// Returns: NO_ERROR - success
|
|||
|
// ERROR_NOT_ENOUGH_MEMORY
|
|||
|
// non-zero return codes from registry apis.
|
|||
|
//
|
|||
|
// Description: This procedure will read in a volume at a time from the
|
|||
|
// registry, and then register this volume with the server.
|
|||
|
// This procedure will only return fatal errors that will
|
|||
|
// require that the service to fail initialization. All other
|
|||
|
// error will be logged by this routine. All returns from the
|
|||
|
// the FSD are treated as non-fatal.
|
|||
|
//
|
|||
|
DWORD
|
|||
|
AfpInitServerVolumes(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwRetCode;
|
|||
|
LPWSTR lpwsValName, lpwsSrcIconPath, lpwsDstIconPath;
|
|||
|
DWORD dwMaxValNameLen;
|
|||
|
DWORD dwValNameBufSize;
|
|||
|
DWORD dwNumValues;
|
|||
|
DWORD dwMaxValueDataSize;
|
|||
|
DWORD dwIndex;
|
|||
|
DWORD dwType;
|
|||
|
DWORD dwBufSize;
|
|||
|
AFP_REQUEST_PACKET AfpRequestPkt;
|
|||
|
AFP_VOLUME_INFO VolumeInfo;
|
|||
|
LPBYTE lpbMultiSz;
|
|||
|
LPBYTE lpbFSDBuf;
|
|||
|
DWORD dwLength;
|
|||
|
DWORD dwCount;
|
|||
|
WCHAR wchServerIconFile[AFPSERVER_VOLUME_ICON_FILE_SIZE] = AFPSERVER_VOLUME_ICON_FILE;
|
|||
|
BOOLEAN fCopiedIcon;
|
|||
|
DWORD dwLastDstCharIndex;
|
|||
|
|
|||
|
// Find out the size of the largest data value and the largest
|
|||
|
// value name.
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpRegGetKeyInfo( AfpGlobals.hkeyVolumesList,
|
|||
|
&dwMaxValNameLen,
|
|||
|
&dwNumValues,
|
|||
|
&dwMaxValueDataSize
|
|||
|
))
|
|||
|
return( dwRetCode );
|
|||
|
|
|||
|
// If there are no volumes to add then simply return
|
|||
|
//
|
|||
|
if ( dwNumValues == 0 )
|
|||
|
return( NO_ERROR );
|
|||
|
|
|||
|
if (( lpwsValName = (LPWSTR)LocalAlloc( LPTR, dwMaxValNameLen ) ) == NULL )
|
|||
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|||
|
|
|||
|
if ((lpbMultiSz = (LPBYTE)LocalAlloc( LPTR, dwMaxValueDataSize )) == NULL ){
|
|||
|
LocalFree( lpwsValName );
|
|||
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|||
|
}
|
|||
|
|
|||
|
if (( lpwsSrcIconPath = (LPWSTR)LocalAlloc( LPTR, MAX_PATH * sizeof(WCHAR) ) ) == NULL )
|
|||
|
{
|
|||
|
LocalFree( lpwsValName );
|
|||
|
LocalFree( lpbMultiSz );
|
|||
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|||
|
}
|
|||
|
|
|||
|
if (( lpwsDstIconPath = (LPWSTR)LocalAlloc( LPTR, (MAX_PATH +
|
|||
|
AFPSERVER_VOLUME_ICON_FILE_SIZE + 1 +
|
|||
|
(sizeof(AFPSERVER_RESOURCE_STREAM)/sizeof(WCHAR))) *
|
|||
|
sizeof(WCHAR)) ) == NULL )
|
|||
|
{
|
|||
|
LocalFree( lpwsValName );
|
|||
|
LocalFree( lpbMultiSz );
|
|||
|
LocalFree( lpwsSrcIconPath );
|
|||
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|||
|
}
|
|||
|
|
|||
|
// Construct a path to the NTSFM volume custom icon
|
|||
|
//
|
|||
|
*lpwsSrcIconPath = 0;
|
|||
|
if ( GetSystemDirectory( lpwsSrcIconPath, MAX_PATH * sizeof(WCHAR) ))
|
|||
|
{
|
|||
|
wcscat( lpwsSrcIconPath, AFP_DEF_VOLICON_SRCNAME );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
for ( dwIndex = 0,
|
|||
|
dwBufSize = dwMaxValueDataSize,
|
|||
|
dwValNameBufSize = dwMaxValNameLen;
|
|||
|
|
|||
|
dwIndex < dwNumValues;
|
|||
|
|
|||
|
dwIndex++,
|
|||
|
dwBufSize = dwMaxValueDataSize,
|
|||
|
dwValNameBufSize = dwMaxValNameLen ) {
|
|||
|
|
|||
|
ZeroMemory( lpbMultiSz, dwBufSize );
|
|||
|
|
|||
|
// Get the volume info from the registry in multi-sz form.
|
|||
|
//
|
|||
|
if ( dwRetCode = RegEnumValue( AfpGlobals.hkeyVolumesList,
|
|||
|
dwIndex,
|
|||
|
lpwsValName,
|
|||
|
&dwValNameBufSize,
|
|||
|
NULL,
|
|||
|
&dwType,
|
|||
|
lpbMultiSz,
|
|||
|
&dwBufSize
|
|||
|
))
|
|||
|
break;
|
|||
|
|
|||
|
// Parse the mult sz and extract info into volume info structure
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpBufParseMultiSz(
|
|||
|
AFP_VOLUME_STRUCT,
|
|||
|
lpbMultiSz,
|
|||
|
(LPBYTE)&VolumeInfo ) ) {
|
|||
|
|
|||
|
// If this volume contained invalid registry information then log
|
|||
|
// it and store the volume name in the list of invalid volumes.
|
|||
|
//
|
|||
|
AfpAddInvalidVolume( lpwsValName, NULL );
|
|||
|
|
|||
|
AfpLogEvent( AFPLOG_INVALID_VOL_REG,1,&lpwsValName,
|
|||
|
dwRetCode, EVENTLOG_WARNING_TYPE );
|
|||
|
dwRetCode = NO_ERROR;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// Insert the volume name viz. the valuename
|
|||
|
//
|
|||
|
VolumeInfo.afpvol_name = lpwsValName;
|
|||
|
|
|||
|
// Validate the volume info structure
|
|||
|
//
|
|||
|
if ( !IsAfpVolumeInfoValid( AFP_VALIDATE_ALL_FIELDS, &VolumeInfo ) ) {
|
|||
|
|
|||
|
// If this volume contained invalid registry information then log
|
|||
|
// it and store the volume name in the list of invalid volumes.
|
|||
|
//
|
|||
|
AfpAddInvalidVolume( lpwsValName, NULL );
|
|||
|
|
|||
|
AfpLogEvent( AFPLOG_INVALID_VOL_REG,1,&lpwsValName,
|
|||
|
dwRetCode, EVENTLOG_WARNING_TYPE );
|
|||
|
dwRetCode = NO_ERROR;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// If there is a password then decrypt it
|
|||
|
//
|
|||
|
if ( VolumeInfo.afpvol_password != (LPWSTR)NULL ){
|
|||
|
|
|||
|
dwLength = STRLEN( VolumeInfo.afpvol_password );
|
|||
|
|
|||
|
for ( dwCount = 0; dwCount < dwLength; dwCount++ )
|
|||
|
VolumeInfo.afpvol_password[dwCount] ^= 0xF000;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Construct a path to the destination volume "Icon<0D>" file
|
|||
|
//
|
|||
|
|
|||
|
fCopiedIcon = FALSE;
|
|||
|
|
|||
|
wcscpy( lpwsDstIconPath, VolumeInfo.afpvol_path );
|
|||
|
if (lpwsDstIconPath[wcslen(lpwsDstIconPath) - 1] != TEXT('\\'))
|
|||
|
{
|
|||
|
wcscat( lpwsDstIconPath, TEXT("\\") );
|
|||
|
}
|
|||
|
wcscat( lpwsDstIconPath, wchServerIconFile );
|
|||
|
// Keep track of end of name without the resource fork tacked on
|
|||
|
//
|
|||
|
dwLastDstCharIndex = wcslen(lpwsDstIconPath);
|
|||
|
wcscat( lpwsDstIconPath, AFPSERVER_RESOURCE_STREAM );
|
|||
|
|
|||
|
// Copy the icon file to the root of the volume (do not overwrite)
|
|||
|
//
|
|||
|
if ((fCopiedIcon = (BOOLEAN)CopyFile( lpwsSrcIconPath, lpwsDstIconPath, TRUE )) ||
|
|||
|
(GetLastError() == ERROR_FILE_EXISTS))
|
|||
|
{
|
|||
|
VolumeInfo.afpvol_props_mask |= AFP_VOLUME_HAS_CUSTOM_ICON;
|
|||
|
|
|||
|
// Make sure the file is hidden
|
|||
|
SetFileAttributes( lpwsDstIconPath,
|
|||
|
FILE_ATTRIBUTE_HIDDEN |
|
|||
|
FILE_ATTRIBUTE_ARCHIVE );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Make this a self relative buffer
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpBufMakeFSDRequest(
|
|||
|
(LPBYTE)&VolumeInfo,
|
|||
|
0,
|
|||
|
AFP_VOLUME_STRUCT,
|
|||
|
&lpbFSDBuf,
|
|||
|
&dwBufSize
|
|||
|
))
|
|||
|
break;
|
|||
|
|
|||
|
// Initialize the FSD with this volume
|
|||
|
//
|
|||
|
AfpRequestPkt.dwRequestCode = OP_VOLUME_ADD;
|
|||
|
AfpRequestPkt.dwApiType = AFP_API_TYPE_ADD;
|
|||
|
AfpRequestPkt.Type.Add.pInputBuf = lpbFSDBuf;
|
|||
|
AfpRequestPkt.Type.Add.cbInputBufSize = dwBufSize;
|
|||
|
|
|||
|
dwRetCode = AfpServerIOCtrl( &AfpRequestPkt );
|
|||
|
|
|||
|
if ( dwRetCode ) {
|
|||
|
|
|||
|
// If this volume could not be added by the FSD then we errorlog
|
|||
|
// this and insert this volume into the list of invalid volumes.
|
|||
|
//
|
|||
|
AfpAddInvalidVolume( lpwsValName, VolumeInfo.afpvol_path );
|
|||
|
|
|||
|
AfpLogEvent( AFPLOG_CANT_ADD_VOL, 1, &lpwsValName,
|
|||
|
dwRetCode, EVENTLOG_WARNING_TYPE );
|
|||
|
dwRetCode = NO_ERROR;
|
|||
|
|
|||
|
// Delete the icon file we just copied if the volume add failed
|
|||
|
//
|
|||
|
if ( fCopiedIcon )
|
|||
|
{
|
|||
|
// Truncate the resource fork name so we delete the whole file
|
|||
|
lpwsDstIconPath[dwLastDstCharIndex] = 0;
|
|||
|
DeleteFile( lpwsDstIconPath );
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
LocalFree( lpbFSDBuf );
|
|||
|
}
|
|||
|
|
|||
|
LocalFree( lpwsValName );
|
|||
|
LocalFree( lpbMultiSz );
|
|||
|
LocalFree( lpwsSrcIconPath );
|
|||
|
LocalFree( lpwsDstIconPath );
|
|||
|
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: AfpInitETCMaps
|
|||
|
//
|
|||
|
// Returns: NO_ERROR success
|
|||
|
// non-zero returns from the IOCTL
|
|||
|
// non-zero returns from the AfpRegXXX apis.
|
|||
|
//
|
|||
|
//
|
|||
|
// Description: This routine will read in all the type/creators and extensions
|
|||
|
// from the registry and store them in a cache. It will then
|
|||
|
// create a list of mappings from the cache and then IOCTL the
|
|||
|
// the FSD to add them. If the default is not in the registry,
|
|||
|
// a hardcoded one is used. All non-zero returns from this
|
|||
|
// routine are fatal. All non-fatal errors will be logged.
|
|||
|
//
|
|||
|
//
|
|||
|
DWORD
|
|||
|
AfpInitETCMaps(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwRetCode;
|
|||
|
AFP_REQUEST_PACKET AfpSrp;
|
|||
|
AFP_EXTENSION DefExtension;
|
|||
|
AFP_TYPE_CREATOR DefTypeCreator;
|
|||
|
BYTE bDefaultETC[sizeof(ETCMAPINFO2)+sizeof(SETINFOREQPKT)];
|
|||
|
PAFP_TYPE_CREATOR pTypeCreator;
|
|||
|
DWORD dwNumTypeCreators;
|
|||
|
AFP_TYPE_CREATOR AfpTypeCreatorKey;
|
|||
|
|
|||
|
// Get all type-creators from the registry and store them in a global cache.
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpRegTypeCreatorEnum() )
|
|||
|
return( dwRetCode );
|
|||
|
|
|||
|
// Get all extensions from the registry and store them in a global cache.
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpRegExtensionEnum() )
|
|||
|
return( dwRetCode );
|
|||
|
|
|||
|
// If there are no mappings do not IOCTL.
|
|||
|
//
|
|||
|
if ( AfpGlobals.AfpETCMapInfo.afpetc_num_extensions > 0 ) {
|
|||
|
|
|||
|
// IOCTL the FSD to Add these mappings
|
|||
|
//
|
|||
|
AfpSrp.dwRequestCode = OP_SERVER_ADD_ETC;
|
|||
|
AfpSrp.dwApiType = AFP_API_TYPE_ADD;
|
|||
|
|
|||
|
// Make a buffer with the type/creator mappings in the form as required
|
|||
|
// by the FSD
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpBufMakeFSDETCMappings(
|
|||
|
(PSRVETCPKT*)&(AfpSrp.Type.Add.pInputBuf),
|
|||
|
&(AfpSrp.Type.Add.cbInputBufSize) ) )
|
|||
|
return( dwRetCode );
|
|||
|
|
|||
|
if ( AfpSrp.Type.Add.cbInputBufSize > 0 ) {
|
|||
|
|
|||
|
dwRetCode = AfpServerIOCtrl( &AfpSrp );
|
|||
|
|
|||
|
LocalFree( AfpSrp.Type.Add.pInputBuf );
|
|||
|
|
|||
|
if ( dwRetCode )
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
else
|
|||
|
LocalFree( AfpSrp.Type.Add.pInputBuf );
|
|||
|
}
|
|||
|
|
|||
|
// Check to see if the default type/creator is in the registry
|
|||
|
//
|
|||
|
AfpTypeCreatorKey.afptc_id = AFP_DEF_TCID;
|
|||
|
|
|||
|
dwNumTypeCreators = AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators;
|
|||
|
|
|||
|
pTypeCreator = _lfind( &AfpTypeCreatorKey,
|
|||
|
AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
|
|||
|
(unsigned int *)&dwNumTypeCreators,
|
|||
|
sizeof(AFP_TYPE_CREATOR),
|
|||
|
AfpLCompareTypeCreator );
|
|||
|
|
|||
|
// If the default is not in the registry use the hard-coded defaults.
|
|||
|
//
|
|||
|
if ( pTypeCreator == NULL ) {
|
|||
|
|
|||
|
STRCPY( DefTypeCreator.afptc_type, AFP_DEF_TYPE );
|
|||
|
STRCPY( DefTypeCreator.afptc_creator, AFP_DEF_CREATOR );
|
|||
|
STRCPY( DefTypeCreator.afptc_comment, AfpGlobals.wchDefTCComment );
|
|||
|
DefTypeCreator.afptc_id = AFP_DEF_TCID;
|
|||
|
}
|
|||
|
else
|
|||
|
DefTypeCreator = *pTypeCreator;
|
|||
|
|
|||
|
ZeroMemory( (LPBYTE)(DefExtension.afpe_extension),
|
|||
|
AFP_FIELD_SIZE( AFP_EXTENSION, afpe_extension) );
|
|||
|
|
|||
|
STRCPY( DefExtension.afpe_extension, AFP_DEF_EXTENSION_W );
|
|||
|
|
|||
|
AfpBufCopyFSDETCMapInfo( &DefTypeCreator,
|
|||
|
&DefExtension,
|
|||
|
(PETCMAPINFO2)(bDefaultETC+sizeof(SETINFOREQPKT)));
|
|||
|
|
|||
|
// IOCTL the FSD to set the default
|
|||
|
//
|
|||
|
AfpSrp.dwRequestCode = OP_SERVER_SET_ETC;
|
|||
|
AfpSrp.dwApiType = AFP_API_TYPE_SETINFO;
|
|||
|
AfpSrp.Type.SetInfo.pInputBuf = bDefaultETC;
|
|||
|
AfpSrp.Type.SetInfo.cbInputBufSize = sizeof( bDefaultETC );
|
|||
|
|
|||
|
if ( dwRetCode = AfpServerIOCtrl( &AfpSrp ) )
|
|||
|
return( dwRetCode );
|
|||
|
|
|||
|
// If the default was not in the cache, add it now.
|
|||
|
//
|
|||
|
if ( pTypeCreator == NULL ) {
|
|||
|
|
|||
|
// 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 )
|
|||
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|||
|
|
|||
|
pTypeCreator[dwNumTypeCreators++] = DefTypeCreator;
|
|||
|
|
|||
|
AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators = dwNumTypeCreators;
|
|||
|
AfpGlobals.AfpETCMapInfo.afpetc_type_creator = pTypeCreator;
|
|||
|
|
|||
|
// Sort the table
|
|||
|
//
|
|||
|
qsort( pTypeCreator,
|
|||
|
dwNumTypeCreators,
|
|||
|
sizeof(AFP_TYPE_CREATOR),
|
|||
|
AfpBCompareTypeCreator );
|
|||
|
}
|
|||
|
|
|||
|
return( NO_ERROR );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: AfpInitServerIcons
|
|||
|
//
|
|||
|
// Returns: NO_ERROR - success
|
|||
|
// ERROR_NOT_ENOUGH_MEMORY
|
|||
|
// non-zero return codes from registry apis.
|
|||
|
//
|
|||
|
// Description: This procedure will read in an icon at a time from the
|
|||
|
// registry, and then register this icon with the server.
|
|||
|
// This procedure will only return fatal errors that will
|
|||
|
// require that the service fail initialization. All other
|
|||
|
// error will be logged by this routine. All returns from the
|
|||
|
// the FSD are treated as non-fatal.
|
|||
|
//
|
|||
|
//
|
|||
|
DWORD
|
|||
|
AfpInitServerIcons(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwRetCode;
|
|||
|
LPWSTR lpwsValName;
|
|||
|
DWORD dwMaxValNameLen;
|
|||
|
DWORD dwNumValues;
|
|||
|
DWORD dwMaxValueDataSize;
|
|||
|
DWORD dwIndex;
|
|||
|
DWORD dwType;
|
|||
|
DWORD dwBufSize;
|
|||
|
DWORD dwValNameBufSize;
|
|||
|
AFP_REQUEST_PACKET AfpRequestPkt;
|
|||
|
LPBYTE lpbMultiSz;
|
|||
|
AFP_ICON_INFO IconInfo;
|
|||
|
|
|||
|
// Find out the size of the largest data value and the largest
|
|||
|
// value name.
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpRegGetKeyInfo( AfpGlobals.hkeyIcons,
|
|||
|
&dwMaxValNameLen,
|
|||
|
&dwNumValues,
|
|||
|
&dwMaxValueDataSize
|
|||
|
))
|
|||
|
return( dwRetCode );
|
|||
|
|
|||
|
// If there are no icons in the registry then simply return
|
|||
|
//
|
|||
|
if ( dwNumValues == 0 )
|
|||
|
return( NO_ERROR );
|
|||
|
|
|||
|
if (( lpwsValName = (LPWSTR)LocalAlloc( LPTR, dwMaxValNameLen )) == NULL )
|
|||
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|||
|
|
|||
|
if (( lpbMultiSz = (LPBYTE)LocalAlloc( LPTR, dwMaxValueDataSize))== NULL){
|
|||
|
LocalFree( lpwsValName );
|
|||
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|||
|
}
|
|||
|
|
|||
|
for ( dwIndex = 0,
|
|||
|
dwBufSize = dwMaxValueDataSize,
|
|||
|
dwValNameBufSize = dwMaxValNameLen;
|
|||
|
|
|||
|
dwIndex < dwNumValues;
|
|||
|
|
|||
|
dwIndex++,
|
|||
|
dwBufSize = dwMaxValueDataSize,
|
|||
|
dwValNameBufSize = dwMaxValNameLen ) {
|
|||
|
|
|||
|
ZeroMemory( lpbMultiSz, dwBufSize );
|
|||
|
|
|||
|
// Get the icon from the registry.
|
|||
|
//
|
|||
|
if ( dwRetCode = RegEnumValue( AfpGlobals.hkeyIcons,
|
|||
|
dwIndex,
|
|||
|
lpwsValName,
|
|||
|
&dwValNameBufSize,
|
|||
|
NULL,
|
|||
|
&dwType,
|
|||
|
lpbMultiSz,
|
|||
|
&dwBufSize
|
|||
|
))
|
|||
|
break;
|
|||
|
|
|||
|
// Parse the mult sz and extract info into icon info structure
|
|||
|
//
|
|||
|
if ( dwRetCode = AfpBufParseMultiSz(
|
|||
|
AFP_ICON_STRUCT,
|
|||
|
lpbMultiSz,
|
|||
|
(LPBYTE)&IconInfo
|
|||
|
)) {
|
|||
|
AfpLogEvent( AFPLOG_CANT_ADD_ICON, 1, &lpwsValName,
|
|||
|
dwRetCode, EVENTLOG_WARNING_TYPE );
|
|||
|
dwRetCode = NO_ERROR;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if ( dwRetCode = AfpBufUnicodeToNibble((LPWSTR)IconInfo.afpicon_data)){
|
|||
|
AfpLogEvent( AFPLOG_CANT_ADD_ICON, 1, &lpwsValName,
|
|||
|
dwRetCode, EVENTLOG_WARNING_TYPE );
|
|||
|
dwRetCode = NO_ERROR;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// Validate the icon info structure
|
|||
|
//
|
|||
|
if ( !IsAfpIconValid( &IconInfo ) ) {
|
|||
|
AfpLogEvent( AFPLOG_CANT_ADD_ICON, 1, &lpwsValName,
|
|||
|
dwRetCode, EVENTLOG_WARNING_TYPE );
|
|||
|
dwRetCode = NO_ERROR;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// Copy the icon info into an FSD icon structure.
|
|||
|
// NOTE: Re-use lpbMultiSz to store the FSD Icon structure. We know
|
|||
|
// it is big enough, because the FSD icon structure HAS to be
|
|||
|
// smaller than the MultiSz that contains the same information.
|
|||
|
//
|
|||
|
AfpBufMakeFSDIcon( &IconInfo, lpbMultiSz, &dwBufSize );
|
|||
|
|
|||
|
// Initialize the FSD with this icon
|
|||
|
//
|
|||
|
AfpRequestPkt.dwRequestCode = OP_SERVER_ADD_ICON;
|
|||
|
AfpRequestPkt.dwApiType = AFP_API_TYPE_ADD;
|
|||
|
AfpRequestPkt.Type.Add.pInputBuf = lpbMultiSz;
|
|||
|
AfpRequestPkt.Type.Add.cbInputBufSize = dwBufSize;
|
|||
|
|
|||
|
if ( dwRetCode = AfpServerIOCtrl( &AfpRequestPkt ) ) {
|
|||
|
AfpLogEvent( AFPLOG_CANT_ADD_ICON, 1, &lpwsValName,
|
|||
|
dwRetCode, EVENTLOG_WARNING_TYPE );
|
|||
|
dwRetCode = NO_ERROR;
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
LocalFree( lpwsValName );
|
|||
|
LocalFree( lpbMultiSz );
|
|||
|
|
|||
|
return( dwRetCode );
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: AfpInitRPC
|
|||
|
//
|
|||
|
// Returns: NO_ERROR - success
|
|||
|
// ERROR_NOT_ENOUGH_MEMORY
|
|||
|
// nonzero returns from RPC APIs
|
|||
|
// RpcServerRegisterIf()
|
|||
|
// RpcServerUseProtseqEp()
|
|||
|
//
|
|||
|
// Description: Starts an RPC Server, adds the address (or port/pipe),
|
|||
|
// and adds the interface (dispatch table).
|
|||
|
//
|
|||
|
DWORD
|
|||
|
AfpInitRPC( VOID )
|
|||
|
{
|
|||
|
RPC_STATUS RpcStatus;
|
|||
|
LPWSTR lpwsEndpoint = NULL;
|
|||
|
BOOL Bool;
|
|||
|
|
|||
|
|
|||
|
// We need to concatenate \pipe\ to the front of the interface name.
|
|||
|
//
|
|||
|
lpwsEndpoint = (LPWSTR)LocalAlloc( LPTR, sizeof(NT_PIPE_PREFIX) +
|
|||
|
((STRLEN(AFP_SERVICE_NAME)+1)*sizeof(WCHAR)));
|
|||
|
if ( lpwsEndpoint == NULL)
|
|||
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|||
|
|
|||
|
STRCPY( lpwsEndpoint, NT_PIPE_PREFIX );
|
|||
|
STRCAT( lpwsEndpoint, AFP_SERVICE_NAME );
|
|||
|
|
|||
|
|
|||
|
// Ignore the second argument for now.
|
|||
|
//
|
|||
|
RpcStatus = RpcServerUseProtseqEpW( TEXT("ncacn_np"),
|
|||
|
10,
|
|||
|
lpwsEndpoint,
|
|||
|
NULL );
|
|||
|
|
|||
|
if ( RpcStatus != RPC_S_OK )
|
|||
|
{
|
|||
|
LocalFree( lpwsEndpoint );
|
|||
|
return( I_RpcMapWin32Status( RpcStatus ) );
|
|||
|
}
|
|||
|
|
|||
|
RpcStatus = RpcServerRegisterIf( afpsvc_v0_0_s_ifspec, 0, 0);
|
|||
|
|
|||
|
LocalFree( lpwsEndpoint );
|
|||
|
|
|||
|
if ( RpcStatus == RPC_S_OK )
|
|||
|
return( NO_ERROR );
|
|||
|
else
|
|||
|
return( I_RpcMapWin32Status( RpcStatus ) );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: AfpTerminateRPC
|
|||
|
//
|
|||
|
// Returns: none
|
|||
|
//
|
|||
|
// Description: Deletes the interface.
|
|||
|
//
|
|||
|
VOID
|
|||
|
AfpTerminateRPC(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
RPC_STATUS RpcStatus;
|
|||
|
|
|||
|
if ( AfpGlobals.dwServerState & AFPSTATE_RPC_STARTED )
|
|||
|
{
|
|||
|
RpcStatus = RpcServerUnregisterIf( afpsvc_v0_0_s_ifspec, 0, 0 );
|
|||
|
|
|||
|
if (RpcStatus != RPC_S_OK)
|
|||
|
{
|
|||
|
AFP_PRINT(("RpcServerUnregisterIf failed %ld\n", I_RpcMapWin32Status( RpcStatus )));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//**
|
|||
|
//
|
|||
|
// Call: AfpIniLsa
|
|||
|
//
|
|||
|
// Returns: none.
|
|||
|
//
|
|||
|
// Description: This procedure will register our process with LSA, needed for
|
|||
|
// change-password
|
|||
|
//
|
|||
|
VOID
|
|||
|
AfpIniLsa(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
NTSTATUS ntstatus;
|
|||
|
STRING LsaName;
|
|||
|
LSA_OPERATIONAL_MODE SecurityMode;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// register with Lsa as a logon process
|
|||
|
//
|
|||
|
|
|||
|
RtlInitString(&LsaName, LOGON_PROCESS_NAME);
|
|||
|
|
|||
|
ntstatus = LsaRegisterLogonProcess(&LsaName, &SfmLsaHandle, &SecurityMode);
|
|||
|
if (ntstatus != STATUS_SUCCESS)
|
|||
|
{
|
|||
|
SfmLsaHandle = NULL;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// call Lsa to get the MSV1_0's pkg id, which we need during logon
|
|||
|
//
|
|||
|
|
|||
|
RtlInitString(&LsaName, MSV1_0_PACKAGE_NAME);
|
|||
|
|
|||
|
ntstatus = LsaLookupAuthenticationPackage(SfmLsaHandle, &LsaName, &SfmAuthPkgId);
|
|||
|
if (ntstatus != STATUS_SUCCESS)
|
|||
|
{
|
|||
|
LsaDeregisterLogonProcess( SfmLsaHandle );
|
|||
|
SfmLsaHandle = NULL;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
IsAfpGuestAccountEnabled(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
NTSTATUS rc;
|
|||
|
LSA_HANDLE hLsa;
|
|||
|
PPOLICY_ACCOUNT_DOMAIN_INFO pAcctDomainInfo;
|
|||
|
SECURITY_QUALITY_OF_SERVICE QOS;
|
|||
|
OBJECT_ATTRIBUTES ObjAttribs;
|
|||
|
NTSTATUS status;
|
|||
|
SAM_HANDLE SamHandle;
|
|||
|
SAM_HANDLE DomainHandle;
|
|||
|
PUSER_ACCOUNT_INFORMATION UserAccount = NULL;
|
|||
|
BOOLEAN fGuestEnabled;
|
|||
|
SAMPR_HANDLE GuestAcctHandle;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// for now
|
|||
|
fGuestEnabled = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Open the LSA and obtain a handle to it.
|
|||
|
//
|
|||
|
QOS.Length = sizeof(QOS);
|
|||
|
QOS.ImpersonationLevel = SecurityImpersonation;
|
|||
|
QOS.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
|
|||
|
QOS.EffectiveOnly = FALSE;
|
|||
|
|
|||
|
InitializeObjectAttributes(&ObjAttribs, NULL, 0L, NULL, NULL);
|
|||
|
|
|||
|
ObjAttribs.SecurityQualityOfService = &QOS;
|
|||
|
|
|||
|
status = LsaOpenPolicy(NULL,
|
|||
|
&ObjAttribs,
|
|||
|
POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES,
|
|||
|
&hLsa);
|
|||
|
|
|||
|
if (!NT_SUCCESS(status))
|
|||
|
{
|
|||
|
AFP_PRINT(("LsaOpenPolicy failed %lx\n",status));
|
|||
|
return(fGuestEnabled);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// get the Domain Sid for the local domain: we'll need it very shortly
|
|||
|
//
|
|||
|
rc = LsaQueryInformationPolicy(hLsa,
|
|||
|
PolicyAccountDomainInformation,
|
|||
|
(PVOID) &pAcctDomainInfo);
|
|||
|
if (!NT_SUCCESS(rc))
|
|||
|
{
|
|||
|
AFP_PRINT(("InitLSA: LsaQueryInfo... failed (%lx)\n",rc));
|
|||
|
LsaClose(hLsa);
|
|||
|
return(fGuestEnabled);
|
|||
|
}
|
|||
|
|
|||
|
InitializeObjectAttributes(&ObjAttribs, NULL, 0L, NULL, NULL);
|
|||
|
|
|||
|
status = SamConnect(NULL, &SamHandle, MAXIMUM_ALLOWED, &ObjAttribs);
|
|||
|
|
|||
|
if (!NT_SUCCESS(status))
|
|||
|
{
|
|||
|
AFP_PRINT(("SamConnect failed %lx\n",status));
|
|||
|
LsaFreeMemory(pAcctDomainInfo);
|
|||
|
LsaClose(hLsa);
|
|||
|
return(fGuestEnabled);
|
|||
|
}
|
|||
|
|
|||
|
status = SamOpenDomain(
|
|||
|
SamHandle,
|
|||
|
MAXIMUM_ALLOWED,
|
|||
|
pAcctDomainInfo->DomainSid,
|
|||
|
&DomainHandle);
|
|||
|
|
|||
|
LsaFreeMemory(pAcctDomainInfo);
|
|||
|
|
|||
|
LsaClose(hLsa);
|
|||
|
|
|||
|
if (!NT_SUCCESS(status))
|
|||
|
{
|
|||
|
AFP_PRINT(("SamOpenDomain failed %lx\n",status));
|
|||
|
SamCloseHandle(SamHandle);
|
|||
|
return(fGuestEnabled);
|
|||
|
}
|
|||
|
|
|||
|
status = SamOpenUser(
|
|||
|
DomainHandle,
|
|||
|
MAXIMUM_ALLOWED,
|
|||
|
DOMAIN_USER_RID_GUEST,
|
|||
|
&GuestAcctHandle);
|
|||
|
|
|||
|
if (!NT_SUCCESS(status))
|
|||
|
{
|
|||
|
AFP_PRINT(("SamOpenUser failed %lx\n",status));
|
|||
|
SamCloseHandle(SamHandle);
|
|||
|
return(fGuestEnabled);
|
|||
|
}
|
|||
|
|
|||
|
status = SamQueryInformationUser(
|
|||
|
GuestAcctHandle,
|
|||
|
UserAccountInformation,
|
|||
|
(PVOID *) &UserAccount );
|
|||
|
|
|||
|
if (!NT_SUCCESS(status))
|
|||
|
{
|
|||
|
AFP_PRINT(("SamQueryInformationUser failed %lx\n",status));
|
|||
|
SamCloseHandle(SamHandle);
|
|||
|
return(fGuestEnabled);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// now, see if the guest account is enabled.
|
|||
|
//
|
|||
|
if (!(UserAccount->UserAccountControl & USER_ACCOUNT_DISABLED))
|
|||
|
{
|
|||
|
fGuestEnabled = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
SamFreeMemory(UserAccount);
|
|||
|
|
|||
|
SamCloseHandle(GuestAcctHandle);
|
|||
|
|
|||
|
SamCloseHandle(SamHandle);
|
|||
|
|
|||
|
return(fGuestEnabled);
|
|||
|
}
|
|||
|
|