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.
1348 lines
34 KiB
1348 lines
34 KiB
// MODULE: TSHOOTCTL.CPP
|
|
//
|
|
// PURPOSE: Interface for the componet.
|
|
//
|
|
// PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
|
|
//
|
|
// COMPANY: Saltmine Creative, Inc. (206)-633-4743 [email protected]
|
|
//
|
|
// AUTHOR: Roman Mach
|
|
//
|
|
// ORIGINAL DATE: 6/4/96
|
|
//
|
|
// NOTES:
|
|
// 1. Based on Print Troubleshooter DLL.
|
|
// 2. Richard Meadows wrote the RunQuery, BackUp, Problem Page and
|
|
// PreLoadURL functions.
|
|
//
|
|
// Version Date By Comments
|
|
//--------------------------------------------------------------------
|
|
// V0.1 - RM Original
|
|
// V0.3 04/09/98 JM/OK+ Local Version for NT5
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "ErrorEnums.h"
|
|
|
|
#include "cathelp.h"
|
|
|
|
#include "TSHOOT.h"
|
|
|
|
#include "time.h"
|
|
|
|
#include "apgts.h"
|
|
#include "ErrorEnums.h"
|
|
#include "BasicException.h"
|
|
#include "apgtsfst.h"
|
|
|
|
#include "ErrorEnums.h"
|
|
|
|
#include "CabUnCompress.h"
|
|
|
|
#include "bnts.h"
|
|
#include "BackupInfo.h"
|
|
#include "cachegen.h"
|
|
#include "apgtsinf.h"
|
|
#include "apgtscmd.h"
|
|
#include "apgtshtx.h"
|
|
#include "apgtscls.h"
|
|
|
|
#include "OcxGlobals.h"
|
|
|
|
|
|
class CTSHOOTCtrl;
|
|
|
|
#include "dnldlist.h"
|
|
#include "download.h"
|
|
|
|
#include "TSHOOTCtl.h"
|
|
#include "TSHOOTPpg.h"
|
|
|
|
#include "Functions.h"
|
|
#include "ErrorEnums.h"
|
|
#include "BasicException.h"
|
|
#include "HttpQueryException.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "LaunchServ.h"
|
|
#include "LaunchServ_i.c"
|
|
|
|
// >>> test
|
|
#include "fstream.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
IMPLEMENT_DYNCREATE(CTSHOOTCtrl, COleControl)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Message map
|
|
|
|
BEGIN_MESSAGE_MAP(CTSHOOTCtrl, COleControl)
|
|
//{{AFX_MSG_MAP(CTSHOOTCtrl)
|
|
// NOTE - ClassWizard will add and remove message map entries
|
|
// DO NOT EDIT what you see in these blocks of generated code !
|
|
//}}AFX_MSG_MAP
|
|
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Dispatch map
|
|
|
|
BEGIN_DISPATCH_MAP(CTSHOOTCtrl, COleControl)
|
|
//{{AFX_DISPATCH_MAP(CTSHOOTCtrl)
|
|
DISP_PROPERTY_NOTIFY(CTSHOOTCtrl, "DownloadURL", m_downloadURL, OnDownloadURLChanged, VT_BSTR)
|
|
DISP_PROPERTY_NOTIFY(CTSHOOTCtrl, "DownloadListFilename", m_downloadListFilename, OnDownloadListFilenameChanged, VT_BSTR)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "RunQuery", RunQuery, VT_BSTR, VTS_VARIANT VTS_VARIANT VTS_I2)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "SetSniffResult", SetSniffResult, VT_BOOL, VTS_VARIANT VTS_VARIANT)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "GetExtendedError", GetExtendedError, VT_I4, VTS_NONE)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "GetCurrentFriendlyDownload", GetCurrentFriendlyDownload, VT_BSTR, VTS_NONE)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "GetCurrentFileDownload", GetCurrentFileDownload, VT_BSTR, VTS_NONE)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "DownloadAction", DownloadAction, VT_I4, VTS_I4)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "BackUp", BackUp, VT_BSTR, VTS_NONE)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "ProblemPage", ProblemPage, VT_BSTR, VTS_NONE)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "PreLoadURL", PreLoadURL, VT_BSTR, VTS_BSTR)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "Restart", Restart, VT_BSTR, VTS_NONE)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "RunQuery2", RunQuery2, VT_BSTR, VTS_BSTR VTS_BSTR VTS_BSTR)
|
|
DISP_FUNCTION(CTSHOOTCtrl, "SetPair", SetPair, VT_EMPTY, VTS_BSTR VTS_BSTR)
|
|
//}}AFX_DISPATCH_MAP
|
|
DISP_FUNCTION_ID(CTSHOOTCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
|
|
END_DISPATCH_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Event map
|
|
|
|
BEGIN_EVENT_MAP(CTSHOOTCtrl, COleControl)
|
|
//{{AFX_EVENT_MAP(CTSHOOTCtrl)
|
|
EVENT_CUSTOM("BindProgress", FireBindProgress, VTS_BSTR VTS_I4 VTS_I4)
|
|
EVENT_CUSTOM("BindStatus", FireBindStatus, VTS_I4 VTS_I4 VTS_I4 VTS_BOOL)
|
|
EVENT_CUSTOM("Sniffing", FireSniffing, VTS_BSTR VTS_BSTR VTS_BSTR VTS_BSTR)
|
|
//}}AFX_EVENT_MAP
|
|
END_EVENT_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Property pages
|
|
|
|
// TODO: Add more property pages as needed. Remember to increase the count!
|
|
BEGIN_PROPPAGEIDS(CTSHOOTCtrl, 1)
|
|
PROPPAGEID(CTSHOOTPropPage::guid)
|
|
END_PROPPAGEIDS(CTSHOOTCtrl)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Initialize class factory and guid
|
|
|
|
IMPLEMENT_OLECREATE_EX(CTSHOOTCtrl, "TSHOOT.TSHOOTCtrl.1",
|
|
0x4b106874, 0xdd36, 0x11d0, 0x8b, 0x44, 0, 0xa0, 0x24, 0xdd, 0x9e, 0xff)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Type library ID and version
|
|
|
|
IMPLEMENT_OLETYPELIB(CTSHOOTCtrl, _tlid, _wVerMajor, _wVerMinor)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Interface IDs
|
|
|
|
const IID BASED_CODE IID_DTSHOOT =
|
|
{ 0x4b106872, 0xdd36, 0x11d0, { 0x8b, 0x44, 0, 0xa0, 0x24, 0xdd, 0x9e, 0xff } };
|
|
const IID BASED_CODE IID_DTSHOOTEvents =
|
|
{ 0x4b106873, 0xdd36, 0x11d0, { 0x8b, 0x44, 0, 0xa0, 0x24, 0xdd, 0x9e, 0xff } };
|
|
|
|
const CATID CATID_SafeForScripting = {0x7dd95801,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};
|
|
const CATID CATID_SafeForInitializing = {0x7dd95802,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Control type information
|
|
|
|
static const DWORD BASED_CODE _dwTSHOOTOleMisc =
|
|
OLEMISC_ACTIVATEWHENVISIBLE |
|
|
OLEMISC_SETCLIENTSITEFIRST |
|
|
OLEMISC_INSIDEOUT |
|
|
OLEMISC_CANTLINKINSIDE |
|
|
OLEMISC_RECOMPOSEONRESIZE;
|
|
|
|
IMPLEMENT_OLECTLTYPE(CTSHOOTCtrl, IDS_TSHOOT, _dwTSHOOTOleMisc)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTSHOOTCtrl::CTSHOOTCtrlFactory::UpdateRegistry -
|
|
// Adds or removes system registry entries for CTSHOOTCtrl
|
|
|
|
BOOL CTSHOOTCtrl::CTSHOOTCtrlFactory::UpdateRegistry(BOOL bRegister)
|
|
{
|
|
// TODO: Verify that your control follows apartment-model threading rules.
|
|
// Refer to MFC TechNote 64 for more information.
|
|
// If your control does not conform to the apartment-model rules, then
|
|
// you must modify the code below, changing the 6th parameter from
|
|
// afxRegApartmentThreading to 0.
|
|
|
|
HRESULT hr;
|
|
BOOL bRes;
|
|
if (bRegister)
|
|
{
|
|
bRes = AfxOleRegisterControlClass(
|
|
AfxGetInstanceHandle(),
|
|
m_clsid,
|
|
m_lpszProgID,
|
|
IDS_TSHOOT,
|
|
IDB_TSHOOT,
|
|
afxRegApartmentThreading,
|
|
_dwTSHOOTOleMisc,
|
|
_tlid,
|
|
_wVerMajor,
|
|
_wVerMinor);
|
|
|
|
hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls that are safely scriptable");
|
|
ASSERT(SUCCEEDED(hr));
|
|
hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data");
|
|
ASSERT(SUCCEEDED(hr));
|
|
hr = RegisterCLSIDInCategory(m_clsid, CATID_SafeForScripting);
|
|
ASSERT(SUCCEEDED(hr));
|
|
hr = RegisterCLSIDInCategory(m_clsid, CATID_SafeForInitializing);
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
else
|
|
{
|
|
hr = UnRegisterCLSIDInCategory(m_clsid, CATID_SafeForScripting);
|
|
ASSERT(SUCCEEDED(hr));
|
|
hr = UnRegisterCLSIDInCategory(m_clsid, CATID_SafeForInitializing);
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
bRes = AfxOleUnregisterClass(m_clsid, m_lpszProgID);
|
|
}
|
|
return bRes;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTSHOOTCtrl::CTSHOOTCtrl - Constructor
|
|
|
|
CTSHOOTCtrl::CTSHOOTCtrl()
|
|
{
|
|
InitializeIIDs(&IID_DTSHOOT, &IID_DTSHOOTEvents);
|
|
|
|
// TODO: Initialize your control's instance data here.
|
|
m_strCurShooter = _T("");
|
|
m_download = NULL;
|
|
m_bComplete = TRUE;
|
|
m_dwExtendedErr = LTSC_OK;
|
|
m_pSniffedContainer = NULL;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTSHOOTCtrl::~CTSHOOTCtrl - Destructor
|
|
|
|
CTSHOOTCtrl::~CTSHOOTCtrl()
|
|
{
|
|
// TODO: Cleanup your control's instance data here.
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTSHOOTCtrl::OnDraw - Drawing function
|
|
|
|
void CTSHOOTCtrl::OnDraw(
|
|
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
|
|
{
|
|
// TODO: Replace the following code with your own drawing code.
|
|
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
|
|
pdc->Ellipse(rcBounds);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTSHOOTCtrl::DoPropExchange - Persistence support
|
|
|
|
void CTSHOOTCtrl::DoPropExchange(CPropExchange* pPX)
|
|
{
|
|
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
|
|
COleControl::DoPropExchange(pPX);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTSHOOTCtrl::OnResetState - Reset control to default state
|
|
|
|
void CTSHOOTCtrl::OnResetState()
|
|
{
|
|
COleControl::OnResetState(); // Resets defaults found in DoPropExchange
|
|
|
|
// TODO: Reset any other control state here.
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTSHOOTCtrl::AboutBox - Display an "About" box to the user
|
|
|
|
void CTSHOOTCtrl::AboutBox()
|
|
{
|
|
CDialog dlgAbout(IDD_ABOUTBOX_TSHOOT);
|
|
dlgAbout.DoModal();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTSHOOTCtrl message handlers
|
|
|
|
bool CTSHOOTCtrl::SetSniffResult(const VARIANT FAR& varNodeName, const VARIANT FAR& varNodeState)
|
|
{
|
|
BSTR bstrNodeName = NULL;
|
|
int iNodeState = 0;
|
|
short sNodeNameLen = 0;
|
|
TCHAR* tszNodeName = NULL;
|
|
bool ret = true;
|
|
|
|
// >>> test
|
|
#ifdef _DEBUG
|
|
// AfxDebugBreak();
|
|
#endif
|
|
|
|
if (VT_BYREF == (VT_BYREF & varNodeName.vt) && // data type is VT_VARIANT | VT_BYREF
|
|
VT_VARIANT == (VT_VARIANT & varNodeName.vt) // this means that data in VB script was passed as a variable
|
|
)
|
|
{
|
|
bstrNodeName = varNodeName.pvarVal->bstrVal;
|
|
}
|
|
else
|
|
{
|
|
if (VT_BSTR == (VT_BSTR & varNodeName.vt)) // data is of VT_BSTR type
|
|
// this means that data in VB script was passed as a constant
|
|
bstrNodeName = varNodeName.bstrVal;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
if (VT_BYREF == (VT_BYREF & varNodeState.vt) && // data type is VT_VARIANT | VT_BYREF
|
|
VT_VARIANT == (VT_VARIANT & varNodeState.vt) // this means that data in VB script was passed as a variable
|
|
)
|
|
{
|
|
iNodeState = varNodeState.pvarVal->iVal;
|
|
}
|
|
else
|
|
{
|
|
if (VT_I2 == (VT_I2 & varNodeState.vt)) // data is of VT_I2 type
|
|
// this means that data in VB script was passed as a constant
|
|
iNodeState = varNodeState.iVal;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
sNodeNameLen = (short)::SysStringLen(bstrNodeName);
|
|
tszNodeName = new TCHAR[sNodeNameLen+1];
|
|
|
|
tszNodeName[sNodeNameLen] = 0;
|
|
::BSTRToTCHAR(tszNodeName, bstrNodeName, sNodeNameLen);
|
|
|
|
//
|
|
// implement set node state functionality here
|
|
//
|
|
if (m_pSniffedContainer)
|
|
{
|
|
ret = m_pSniffedContainer->AddNode(tszNodeName, iNodeState);
|
|
}
|
|
else
|
|
{
|
|
MessageBox(_T("Sniffed data will be lost!"));
|
|
ret = false;
|
|
}
|
|
//
|
|
|
|
delete [] tszNodeName;
|
|
return ret;
|
|
}
|
|
|
|
BSTR CTSHOOTCtrl::RunQuery(const VARIANT FAR& varCmds, const VARIANT FAR& varVals, short size)
|
|
{
|
|
CString strCmd1;
|
|
CString strTxt;
|
|
CString strResult = _T("");
|
|
|
|
try
|
|
{
|
|
HMODULE hModule = AfxGetInstanceHandle();
|
|
ASSERT(INVALID_HANDLE_VALUE != hModule);
|
|
|
|
m_httpQuery.Initialize(varCmds, varVals, size);
|
|
|
|
if (m_httpQuery.GetFirstCmd() == C_ASK_LIBRARY)
|
|
{
|
|
// Added to support launching by the TS Launcher.
|
|
// Get an ILaunchTS interface.
|
|
HRESULT hRes;
|
|
DWORD dwResult;
|
|
ILaunchTS *pILaunchTS = NULL;
|
|
CLSID clsidLaunchTS = CLSID_LaunchTS;
|
|
IID iidLaunchTS = IID_ILaunchTS;
|
|
|
|
// Get an interface on the launch server
|
|
hRes = CoCreateInstance(clsidLaunchTS, NULL,
|
|
CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER | CLSCTX_INPROC_SERVER,
|
|
iidLaunchTS, (void **) &pILaunchTS);
|
|
if (FAILED(hRes))
|
|
{
|
|
m_dwExtendedErr = TSERR_LIB_STATE_INFO;
|
|
strResult = _T("LaunchServ interface not found.");
|
|
return strResult.AllocSysString();
|
|
}
|
|
|
|
// Get all of the query values.
|
|
hRes = pILaunchTS->GetShooterStates(&dwResult);
|
|
if (FAILED(hRes))
|
|
{
|
|
m_dwExtendedErr = dwResult;
|
|
strResult.Format(_T("<html>GetShooterStates Failed. %ld</html>"), dwResult);
|
|
pILaunchTS->Release();
|
|
return strResult.AllocSysString();
|
|
}
|
|
|
|
// Run the query.
|
|
OLECHAR *poleShooter;
|
|
hRes = pILaunchTS->GetTroubleShooter(&poleShooter);
|
|
if (FAILED(hRes))
|
|
{
|
|
m_dwExtendedErr = TSERR_LIB_STATE_INFO;
|
|
strResult = _T("<html>GetTroubleShooter Failed. </html>");
|
|
pILaunchTS->Release();
|
|
return strResult.AllocSysString();
|
|
}
|
|
m_strCurShooter = poleShooter;
|
|
|
|
// Ignoring, for now, any other information we may get from the launch server
|
|
// (e.g. problem node) set up m_httpQuery and other things as if we just had
|
|
// a request for this troubleshooting belief network.
|
|
m_httpQuery.SetFirst(CString(C_TYPE), m_strCurShooter);
|
|
SysFreeString(poleShooter);
|
|
m_Conf.Initialize(hModule, (LPCTSTR) m_strCurShooter
|
|
); // CDBLoadConfiguration
|
|
m_apgts.Initialize( m_Conf.GetAPI(), // APGTSContext
|
|
&m_Conf,
|
|
&m_httpQuery);
|
|
m_apgts.RemoveSkips();
|
|
m_Conf.GetAPI()->api.pAPI->SetHttpQuery(&m_httpQuery);
|
|
|
|
// sniffing
|
|
m_Conf.GetAPI()->api.pAPI->ReadTheDscModel();
|
|
m_pSniffedContainer = m_Conf.GetAPI()->api.pAPI;
|
|
|
|
m_httpQuery.FinishInitFromServ(m_Conf.GetAPI()->api.pAPI, pILaunchTS);
|
|
|
|
FireSniffing(m_httpQuery.GetMachine(),
|
|
m_httpQuery.GetPNPDevice(),
|
|
m_httpQuery.GetDeviceInstance(),
|
|
m_httpQuery.GetGuidClass());
|
|
|
|
pILaunchTS->Release();
|
|
pILaunchTS = NULL;
|
|
|
|
m_httpQuery.SetStackDirection();
|
|
m_Conf.SetValues(m_httpQuery);
|
|
m_apgts.ClearBackup();
|
|
|
|
m_Conf.GetAPI()->api.pAPI->SetReverse(false);
|
|
m_apgts.DoContent(&m_httpQuery);
|
|
|
|
// now add sniffed nodes that were automatically traversed
|
|
// to the stack of navigated nodes - UGLY
|
|
m_httpQuery.PushNodesLastSniffed(m_Conf.GetAPI()->api.pAPI->GetArrLastSniffed());
|
|
|
|
// Now that we've done all the processing render the appropriate page.
|
|
// This is the first page the user sees when launching a torubleshooter.
|
|
m_apgts.RenderNext(strResult);
|
|
m_apgts.Empty();
|
|
}
|
|
else if (m_httpQuery.GetFirstCmd() == C_SELECT)
|
|
{ // Unsupported function.
|
|
// Returns a page that has all of the trouble shooters.
|
|
try
|
|
{
|
|
CFirstPage firstPage;
|
|
CString str = m_httpQuery.GetTroubleShooter();
|
|
firstPage.RenderFirst(strResult, str); // Here I am getting an hit file.
|
|
}
|
|
catch(CBasicException *pExc)
|
|
{
|
|
m_dwExtendedErr = pExc->m_dwBErr;
|
|
strResult = _T("");
|
|
delete pExc;
|
|
}
|
|
}
|
|
else
|
|
{ // Normal operation.
|
|
if (m_httpQuery.GetTroubleShooter() != m_strCurShooter)
|
|
{
|
|
m_strCurShooter = m_httpQuery.GetTroubleShooter();
|
|
m_Conf.Initialize(hModule, (LPCTSTR) m_strCurShooter
|
|
); // CDBLoadConfiguration
|
|
m_apgts.Initialize( m_Conf.GetAPI(), // APGTSContext
|
|
&m_Conf,
|
|
&m_httpQuery);
|
|
m_apgts.RemoveSkips();
|
|
m_Conf.GetAPI()->api.pAPI->SetHttpQuery(&m_httpQuery);
|
|
|
|
// sniffing
|
|
m_Conf.GetAPI()->api.pAPI->ReadTheDscModel();
|
|
m_pSniffedContainer = m_Conf.GetAPI()->api.pAPI;
|
|
FireSniffing(m_httpQuery.GetMachine(),
|
|
m_httpQuery.GetPNPDevice(),
|
|
m_httpQuery.GetDeviceInstance(),
|
|
m_httpQuery.GetGuidClass());
|
|
}
|
|
m_httpQuery.FinishInit(m_Conf.GetAPI()->api.pAPI, varCmds, varVals);
|
|
|
|
m_httpQuery.SetStackDirection();
|
|
m_Conf.SetValues(m_httpQuery);
|
|
m_apgts.ClearBackup();
|
|
|
|
m_Conf.GetAPI()->api.pAPI->SetReverse(false);
|
|
m_apgts.DoContent(&m_httpQuery);
|
|
|
|
// now add sniffed nodes that were automatically traversed
|
|
// to the stack of navigated nodes - UGLY
|
|
m_httpQuery.PushNodesLastSniffed(m_Conf.GetAPI()->api.pAPI->GetArrLastSniffed());
|
|
|
|
// >>> test
|
|
//static int step = 0;
|
|
//char name[16] = {0};
|
|
//sprintf(name, "next_step%d.htm", ++step);
|
|
//ofstream file(name);
|
|
m_apgts.RenderNext(strResult);
|
|
//file << (LPCTSTR)strResult;
|
|
m_apgts.Empty();
|
|
}
|
|
}
|
|
catch(COleException *pOExc)
|
|
{
|
|
m_dwExtendedErr = (DLSTATTYPES) pOExc->m_sc;
|
|
pOExc->Delete();
|
|
strResult = _T("");
|
|
}
|
|
catch(CBasicException *pExc)
|
|
{
|
|
m_dwExtendedErr = pExc->m_dwBErr;
|
|
delete pExc;
|
|
strResult = _T("");
|
|
}
|
|
unsigned short pErrorStr[2] = { NULL, NULL };
|
|
if (strResult.GetLength() > 0)
|
|
{
|
|
return strResult.AllocSysString();
|
|
}
|
|
else
|
|
{
|
|
return SysAllocString((unsigned short *) pErrorStr);
|
|
}
|
|
}
|
|
|
|
BSTR CTSHOOTCtrl::BackUp()
|
|
{
|
|
BCache *pApi = m_Conf.GetAPI()->api.pAPI;
|
|
CString strResult = _T("");
|
|
if (m_httpQuery.BackUp(pApi, &m_apgts))
|
|
{
|
|
m_Conf.GetAPI()->api.pAPI->SetReverse(true);
|
|
m_apgts.DoContent(&m_httpQuery);
|
|
m_apgts.RenderNext(strResult);
|
|
m_apgts.Empty();
|
|
}
|
|
else
|
|
m_dwExtendedErr = TSERR_AT_START;
|
|
return strResult.AllocSysString();
|
|
}
|
|
// Starter
|
|
// Historically (until March '98) this was called when the "Restart button" is pressed.
|
|
// However, that assumed we would always want to go clear back to the problem page, which
|
|
// is no longer policy now that the Launcher is introduced.
|
|
BSTR CTSHOOTCtrl::ProblemPage()
|
|
{
|
|
BCache *pApi = m_Conf.GetAPI()->api.pAPI;
|
|
CString strResult = _T("");
|
|
if (m_strCurShooter.GetLength() > 0)
|
|
{
|
|
m_httpQuery.RemoveNodes(pApi);
|
|
m_apgts.DoContent(&m_httpQuery);
|
|
m_apgts.RenderNext(strResult);
|
|
m_apgts.Empty();
|
|
}
|
|
else
|
|
m_dwExtendedErr = TSERR_NOT_STARTED;
|
|
m_apgts.ResetService();
|
|
return strResult.AllocSysString();
|
|
}
|
|
|
|
// Called when the "Restart button" is pressed.
|
|
// If TS Launcher was not involved, go clear back to the problem page.
|
|
// If TS Launcher is involved, go back to the page we launched to, which may or may not
|
|
// be the problem page.
|
|
BSTR CTSHOOTCtrl::Restart()
|
|
{
|
|
BCache *pApi = m_Conf.GetAPI()->api.pAPI;
|
|
CString strResult;
|
|
|
|
// >>> test
|
|
#ifdef _DEBUG
|
|
// AfxDebugBreak();
|
|
#endif
|
|
|
|
// resniffing
|
|
m_pSniffedContainer->Flush();
|
|
FireSniffing(m_httpQuery.GetMachine(),
|
|
m_httpQuery.GetPNPDevice(),
|
|
m_httpQuery.GetDeviceInstance(),
|
|
m_httpQuery.GetGuidClass());
|
|
|
|
if (m_strCurShooter.GetLength() > 0)
|
|
{
|
|
m_httpQuery.RemoveNodes(pApi);
|
|
m_httpQuery.RestoreStatesFromServ();
|
|
m_apgts.ClearBackup();
|
|
m_apgts.DoContent(&m_httpQuery);
|
|
m_apgts.RenderNext(strResult);
|
|
m_apgts.Empty();
|
|
}
|
|
else
|
|
m_dwExtendedErr = TSERR_NOT_STARTED;
|
|
|
|
return strResult.AllocSysString();
|
|
}
|
|
|
|
|
|
BSTR CTSHOOTCtrl::PreLoadURL(LPCTSTR szRoot)
|
|
{
|
|
// SzRoot should look like one of these.
|
|
// _T("http://www.microsoft.com/isapi/support/apgts/");
|
|
// _T("http://localhost/isapi/support/apgts/");
|
|
// _T("http://catbert.saltmine.com/scripts/apgts/");
|
|
CString strResult;
|
|
strResult = szRoot;
|
|
strResult += PRELOAD_LIBRARY + m_strCurShooter +
|
|
m_httpQuery.GetSubmitString(m_Conf.GetAPI()->api.pAPI);
|
|
return strResult.AllocSysString();
|
|
}
|
|
|
|
const CString CTSHOOTCtrl::GetListPath()
|
|
{
|
|
if (!m_downloadURL.GetLength() || !m_downloadListFilename.GetLength())
|
|
return _T("");
|
|
|
|
return m_downloadURL + m_downloadListFilename;
|
|
}
|
|
|
|
//
|
|
// Types:
|
|
//
|
|
// 0 = Get INI file contents and fill up list
|
|
// Returns: 0 = ok, other = Error connecting
|
|
//
|
|
// 1 = Download and register DSC files based on list
|
|
// Returns: 0 = ok, other = Error, typically no more data in list
|
|
//
|
|
// Notes:
|
|
// 1. This function starts downloading and calls BindStatus event
|
|
// as download progresses.
|
|
// 2. Type 0 must always be called after type 1 is finished to reset
|
|
// the list otherwise an error is returned
|
|
// 3. Keep dwActionType and DLITEMTYPES in sync
|
|
//
|
|
long CTSHOOTCtrl::DownloadAction(long dwActionType)
|
|
{
|
|
DLITEMTYPES dwType;
|
|
CString sURL;
|
|
|
|
if (!GetListPath().GetLength())
|
|
return LTSCERR_NOPATH;
|
|
|
|
if (dwActionType == 0)
|
|
{
|
|
dwType = DLITEM_INI;
|
|
sURL = GetListPath();
|
|
// initialize to 'no error'
|
|
m_dwExtendedErr = LTSC_OK;
|
|
//m_bComplete = FALSE;
|
|
}
|
|
else if (dwActionType == 1)
|
|
{
|
|
//if (!m_bComplete)
|
|
// return LTSCERR_DNLDNOTDONE;
|
|
|
|
dwType = DLITEM_DSC;
|
|
sURL = m_downloadURL;
|
|
|
|
if (!m_dnldList.FindNextItem())
|
|
return LTSC_NOMOREITEMS;
|
|
|
|
|
|
sURL += m_dnldList.GetCurrFile();
|
|
}
|
|
else
|
|
return LTSCERR_UNKNATYPE;
|
|
|
|
if (m_download == NULL)
|
|
m_download = new CDownload();
|
|
|
|
if (m_download == NULL)
|
|
return LTSCERR_NOMEM;
|
|
|
|
HRESULT hr = m_download->DoDownload( this, sURL, dwType);
|
|
|
|
if (FAILED(hr))
|
|
return LTSCERR_DNLD;
|
|
|
|
return LTSC_OK;
|
|
}
|
|
|
|
void CTSHOOTCtrl::OnDownloadListFilenameChanged()
|
|
{
|
|
SetModifiedFlag();
|
|
}
|
|
|
|
void CTSHOOTCtrl::OnDownloadURLChanged()
|
|
{
|
|
SetModifiedFlag();
|
|
}
|
|
|
|
BSTR CTSHOOTCtrl::GetCurrentFileDownload()
|
|
{
|
|
CString strResult = m_dnldList.GetCurrFile();
|
|
|
|
return strResult.AllocSysString();
|
|
}
|
|
|
|
BSTR CTSHOOTCtrl::GetCurrentFriendlyDownload()
|
|
{
|
|
CString strResult = m_dnldList.GetCurrFriendly();
|
|
|
|
return strResult.AllocSysString();
|
|
}
|
|
|
|
long CTSHOOTCtrl::GetExtendedError()
|
|
{
|
|
return (m_dwExtendedErr & 0x0000FFFF);
|
|
}
|
|
|
|
VOID CTSHOOTCtrl::StatusEventHelper(DLITEMTYPES dwItem,
|
|
DLSTATTYPES dwStat,
|
|
DWORD dwExtended,
|
|
BOOL bComplete)
|
|
{
|
|
m_bComplete = bComplete;
|
|
FireBindStatus(dwItem, dwStat, dwExtended, bComplete);
|
|
}
|
|
|
|
VOID CTSHOOTCtrl::ProgressEventHelper( DLITEMTYPES dwItem, ULONG ulCurr, ULONG ulTotal )
|
|
{
|
|
if (dwItem == DLITEM_INI)
|
|
FireBindProgress(m_downloadListFilename, ulCurr, ulTotal);
|
|
else
|
|
FireBindProgress(m_dnldList.GetCurrFile(), ulCurr, ulTotal);
|
|
}
|
|
|
|
// Input data is null terminated for both binary and text data to simplify processing
|
|
//
|
|
DLSTATTYPES CTSHOOTCtrl::ProcessReceivedData(DLITEMTYPES dwItem, TCHAR *pData, UINT uLen)
|
|
{
|
|
DLSTATTYPES dwStat = LTSC_OK;
|
|
|
|
switch(dwItem)
|
|
{
|
|
case DLITEM_INI:
|
|
// processing INI file
|
|
dwStat = ProcessINI(pData);
|
|
break;
|
|
|
|
case DLITEM_DSC:
|
|
// processing DSC file
|
|
dwStat = ProcessDSC(pData, uLen);
|
|
break;
|
|
|
|
default:
|
|
dwStat = LTSCERR_UNSUPP;
|
|
break;
|
|
}
|
|
return dwStat;
|
|
}
|
|
|
|
// Returns true if we need to update this file
|
|
//
|
|
BOOL CTSHOOTCtrl::FileRegCheck(CString &sType,
|
|
CString &sFilename,
|
|
CString &sKeyName,
|
|
DWORD dwCurrVersion)
|
|
{
|
|
HKEY hk, hknew;
|
|
BOOL bStat = FALSE;
|
|
CString sMainKey;
|
|
|
|
// figure out what our main key is for this file
|
|
if (sType == TSINI_TYPE_TS)
|
|
sMainKey = TSREGKEY_TL;
|
|
else if (sType == TSINI_TYPE_SF)
|
|
sMainKey = TSREGKEY_SFL;
|
|
else
|
|
{
|
|
m_dwExtendedErr = LTSCERR_BADTYPE;
|
|
return FALSE;
|
|
}
|
|
|
|
// first open the main key (try open all access now just in case of permissions problems)
|
|
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
sMainKey,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hk) == ERROR_SUCCESS)
|
|
{
|
|
CString sValueName;
|
|
CString sValueClass;
|
|
FILETIME ftLastWriteTime;
|
|
|
|
DWORD count = 0;
|
|
LONG ldStat = ERROR_SUCCESS;
|
|
BOOL bFound = FALSE;
|
|
|
|
while (ldStat == ERROR_SUCCESS)
|
|
{
|
|
LPTSTR lptname = sValueName.GetBuffer(MAX_PATH + 1);
|
|
LPTSTR lptclass = sValueClass.GetBuffer(MAX_PATH + 1);
|
|
|
|
DWORD namesize = MAX_PATH;
|
|
DWORD classsize = MAX_PATH;
|
|
|
|
ldStat = RegEnumKeyEx( hk,
|
|
count,
|
|
lptname,
|
|
&namesize,
|
|
NULL,
|
|
lptclass,
|
|
&classsize,
|
|
&ftLastWriteTime);
|
|
|
|
sValueName.ReleaseBuffer();
|
|
sValueClass.ReleaseBuffer();
|
|
|
|
if (ldStat != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (!sValueName.CompareNoCase(sKeyName))
|
|
{
|
|
// open specific troubleshooter key data (read only)
|
|
|
|
if (RegOpenKeyEx( hk,
|
|
sKeyName,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hknew) == ERROR_SUCCESS)
|
|
{
|
|
DWORD dwData, dwValue;
|
|
BYTE szValue[MAXCHAR];
|
|
//dwData = REG_DWORD;
|
|
dwData = REG_SZ;
|
|
DWORD dwSize = MAXCHAR;
|
|
|
|
if (RegQueryValueEx(hknew,
|
|
TSLCL_FVERSION,
|
|
0,
|
|
&dwData,
|
|
szValue,
|
|
&dwSize) == ERROR_SUCCESS)
|
|
{
|
|
dwValue = _ttoi((TCHAR *) szValue);
|
|
if (dwValue < dwCurrVersion)
|
|
bStat = TRUE;
|
|
else
|
|
{
|
|
// check if file exists
|
|
HANDLE hCurrFind;
|
|
WIN32_FIND_DATA FindCurrData;
|
|
CString sFullPath;
|
|
|
|
sFullPath = m_sBasePath + _T("\\") + sFilename;
|
|
|
|
hCurrFind = FindFirstFile(sFullPath, &FindCurrData);
|
|
if (hCurrFind != INVALID_HANDLE_VALUE)
|
|
{
|
|
FindClose(hCurrFind);
|
|
}
|
|
else
|
|
bStat = TRUE;
|
|
}
|
|
|
|
}
|
|
else
|
|
m_dwExtendedErr = LTSCERR_KEYQUERY;
|
|
|
|
RegCloseKey(hknew);
|
|
}
|
|
else
|
|
m_dwExtendedErr = LTSCERR_KEYOPEN2;
|
|
|
|
// this is important: set this true to prevent default from trying to download
|
|
// we wont download if we found the key but can't update
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
count++;
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
bStat = TRUE;
|
|
}
|
|
|
|
RegCloseKey(hk);
|
|
}
|
|
else
|
|
m_dwExtendedErr = LTSCERR_KEYOPEN;
|
|
|
|
return bStat;
|
|
}
|
|
|
|
DLSTATTYPES CTSHOOTCtrl::ProcessINI(TCHAR *pData)
|
|
{
|
|
BOOL bFoundHeader = FALSE;
|
|
int dwCount = 0;
|
|
int dwMaxLines = 10000;
|
|
DLSTATTYPES dwStat = LTSC_OK;
|
|
|
|
dwStat = GetPathToFiles();
|
|
if (dwStat != LTSC_OK)
|
|
return dwStat;
|
|
|
|
m_dnldList.RemoveAll();
|
|
|
|
CString sData = pData;
|
|
|
|
int dwFullLen = sData.GetLength();
|
|
|
|
// just to be safe...
|
|
while (dwMaxLines--)
|
|
{
|
|
CString sFullString = sData.SpanExcluding(_T("\r\n"));
|
|
int dwPartLen = sFullString.GetLength();
|
|
|
|
if (!dwPartLen)
|
|
break;
|
|
|
|
dwFullLen -= dwPartLen;
|
|
|
|
CString sSkipString1 = sData.Right(dwFullLen);
|
|
CString sSkipString2 = sSkipString1.SpanIncluding(_T("\r\n"));
|
|
|
|
dwFullLen -= sSkipString2.GetLength();
|
|
|
|
sData = sSkipString1.Right(dwFullLen);
|
|
|
|
sFullString.TrimLeft();
|
|
sFullString.TrimRight();
|
|
|
|
int dwLineLen = sFullString.GetLength();
|
|
|
|
if (!dwLineLen)
|
|
continue;
|
|
|
|
if (sFullString[0] == _T(';'))
|
|
continue;
|
|
|
|
if (sFullString == TSINI_GROUP_STR)
|
|
{
|
|
bFoundHeader = TRUE;
|
|
continue;
|
|
}
|
|
else if (sFullString[0] == _T('['))
|
|
{
|
|
bFoundHeader = FALSE;
|
|
continue;
|
|
}
|
|
|
|
if (bFoundHeader)
|
|
{
|
|
CString sParam[TSINI_LINE_PARAM_COUNT];
|
|
int posstart = 0;
|
|
|
|
// now break apart components
|
|
for (int i=0;i<TSINI_LINE_PARAM_COUNT;i++)
|
|
{
|
|
int posend = sFullString.Find(_T(','));
|
|
if (posend == -1 && i < (TSINI_LINE_PARAM_COUNT - 1))
|
|
{
|
|
m_dwExtendedErr = LTSCERR_PARAMMISS;
|
|
break;
|
|
}
|
|
|
|
// so we don't find it next time
|
|
if (posend != -1)
|
|
sFullString.SetAt(posend, _T('.'));
|
|
else
|
|
posend = dwLineLen;
|
|
|
|
sParam[i] = sFullString.Mid(posstart, posend - posstart);
|
|
sParam[i].TrimLeft();
|
|
sParam[i].TrimRight();
|
|
|
|
posstart = posend + 1;
|
|
}
|
|
|
|
if (i==TSINI_LINE_PARAM_COUNT)
|
|
{
|
|
// add to object list if (1) version newer or (2) not in list yet
|
|
CString sKeyName;
|
|
DWORD dwVersion = _ttoi(sParam[TSINI_OFFSET_VERSION]);
|
|
int pos;
|
|
|
|
pos = sParam[TSINI_OFFSET_FILENAME].Find(_T('\\'));
|
|
if (pos == -1)
|
|
{
|
|
pos = sParam[TSINI_OFFSET_FILENAME].Find(_T('.'));
|
|
if (pos != -1)
|
|
{
|
|
if (sParam[TSINI_OFFSET_TYPE] == TSINI_TYPE_TS)
|
|
sKeyName = sParam[TSINI_OFFSET_FILENAME].Left(pos);
|
|
else {
|
|
sKeyName = sParam[TSINI_OFFSET_FILENAME];
|
|
//sKeyName.SetAt(pos, _T('_'));
|
|
}
|
|
|
|
// for now, check if we meet criteria
|
|
// if yes, just add to list and download on a later iteration
|
|
if (FileRegCheck(sParam[TSINI_OFFSET_TYPE], sParam[TSINI_OFFSET_FILENAME], sKeyName, dwVersion))
|
|
{
|
|
CDnldObj *pDnld = new CDnldObj( sParam[TSINI_OFFSET_TYPE],
|
|
sParam[TSINI_OFFSET_FILENAME],
|
|
dwVersion,
|
|
sParam[TSINI_OFFSET_FRIENDLY],
|
|
sKeyName);
|
|
|
|
if (pDnld)
|
|
{
|
|
m_dnldList.AddTail(pDnld);
|
|
dwCount++;
|
|
}
|
|
else
|
|
{
|
|
dwStat = LTSCERR_NOMEM;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
m_dwExtendedErr = LTSCERR_PARAMNODOT;
|
|
}
|
|
else
|
|
m_dwExtendedErr = LTSCERR_PARAMSLASH;
|
|
}
|
|
}
|
|
}
|
|
|
|
ASSERT(dwCount == m_dnldList.GetCount());
|
|
|
|
if (!dwCount)
|
|
dwStat = LTSCERR_NOITEMS;
|
|
|
|
m_dnldList.SetFirstItem();
|
|
|
|
return dwStat;
|
|
}
|
|
|
|
//
|
|
//
|
|
DLSTATTYPES CTSHOOTCtrl::GetPathToFiles()
|
|
{
|
|
DLSTATTYPES dwStat = LTSC_OK;
|
|
HKEY hk;
|
|
|
|
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
TSREGKEY_MAIN,
|
|
0,
|
|
KEY_READ,
|
|
&hk) == ERROR_SUCCESS)
|
|
{
|
|
DWORD dwData = REG_SZ;
|
|
DWORD dwSize = MAX_PATH;
|
|
LPTSTR lptBuf = m_sBasePath.GetBuffer(MAX_PATH + 2);
|
|
|
|
if (RegQueryValueEx(hk,
|
|
FULLRESOURCE_STR,
|
|
0,
|
|
&dwData,
|
|
(LPBYTE) lptBuf,
|
|
&dwSize) != ERROR_SUCCESS)
|
|
{
|
|
dwStat = LTSCERR_BASEKQ;
|
|
}
|
|
|
|
m_sBasePath.ReleaseBuffer();
|
|
|
|
RegCloseKey(hk);
|
|
}
|
|
else
|
|
dwStat = LTSCERR_NOBASEPATH;
|
|
return dwStat;
|
|
}
|
|
|
|
|
|
DLSTATTYPES CTSHOOTCtrl::ProcessDSC(TCHAR *pData, UINT uLen)
|
|
{
|
|
DLSTATTYPES dwStat = LTSC_OK;
|
|
HKEY hknew;
|
|
DWORD dwDisposition;
|
|
CString sMainKey;
|
|
|
|
// we get here if we need to update this file
|
|
// at this point we have the file downloaded and need to save it
|
|
// we also need to create/update the necessary registry keys
|
|
|
|
// since we know the entire key name, let's go ahead to create it
|
|
if (m_dnldList.GetCurrType() == TSINI_TYPE_SF)
|
|
sMainKey = TSREGKEY_SFL;
|
|
else
|
|
sMainKey = TSREGKEY_TL;
|
|
|
|
sMainKey += _T("\\") + m_dnldList.GetCurrFileKey();
|
|
|
|
// open specific troubleshooter key data
|
|
if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
|
|
sMainKey,
|
|
0,
|
|
TSLCL_REG_CLASS,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hknew,
|
|
&dwDisposition) == ERROR_SUCCESS)
|
|
{
|
|
if (dwDisposition == REG_CREATED_NEW_KEY || dwDisposition == REG_OPENED_EXISTING_KEY)
|
|
{
|
|
DWORD dwData = m_dnldList.GetCurrVersion();
|
|
CString str;
|
|
str.Format(_T("%d"), dwData);
|
|
if (RegSetValueEx( hknew,
|
|
TSLCL_FVERSION,
|
|
0,
|
|
//REG_DWORD,
|
|
REG_SZ,
|
|
(LPBYTE) (LPCTSTR) str,
|
|
str.GetLength() + sizeof(TCHAR)) != ERROR_SUCCESS)
|
|
{
|
|
dwStat = LTSCERR_FILEUPDATE;
|
|
m_dwExtendedErr = LTSCERR_KEYSET1;
|
|
}
|
|
|
|
if (dwStat == LTSC_OK)
|
|
{
|
|
CString sTemp = m_dnldList.GetCurrFriendly();
|
|
DWORD dwSize = sTemp.GetLength() + sizeof(TCHAR);
|
|
LPCTSTR lpctFN = sTemp.GetBuffer(100);
|
|
|
|
if (RegSetValueEx( hknew,
|
|
FRIENDLY_NAME,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE) lpctFN,
|
|
dwSize) == ERROR_SUCCESS)
|
|
{
|
|
CFile sF;
|
|
CFileException exc;
|
|
CString sFullPath;
|
|
|
|
sFullPath = m_sBasePath + _T("\\") + m_dnldList.GetCurrFile();
|
|
|
|
if (sF.Open(sFullPath, CFile::modeCreate | CFile::modeWrite, &exc))
|
|
{
|
|
TRY
|
|
{
|
|
sF.Write(pData, uLen);
|
|
}
|
|
CATCH (CFileException, e)
|
|
{
|
|
dwStat = LTSCERR_FILEUPDATE;
|
|
m_dwExtendedErr = LTSCERR_FILEWRITE;
|
|
}
|
|
END_CATCH
|
|
|
|
sF.Close();
|
|
|
|
// uncompress if a cab file (be dumb, assume .cab really means a cab file)
|
|
|
|
int pos = sFullPath.Find(_T('.'));
|
|
if (pos != -1)
|
|
{
|
|
CString sTemp = sFullPath.Right(sFullPath.GetLength() - pos);
|
|
if (!sTemp.CompareNoCase(_T(".cab")))
|
|
{
|
|
CCabUnCompress cab;
|
|
CString strDestDir = m_sBasePath + "\\";
|
|
|
|
if (!cab.ExtractCab(sFullPath, strDestDir, ""))
|
|
{
|
|
dwStat = LTSCERR_FILEUPDATE;
|
|
m_dwExtendedErr = LTSCERR_CABWRITE;
|
|
}
|
|
|
|
TRY
|
|
{
|
|
CFile::Remove(sFullPath);
|
|
}
|
|
CATCH (CFileException, e)
|
|
{
|
|
// error is not very interesting
|
|
}
|
|
END_CATCH
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwStat = LTSCERR_FILEUPDATE;
|
|
m_dwExtendedErr = LTSCERR_FILEWRITE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwStat = LTSCERR_FILEUPDATE;
|
|
m_dwExtendedErr = LTSCERR_KEYSET2;
|
|
}
|
|
sTemp.ReleaseBuffer();
|
|
}
|
|
|
|
if (dwStat == LTSC_OK)
|
|
{
|
|
CString sTemp = m_dnldList.GetCurrExt();
|
|
DWORD dwSize = sTemp.GetLength() + sizeof(TCHAR);
|
|
LPCTSTR lpctFN = sTemp.GetBuffer(100);
|
|
|
|
if (RegSetValueEx( hknew,
|
|
TSLCL_FMAINEXT,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE) lpctFN,
|
|
dwSize) != ERROR_SUCCESS)
|
|
{
|
|
dwStat = LTSCERR_FILEUPDATE;
|
|
m_dwExtendedErr = LTSCERR_KEYSET3;
|
|
}
|
|
sTemp.ReleaseBuffer();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwStat = LTSCERR_FILEUPDATE;
|
|
m_dwExtendedErr = LTSCERR_KEYUNSUPP;
|
|
}
|
|
|
|
RegCloseKey(hknew);
|
|
}
|
|
else
|
|
{
|
|
dwStat = LTSCERR_FILEUPDATE;
|
|
m_dwExtendedErr = LTSCERR_KEYCREATE;
|
|
}
|
|
return dwStat;
|
|
}
|
|
|
|
// Added 1/20/99 JM because RunQuery() can't be made to work with JScript, even though it
|
|
// worked fine with VB Script.
|
|
// Simulates the form in which RunQuery() would normally get its arguments, then pass them
|
|
// into RunQuery.
|
|
BSTR CTSHOOTCtrl::RunQuery2(LPCTSTR szTopic, LPCTSTR szCmd, LPCTSTR szVal)
|
|
{
|
|
VARIANT varCommands;
|
|
VARIANT varValues;
|
|
VARIANT varCommandsWrap;
|
|
VARIANT varValuesWrap;
|
|
SAFEARRAY *psafearrayCmds;
|
|
SAFEARRAY *psafearrayVals;
|
|
|
|
VariantInit(&varCommands);
|
|
VariantInit(&varValues);
|
|
VariantInit(&varCommandsWrap);
|
|
VariantInit(&varValuesWrap);
|
|
|
|
SAFEARRAYBOUND sabCmd;
|
|
sabCmd.cElements = 2;
|
|
sabCmd.lLbound = 0;
|
|
SAFEARRAYBOUND sabVal = sabCmd;
|
|
|
|
V_VT(&varCommands) = VT_ARRAY | VT_BYREF | VT_VARIANT;
|
|
V_VT(&varValues) = VT_ARRAY | VT_BYREF | VT_VARIANT;
|
|
V_ARRAYREF(&varCommands) = &psafearrayCmds;
|
|
V_ARRAYREF(&varValues) = &psafearrayVals;
|
|
|
|
V_VT(&varCommandsWrap) = VT_BYREF | VT_VARIANT;
|
|
V_VT(&varValuesWrap) = VT_BYREF | VT_VARIANT;
|
|
|
|
V_VARIANTREF(&varCommandsWrap) = &varCommands;
|
|
V_VARIANTREF(&varValuesWrap) = &varValues;
|
|
|
|
// If first character in szCmd is a null, then there will be only one significant
|
|
// element in each of the arrays we are constructing below, otherwise 2.
|
|
short size = (*szCmd) ? 2 : 1;
|
|
|
|
CString strType(C_TYPE);
|
|
BSTR bstrType = strType.AllocSysString();
|
|
VARIANT varType;
|
|
VariantInit(&varType);
|
|
V_VT(&varType) = VT_BSTR;
|
|
varType.bstrVal=bstrType;
|
|
|
|
CString strTopic(szTopic);
|
|
BSTR bstrTopic = strTopic.AllocSysString();
|
|
VARIANT varTopic;
|
|
VariantInit(&varTopic);
|
|
V_VT(&varTopic) = VT_BSTR;
|
|
varTopic.bstrVal=bstrTopic;
|
|
|
|
CString strCmd(szCmd);
|
|
BSTR bstrCmd = strCmd.AllocSysString();
|
|
VARIANT varCmd;
|
|
VariantInit(&varCmd);
|
|
V_VT(&varCmd) = VT_BSTR;
|
|
varCmd.bstrVal=bstrCmd;
|
|
|
|
CString strVal(szVal);
|
|
BSTR bstrVal = strVal.AllocSysString();
|
|
VARIANT varVal;
|
|
VariantInit(&varVal);
|
|
V_VT(&varVal) = VT_BSTR;
|
|
varVal.bstrVal=bstrVal;
|
|
|
|
// create two vectors of BSTRs
|
|
psafearrayCmds = SafeArrayCreate( VT_VARIANT, 1, &sabCmd);
|
|
psafearrayVals = SafeArrayCreate( VT_VARIANT, 1, &sabVal);
|
|
|
|
long i=0;
|
|
SafeArrayPutElement(psafearrayCmds, &i, &varType);
|
|
SafeArrayPutElement(psafearrayVals, &i, &varTopic);
|
|
|
|
i=1;
|
|
SafeArrayPutElement(psafearrayCmds, &i, &varCmd);
|
|
SafeArrayPutElement(psafearrayVals, &i, &varVal);
|
|
|
|
BSTR ret = RunQuery(varCommandsWrap, varValuesWrap, size);
|
|
|
|
SafeArrayDestroy(psafearrayCmds);
|
|
SafeArrayDestroy(psafearrayVals);
|
|
|
|
SysFreeString(bstrType);
|
|
SysFreeString(bstrTopic);
|
|
SysFreeString(bstrCmd);
|
|
SysFreeString(bstrVal);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// This function is a no-op and exist solely to allow us to write JScript that is
|
|
// forward compatible to Local Troubleshooter version 3.1
|
|
void CTSHOOTCtrl::SetPair(LPCTSTR szName, LPCTSTR szValue)
|
|
{
|
|
}
|