windows-nt/Source/XPSP1/NT/enduser/troubleshoot/launcher/server/launch.cpp
2020-09-26 16:20:57 +08:00

1002 lines
25 KiB
C++

//
// MODULE: Launch.cpp
//
// PURPOSE: Starts the container that will query the LaunchServ for
// troubleshooter network and nodes.
//
// PROJECT: Local Troubleshooter Launcher for the Device Manager
//
// COMPANY: Saltmine Creative, Inc. (206)-633-4743 support@saltmine.com
//
// AUTHOR: Richard Meadows
//
// ORIGINAL DATE: 2-26-98
//
//
// Version Date By Comments
//--------------------------------------------------------------------
// V0.1 - RM Original
///////////////////////
#include "stdafx.h"
#include "StateInfo.h"
#include "RSSTACK.H"
#include "TSMapAbstract.h"
#include "TSMap.h"
#include "TSMapClient.h"
#include "Launch.h"
#include "ComGlobals.h"
#include "TSLError.h"
#include "Registry.h"
#include <rpc.h>
#define LAUNCH_WAIT_TIMEOUT 60 * 1000 // One minute wait.
#define SZ_WEB_PAGE _T("asklibrary.htm") // name of hardcoded .htm file that contains troubleshooter OCX
// uncomment the following line to turn on Joe's hard-core debugging
//#define JDEBUG 1
#ifdef JDEBUG
#include <stdio.h>
// Convert TCHAR *szt to char *sz. *sz should point to a big enough buffer
// to contain an SNCS version of *szt. count indicates the size of buffer *sz.
// returns sz (convenient for use in string functions).
static char* ToSBCS (char * const sz, const TCHAR * szt, size_t count)
{
if (sz)
{
if (count != 0 && !szt)
sz[0] = '\0';
else
{
#ifdef _UNICODE
wcstombs( sz, szt, count );
#else
strcpy(sz, szt);
#endif
}
}
return sz;
}
#endif
CLaunch::CLaunch()
{
InitFiles();
InitRequest();
m_lLaunchWaitTimeOut = LAUNCH_WAIT_TIMEOUT;
m_bPreferOnline = false;
}
CLaunch::~CLaunch()
{
if (m_pMap)
delete(m_pMap);
}
// This initialization happens exactly once for the object.
// Once we've looked in the registry and found a file, it isn't going anywhere.
void CLaunch::InitFiles()
{
DWORD dwBufSize;
CRegKey reg;
DWORD dwBytesUsed;
m_bHaveMapPath = false;
m_bHaveDefMapFile = false;
m_bHaveDszPath = false;
m_szLauncherResources[0] = NULL;
m_szDefMapFile[0] = NULL;
m_szLaunchMapFile[0] = NULL;
m_szDszResPath[0] = NULL;
m_szMapFile[0] = NULL;
m_pMap = NULL;
if (ERROR_SUCCESS == reg.Open(
HKEY_LOCAL_MACHINE, SZ_LAUNCHER_ROOT))
{
dwBufSize = MAX_PATH;
TCHAR szLauncherResources[MAX_PATH];
if (ERROR_SUCCESS == reg.QueryValue(
szLauncherResources, SZ_GLOBAL_LAUNCHER_RES, &dwBufSize))
{
if ('\\' != szLauncherResources[_tcslen(szLauncherResources) - 1])
_tcscat(szLauncherResources, _T("\\"));
dwBufSize = MAX_PATH;
dwBytesUsed = ExpandEnvironmentStrings(szLauncherResources, m_szLauncherResources, dwBufSize); // The value returned by ExpandEnviromentStrings is larger than the required size.
}
dwBufSize = MAX_PATH;
TCHAR szDefMapFile[MAX_PATH];
if (ERROR_SUCCESS == reg.QueryValue(
szDefMapFile, SZ_GLOBAL_MAP_FILE, &dwBufSize))
{
WIN32_FIND_DATA data;
HANDLE hFind;
dwBufSize = MAX_PATH;
dwBytesUsed = ExpandEnvironmentStrings(szDefMapFile, m_szDefMapFile, dwBufSize); // The value returned by ExpandEnviromentStrings is larger than the required size.
if (0 != dwBytesUsed)
{
m_bHaveMapPath = true;
_tcscpy(m_szLaunchMapFile, m_szLauncherResources);
_tcscat(m_szLaunchMapFile, m_szDefMapFile);
hFind = FindFirstFile(m_szLaunchMapFile, &data);
if (INVALID_HANDLE_VALUE != hFind)
{
m_bHaveDefMapFile = true;
FindClose(hFind);
}
else
{
m_bHaveDefMapFile = false;
}
}
}
reg.Close();
}
// Need the TShoot.ocx resource path to verify that the networks exist.
if (ERROR_SUCCESS == reg.Open(HKEY_LOCAL_MACHINE, SZ_TSHOOT_ROOT))
{
dwBufSize = MAX_PATH;
TCHAR szDszResPath[MAX_PATH];
if (ERROR_SUCCESS == reg.QueryValue(szDszResPath, SZ_TSHOOT_RES, &dwBufSize))
{
if ('\\' != szDszResPath[_tcslen(szDszResPath) - 1])
_tcscat(szDszResPath, _T("\\"));
dwBufSize = MAX_PATH;
dwBytesUsed = ExpandEnvironmentStrings(szDszResPath, m_szDszResPath, dwBufSize); // The value returned by ExpandEnviromentStrings is larger than the required size.
if (0 == dwBytesUsed)
m_bHaveDszPath = false;
else
m_bHaveDszPath = true;
}
reg.Close();
}
return;
}
// This initialization can happen more than once for the object.
// If we are going to use the same object to make a second request, there are things we
// want to clean up.
void CLaunch::InitRequest()
{
m_szAppName[0] = NULL;
m_szAppVersion[0] = NULL;
m_szAppProblem[0] = NULL;
m_stkStatus.RemoveAll();
m_Item.ReInit();
}
// >>> Why does this exist distinct from InitRequest()?
void CLaunch::ReInit()
{
InitRequest();
return;
}
// >>> What exactly is the use of this? What is the distinction from InitRequest()?
void CLaunch::Clear()
{
m_szAppName[0] = NULL;
m_szAppVersion[0] = NULL;
m_szAppProblem[0] = NULL;
m_stkStatus.RemoveAll();
m_Item.Clear();
return;
}
// Verify that a given troubleshooting belief network exists.
bool CLaunch::VerifyNetworkExists(LPCTSTR szNetwork)
{
bool bResult = true;
if (NULL == szNetwork || NULL == szNetwork[0])
{
// Null name, don't even bother with a lookup.
m_stkStatus.Push(TSL_E_NETWORK_NF);
bResult = false;
}
else
{
if (m_bHaveDszPath)
{
WIN32_FIND_DATA data;
HANDLE hFind;
TCHAR szDszFile[MAX_PATH];
_tcscpy(szDszFile, m_szDszResPath);
_tcscat(szDszFile, szNetwork);
_tcscat(szDszFile, _T(".ds?"));
hFind = FindFirstFile(szDszFile, &data);
if (INVALID_HANDLE_VALUE == hFind)
{
m_stkStatus.Push(TSL_E_NETWORK_NF);
bResult = false;
}
FindClose(hFind);
}
else
{
// we don't know what directory to look in.
m_stkStatus.Push(TSL_E_NETWORK_REG);
bResult = false;
}
}
return bResult;
}
// Allows explicit specification of the troubleshooting network (and, optionally,
// problem node) to launch to.
// This is an alternative to determining network/node via a mapping.
// INPUT szNetwork
// INPUT szProblem: null pointer of null string ==> no problem node
// any other value is symbolic name of problem node
bool CLaunch::SpecifyProblem(LPCTSTR szNetwork, LPCTSTR szProblem)
{
bool bResult = true;
if (!VerifyNetworkExists(szNetwork)) // Sets the network not found error.
{
bResult = false;
}
else
{
m_Item.SetNetwork(szNetwork);
// Set problem node, if any. OK if there is none.
if (NULL != szProblem && NULL != szProblem[0])
m_Item.SetProblem(szProblem);
}
return bResult;
}
// Allows explicit setting of a non-problem node.
// Obviously, node names only acquire meaning in the context of a belief network.
// INPUT szNode: symbolic node name
// INPUT szState: >>> not sure what is intended. The corresponding value in TSLaunch API is
// an integer state value. Is this the decimal representation of that value or what? JM
bool CLaunch::SetNode(LPCTSTR szNode, LPCTSTR szState)
{
bool bResult = true;
if (NULL != szNode && NULL != szState)
{
m_Item.SetNode(szNode, szState);
}
else
{
m_stkStatus.Push(TSL_E_NODE_EMP);
bResult = false;
}
return bResult;
}
// Sets machine ID so that WBEM can sniff on a remote machine.
HRESULT CLaunch::MachineID(BSTR &bstrMachineID, DWORD *pdwResult)
{
HRESULT hRes = S_OK;
if (!BSTRToTCHAR(m_Item.m_szMachineID, bstrMachineID, CItem::GUID_LEN))
{
*pdwResult = TSL_E_MEM_EXCESSIVE;
hRes = TSL_E_FAIL;
}
return hRes;
}
// Sets Device Instance ID so that WBEM can sniff correct device
HRESULT CLaunch::DeviceInstanceID(BSTR &bstrDeviceInstanceID, DWORD *pdwResult)
{
HRESULT hRes = S_OK;
if (!BSTRToTCHAR(m_Item.m_szDeviceInstanceID, bstrDeviceInstanceID, CItem::GUID_LEN))
{
*pdwResult = TSL_E_MEM_EXCESSIVE;
hRes = TSL_E_FAIL;
}
return hRes;
}
void CLaunch::SetPreferOnline(short bPreferOnline)
{
// The next line's ugly, but correct. bPreferOnline is not necessarily a valid
// Boolean; we want to make sure we get a valid Boolean in m_bPreferOnline.
m_bPreferOnline = (0 != bPreferOnline);
return;
}
// CheckMapFile: Uses szAppName member to set szMapFile.
// First, check the registry for an application-specific map file. If we can't find one,
// check for a default map file. If that doesn't exist either, fail.
// INPUT szAppName
// OUTPUT szMapFile
bool CLaunch::CheckMapFile(TCHAR * szAppName, TCHAR szMapFile[MAX_PATH], DWORD *pdwResult)
{
bool bHaveMapFile = false;
if (NULL == szAppName || NULL == szAppName[0])
{
// Application name may not be null.
m_stkStatus.Push(TSL_ERROR_UNKNOWN_APP);
*pdwResult = TSL_ERROR_GENERAL;
return false;
}
else
{
DWORD dwBufSize;
CRegKey reg;
if (ERROR_SUCCESS == reg.Open(HKEY_LOCAL_MACHINE, SZ_LAUNCHER_APP_ROOT))
{
dwBufSize = MAX_PATH;
if (ERROR_SUCCESS == reg.Open(reg.m_hKey, szAppName))
{
if (ERROR_SUCCESS == reg.QueryValue(szMapFile, SZ_APPS_MAP_FILE, &dwBufSize))
return true;
}
}
}
// Does a default map file exist?
if (m_bHaveDefMapFile)
{
_tcscpy(szMapFile, m_szLaunchMapFile);
}
else
{ // Either the registry setting is missing or the file is not
// where the registry says it is.
if (m_bHaveMapPath) // Have the registry entry.
m_stkStatus.Push(TSL_E_MAPPING_DB_NF);
else
m_stkStatus.Push(TSL_E_MAPPING_DB_REG);
*pdwResult = TSL_ERROR_GENERAL;
}
return m_bHaveDefMapFile;
}
// Uses the mapping classes to map Caller() and DeviceID() information, then copies the
// CItem to global memory.
// >> Why is this called TestPut()?
// Returns false when the mapping fails.
bool CLaunch::TestPut()
{
extern CSMStateInfo g_StateInfo;
DWORD dwResult;
Map(&dwResult);
if (TSL_OK != dwResult)
return false;
g_StateInfo.TestPut(m_Item); // Copies m_Item to global memory.
return true;
}
// Perform any necessary mapping, then launch the Local Troubleshooter.
bool CLaunch::Go(DWORD dwTimeOut, DWORD *pdwResult)
{
DWORD dwRes;
bool bResult = true;
extern CSMStateInfo g_StateInfo;
TCHAR szContainerPathName[MAX_PATH]; szContainerPathName[0] = 0;
TCHAR szSniffScriptFile[MAX_PATH]; szSniffScriptFile[0] = 0;
TCHAR szSniffStandardFile[MAX_PATH]; szSniffStandardFile[0] = 0;
TCHAR szWebPage[MAX_PATH]; szWebPage[0] = 0;
TCHAR szDefaultNetwork[SYM_LEN]; szDefaultNetwork[0] = 0;
TCHAR *szCmd = NULL, *szNetwork = NULL;
if (TSL_OK == (dwRes = GetContainerPathName(szContainerPathName)))
{
m_Item.SetContainerPathName(szContainerPathName);
m_Item.SetSniffScriptFile(szSniffScriptFile);
}
else
{
m_stkStatus.Push(dwRes);
// if container is not found - no reason to continue
*pdwResult = TSL_ERROR_GENERAL;
return false;
}
if (!m_Item.NetworkSet())
{
if (Map(&dwRes) &&
TSL_OK == (dwRes = GetWebPage(szWebPage)) // get web page
)
{
m_Item.SetWebPage(szWebPage);
// network and problem are set by Map function
m_Item.SetLaunchRegime(launchMap);
}
else
{
m_stkStatus.Push(dwRes);
if (TSL_OK == (dwRes = GetDefaultURL(szWebPage))) // get "DEFAULT PAGE",
// actually a URL which might (for example)
// refernce a page compiled into a .CHM file
{
m_Item.SetWebPage(szWebPage);
m_Item.SetNetwork(NULL); // network are set to NULL in this case
m_Item.SetProblem(NULL); // problem are set to NULL in this case
m_Item.SetLaunchRegime(launchDefaultWebPage);
}
else
{
if (TSL_OK == (dwRes = GetDefaultNetwork(szDefaultNetwork)) && // get default network
TSL_OK == (dwRes = GetWebPage(szWebPage)) // get web page
)
{
m_Item.SetWebPage(szWebPage);
m_Item.SetNetwork(szDefaultNetwork);
m_Item.SetProblem(NULL); // problem is set to NULL in this case
m_Item.SetLaunchRegime(launchDefaultNetwork);
}
else
{
// complete failure
m_stkStatus.Push(dwRes);
*pdwResult = TSL_ERROR_GENERAL;
m_Item.SetLaunchRegime(launchIndefinite);
return false;
}
}
}
}
else
{
if (TSL_OK == (dwRes = GetWebPage(szWebPage)))
{
m_Item.SetWebPage(szWebPage);
// network is known, problem can be either known(set) or unknown(not set)
m_Item.SetLaunchRegime(launchKnownNetwork);
}
else
{
// complete failure
m_stkStatus.Push(dwRes);
*pdwResult = TSL_ERROR_GENERAL;
m_Item.SetLaunchRegime(launchIndefinite);
return false;
}
}
// set sniff script and standard file
m_Item.GetNetwork(&szCmd, &szNetwork);
if (TSL_OK == (dwRes = GetSniffScriptFile(szSniffScriptFile, szNetwork[0] ? szNetwork : NULL)) &&
TSL_OK == (dwRes = GetSniffStandardFile(szSniffStandardFile))
)
{
m_Item.SetSniffScriptFile(szSniffScriptFile);
m_Item.SetSniffStandardFile(szSniffStandardFile);
}
else
{
// can not find script file path - failure
m_stkStatus.Push(dwRes);
*pdwResult = TSL_ERROR_GENERAL;
m_Item.SetLaunchRegime(launchIndefinite);
return false;
}
// parse warnings according to the launch regime
//
if (launchMap == m_Item.GetLaunchRegime() ||
launchKnownNetwork == m_Item.GetLaunchRegime()
)
{
if (!m_Item.ProblemSet())
{
m_stkStatus.Push(TSL_WARNING_NO_PROBLEM_NODE);
*pdwResult = TSL_WARNING_GENERAL;
}
}
// parse launches according to the launch regime
//
if (launchMap == m_Item.GetLaunchRegime() ||
launchDefaultNetwork == m_Item.GetLaunchRegime()
)
{
if (m_Item.NetworkSet())
{
#ifdef JDEBUG
HANDLE hDebugFile;
char* szStart = "START\n";
char* szEnd = "END\n";
DWORD dwBytesWritten;
hDebugFile = CreateFile(
_T("jdebug.txt"),
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
WriteFile(
hDebugFile,
szStart,
strlen(szStart),
&dwBytesWritten,
NULL);
TCHAR *sztCmd, *sztVal;
char sz[200], szCmd[100], szVal[100];
m_Item.GetNetwork(&sztCmd, &sztVal);
ToSBCS (szCmd, sztCmd, 100);
ToSBCS (szVal, sztVal, 100);
sprintf(sz, "%s %s\n", szCmd, szVal);
WriteFile(
hDebugFile,
sz,
strlen(sz),
&dwBytesWritten,
NULL);
if (m_Item.ProblemSet())
{
m_Item.GetProblem(&sztCmd, &sztVal);
ToSBCS (szCmd, sztCmd, 100);
ToSBCS (szVal, sztVal, 100);
sprintf(sz, "%s %s\n", szCmd, szVal);
WriteFile(
hDebugFile,
sz,
strlen(sz),
&dwBytesWritten,
NULL);
}
WriteFile(
hDebugFile,
szEnd,
strlen(szEnd),
&dwBytesWritten,
NULL);
CloseHandle(hDebugFile);
#endif
bResult = g_StateInfo.GoGo(dwTimeOut, m_Item, pdwResult);
}
else
{
*pdwResult = TSL_ERROR_GENERAL;
m_stkStatus.Push(TSL_ERROR_NO_NETWORK);
bResult = false;
}
}
if (launchKnownNetwork == m_Item.GetLaunchRegime() )
{
bResult = g_StateInfo.GoGo(dwTimeOut, m_Item, pdwResult);
}
if (launchDefaultWebPage == m_Item.GetLaunchRegime())
{
bResult = g_StateInfo.GoURL(m_Item, pdwResult);
}
return bResult;
}
HRESULT CLaunch::LaunchKnown(DWORD * pdwResult)
{
HRESULT hRes = S_OK;
// Launch the shooter.
if (!Go(m_lLaunchWaitTimeOut, pdwResult))
hRes = TSL_E_FAIL;
return hRes;
}
HRESULT CLaunch::Launch(BSTR bstrCallerName, BSTR bstrCallerVersion,
BSTR bstrAppProblem, short bLaunch, DWORD * pdwResult)
{
HRESULT hRes = S_OK;
Clear();
if (!BSTRToTCHAR(m_szAppName, bstrCallerName, SYM_LEN))
{
*pdwResult = TSL_E_MEM_EXCESSIVE;
return TSL_E_FAIL;
}
if (!BSTRToTCHAR(m_szAppVersion, bstrCallerVersion, SYM_LEN))
{
*pdwResult = TSL_E_MEM_EXCESSIVE;
return TSL_E_FAIL;
}
if (!BSTRToTCHAR(m_szAppProblem, bstrAppProblem, SYM_LEN))
{
*pdwResult = TSL_E_MEM_EXCESSIVE;
return TSL_E_FAIL;
}
if (bLaunch)
{
if (!Go(m_lLaunchWaitTimeOut, pdwResult))
hRes = TSL_E_FAIL;
}
else
{
if (!Map(pdwResult))
hRes = TSL_E_FAIL;
}
return hRes;
}
HRESULT CLaunch::LaunchDevice(BSTR bstrCallerName, BSTR bstrCallerVersion, BSTR bstrPNPDeviceID,
BSTR bstrDeviceClassGUID, BSTR bstrAppProblem, short bLaunch, DWORD * pdwResult)
{
HRESULT hRes;
Clear();
if (!BSTRToTCHAR(m_szAppName, bstrCallerName, SYM_LEN))
{
*pdwResult = TSL_E_MEM_EXCESSIVE;
return TSL_E_FAIL;
}
if (!BSTRToTCHAR(m_szAppVersion, bstrCallerVersion, SYM_LEN))
{
*pdwResult = TSL_E_MEM_EXCESSIVE;
return TSL_E_FAIL;
}
if (!BSTRToTCHAR(m_szAppProblem, bstrAppProblem, SYM_LEN))
{
*pdwResult = TSL_E_MEM_EXCESSIVE;
return TSL_E_FAIL;
}
if (!BSTRToTCHAR(m_Item.m_szPNPDeviceID, bstrPNPDeviceID, CItem::GUID_LEN))
{
*pdwResult = TSL_E_MEM_EXCESSIVE;
return TSL_E_FAIL;
}
if (!BSTRToTCHAR(m_Item.m_szGuidClass, bstrDeviceClassGUID, CItem::GUID_LEN))
{
*pdwResult = TSL_E_MEM_EXCESSIVE;
return TSL_E_FAIL;
}
if (m_Item.m_szGuidClass[0])
{
// Device Class GUID is non-null. Make sure it's a valid GUID.
GUID guidClass;
#ifdef _UNICODE
RPC_STATUS rpcstatus = UuidFromString(
m_Item.m_szGuidClass, &guidClass );
#else
RPC_STATUS rpcstatus = UuidFromString(
(unsigned char *) m_Item.m_szGuidClass, &guidClass );
#endif
if ( rpcstatus == RPC_S_INVALID_STRING_UUID)
{
m_stkStatus.Push(TSL_WARNING_ILLFORMED_CLASS_GUID);
}
}
if (bLaunch)
{
if (!Go(m_lLaunchWaitTimeOut, pdwResult))
hRes = TSL_E_FAIL;
}
else
{
if (!Map(pdwResult))
hRes = TSL_E_FAIL;
}
return hRes;
}
DWORD CLaunch::GetStatus()
{
DWORD dwStatus = TSL_OK;
if (!m_stkStatus.Empty())
dwStatus = m_stkStatus.Pop();
return dwStatus;
}
// OUTPUT *szPathName = Name of application to launch to (either IE or HTML Help System)
// Returns:
// TSL_OK - success
// TSL_E_CONTAINER_REG - failure to find IE (Internet Explorer) in registry
// TSL_E_CONTAINER_NF - IE isn't where registry says to find it.
int CLaunch::GetContainerPathName(TCHAR szPathName[MAX_PATH])
{
DWORD dwPathNameLen = MAX_PATH;
int tslaHaveContainer = TSL_OK;
#ifndef _HH_CHM
// use IE instead of HTML Help System
if (!ReadRegSZ(HKEY_LOCAL_MACHINE,
SZ_CONTAINER_APP_KEY,
SZ_CONTAINER_APP_VALUE, szPathName, &dwPathNameLen))
{
tslaHaveContainer = TSL_E_CONTAINER_REG;
}
else
{ // Need to verify that the container exists.
WIN32_FIND_DATA data;
HANDLE hContainer = FindFirstFile(szPathName, &data);
if (INVALID_HANDLE_VALUE == hContainer)
tslaHaveContainer = TSL_E_CONTAINER_NF;
else
FindClose(hContainer);
}
#else
_tcscpy(szPathName, _T("hh.exe"));
#endif
return tslaHaveContainer;
}
// OUTPUT *szWebPage = Name of web page to launch to
// We always launch to the same web page. The information passed in m_Item ditinguishes
// what will actually show on the screen.
// Path is from registry. We concatenate on a backslash and SZ_WEB_PAGE (== "asklibrary.htm")
// Returns:
// TSL_OK - success
// TSL_E_WEB_PAGE_REG - failure to find web page for this purpose in registry
// TSL_E_MEM_EXCESSIVE - Web page name longer than we can handle
// TSL_E_WEB_PAGE_NF - Web page isn't where registry says to find it.
int CLaunch::GetWebPage(TCHAR szWebPage[MAX_PATH])
{
int tslaHavePage = TSL_OK;
DWORD dwWebPageLen = MAX_PATH;
if (!ReadRegSZ(HKEY_LOCAL_MACHINE,
SZ_LAUNCHER_ROOT,
SZ_GLOBAL_LAUNCHER_RES,
szWebPage,
&dwWebPageLen))
{
tslaHavePage = TSL_E_WEB_PAGE_REG;
}
else
{
int Len = _tcslen(szWebPage);
dwWebPageLen = Len + 1 + _tcslen(SZ_WEB_PAGE);
if (dwWebPageLen > MAX_PATH)
{
tslaHavePage = TSL_E_MEM_EXCESSIVE;
}
else
{
if (szWebPage[Len - 1] != '\\')
_tcscat(szWebPage, _T("\\"));
_tcscat(szWebPage, SZ_WEB_PAGE);
WIN32_FIND_DATA data;
HANDLE hWebPage = FindFirstFile(szWebPage, &data);
if (INVALID_HANDLE_VALUE == hWebPage)
tslaHavePage = TSL_E_WEB_PAGE_NF;
else
FindClose(hWebPage);
}
}
return tslaHavePage;
}
// OUTPUT *szSniffScriptFile = full path and file name either to "network"_sniff.htm file or null len string if file is not found
// TSL_OK - success
// TSL_E_SNIFF_SCRIPT_REG - failure to find file for this purpose in registry
int CLaunch::GetSniffScriptFile(TCHAR szSniffScriptFile[MAX_PATH], TCHAR* szNetwork)
{
int tslaHavePage = TSL_OK;
DWORD dwSniffScriptLen = MAX_PATH;
TCHAR szSniffScriptPath[MAX_PATH] = {0};
if (ReadRegSZ(HKEY_LOCAL_MACHINE,
SZ_TSHOOT_ROOT,
SZ_TSHOOT_RES,
szSniffScriptPath,
&dwSniffScriptLen))
{
int Len = _tcslen(szSniffScriptPath);
dwSniffScriptLen = Len + 1 + (szNetwork ? _tcslen(szNetwork) + _tcslen(SZ_SNIFF_SCRIPT_APPENDIX)
: 0);
if (dwSniffScriptLen > MAX_PATH)
{
tslaHavePage = TSL_E_MEM_EXCESSIVE;
}
else
{
if (szSniffScriptPath[Len - 1] != '\\')
_tcscat(szSniffScriptPath, _T("\\"));
if (szNetwork)
{
TCHAR tmp[MAX_PATH] = {0};
_tcscpy(tmp, szSniffScriptPath);
_tcscat(tmp, szNetwork);
_tcscat(tmp, SZ_SNIFF_SCRIPT_APPENDIX);
WIN32_FIND_DATA data;
HANDLE hSniffScript = FindFirstFile(tmp, &data);
if (INVALID_HANDLE_VALUE == hSniffScript)
{
szSniffScriptFile[0] = 0;
}
else
{
_tcscpy(szSniffScriptFile, tmp);
FindClose(hSniffScript);
}
}
else
{
szSniffScriptFile[0] = 0;
}
}
}
else
{
tslaHavePage = TSL_E_SNIFF_SCRIPT_REG;
}
return tslaHavePage;
}
// OUTPUT *szSniffScriptFile = full path and file name of tssniffAsk.htm file no matter if it exists
// TSL_OK - success
// TSL_E_SNIFF_SCRIPT_REG - failure to find file for this purpose in registry
int CLaunch::GetSniffStandardFile(TCHAR szSniffStandardFile[MAX_PATH])
{
int tslaHavePage = TSL_OK;
DWORD dwSniffStandardLen = MAX_PATH;
TCHAR szSniffStandardPath[MAX_PATH] = {0};
if (ReadRegSZ(HKEY_LOCAL_MACHINE,
SZ_LAUNCHER_ROOT,
SZ_GLOBAL_LAUNCHER_RES,
szSniffStandardPath,
&dwSniffStandardLen))
{
int Len = _tcslen(szSniffStandardPath);
dwSniffStandardLen = Len + 1 + _tcslen(SZ_SNIFF_SCRIPT_NAME);
if (dwSniffStandardLen > MAX_PATH)
{
tslaHavePage = TSL_E_MEM_EXCESSIVE;
}
else
{
if (szSniffStandardPath[Len - 1] != '\\')
_tcscat(szSniffStandardPath, _T("\\"));
_tcscpy(szSniffStandardFile, szSniffStandardPath);
_tcscat(szSniffStandardFile, SZ_SNIFF_SCRIPT_NAME);
}
}
else
{
tslaHavePage = TSL_E_SNIFF_SCRIPT_REG;
}
return tslaHavePage;
}
// OUTPUT *szURL = URL to go to when mapping fails. We get this from registry.
// TSL_OK - success
// TSL_E_WEB_PAGE_REG - failure to find web page for this purpose in registry
int CLaunch::GetDefaultURL(TCHAR szURL[MAX_PATH])
{
int tslaHaveURL = TSL_OK;
DWORD dwURLLen = MAX_PATH;
if (!ReadRegSZ(HKEY_LOCAL_MACHINE,
SZ_LAUNCHER_ROOT,
SZ_DEFAULT_PAGE,
szURL,
&dwURLLen))
{
tslaHaveURL = TSL_E_WEB_PAGE_REG;
}
return tslaHaveURL;
}
// Returns TSL_OK and default network name in szDefaultNetwork
// if successful
int CLaunch::GetDefaultNetwork(TCHAR szDefaultNetwork[SYM_LEN])
{
DWORD dwLen = SYM_LEN;
if (ReadRegSZ(HKEY_LOCAL_MACHINE, SZ_LAUNCHER_ROOT, SZ_DEFAULT_NETWORK,
szDefaultNetwork, &dwLen))
if (VerifyNetworkExists(szDefaultNetwork))
return TSL_OK;
return TSL_E_NO_DEFAULT_NET;
}
bool CLaunch::Map(DWORD *pdwResult)
{
bool bOK = true;
TCHAR szMapFile[MAX_PATH];
TCHAR szNetwork[SYM_LEN]; szNetwork[0] = NULL;
TCHAR szTShootProblem[SYM_LEN]; szTShootProblem[0] = NULL;
bOK = CheckMapFile(m_szAppName, szMapFile, pdwResult);
// bOK false at this point means either the registry setting is missing or the file
// is not where the registry says it is. PdwResult has already been set in CheckMapFile.
if (bOK && _tcscmp(m_szMapFile, szMapFile))
{
// The mapping file we desire is _not_ already loaded
if (m_pMap)
{
// we were using a different mapping file. We have to get rid of it.
delete m_pMap;
}
// else we weren't using a mapping file yet.
m_pMap = new TSMapClient(szMapFile);
if (TSL_OK != m_pMap->GetStatus())
{
*pdwResult = m_pMap->GetStatus();
bOK = false;
}
else
{
// We've successfully init'd m_pMap on the basis of the new map file.
// Indicate that it's loaded.
_tcscpy(m_szMapFile, szMapFile);
}
}
if (bOK)
{
DWORD dwRes;
// Now perform mapping itself
//
dwRes = m_pMap->FromAppVerDevAndClassToTS(m_szAppName, m_szAppVersion,
m_Item.m_szPNPDeviceID, m_Item.m_szGuidClass, m_szAppProblem,
szNetwork, szTShootProblem);
// As documented for TSMapRuntimeAbstract::FromAppVerDevAndClassToTS(), there are two
// return values here which require that we check for further status details: TSL_OK
// (which means we found a mapping, but doesn't rule out warnings) and
// TSL_ERROR_NO_NETWORK (which means we didn't find a mapping, and is typically
// accompanied by further clarifications).
if (TSL_OK == dwRes || TSL_ERROR_NO_NETWORK == dwRes)
{
DWORD dwStatus;
while (0 != (dwStatus = m_pMap->MoreStatus()))
m_stkStatus.Push(dwStatus);
}
if (TSL_OK != dwRes)
m_stkStatus.Push(dwRes); // save the precise error status
if (TSLIsError(dwRes) )
bOK = false;
if (bOK)
{
// We have a network name.
bOK = VerifyNetworkExists(szNetwork);
}
if (bOK)
{
// We have a network name and we've verified that the network exists.
// Set the item's network and tshoot problem.
m_Item.SetNetwork(szNetwork);
m_Item.SetProblem(szTShootProblem);
}
else
*pdwResult = TSL_ERROR_GENERAL;
}
return bOK;
}