895 lines
25 KiB
C++
895 lines
25 KiB
C++
/**********************************************************************/
|
|
/** Microsoft Windows NT **/
|
|
/** Copyright(c) Microsoft Corp., 1993 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
ftpmcpl.cxx
|
|
This is the main module for the FTP Server Control Panel Applet.
|
|
It contains the "CplApplet" function.
|
|
|
|
|
|
FILE HISTORY:
|
|
YiHsinS 22-Mar-1993 Templated from Keithmo's srvmcpl.cxx.
|
|
JonN 26-Jun-2000 CPlApplet takes HWND, UINT, LPARAM, LPARAM
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define INCL_NET
|
|
#define INCL_NETLIB
|
|
#define INCL_NETSERVICE
|
|
#define INCL_WINDOWS
|
|
#define INCL_WINDOWS_GDI
|
|
#define INCL_NETERRORS
|
|
#define INCL_DOSERRORS
|
|
#include <lmui.hxx>
|
|
|
|
#if defined(DEBUG)
|
|
static const CHAR szFileName[] = __FILE__;
|
|
#define _FILENAME_DEFINED_ONCE szFileName
|
|
#endif
|
|
|
|
#include <uiassert.hxx>
|
|
#include <uitrace.hxx>
|
|
|
|
#define INCL_BLT_WINDOW
|
|
#define INCL_BLT_DIALOG
|
|
#define INCL_BLT_CONTROL
|
|
#define INCL_BLT_CLIENT
|
|
#define INCL_BLT_MSGPOPUP
|
|
#define INCL_BLT_EVENT
|
|
#define INCL_BLT_MISC
|
|
#define INCL_BLT_TIMER
|
|
#define INCL_BLT_CC
|
|
#include <blt.hxx>
|
|
|
|
#include <dbgstr.hxx>
|
|
#include <uatom.hxx>
|
|
#include <regkey.hxx>
|
|
#include <lmoloc.hxx>
|
|
#include <srvsvc.hxx>
|
|
|
|
extern "C"
|
|
{
|
|
#include <cpl.h> // Multimedia CPL defs
|
|
#include <ftpmgr.h>
|
|
#include <ftpd.h>
|
|
}
|
|
|
|
|
|
extern "C"
|
|
{
|
|
//
|
|
// Control Panel Applet entry point.
|
|
//
|
|
|
|
LONG FAR PASCAL CPlApplet( HWND hwndCPl,
|
|
UINT nMsg,
|
|
LPARAM lParam1,
|
|
LPARAM lparam2 );
|
|
|
|
//
|
|
// DLL load/unload entry point.
|
|
//
|
|
|
|
BOOL FAR PASCAL FtpMgrDllInitialize( HINSTANCE hInstance,
|
|
DWORD nReason,
|
|
LPVOID pReserved );
|
|
|
|
//
|
|
// Globals.
|
|
//
|
|
|
|
HINSTANCE _hCplInstance = NULL;
|
|
|
|
} // extern "C"
|
|
|
|
#include <ftpmgr.hxx>
|
|
|
|
//
|
|
// This is the "type" for an applet startup function.
|
|
//
|
|
|
|
typedef APIERR (* PCPL_APPLET_FUNC)( HWND hWnd );
|
|
|
|
|
|
//
|
|
// We'll keep one of these structures for each applet in this DLL.
|
|
//
|
|
|
|
typedef struct _CPL_APPLET
|
|
{
|
|
int idIcon;
|
|
int idName;
|
|
int idInfo;
|
|
int idHelpFile;
|
|
DWORD dwHelpContext;
|
|
LONG lData;
|
|
PCPL_APPLET_FUNC pfnApplet;
|
|
|
|
} CPL_APPLET;
|
|
|
|
|
|
//
|
|
// Forward reference prototypes.
|
|
//
|
|
|
|
APIERR RunFtpSvcMgr( HWND hWnd );
|
|
|
|
|
|
//
|
|
// Our applet descriptors.
|
|
//
|
|
|
|
CPL_APPLET CplApplets[] = {
|
|
{ // FTP Server applet
|
|
IDI_FTPCPA_ICON,
|
|
IDS_FTPCPA_NAME_STRING,
|
|
IDS_FTPCPA_INFO_STRING,
|
|
IDS_CPL_HELPFILENAME,
|
|
HC_FTPSVCMGR_DIALOG,
|
|
0L,
|
|
&RunFtpSvcMgr
|
|
}
|
|
};
|
|
|
|
#define NUM_APPLETS ( sizeof(CplApplets) / sizeof(CplApplets[0]) )
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: InitializeDll
|
|
|
|
SYNOPSIS: Perform DLL initialiazation functions on a
|
|
once-per-process basis.
|
|
|
|
ENTRY: hInstance - Program instance of the caller.
|
|
|
|
EXIT: If this is the first initialization request for this
|
|
process, then all necessary BLT initializers have
|
|
been invoked.
|
|
|
|
RETURNS: BOOL - TRUE = Initialization OK.
|
|
FALSE = Initialization failed.
|
|
|
|
HISTORY:
|
|
YiHsinS 22-Mar-1993 Templated from Keithmo's srvmcpl.cxx.
|
|
|
|
********************************************************************/
|
|
BOOL InitializeDll( HINSTANCE hInstance )
|
|
{
|
|
//
|
|
// Save the instance handle.
|
|
//
|
|
|
|
_hCplInstance = hInstance;
|
|
|
|
return TRUE;
|
|
|
|
} // InitializeDll
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: TerminateDll
|
|
|
|
SYNOPSIS: Perform DLL termination functions on a
|
|
once-per-process basis.
|
|
|
|
EXIT: All necessary BLT terminators have been invoked.
|
|
|
|
HISTORY:
|
|
YiHsinS 22-Mar-1993 Templated from Keithmo's srvmcpl.cxx.
|
|
|
|
********************************************************************/
|
|
VOID TerminateDll( VOID )
|
|
{
|
|
//
|
|
// Just in case we try to do anything goofy.
|
|
//
|
|
|
|
_hCplInstance = NULL;
|
|
|
|
} // TerminateDll
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: IsFtpServerInstalled
|
|
|
|
SYNOPSIS: Determines if the FTP Server service is installed.
|
|
This doesn't necessarily mean the service is actually
|
|
running, just that it is installed on the system.
|
|
|
|
RETURNS: BOOL - TRUE = FTP Server service is installed.
|
|
FALSE = FTP Server service isn't installed.
|
|
|
|
NOTES: We could perform this check by trying to open the
|
|
service via the Service Controller, but this would
|
|
cause a lot of extraneous code to get paged in.
|
|
Instead, we'll check for the presence of the registry
|
|
key that controls the service.
|
|
|
|
HISTORY:
|
|
KeithMo 09-Apr-1993 Created.
|
|
|
|
********************************************************************/
|
|
BOOL IsFtpServerInstalled( VOID )
|
|
{
|
|
BOOL fInstalled = FALSE; // until proven otherwise...
|
|
|
|
//
|
|
// Open the registry root.
|
|
//
|
|
|
|
REG_KEY RootKey( HKEY_LOCAL_MACHINE );
|
|
|
|
APIERR err = RootKey.QueryError();
|
|
|
|
if( err == NERR_Success )
|
|
{
|
|
//
|
|
// Open the FTPSVC registry key.
|
|
//
|
|
|
|
ALIAS_STR nlsKeyName( (TCHAR *)FTPD_PARAMETERS_KEY );
|
|
UIASSERT( !!nlsKeyName );
|
|
|
|
REG_KEY RegKey( RootKey, nlsKeyName );
|
|
err = RegKey.QueryError();
|
|
|
|
if( err == NERR_Success )
|
|
{
|
|
//
|
|
// Since we successfully opened the FTP Server's
|
|
// parameters key, we'll assume that the service
|
|
// is indeed installed.
|
|
//
|
|
|
|
fInstalled = TRUE;
|
|
}
|
|
}
|
|
|
|
return fInstalled;
|
|
|
|
} // IsFtpServerInstalled
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: InitializeAllApplets
|
|
|
|
SYNOPSIS: Called before applet proper is run.
|
|
|
|
ENTRY: hWnd - Window handle of parent window.
|
|
|
|
RETURNS: BOOL - TRUE = Applet should be installed.
|
|
FALSE = Applet cannot be installed.
|
|
|
|
HISTORY:
|
|
YiHsinS 22-Mar-1993 Templated from Keithmo's srvmcpl.cxx.
|
|
KeithMo 09-Apr-1993 Don't init if service not installed.
|
|
JonN 05-Oct-1994 Added lParam parameters to CPL_INIT, CPL_TERM
|
|
JonN 22-Sep-1995 Only called when applet is run
|
|
|
|
********************************************************************/
|
|
BOOL InitializeAllApplets( HWND hWnd, LPARAM lParam1, LPARAM lParam2 )
|
|
{
|
|
TRACEEOL( "FTPMGR.CPL: InitializeAllApplets enter" );
|
|
//
|
|
// Before we do anything, check to see if the FTP Server service
|
|
// is installed. If it isn't there's not much point in running
|
|
// this applet.
|
|
//
|
|
|
|
if( !IsFtpServerInstalled() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Initialize all of the NetUI goodies.
|
|
//
|
|
|
|
APIERR err = BLT::Init( _hCplInstance,
|
|
IDRSRC_FTPMGR_BASE, IDRSRC_FTPMGR_LAST,
|
|
IDS_UI_FTPMGR_BASE, IDS_UI_FTPMGR_LAST );
|
|
|
|
TRACEEOL( "FTPMGR.CPL: InitializeAllApplets BLT::Init returns " << err );
|
|
|
|
if( err == NERR_Success )
|
|
{
|
|
TRACEEOL( "FTPMGR.CPL: InitializeAllApplets BLT::_MASTER_TIMER::Init next" );
|
|
|
|
err = BLT_MASTER_TIMER::Init();
|
|
|
|
TRACEEOL( "FTPMGR.CPL: InitializeAllApplets BLT::_MASTER_TIMER::Init returns " << err );
|
|
|
|
if( err != NERR_Success )
|
|
{
|
|
//
|
|
// BLT initialized OK, but BLT_MASTER_TIMER
|
|
// failed. So, before we bag-out, we must
|
|
// deinitialize BLT.
|
|
//
|
|
|
|
BLT::Term( _hCplInstance );
|
|
}
|
|
}
|
|
|
|
if( err == NERR_Success )
|
|
{
|
|
err = BLT::RegisterHelpFile( _hCplInstance,
|
|
IDS_CPL_HELPFILENAME,
|
|
HC_UI_FTPMGR_BASE,
|
|
HC_UI_FTPMGR_LAST );
|
|
|
|
if( err != NERR_Success )
|
|
{
|
|
//
|
|
// This is the only place where we can safely
|
|
// invoke MsgPopup, since we *know* that all of
|
|
// the BLT goodies were initialized properly.
|
|
//
|
|
::MsgPopup( hWnd, err );
|
|
|
|
BLT::Term( _hCplInstance );
|
|
}
|
|
}
|
|
|
|
TRACEEOL( "FTPMGR.CPL: InitializeAllApplets exit" );
|
|
|
|
return err == NERR_Success;
|
|
|
|
} // InitializeAllApplets
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: TerminateAllApplets
|
|
|
|
SYNOPSIS: Called after applet is run.
|
|
|
|
ENTRY: hWnd - Window handle of parent window.
|
|
|
|
HISTORY:
|
|
YiHsinS 22-Mar-1993 Templated from Keithmo's srvmcpl.cxx.
|
|
JonN 04-Oct-1994 Added lParam parameters to CPL_INIT, CPL_TERM
|
|
JonN 22-Sep-1995 Only called when applet is run
|
|
|
|
********************************************************************/
|
|
VOID TerminateAllApplets( HWND hWnd, LPARAM lParam1, LPARAM lParam2 )
|
|
{
|
|
UNREFERENCED( hWnd );
|
|
|
|
TRACEEOL( "FTPMGR.CPL: TerminateAllApplets enter" );
|
|
//
|
|
// Kill the NetUI goodies.
|
|
//
|
|
|
|
BLT::DeregisterHelpFile( _hCplInstance, 0 );
|
|
TRACEEOL( "FTPMGR.CPL: TerminateAllApplets BLT::_MASTER_TIMER::Term next" );
|
|
BLT_MASTER_TIMER::Term();
|
|
TRACEEOL( "FTPMGR.CPL: TerminateAllApplets BLT::_MASTER_TIMER::Term complete" );
|
|
BLT::Term( _hCplInstance );
|
|
|
|
TRACEEOL( "FTPMGR.CPL: TerminateAllApplets exit" );
|
|
|
|
} // TerminateAllApplets
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: AutoStartFtpServer
|
|
|
|
SYNOPSIS: Check the state of the FTP Server service. If it
|
|
isn't started, ask the user if it should be started.
|
|
If the user wants us to start the service, start it.
|
|
|
|
ENTRY: hWnd - Window handle of parent window.
|
|
|
|
RETURNS: BOOL - TRUE == FTP Server service is running.
|
|
FALSE == FTP Server service isn't running.
|
|
This may indicate either an error
|
|
or the user didn't want the service
|
|
started. If an error occurs, this
|
|
routine is responsible for displaying
|
|
it to the user.
|
|
|
|
HISTORY:
|
|
KeithMo 09-Apr-1993 Created.
|
|
|
|
********************************************************************/
|
|
BOOL AutoStartFtpServer( HWND hWnd )
|
|
{
|
|
BOOL fStarted = FALSE; // until proven otherwise...
|
|
|
|
//
|
|
// Get the "display name" for the local machine.
|
|
//
|
|
|
|
LOCATION loc( LOC_TYPE_LOCAL );
|
|
NLS_STR nlsDisplayName;
|
|
|
|
APIERR err = loc.QueryError();
|
|
err = err ? err : nlsDisplayName.QueryError();
|
|
err = err ? err : loc.QueryDisplayName( &nlsDisplayName );
|
|
|
|
if( err == NERR_Success )
|
|
{
|
|
//
|
|
// Determine the state of the service.
|
|
//
|
|
|
|
GENERIC_SERVICE * psvc = new GENERIC_SERVICE( hWnd,
|
|
NULL,
|
|
nlsDisplayName,
|
|
(TCHAR *)FTPD_SERVICE_NAME );
|
|
|
|
err = ( psvc == NULL ) ? ERROR_NOT_ENOUGH_MEMORY
|
|
: psvc->QueryError();
|
|
|
|
if( err == NERR_Success )
|
|
{
|
|
fStarted = psvc->IsInstalled( &err );
|
|
|
|
if( !fStarted && ( err == NERR_Success ) )
|
|
{
|
|
//
|
|
// Service isn't started. See if the user wants us
|
|
// to start it.
|
|
//
|
|
|
|
if( ::MsgPopup( hWnd,
|
|
IDS_START_FTPSVC_NOW,
|
|
MPSEV_WARNING,
|
|
MP_YESNO,
|
|
MP_YES ) == IDYES )
|
|
{
|
|
err = psvc->Start();
|
|
|
|
if( err == NERR_ServiceInstalled )
|
|
{
|
|
//
|
|
// Somebody must have started the service
|
|
// behind our backs...
|
|
//
|
|
|
|
err = NERR_Success;
|
|
}
|
|
|
|
if( err == NERR_Success )
|
|
{
|
|
//
|
|
// Whew!
|
|
//
|
|
|
|
fStarted = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
delete psvc;
|
|
}
|
|
|
|
//
|
|
// If anything tragic occurred, tell the user.
|
|
//
|
|
|
|
if( err != NERR_Success )
|
|
{
|
|
::MsgPopup( hWnd, err );
|
|
}
|
|
|
|
return fStarted;
|
|
|
|
} // AutoStartFtpServer
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunFtpSvcMgr
|
|
|
|
SYNOPSIS: Invoke the main dialog of the FTP Server Control
|
|
Panel Applet.
|
|
|
|
ENTRY: hWnd - Window handle of parent window.
|
|
|
|
RETURNS: APIERR
|
|
|
|
HISTORY:
|
|
YiHsinS 18-Mar-1993 Created
|
|
KeithMo 09-Apr-1993 Autostart FTP service.
|
|
|
|
********************************************************************/
|
|
APIERR RunFtpSvcMgr( HWND hWnd )
|
|
{
|
|
//
|
|
// If the service isn't started, ask the user if
|
|
// it should be started.
|
|
//
|
|
|
|
if( !AutoStartFtpServer( hWnd ) )
|
|
{
|
|
//
|
|
// The user doesn't want to play right now.
|
|
//
|
|
|
|
return NERR_Success;
|
|
}
|
|
|
|
AUTO_CURSOR autocur;
|
|
|
|
// In the control panel applet, we will only be focusing on
|
|
// the local machine.
|
|
|
|
POPUP::SetCaption( IDS_FTPCPA_CAPTION );
|
|
|
|
FTP_SVCMGR_DIALOG * pDlg = new FTP_SVCMGR_DIALOG( hWnd,
|
|
NULL ); // local computer
|
|
|
|
APIERR err = ( pDlg == NULL ) ? ERROR_NOT_ENOUGH_MEMORY
|
|
: pDlg->QueryError();
|
|
|
|
if ( err == NERR_Success )
|
|
err = pDlg->Process();
|
|
|
|
delete pDlg;
|
|
pDlg = NULL;
|
|
|
|
if( err != NERR_Success )
|
|
{
|
|
if ( err == RPC_S_SERVER_UNAVAILABLE )
|
|
err = IERR_FTP_SERVICE_UNAVAILABLE;
|
|
::MsgPopup( hWnd, err );
|
|
}
|
|
|
|
POPUP::ResetCaption();
|
|
return err;
|
|
|
|
} // RunFtpSvcMgr
|
|
|
|
|
|
BOOL strLoad( INT idString, WCHAR * pszBuffer, INT cchBuffer )
|
|
{
|
|
int result = ::LoadString( ::_hCplInstance,
|
|
idString,
|
|
pszBuffer,
|
|
cchBuffer );
|
|
|
|
return ( result > 0 ) && ( result < cchBuffer );
|
|
|
|
} // strLoad
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: CPlApplet
|
|
|
|
SYNOPSIS: Exported function to start the FTP Server Control
|
|
Panel Applet.
|
|
|
|
ENTRY: hwndCPl - Window handle of parent.
|
|
|
|
nMsg - CPL user message (see CPL.H
|
|
in WINDOWS\SHELL\CONTROL\H).
|
|
|
|
lParam1 - Message-specific pointer.
|
|
|
|
lParam2 - Message-specific pointer.
|
|
|
|
RETURNS: LONG
|
|
|
|
HISTORY:
|
|
YiHsinS 22-Mar-1993 Templated from Keithmo's srvmcpl.cxx.
|
|
JonN 04-Oct-1994 Added lParam parameters to CPL_INIT, CPL_TERM
|
|
JonN 22-Sep-1995 BLT::Init only called when applet is run
|
|
JonN 26-Jun-2000 CPlApplet takes HWND, UINT, LPARAM, LPARAM
|
|
|
|
********************************************************************/
|
|
LONG FAR PASCAL CPlApplet( HWND hwndCPl,
|
|
UINT nMsg,
|
|
LPARAM lParam1,
|
|
LPARAM lParam2 )
|
|
{
|
|
LPCPLINFO pCplInfo;
|
|
LPNEWCPLINFO pNewInfo;
|
|
LONG nResult = 0;
|
|
|
|
switch( nMsg )
|
|
{
|
|
case CPL_INIT:
|
|
//
|
|
// This message is sent to indicate that CPlApplet() was found.
|
|
//
|
|
// lParam1 is not used, but we pass it anyway.
|
|
//
|
|
// lParam2 is -1 iff the DLL will be used only to confirm the
|
|
// number of applets.
|
|
//
|
|
// Return TRUE if applet should be installed, FALSE otherwise.
|
|
//
|
|
// Before we do anything, check to see if the FTP Server service
|
|
// is installed. If it isn't there's not much point in running
|
|
// this applet.
|
|
//
|
|
|
|
return IsFtpServerInstalled();
|
|
|
|
case CPL_GETCOUNT:
|
|
//
|
|
// This message is set to determine the number of applets contained
|
|
// in this DLL.
|
|
//
|
|
// lParam1 and lParam2 are not used.
|
|
//
|
|
// Return the number of applets contained in this DLL.
|
|
//
|
|
|
|
return NUM_APPLETS;
|
|
|
|
case CPL_INQUIRE:
|
|
//
|
|
// This message is sent once per applet to retrieve information
|
|
// about each applet.
|
|
//
|
|
// lParam1 is the applet number to register.
|
|
//
|
|
// lParam2 is a pointer to a CPLINFO structure. The CPLINFO
|
|
// structure's idIcon, idName, idInfo, and lData fields should
|
|
// be initialized as appropriate for the applet.
|
|
//
|
|
// There is no return value.
|
|
//
|
|
|
|
pCplInfo = (LPCPLINFO)lParam2;
|
|
|
|
if( lParam1 < NUM_APPLETS )
|
|
{
|
|
CPL_APPLET * pApplet = &CplApplets[lParam1];
|
|
|
|
pCplInfo->idIcon = pApplet->idIcon;
|
|
pCplInfo->idName = pApplet->idName;
|
|
pCplInfo->idInfo = pApplet->idInfo;
|
|
pCplInfo->lData = pApplet->lData;
|
|
}
|
|
break;
|
|
|
|
case CPL_SELECT:
|
|
//
|
|
// This message is sent when the applet's icon has been
|
|
// selected.
|
|
//
|
|
// lParam1 is the applet number that was selected.
|
|
//
|
|
// lParam2 is the applet's lData value.
|
|
//
|
|
// There is no return value.
|
|
//
|
|
|
|
break;
|
|
|
|
case CPL_DBLCLK:
|
|
//
|
|
// This message is sent when the applet's icon has been
|
|
// double-clicked. This message should initiate the
|
|
// applet's dialog box.
|
|
//
|
|
// lParam1 is the applet number that was selected.
|
|
//
|
|
// lParam2 is the applet's lData value.
|
|
//
|
|
// There is no return value.
|
|
//
|
|
|
|
if( lParam1 < NUM_APPLETS )
|
|
{
|
|
if ((LONG)InitializeAllApplets( hwndCPl, lParam1, lParam2 ))
|
|
{
|
|
(CplApplets[lParam1].pfnApplet)( hwndCPl );
|
|
TerminateAllApplets( hwndCPl, lParam1, lParam2 );
|
|
}
|
|
else
|
|
{
|
|
ASSERT( FALSE );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CPL_STOP:
|
|
//
|
|
// This message is sent once for each applet when the
|
|
// control panel is shutting down. This message should
|
|
// initiate applet specific cleanup.
|
|
//
|
|
// lParam1 is the applet number being stopped.
|
|
//
|
|
// lParam2 is the applet's lData value.
|
|
//
|
|
// There is no return value.
|
|
//
|
|
|
|
break;
|
|
|
|
case CPL_EXIT:
|
|
//
|
|
// This message is sent just before the control panel calls
|
|
// FreeLibrary. This message should initiate non applet
|
|
// specific cleanup.
|
|
//
|
|
// lParam1 is not used, but we pass it anyway.
|
|
//
|
|
// lParam2 is -1 iff the DLL was used only to confirm the
|
|
// number of applets.
|
|
//
|
|
// There is no return value.
|
|
//
|
|
|
|
break;
|
|
|
|
case CPL_NEWINQUIRE:
|
|
//
|
|
// This message is basically the same as CPL_INQUIRE, except
|
|
// lParam2 points to a NEWCPLINFO structure. This message will
|
|
// be sent *before* CPL_INQUIRE. If the applet returns a non
|
|
// zero value, then CPL_INQUIRE will not be sent.
|
|
//
|
|
// lParam1 is the applet number to register.
|
|
//
|
|
// lParam2 is a pointer to a NEWCPLINFO structure.
|
|
//
|
|
// Return TRUE this message was handled, otherwise return FALSE.
|
|
//
|
|
|
|
pNewInfo = (LPNEWCPLINFO)lParam2;
|
|
|
|
if( lParam1 < NUM_APPLETS )
|
|
{
|
|
CPL_APPLET * pApplet = &CplApplets[lParam1];
|
|
|
|
pNewInfo->dwSize = sizeof(*pNewInfo);
|
|
pNewInfo->dwFlags = 0;
|
|
pNewInfo->dwHelpContext = pApplet->dwHelpContext;
|
|
pNewInfo->lData = pApplet->lData;
|
|
|
|
pNewInfo->hIcon = ::LoadIcon( ::_hCplInstance,
|
|
MAKEINTRESOURCE( pApplet->idIcon ) );
|
|
|
|
if( ( pNewInfo->hIcon != NULL ) &&
|
|
strLoad( pApplet->idName,
|
|
pNewInfo->szName,
|
|
sizeof(pNewInfo->szName) ) &&
|
|
strLoad( pApplet->idInfo,
|
|
pNewInfo->szInfo,
|
|
sizeof(pNewInfo->szInfo) ) &&
|
|
strLoad( pApplet->idHelpFile,
|
|
pNewInfo->szHelpFile,
|
|
sizeof(pNewInfo->szHelpFile) ) )
|
|
{
|
|
nResult = TRUE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
//
|
|
// Who knows. Ignore it.
|
|
//
|
|
|
|
break;
|
|
}
|
|
|
|
return nResult;
|
|
|
|
} // CPlApplet
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: FtpMgrDllInitialize
|
|
|
|
SYNOPSIS: This DLL entry point is called when processes & threads
|
|
are initialized and terminated, or upon calls to
|
|
LoadLibrary() and FreeLibrary().
|
|
|
|
ENTRY: hInstance - A handle to the DLL.
|
|
|
|
nReason - Indicates why the DLL entry
|
|
point is being called.
|
|
|
|
pReserved - Reserved.
|
|
|
|
RETURNS: BOOL - TRUE = DLL init was successful.
|
|
FALSE = DLL init failed.
|
|
|
|
NOTES: The return value is only relevant during processing of
|
|
DLL_PROCESS_ATTACH notifications.
|
|
|
|
HISTORY:
|
|
YiHsinS 22-Mar-1993 Templated from Keithmo's srvmcpl.cxx.
|
|
|
|
********************************************************************/
|
|
|
|
BOOL FAR PASCAL FtpMgrDllInitialize( HINSTANCE hInstance,
|
|
DWORD nReason,
|
|
LPVOID pReserved )
|
|
{
|
|
UNREFERENCED( pReserved );
|
|
|
|
BOOL fResult = TRUE;
|
|
|
|
switch( nReason )
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
//
|
|
// This notification indicates that the DLL is attaching to
|
|
// the address space of the current process. This is either
|
|
// the result of the process starting up, or after a call to
|
|
// LoadLibrary(). The DLL should us this as a hook to
|
|
// initialize any instance data or to allocate a TLS index.
|
|
//
|
|
// This call is made in the context of the thread that
|
|
// caused the process address space to change.
|
|
//
|
|
|
|
fResult = InitializeDll( hInstance );
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
//
|
|
// This notification indicates that the calling process is
|
|
// detaching the DLL from its address space. This is either
|
|
// due to a clean process exit or from a FreeLibrary() call.
|
|
// The DLL should use this opportunity to return any TLS
|
|
// indexes allocated and to free any thread local data.
|
|
//
|
|
// Note that this notification is posted only once per
|
|
// process. Individual threads do not invoke the
|
|
// DLL_THREAD_DETACH notification.
|
|
//
|
|
|
|
TerminateDll();
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
//
|
|
// This notfication indicates that a new thread is being
|
|
// created in the current process. All DLLs attached to
|
|
// the process at the time the thread starts will be
|
|
// notified. The DLL should use this opportunity to
|
|
// initialize a TLS slot for the thread.
|
|
//
|
|
// Note that the thread that posts the DLL_PROCESS_ATTACH
|
|
// notification will not post a DLL_THREAD_ATTACH.
|
|
//
|
|
// Note also that after a DLL is loaded with LoadLibrary,
|
|
// only threads created after the DLL is loaded will
|
|
// post this notification.
|
|
//
|
|
|
|
break;
|
|
|
|
case DLL_THREAD_DETACH:
|
|
//
|
|
// This notification indicates that a thread is exiting
|
|
// cleanly. The DLL should use this opportunity to
|
|
// free any data stored in TLS indices.
|
|
//
|
|
|
|
break;
|
|
|
|
default:
|
|
//
|
|
// Who knows? Just ignore it.
|
|
//
|
|
|
|
break;
|
|
}
|
|
|
|
return fResult;
|
|
|
|
|
|
} // FtpMgrDllInitialize
|
|
|