|
|
// pwsDoc.cpp : implementation of the CPwsDoc class
//
#include "stdafx.h"
#include "resource.h"
#include "pwsform.h"
#include "Title.h"
#include "HotLink.h"
#include "PWSChart.h"
#include "pwsDoc.h"
//#include "PwsForm.h"
#include "Tip.h"
#include "TipDlg.h"
#include "EdDir.h"
#include "FormMain.h"
#include "FormAdv.h"
#include <isvctrl.h>
#include "ServCntr.h"
#include "pwstray.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
// location of the installation path in the registry
#define REG_INSTALL_PATH _T("Software\\Microsoft\\InetStp")
#define REG_PATH_VAL _T("InstallPath")
#define SZ_KEY_RUN_TRAY _T("software\\microsoft\\windows\\currentversion\\run")
#define SZ_KEY_RUN_VALUE _T("PWSTray")
#define SERVER_WINDOWCLASS_NAME TEXT(INET_SERVER_WINDOW_CLASS)
// globals
//extern CPwsForm* g_p_FormView;
CPwsDoc* g_p_Doc = NULL;
extern CFormMain* g_FormMain; extern IMSAdminBase* g_pMBCom; extern BOOL g_fShutdownMode;
#define REGKEY_STP _T("SOFTWARE\\Microsoft\\INetStp")
#define REGKEY_INSTALLKEY _T("InstallPath")
/////////////////////////////////////////////////////////////////////////////
// CPwsDoc
IMPLEMENT_DYNCREATE(CPwsDoc, CDocument)
BEGIN_MESSAGE_MAP(CPwsDoc, CDocument) //{{AFX_MSG_MAP(CPwsDoc)
ON_COMMAND(ID_START, OnStart) ON_COMMAND(ID_STOP, OnStop) ON_UPDATE_COMMAND_UI(ID_START, OnUpdateStart) ON_UPDATE_COMMAND_UI(ID_STOP, OnUpdateStop) ON_COMMAND(ID_PAUSE, OnPause) ON_UPDATE_COMMAND_UI(ID_PAUSE, OnUpdatePause) ON_COMMAND(ID_SHOW_TIPS, OnShowTips) ON_UPDATE_COMMAND_UI(ID_SHOW_TIPS, OnUpdateShowTips) ON_COMMAND(ID_HELP_DOCUMENTATION, OnHelpDocumentation) ON_COMMAND(ID_HELP_HELP_TROUBLESHOOTING, OnHelpHelpTroubleshooting) ON_UPDATE_COMMAND_UI(ID_CONTINUE, OnUpdateContinue) ON_COMMAND(ID_CONTINUE, OnContinue) ON_UPDATE_COMMAND_UI(ID_TRAYICON, OnUpdateTrayicon) ON_COMMAND(ID_TRAYICON, OnTrayicon) //}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP(CPwsDoc, CDocument) //{{AFX_DISPATCH_MAP(CPwsDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
static const IID IID_IPws = { 0x35c43e1, 0x8464, 0x11d0, { 0xa9, 0x2d, 0x8, 0x0, 0x2b, 0x2c, 0x6f, 0x32 } };
BEGIN_INTERFACE_MAP(CPwsDoc, CDocument) INTERFACE_PART(CPwsDoc, IID_IPws, Dispatch) END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPwsDoc construction/destruction
//------------------------------------------------------------------
CPwsDoc::CPwsDoc(): m_ActionToDo( 0 ), m_ExpectedResult( 0 ),
m_dwSinkCookie( 0 ), m_pEventSink( NULL ), m_pConnPoint( NULL ), m_fIsPWSTrayAvailable( FALSE ) { EnableAutomation(); AfxOleLockApp(); g_p_Doc = this;
OSVERSIONINFO info_os; info_os.dwOSVersionInfoSize = sizeof(info_os);
// record what sort of operating system we are running on
m_fIsWinNT = FALSE; if ( GetVersionEx( &info_os ) ) { if ( info_os.dwPlatformId == VER_PLATFORM_WIN32_NT ) m_fIsWinNT = TRUE; } }
//------------------------------------------------------------------
CPwsDoc::~CPwsDoc() { TerminateSink(); g_p_Doc = NULL; AfxOleUnlockApp(); }
//------------------------------------------------------------------
// builds something akin to "http://boydm"
BOOL CPwsDoc::BuildHomePageString( CString &cs ) { CHAR nameBuf[MAX_PATH+1];
// if the server is not running, fail
CW3ServerControl serverController; if ( serverController.GetServerState() != MD_SERVER_STATE_STARTED ) return FALSE;
// start it off with the mandatory http header
cs.LoadString( IDS_HTTP_HEADER ); // get the host name of the machine
gethostname( nameBuf, sizeof(nameBuf)); cs += nameBuf;
return TRUE; }
//------------------------------------------------------------------
BOOL CPwsDoc::InitializeSink() { IConnectionPointContainer * pConnPointContainer = NULL; HRESULT hRes; BOOL fSinkConnected = FALSE;
// g_pMBCom is defined in wrapmb
IUnknown* pmb = (IUnknown*)g_pMBCom;
m_pEventSink = new CImpIMSAdminBaseSink();
if ( !m_pEventSink ) { return FALSE; }
//
// First query the object for its Connection Point Container. This
// essentially asks the object in the server if it is connectable.
//
hRes = pmb->QueryInterface( IID_IConnectionPointContainer, (PVOID *)&pConnPointContainer); if SUCCEEDED(hRes) { // Find the requested Connection Point. This AddRef's the
// returned pointer.
hRes = pConnPointContainer->FindConnectionPoint( IID_IMSAdminBaseSink, &m_pConnPoint);
if (SUCCEEDED(hRes)) { hRes = m_pConnPoint->Advise( (IUnknown *)m_pEventSink, &m_dwSinkCookie);
if (SUCCEEDED(hRes)) { fSinkConnected = TRUE; } }
if ( pConnPointContainer ) { pConnPointContainer->Release(); pConnPointContainer = NULL; } }
if ( !fSinkConnected ) { delete m_pEventSink; }
return fSinkConnected; }
//------------------------------------------------------------------
void CPwsDoc::TerminateSink() { HRESULT hRes;
if ( m_dwSinkCookie ) { hRes = m_pConnPoint->Unadvise( m_dwSinkCookie ); }
// don't need to delete m_pEventSink because the Unadvise
// above decrements is reference count and that causes it
// to delete itself....
}
//------------------------------------------------------------------
BOOL CPwsDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE;
if (!FInitServerInfo()) return FALSE;
// start up the sink
InitializeSink();
// see if the pwstray executable is available
CString pathTray; if ( GetPWSTrayPath(pathTray) ) { m_fIsPWSTrayAvailable = (GetFileAttributes(pathTray) != 0xFFFFFFFF); }
// return success
return TRUE; }
/////////////////////////////////////////////////////////////////////////////
// CPwsDoc serialization
//------------------------------------------------------------------
void CPwsDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { } else { } }
/////////////////////////////////////////////////////////////////////////////
// CPwsDoc diagnostics
#ifdef _DEBUG
//------------------------------------------------------------------
void CPwsDoc::AssertValid() const { CDocument::AssertValid(); }
//------------------------------------------------------------------
void CPwsDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// Access to the server methods
//------------------------------------------------------------------
// initialize the location of the server - it is stored in the registry
BOOL CPwsDoc::FInitServerInfo() { DWORD err; HKEY hKey;
DWORD iType = REG_SZ; DWORD cbPath = MAX_PATH+1; LPTSTR pPath;
// open the registry key, if it exists
err = RegOpenKeyEx( HKEY_LOCAL_MACHINE, // handle of open key
REG_INSTALL_PATH, // address of name of subkey to open
0, // reserved
KEY_READ, // security access mask
&hKey // address of handle of open key
);
// if we were not able to open the key, then there was an error in the installation
if ( err != ERROR_SUCCESS ) { AfxMessageBox( IDS_INSTALL_ERROR ); return FALSE; }
// set up the buffer
pPath = m_szServerPath.GetBuffer( cbPath );
// get the base installation path for the server executable
err = RegQueryValueEx( hKey, REG_PATH_VAL, NULL, &iType, (PUCHAR)pPath, &cbPath );
// release the name buffers
m_szServerPath.ReleaseBuffer();
// all done, close the key before leaving
RegCloseKey( hKey );
// check the error code and fail if necessary
if ( err != ERROR_SUCCESS ) AfxMessageBox( IDS_INSTALL_ERROR );
// return success
return (err == ERROR_SUCCESS); }
//------------------------------------------------------------------
// updates the state of the server. Affects both the status strings and the
// avis. Can be called from either a change notify or OnIdle.
void CPwsDoc::UpdateServerState() { }
//------------------------------------------------------------------
BOOL CPwsDoc::LauchAppIfNecessary() { BOOL f; STARTUPINFO startupInfo; PROCESS_INFORMATION processInfo; TCHAR path[MAX_PATH+1];
// if this is running under NT, skip this part
OSVERSIONINFO osver; osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx( &osver );
if ( osver.dwPlatformId == VER_PLATFORM_WIN32_NT ) return TRUE;
// if the window is there, the exe is running and we don't have to do anything
if ( FindWindow(SERVER_WINDOWCLASS_NAME, NULL) ) return TRUE;
CString szExeName; szExeName.LoadString( IDS_EXECUTABLE );
ZeroMemory(&startupInfo,sizeof(STARTUPINFO)); startupInfo.cb = sizeof(STARTUPINFO);
CString szAppl; szAppl.LoadString( IDS_INETINFO_EXE );
_tcscpy(path, m_szServerPath); _tcscat(path, _T("\\")); _tcscat(path, szAppl);
//
// the app is not running. Attempt to start the executable
//
f = CreateProcess( (LPCTSTR)path, (LPTSTR)(LPCTSTR)szExeName, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo );
if ( !f ) { AfxMessageBox( IDS_ERROR_START ); // failure
return FALSE; }
// success
return TRUE; }
//------------------------------------------------------------------
void CPwsDoc::PerformAction( DWORD action, DWORD expected ) { }
//------------------------------------------------------------------
// if the service is running, stop it. If it is stopped, start it
void CPwsDoc::ToggleService() { }
/////////////////////////////////////////////////////////////////////////////
// CPwsDoc commands
//------------------------------------------------------------------
void CPwsDoc::OnUpdateShowTips(CCmdUI* pCmdUI) { pCmdUI->Enable( TRUE ); }
//------------------------------------------------------------------
void CPwsDoc::OnUpdateStart(CCmdUI* pCmdUI) { CW3ServerControl serverController; DWORD dwState = serverController.GetServerState(); pCmdUI->Enable( dwState == MD_SERVER_STATE_STOPPED ); }
//------------------------------------------------------------------
void CPwsDoc::OnUpdateStop(CCmdUI* pCmdUI) { CW3ServerControl serverController; DWORD dwState = serverController.GetServerState(); pCmdUI->Enable( (dwState == MD_SERVER_STATE_STARTED) || (dwState == MD_SERVER_STATE_PAUSED) ); }
//------------------------------------------------------------------
void CPwsDoc::OnUpdatePause(CCmdUI* pCmdUI) { CW3ServerControl serverController; DWORD dwState = serverController.GetServerState(); pCmdUI->Enable( dwState == MD_SERVER_STATE_STARTED ); }
//------------------------------------------------------------------
void CPwsDoc::OnUpdateContinue(CCmdUI* pCmdUI) { CW3ServerControl serverController; DWORD dwState = serverController.GetServerState(); pCmdUI->Enable( dwState == MD_SERVER_STATE_PAUSED ); }
//------------------------------------------------------------------
void CPwsDoc::OnStart() { CW3ServerControl serverController; serverController.StartServer(); }
//------------------------------------------------------------------
void CPwsDoc::OnStop() { CW3ServerControl serverController; serverController.StopServer();
// if this is win95 and the main pane is showing, tell it to update
if ( !m_fIsWinNT && g_FormMain ) g_FormMain->UpdateServerState(); }
//------------------------------------------------------------------
void CPwsDoc::OnPause() { CW3ServerControl serverController; serverController.PauseServer(); }
//------------------------------------------------------------------
void CPwsDoc::OnContinue() { CW3ServerControl serverController; serverController.ContinueServer(); }
//------------------------------------------------------------------
void CPwsDoc::OnShowTips() { CTipDlg dlg; dlg.DoModal(); } /*
//------------------------------------------------------------------
void CPwsDoc::OnHelpFinder() { DWORD err;
// build the path to the help file
CString szPath; szPath.LoadString( IDS_HELP_LOC ); szPath = m_szServerPath + szPath;
// use shellexecute to open the file
ShellExecute( NULL, NULL, (PCHAR)(LPCSTR)szPath, NULL, NULL, SW_SHOW ); err = GetLastError(); if ( err ) { // just re-use szPath
szPath.LoadString(IDS_NO_HELP); szPath.Format( "%s\nError = %d", szPath, err ); AfxMessageBox( szPath ); } } */
//------------------------------------------------------------------
void CPwsDoc::OnHelpDocumentation() { // this documentation only works if it is served. Thus, if the local
// server is not running, we should tell that to the user.
CW3ServerControl serverController; if ( g_fShutdownMode || (serverController.GetServerState() != MD_SERVER_STATE_STARTED) ) { AfxMessageBox( IDS_HELPERR_REQUIRES_SERVER ); return; }
// load the served help docs url
CString szHelpURL; szHelpURL.LoadString( IDS_HELPLOC_DOCS );
// use shellexecute to access the help via the browser
ShellExecute( NULL, // handle to parent window
NULL, // pointer to string that specifies operation to perform
szHelpURL, // pointer to filename or folder name string
NULL, // pointer to string that specifies executable-file parameters
NULL, // pointer to string that specifies default directory
SW_SHOW // whether file is shown when opened
); }
//------------------------------------------------------------------
void CPwsDoc::OnHelpHelpTroubleshooting() { // load the relative file path for the troublshooting
CString szTroublePath; szTroublePath.LoadString( IDS_HELPLOC_README );
// expand the path
CString szExpandedPath; ExpandEnvironmentStrings( szTroublePath, // pointer to string with environment variables
szExpandedPath.GetBuffer(MAX_PATH + 1), // pointer to string with expanded environment variables
MAX_PATH // maximum characters in expanded string
); szExpandedPath.ReleaseBuffer();
// use shellexecute to access the help via the browser
ShellExecute( NULL, // handle to parent window
NULL, // pointer to string that specifies operation to perform
szExpandedPath, // pointer to filename or folder name string
NULL, // pointer to string that specifies executable-file parameters
NULL, // pointer to string that specifies default directory
SW_SHOW // whether file is shown when opened
); }
//------------------------------------------------------------------
void CPwsDoc::OnUpdateTrayicon(CCmdUI* pCmdUI) { // if the exe is available, show the right thing
if ( m_fIsPWSTrayAvailable ) { pCmdUI->Enable( TRUE ); pCmdUI->SetCheck( (::FindWindow(PWS_TRAY_WINDOW_CLASS,NULL) != NULL) ); } else { pCmdUI->Enable( FALSE ); pCmdUI->SetCheck( FALSE ); } } //------------------------------------------------------------------
void CPwsDoc::OnTrayicon() { HWND hwndTray = FindWindow(PWS_TRAY_WINDOW_CLASS,NULL); CString sz;
// first, act directly on the application
if ( hwndTray != NULL ) { PostMessage( hwndTray, WM_CLOSE, 0, 0 ); // make sure it doesn't start up again
} // else start it up
else { if ( GetPWSTrayPath( sz ) ) { ShellExecute( NULL, // handle to parent window
NULL, // pointer to string that specifies operation to perform
sz, // pointer to filename or folder name string
NULL, // pointer to string that specifies executable-file parameters
NULL, // pointer to string that specifies default directory
0 // whether file is shown when opened
); } // make sure it starts up again
}
// now write the proper value to the registry so that pwstray does, or doesn't
// get launched the next time you log on to the system
sz.LoadString( IDS_PWSTRAY_EXE ); DWORD err; HKEY hKey; DWORD cbdata = sizeof(TCHAR) * (sz.GetLength() + 1);
// open the registry key, if it exists
err = RegOpenKeyEx( HKEY_LOCAL_MACHINE, // handle of open key
SZ_KEY_RUN_TRAY, // address of name of subkey to open
0, // reserved
KEY_WRITE, // security access mask
&hKey // address of handle of open key
); // if we did not open the key for any reason (say... it doesn't exist)
// then show the icon
if ( err != ERROR_SUCCESS ) return;
//do the right thing
if ( hwndTray ) { // remove it
err = RegDeleteValue( hKey, // handle of key
SZ_KEY_RUN_VALUE // address of value name
); } else { // add it
err = RegSetValueEx( hKey, // handle of key to query
SZ_KEY_RUN_VALUE, // address of name of value to query
0, // reserved
REG_SZ, // address of buffer for value type
(LPBYTE)(LPCTSTR)sz, // address of data buffer
cbdata // address of data buffer size
); }
// all done, close the key before leaving
RegCloseKey( hKey ); }
//------------------------------------------------------------------
BOOL CPwsDoc::GetPWSTrayPath( CString &sz ) { if ( !GetSystemDirectory(sz.GetBuffer(MAX_PATH+1),MAX_PATH) ) return FALSE;
sz.ReleaseBuffer(); // add on the executable part
CString szExe; szExe.LoadString( IDS_PWSTRAY_EXE ); sz += '\\'; sz += szExe; return TRUE; }
|