Leaked source code of windows server 2003
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.

1001 lines
26 KiB

  1. //
  2. // MODULE: Launch.cpp
  3. //
  4. // PURPOSE: Starts the container that will query the LaunchServ for
  5. // troubleshooter network and nodes.
  6. //
  7. // PROJECT: Local Troubleshooter Launcher for the Device Manager
  8. //
  9. // COMPANY: Saltmine Creative, Inc. (206)-633-4743 [email protected]
  10. //
  11. // AUTHOR: Richard Meadows
  12. //
  13. // ORIGINAL DATE: 2-26-98
  14. //
  15. //
  16. // Version Date By Comments
  17. //--------------------------------------------------------------------
  18. // V0.1 - RM Original
  19. ///////////////////////
  20. #include "stdafx.h"
  21. #include "StateInfo.h"
  22. #include "RSSTACK.H"
  23. #include "TSMapAbstract.h"
  24. #include "TSMap.h"
  25. #include "TSMapClient.h"
  26. #include "Launch.h"
  27. #include "ComGlobals.h"
  28. #include "TSLError.h"
  29. #include "Registry.h"
  30. #include <rpc.h>
  31. #define LAUNCH_WAIT_TIMEOUT 60 * 1000 // One minute wait.
  32. #define SZ_WEB_PAGE _T("asklibrary.htm") // name of hardcoded .htm file that contains troubleshooter OCX
  33. // uncomment the following line to turn on Joe's hard-core debugging
  34. //#define JDEBUG 1
  35. #ifdef JDEBUG
  36. #include <stdio.h>
  37. // Convert TCHAR *szt to char *sz. *sz should point to a big enough buffer
  38. // to contain an SNCS version of *szt. count indicates the size of buffer *sz.
  39. // returns sz (convenient for use in string functions).
  40. static char* ToSBCS (char * const sz, const TCHAR * szt, size_t count)
  41. {
  42. if (sz)
  43. {
  44. if (count != 0 && !szt)
  45. sz[0] = '\0';
  46. else
  47. {
  48. #ifdef _UNICODE
  49. wcstombs( sz, szt, count );
  50. #else
  51. strcpy(sz, szt);
  52. #endif
  53. }
  54. }
  55. return sz;
  56. }
  57. #endif
  58. CLaunch::CLaunch()
  59. {
  60. InitFiles();
  61. InitRequest();
  62. m_lLaunchWaitTimeOut = LAUNCH_WAIT_TIMEOUT;
  63. m_bPreferOnline = false;
  64. }
  65. CLaunch::~CLaunch()
  66. {
  67. if (m_pMap)
  68. delete(m_pMap);
  69. }
  70. // This initialization happens exactly once for the object.
  71. // Once we've looked in the registry and found a file, it isn't going anywhere.
  72. void CLaunch::InitFiles()
  73. {
  74. DWORD dwBufSize;
  75. CRegKey reg;
  76. DWORD dwBytesUsed;
  77. m_bHaveMapPath = false;
  78. m_bHaveDefMapFile = false;
  79. m_bHaveDszPath = false;
  80. m_szLauncherResources[0] = NULL;
  81. m_szDefMapFile[0] = NULL;
  82. m_szLaunchMapFile[0] = NULL;
  83. m_szDszResPath[0] = NULL;
  84. m_szMapFile[0] = NULL;
  85. m_pMap = NULL;
  86. if (ERROR_SUCCESS == reg.Open(
  87. HKEY_LOCAL_MACHINE, SZ_LAUNCHER_ROOT))
  88. {
  89. dwBufSize = MAX_PATH;
  90. TCHAR szLauncherResources[MAX_PATH];
  91. if (ERROR_SUCCESS == reg.QueryValue(
  92. szLauncherResources, SZ_GLOBAL_LAUNCHER_RES, &dwBufSize))
  93. {
  94. if ('\\' != szLauncherResources[_tcslen(szLauncherResources) - 1])
  95. _tcscat(szLauncherResources, _T("\\"));
  96. dwBufSize = MAX_PATH;
  97. dwBytesUsed = ExpandEnvironmentStrings(szLauncherResources, m_szLauncherResources, dwBufSize); // The value returned by ExpandEnviromentStrings is larger than the required size.
  98. }
  99. dwBufSize = MAX_PATH;
  100. TCHAR szDefMapFile[MAX_PATH];
  101. if (ERROR_SUCCESS == reg.QueryValue(
  102. szDefMapFile, SZ_GLOBAL_MAP_FILE, &dwBufSize))
  103. {
  104. WIN32_FIND_DATA data;
  105. HANDLE hFind;
  106. dwBufSize = MAX_PATH;
  107. dwBytesUsed = ExpandEnvironmentStrings(szDefMapFile, m_szDefMapFile, dwBufSize); // The value returned by ExpandEnviromentStrings is larger than the required size.
  108. if (0 != dwBytesUsed)
  109. {
  110. m_bHaveMapPath = true;
  111. _tcscpy(m_szLaunchMapFile, m_szLauncherResources);
  112. _tcscat(m_szLaunchMapFile, m_szDefMapFile);
  113. hFind = FindFirstFile(m_szLaunchMapFile, &data);
  114. if (INVALID_HANDLE_VALUE != hFind)
  115. {
  116. m_bHaveDefMapFile = true;
  117. FindClose(hFind);
  118. }
  119. else
  120. {
  121. m_bHaveDefMapFile = false;
  122. }
  123. }
  124. }
  125. reg.Close();
  126. }
  127. // Need the TShoot.ocx resource path to verify that the networks exist.
  128. if (ERROR_SUCCESS == reg.Open(HKEY_LOCAL_MACHINE, SZ_TSHOOT_ROOT))
  129. {
  130. dwBufSize = MAX_PATH;
  131. TCHAR szDszResPath[MAX_PATH];
  132. if (ERROR_SUCCESS == reg.QueryValue(szDszResPath, SZ_TSHOOT_RES, &dwBufSize))
  133. {
  134. if ('\\' != szDszResPath[_tcslen(szDszResPath) - 1])
  135. _tcscat(szDszResPath, _T("\\"));
  136. dwBufSize = MAX_PATH;
  137. dwBytesUsed = ExpandEnvironmentStrings(szDszResPath, m_szDszResPath, dwBufSize); // The value returned by ExpandEnviromentStrings is larger than the required size.
  138. if (0 == dwBytesUsed)
  139. m_bHaveDszPath = false;
  140. else
  141. m_bHaveDszPath = true;
  142. }
  143. reg.Close();
  144. }
  145. return;
  146. }
  147. // This initialization can happen more than once for the object.
  148. // If we are going to use the same object to make a second request, there are things we
  149. // want to clean up.
  150. void CLaunch::InitRequest()
  151. {
  152. m_szAppName[0] = NULL;
  153. m_szAppVersion[0] = NULL;
  154. m_szAppProblem[0] = NULL;
  155. m_stkStatus.RemoveAll();
  156. m_Item.ReInit();
  157. }
  158. // >>> Why does this exist distinct from InitRequest()?
  159. void CLaunch::ReInit()
  160. {
  161. InitRequest();
  162. return;
  163. }
  164. // >>> What exactly is the use of this? What is the distinction from InitRequest()?
  165. void CLaunch::Clear()
  166. {
  167. m_szAppName[0] = NULL;
  168. m_szAppVersion[0] = NULL;
  169. m_szAppProblem[0] = NULL;
  170. m_stkStatus.RemoveAll();
  171. m_Item.Clear();
  172. return;
  173. }
  174. // Verify that a given troubleshooting belief network exists.
  175. bool CLaunch::VerifyNetworkExists(LPCTSTR szNetwork)
  176. {
  177. bool bResult = true;
  178. if (NULL == szNetwork || NULL == szNetwork[0])
  179. {
  180. // Null name, don't even bother with a lookup.
  181. m_stkStatus.Push(TSL_E_NETWORK_NF);
  182. bResult = false;
  183. }
  184. else
  185. {
  186. if (m_bHaveDszPath)
  187. {
  188. WIN32_FIND_DATA data;
  189. HANDLE hFind;
  190. TCHAR szDszFile[MAX_PATH];
  191. _tcscpy(szDszFile, m_szDszResPath);
  192. _tcscat(szDszFile, szNetwork);
  193. _tcscat(szDszFile, _T(".ds?"));
  194. hFind = FindFirstFile(szDszFile, &data);
  195. if (INVALID_HANDLE_VALUE == hFind)
  196. {
  197. m_stkStatus.Push(TSL_E_NETWORK_NF);
  198. bResult = false;
  199. }
  200. FindClose(hFind);
  201. }
  202. else
  203. {
  204. // we don't know what directory to look in.
  205. m_stkStatus.Push(TSL_E_NETWORK_REG);
  206. bResult = false;
  207. }
  208. }
  209. return bResult;
  210. }
  211. // Allows explicit specification of the troubleshooting network (and, optionally,
  212. // problem node) to launch to.
  213. // This is an alternative to determining network/node via a mapping.
  214. // INPUT szNetwork
  215. // INPUT szProblem: null pointer of null string ==> no problem node
  216. // any other value is symbolic name of problem node
  217. bool CLaunch::SpecifyProblem(LPCTSTR szNetwork, LPCTSTR szProblem)
  218. {
  219. bool bResult = true;
  220. if (!VerifyNetworkExists(szNetwork)) // Sets the network not found error.
  221. {
  222. bResult = false;
  223. }
  224. else
  225. {
  226. m_Item.SetNetwork(szNetwork);
  227. // Set problem node, if any. OK if there is none.
  228. if (NULL != szProblem && NULL != szProblem[0])
  229. m_Item.SetProblem(szProblem);
  230. }
  231. return bResult;
  232. }
  233. // Allows explicit setting of a non-problem node.
  234. // Obviously, node names only acquire meaning in the context of a belief network.
  235. // INPUT szNode: symbolic node name
  236. // INPUT szState: >>> not sure what is intended. The corresponding value in TSLaunch API is
  237. // an integer state value. Is this the decimal representation of that value or what? JM
  238. bool CLaunch::SetNode(LPCTSTR szNode, LPCTSTR szState)
  239. {
  240. bool bResult = true;
  241. if (NULL != szNode && NULL != szState)
  242. {
  243. m_Item.SetNode(szNode, szState);
  244. }
  245. else
  246. {
  247. m_stkStatus.Push(TSL_E_NODE_EMP);
  248. bResult = false;
  249. }
  250. return bResult;
  251. }
  252. // Sets machine ID so that WBEM can sniff on a remote machine.
  253. HRESULT CLaunch::MachineID(BSTR &bstrMachineID, DWORD *pdwResult)
  254. {
  255. HRESULT hRes = S_OK;
  256. if (!BSTRToTCHAR(m_Item.m_szMachineID, bstrMachineID, CItem::GUID_LEN))
  257. {
  258. *pdwResult = TSL_E_MEM_EXCESSIVE;
  259. hRes = TSL_E_FAIL;
  260. }
  261. return hRes;
  262. }
  263. // Sets Device Instance ID so that WBEM can sniff correct device
  264. HRESULT CLaunch::DeviceInstanceID(BSTR &bstrDeviceInstanceID, DWORD *pdwResult)
  265. {
  266. HRESULT hRes = S_OK;
  267. if (!BSTRToTCHAR(m_Item.m_szDeviceInstanceID, bstrDeviceInstanceID, CItem::GUID_LEN))
  268. {
  269. *pdwResult = TSL_E_MEM_EXCESSIVE;
  270. hRes = TSL_E_FAIL;
  271. }
  272. return hRes;
  273. }
  274. void CLaunch::SetPreferOnline(short bPreferOnline)
  275. {
  276. // The next line's ugly, but correct. bPreferOnline is not necessarily a valid
  277. // Boolean; we want to make sure we get a valid Boolean in m_bPreferOnline.
  278. m_bPreferOnline = (0 != bPreferOnline);
  279. return;
  280. }
  281. // CheckMapFile: Uses szAppName member to set szMapFile.
  282. // First, check the registry for an application-specific map file. If we can't find one,
  283. // check for a default map file. If that doesn't exist either, fail.
  284. // INPUT szAppName
  285. // OUTPUT szMapFile
  286. bool CLaunch::CheckMapFile(TCHAR * szAppName, TCHAR szMapFile[MAX_PATH], DWORD *pdwResult)
  287. {
  288. bool bHaveMapFile = false;
  289. if (NULL == szAppName || NULL == szAppName[0])
  290. {
  291. // Application name may not be null.
  292. m_stkStatus.Push(TSL_ERROR_UNKNOWN_APP);
  293. *pdwResult = TSL_ERROR_GENERAL;
  294. return false;
  295. }
  296. else
  297. {
  298. DWORD dwBufSize;
  299. CRegKey reg;
  300. if (ERROR_SUCCESS == reg.Open(HKEY_LOCAL_MACHINE, SZ_LAUNCHER_APP_ROOT))
  301. {
  302. dwBufSize = MAX_PATH;
  303. if (ERROR_SUCCESS == reg.Open(reg.m_hKey, szAppName))
  304. {
  305. if (ERROR_SUCCESS == reg.QueryValue(szMapFile, SZ_APPS_MAP_FILE, &dwBufSize))
  306. return true;
  307. }
  308. }
  309. }
  310. // Does a default map file exist?
  311. if (m_bHaveDefMapFile)
  312. {
  313. _tcscpy(szMapFile, m_szLaunchMapFile);
  314. }
  315. else
  316. { // Either the registry setting is missing or the file is not
  317. // where the registry says it is.
  318. if (m_bHaveMapPath) // Have the registry entry.
  319. m_stkStatus.Push(TSL_E_MAPPING_DB_NF);
  320. else
  321. m_stkStatus.Push(TSL_E_MAPPING_DB_REG);
  322. *pdwResult = TSL_ERROR_GENERAL;
  323. }
  324. return m_bHaveDefMapFile;
  325. }
  326. // Uses the mapping classes to map Caller() and DeviceID() information, then copies the
  327. // CItem to global memory.
  328. // >> Why is this called TestPut()?
  329. // Returns false when the mapping fails.
  330. bool CLaunch::TestPut()
  331. {
  332. extern CSMStateInfo g_StateInfo;
  333. DWORD dwResult;
  334. Map(&dwResult);
  335. if (TSL_OK != dwResult)
  336. return false;
  337. g_StateInfo.TestPut(m_Item); // Copies m_Item to global memory.
  338. return true;
  339. }
  340. // Perform any necessary mapping, then launch the Local Troubleshooter.
  341. bool CLaunch::Go(DWORD dwTimeOut, DWORD *pdwResult)
  342. {
  343. DWORD dwRes;
  344. bool bResult = true;
  345. extern CSMStateInfo g_StateInfo;
  346. TCHAR szContainerPathName[MAX_PATH]; szContainerPathName[0] = 0;
  347. TCHAR szSniffScriptFile[MAX_PATH]; szSniffScriptFile[0] = 0;
  348. TCHAR szSniffStandardFile[MAX_PATH]; szSniffStandardFile[0] = 0;
  349. TCHAR szWebPage[MAX_PATH]; szWebPage[0] = 0;
  350. TCHAR szDefaultNetwork[SYM_LEN]; szDefaultNetwork[0] = 0;
  351. TCHAR *szCmd = NULL, *szNetwork = NULL;
  352. if (TSL_OK == (dwRes = GetContainerPathName(szContainerPathName)))
  353. {
  354. m_Item.SetContainerPathName(szContainerPathName);
  355. m_Item.SetSniffScriptFile(szSniffScriptFile);
  356. }
  357. else
  358. {
  359. m_stkStatus.Push(dwRes);
  360. // if container is not found - no reason to continue
  361. *pdwResult = TSL_ERROR_GENERAL;
  362. return false;
  363. }
  364. if (!m_Item.NetworkSet())
  365. {
  366. if (Map(&dwRes) &&
  367. TSL_OK == (dwRes = GetWebPage(szWebPage)) // get web page
  368. )
  369. {
  370. m_Item.SetWebPage(szWebPage);
  371. // network and problem are set by Map function
  372. m_Item.SetLaunchRegime(launchMap);
  373. }
  374. else
  375. {
  376. m_stkStatus.Push(dwRes);
  377. if (TSL_OK == (dwRes = GetDefaultURL(szWebPage))) // get "DEFAULT PAGE",
  378. // actually a URL which might (for example)
  379. // refernce a page compiled into a .CHM file
  380. {
  381. m_Item.SetWebPage(szWebPage);
  382. m_Item.SetNetwork(NULL); // network are set to NULL in this case
  383. m_Item.SetProblem(NULL); // problem are set to NULL in this case
  384. m_Item.SetLaunchRegime(launchDefaultWebPage);
  385. }
  386. else
  387. {
  388. if (TSL_OK == (dwRes = GetDefaultNetwork(szDefaultNetwork)) && // get default network
  389. TSL_OK == (dwRes = GetWebPage(szWebPage)) // get web page
  390. )
  391. {
  392. m_Item.SetWebPage(szWebPage);
  393. m_Item.SetNetwork(szDefaultNetwork);
  394. m_Item.SetProblem(NULL); // problem is set to NULL in this case
  395. m_Item.SetLaunchRegime(launchDefaultNetwork);
  396. }
  397. else
  398. {
  399. // complete failure
  400. m_stkStatus.Push(dwRes);
  401. *pdwResult = TSL_ERROR_GENERAL;
  402. m_Item.SetLaunchRegime(launchIndefinite);
  403. return false;
  404. }
  405. }
  406. }
  407. }
  408. else
  409. {
  410. if (TSL_OK == (dwRes = GetWebPage(szWebPage)))
  411. {
  412. m_Item.SetWebPage(szWebPage);
  413. // network is known, problem can be either known(set) or unknown(not set)
  414. m_Item.SetLaunchRegime(launchKnownNetwork);
  415. }
  416. else
  417. {
  418. // complete failure
  419. m_stkStatus.Push(dwRes);
  420. *pdwResult = TSL_ERROR_GENERAL;
  421. m_Item.SetLaunchRegime(launchIndefinite);
  422. return false;
  423. }
  424. }
  425. // set sniff script and standard file
  426. m_Item.GetNetwork(&szCmd, &szNetwork);
  427. if (TSL_OK == (dwRes = GetSniffScriptFile(szSniffScriptFile, szNetwork[0] ? szNetwork : NULL)) &&
  428. TSL_OK == (dwRes = GetSniffStandardFile(szSniffStandardFile))
  429. )
  430. {
  431. m_Item.SetSniffScriptFile(szSniffScriptFile);
  432. m_Item.SetSniffStandardFile(szSniffStandardFile);
  433. }
  434. else
  435. {
  436. // can not find script file path - failure
  437. m_stkStatus.Push(dwRes);
  438. *pdwResult = TSL_ERROR_GENERAL;
  439. m_Item.SetLaunchRegime(launchIndefinite);
  440. return false;
  441. }
  442. // parse warnings according to the launch regime
  443. //
  444. if (launchMap == m_Item.GetLaunchRegime() ||
  445. launchKnownNetwork == m_Item.GetLaunchRegime()
  446. )
  447. {
  448. if (!m_Item.ProblemSet())
  449. {
  450. m_stkStatus.Push(TSL_WARNING_NO_PROBLEM_NODE);
  451. *pdwResult = TSL_WARNING_GENERAL;
  452. }
  453. }
  454. // parse launches according to the launch regime
  455. //
  456. if (launchMap == m_Item.GetLaunchRegime() ||
  457. launchDefaultNetwork == m_Item.GetLaunchRegime()
  458. )
  459. {
  460. if (m_Item.NetworkSet())
  461. {
  462. #ifdef JDEBUG
  463. HANDLE hDebugFile;
  464. char* szStart = "START\n";
  465. char* szEnd = "END\n";
  466. DWORD dwBytesWritten;
  467. hDebugFile = CreateFile(
  468. _T("jdebug.txt"),
  469. GENERIC_WRITE,
  470. FILE_SHARE_READ,
  471. NULL,
  472. CREATE_ALWAYS,
  473. FILE_ATTRIBUTE_NORMAL,
  474. NULL);
  475. WriteFile(
  476. hDebugFile,
  477. szStart,
  478. strlen(szStart),
  479. &dwBytesWritten,
  480. NULL);
  481. TCHAR *sztCmd, *sztVal;
  482. char sz[200], szCmd[100], szVal[100];
  483. m_Item.GetNetwork(&sztCmd, &sztVal);
  484. ToSBCS (szCmd, sztCmd, 100);
  485. ToSBCS (szVal, sztVal, 100);
  486. sprintf(sz, "%s %s\n", szCmd, szVal);
  487. WriteFile(
  488. hDebugFile,
  489. sz,
  490. strlen(sz),
  491. &dwBytesWritten,
  492. NULL);
  493. if (m_Item.ProblemSet())
  494. {
  495. m_Item.GetProblem(&sztCmd, &sztVal);
  496. ToSBCS (szCmd, sztCmd, 100);
  497. ToSBCS (szVal, sztVal, 100);
  498. sprintf(sz, "%s %s\n", szCmd, szVal);
  499. WriteFile(
  500. hDebugFile,
  501. sz,
  502. strlen(sz),
  503. &dwBytesWritten,
  504. NULL);
  505. }
  506. WriteFile(
  507. hDebugFile,
  508. szEnd,
  509. strlen(szEnd),
  510. &dwBytesWritten,
  511. NULL);
  512. CloseHandle(hDebugFile);
  513. #endif
  514. bResult = g_StateInfo.GoGo(dwTimeOut, m_Item, pdwResult);
  515. }
  516. else
  517. {
  518. *pdwResult = TSL_ERROR_GENERAL;
  519. m_stkStatus.Push(TSL_ERROR_NO_NETWORK);
  520. bResult = false;
  521. }
  522. }
  523. if (launchKnownNetwork == m_Item.GetLaunchRegime() )
  524. {
  525. bResult = g_StateInfo.GoGo(dwTimeOut, m_Item, pdwResult);
  526. }
  527. if (launchDefaultWebPage == m_Item.GetLaunchRegime())
  528. {
  529. bResult = g_StateInfo.GoURL(m_Item, pdwResult);
  530. }
  531. return bResult;
  532. }
  533. HRESULT CLaunch::LaunchKnown(DWORD * pdwResult)
  534. {
  535. HRESULT hRes = S_OK;
  536. // Launch the shooter.
  537. if (!Go(m_lLaunchWaitTimeOut, pdwResult))
  538. hRes = TSL_E_FAIL;
  539. return hRes;
  540. }
  541. HRESULT CLaunch::Launch(BSTR bstrCallerName, BSTR bstrCallerVersion,
  542. BSTR bstrAppProblem, short bLaunch, DWORD * pdwResult)
  543. {
  544. HRESULT hRes = S_OK;
  545. Clear();
  546. if (!BSTRToTCHAR(m_szAppName, bstrCallerName, SYM_LEN))
  547. {
  548. *pdwResult = TSL_E_MEM_EXCESSIVE;
  549. return TSL_E_FAIL;
  550. }
  551. if (!BSTRToTCHAR(m_szAppVersion, bstrCallerVersion, SYM_LEN))
  552. {
  553. *pdwResult = TSL_E_MEM_EXCESSIVE;
  554. return TSL_E_FAIL;
  555. }
  556. if (!BSTRToTCHAR(m_szAppProblem, bstrAppProblem, SYM_LEN))
  557. {
  558. *pdwResult = TSL_E_MEM_EXCESSIVE;
  559. return TSL_E_FAIL;
  560. }
  561. if (bLaunch)
  562. {
  563. if (!Go(m_lLaunchWaitTimeOut, pdwResult))
  564. hRes = TSL_E_FAIL;
  565. }
  566. else
  567. {
  568. if (!Map(pdwResult))
  569. hRes = TSL_E_FAIL;
  570. }
  571. return hRes;
  572. }
  573. HRESULT CLaunch::LaunchDevice(BSTR bstrCallerName, BSTR bstrCallerVersion, BSTR bstrPNPDeviceID,
  574. BSTR bstrDeviceClassGUID, BSTR bstrAppProblem, short bLaunch, DWORD * pdwResult)
  575. {
  576. HRESULT hRes;
  577. Clear();
  578. if (!BSTRToTCHAR(m_szAppName, bstrCallerName, SYM_LEN))
  579. {
  580. *pdwResult = TSL_E_MEM_EXCESSIVE;
  581. return TSL_E_FAIL;
  582. }
  583. if (!BSTRToTCHAR(m_szAppVersion, bstrCallerVersion, SYM_LEN))
  584. {
  585. *pdwResult = TSL_E_MEM_EXCESSIVE;
  586. return TSL_E_FAIL;
  587. }
  588. if (!BSTRToTCHAR(m_szAppProblem, bstrAppProblem, SYM_LEN))
  589. {
  590. *pdwResult = TSL_E_MEM_EXCESSIVE;
  591. return TSL_E_FAIL;
  592. }
  593. if (!BSTRToTCHAR(m_Item.m_szPNPDeviceID, bstrPNPDeviceID, CItem::GUID_LEN))
  594. {
  595. *pdwResult = TSL_E_MEM_EXCESSIVE;
  596. return TSL_E_FAIL;
  597. }
  598. if (!BSTRToTCHAR(m_Item.m_szGuidClass, bstrDeviceClassGUID, CItem::GUID_LEN))
  599. {
  600. *pdwResult = TSL_E_MEM_EXCESSIVE;
  601. return TSL_E_FAIL;
  602. }
  603. if (m_Item.m_szGuidClass[0])
  604. {
  605. // Device Class GUID is non-null. Make sure it's a valid GUID.
  606. GUID guidClass;
  607. #ifdef _UNICODE
  608. RPC_STATUS rpcstatus = UuidFromString(
  609. m_Item.m_szGuidClass, &guidClass );
  610. #else
  611. RPC_STATUS rpcstatus = UuidFromString(
  612. (unsigned char *) m_Item.m_szGuidClass, &guidClass );
  613. #endif
  614. if ( rpcstatus == RPC_S_INVALID_STRING_UUID)
  615. {
  616. m_stkStatus.Push(TSL_WARNING_ILLFORMED_CLASS_GUID);
  617. }
  618. }
  619. if (bLaunch)
  620. {
  621. if (!Go(m_lLaunchWaitTimeOut, pdwResult))
  622. hRes = TSL_E_FAIL;
  623. }
  624. else
  625. {
  626. if (!Map(pdwResult))
  627. hRes = TSL_E_FAIL;
  628. }
  629. return hRes;
  630. }
  631. DWORD CLaunch::GetStatus()
  632. {
  633. DWORD dwStatus = TSL_OK;
  634. if (!m_stkStatus.Empty())
  635. dwStatus = m_stkStatus.Pop();
  636. return dwStatus;
  637. }
  638. // OUTPUT *szPathName = Name of application to launch to (either IE or HTML Help System)
  639. // Returns:
  640. // TSL_OK - success
  641. // TSL_E_CONTAINER_REG - failure to find IE (Internet Explorer) in registry
  642. // TSL_E_CONTAINER_NF - IE isn't where registry says to find it.
  643. int CLaunch::GetContainerPathName(TCHAR szPathName[MAX_PATH])
  644. {
  645. DWORD dwPathNameLen = MAX_PATH;
  646. int tslaHaveContainer = TSL_OK;
  647. #ifndef _HH_CHM
  648. // use IE instead of HTML Help System
  649. if (!ReadRegSZ(HKEY_LOCAL_MACHINE,
  650. SZ_CONTAINER_APP_KEY,
  651. SZ_CONTAINER_APP_VALUE, szPathName, &dwPathNameLen))
  652. {
  653. tslaHaveContainer = TSL_E_CONTAINER_REG;
  654. }
  655. else
  656. { // Need to verify that the container exists.
  657. WIN32_FIND_DATA data;
  658. HANDLE hContainer = FindFirstFile(szPathName, &data);
  659. if (INVALID_HANDLE_VALUE == hContainer)
  660. tslaHaveContainer = TSL_E_CONTAINER_NF;
  661. else
  662. FindClose(hContainer);
  663. }
  664. #else
  665. _tcscpy(szPathName, _T("hh.exe"));
  666. #endif
  667. return tslaHaveContainer;
  668. }
  669. // OUTPUT *szWebPage = Name of web page to launch to
  670. // We always launch to the same web page. The information passed in m_Item ditinguishes
  671. // what will actually show on the screen.
  672. // Path is from registry. We concatenate on a backslash and SZ_WEB_PAGE (== "asklibrary.htm")
  673. // Returns:
  674. // TSL_OK - success
  675. // TSL_E_WEB_PAGE_REG - failure to find web page for this purpose in registry
  676. // TSL_E_MEM_EXCESSIVE - Web page name longer than we can handle
  677. // TSL_E_WEB_PAGE_NF - Web page isn't where registry says to find it.
  678. int CLaunch::GetWebPage(TCHAR szWebPage[MAX_PATH])
  679. {
  680. int tslaHavePage = TSL_OK;
  681. DWORD dwWebPageLen = MAX_PATH;
  682. if (!ReadRegSZ(HKEY_LOCAL_MACHINE,
  683. SZ_LAUNCHER_ROOT,
  684. SZ_GLOBAL_LAUNCHER_RES,
  685. szWebPage,
  686. &dwWebPageLen))
  687. {
  688. tslaHavePage = TSL_E_WEB_PAGE_REG;
  689. }
  690. else
  691. {
  692. int Len = _tcslen(szWebPage);
  693. dwWebPageLen = Len + 1 + _tcslen(SZ_WEB_PAGE);
  694. if (dwWebPageLen > MAX_PATH)
  695. {
  696. tslaHavePage = TSL_E_MEM_EXCESSIVE;
  697. }
  698. else
  699. {
  700. if (szWebPage[Len - 1] != '\\')
  701. _tcscat(szWebPage, _T("\\"));
  702. _tcscat(szWebPage, SZ_WEB_PAGE);
  703. WIN32_FIND_DATA data;
  704. HANDLE hWebPage = FindFirstFile(szWebPage, &data);
  705. if (INVALID_HANDLE_VALUE == hWebPage)
  706. tslaHavePage = TSL_E_WEB_PAGE_NF;
  707. else
  708. FindClose(hWebPage);
  709. }
  710. }
  711. return tslaHavePage;
  712. }
  713. // OUTPUT *szSniffScriptFile = full path and file name either to "network"_sniff.htm file or null len string if file is not found
  714. // TSL_OK - success
  715. // TSL_E_SNIFF_SCRIPT_REG - failure to find file for this purpose in registry
  716. int CLaunch::GetSniffScriptFile(TCHAR szSniffScriptFile[MAX_PATH], TCHAR* szNetwork)
  717. {
  718. int tslaHavePage = TSL_OK;
  719. DWORD dwSniffScriptLen = MAX_PATH;
  720. TCHAR szSniffScriptPath[MAX_PATH] = {0};
  721. if (ReadRegSZ(HKEY_LOCAL_MACHINE,
  722. SZ_TSHOOT_ROOT,
  723. SZ_TSHOOT_RES,
  724. szSniffScriptPath,
  725. &dwSniffScriptLen))
  726. {
  727. int Len = _tcslen(szSniffScriptPath);
  728. dwSniffScriptLen = Len + 1 + (szNetwork ? _tcslen(szNetwork) + _tcslen(SZ_SNIFF_SCRIPT_APPENDIX)
  729. : 0);
  730. if (dwSniffScriptLen > MAX_PATH)
  731. {
  732. tslaHavePage = TSL_E_MEM_EXCESSIVE;
  733. }
  734. else
  735. {
  736. if (szSniffScriptPath[Len - 1] != '\\')
  737. _tcscat(szSniffScriptPath, _T("\\"));
  738. if (szNetwork)
  739. {
  740. TCHAR tmp[MAX_PATH] = {0};
  741. _tcscpy(tmp, szSniffScriptPath);
  742. _tcscat(tmp, szNetwork);
  743. _tcscat(tmp, SZ_SNIFF_SCRIPT_APPENDIX);
  744. WIN32_FIND_DATA data;
  745. HANDLE hSniffScript = FindFirstFile(tmp, &data);
  746. if (INVALID_HANDLE_VALUE == hSniffScript)
  747. {
  748. szSniffScriptFile[0] = 0;
  749. }
  750. else
  751. {
  752. _tcscpy(szSniffScriptFile, tmp);
  753. FindClose(hSniffScript);
  754. }
  755. }
  756. else
  757. {
  758. szSniffScriptFile[0] = 0;
  759. }
  760. }
  761. }
  762. else
  763. {
  764. tslaHavePage = TSL_E_SNIFF_SCRIPT_REG;
  765. }
  766. return tslaHavePage;
  767. }
  768. // OUTPUT *szSniffScriptFile = full path and file name of tssniffAsk.htm file no matter if it exists
  769. // TSL_OK - success
  770. // TSL_E_SNIFF_SCRIPT_REG - failure to find file for this purpose in registry
  771. int CLaunch::GetSniffStandardFile(TCHAR szSniffStandardFile[MAX_PATH])
  772. {
  773. int tslaHavePage = TSL_OK;
  774. DWORD dwSniffStandardLen = MAX_PATH;
  775. TCHAR szSniffStandardPath[MAX_PATH] = {0};
  776. if (ReadRegSZ(HKEY_LOCAL_MACHINE,
  777. SZ_LAUNCHER_ROOT,
  778. SZ_GLOBAL_LAUNCHER_RES,
  779. szSniffStandardPath,
  780. &dwSniffStandardLen))
  781. {
  782. int Len = _tcslen(szSniffStandardPath);
  783. dwSniffStandardLen = Len + 1 + _tcslen(SZ_SNIFF_SCRIPT_NAME);
  784. if (dwSniffStandardLen > MAX_PATH)
  785. {
  786. tslaHavePage = TSL_E_MEM_EXCESSIVE;
  787. }
  788. else
  789. {
  790. if (szSniffStandardPath[Len - 1] != '\\')
  791. _tcscat(szSniffStandardPath, _T("\\"));
  792. _tcscpy(szSniffStandardFile, szSniffStandardPath);
  793. _tcscat(szSniffStandardFile, SZ_SNIFF_SCRIPT_NAME);
  794. }
  795. }
  796. else
  797. {
  798. tslaHavePage = TSL_E_SNIFF_SCRIPT_REG;
  799. }
  800. return tslaHavePage;
  801. }
  802. // OUTPUT *szURL = URL to go to when mapping fails. We get this from registry.
  803. // TSL_OK - success
  804. // TSL_E_WEB_PAGE_REG - failure to find web page for this purpose in registry
  805. int CLaunch::GetDefaultURL(TCHAR szURL[MAX_PATH])
  806. {
  807. int tslaHaveURL = TSL_OK;
  808. DWORD dwURLLen = MAX_PATH;
  809. if (!ReadRegSZ(HKEY_LOCAL_MACHINE,
  810. SZ_LAUNCHER_ROOT,
  811. SZ_DEFAULT_PAGE,
  812. szURL,
  813. &dwURLLen))
  814. {
  815. tslaHaveURL = TSL_E_WEB_PAGE_REG;
  816. }
  817. return tslaHaveURL;
  818. }
  819. // Returns TSL_OK and default network name in szDefaultNetwork
  820. // if successful
  821. int CLaunch::GetDefaultNetwork(TCHAR szDefaultNetwork[SYM_LEN])
  822. {
  823. DWORD dwLen = SYM_LEN;
  824. if (ReadRegSZ(HKEY_LOCAL_MACHINE, SZ_LAUNCHER_ROOT, SZ_DEFAULT_NETWORK,
  825. szDefaultNetwork, &dwLen))
  826. if (VerifyNetworkExists(szDefaultNetwork))
  827. return TSL_OK;
  828. return TSL_E_NO_DEFAULT_NET;
  829. }
  830. bool CLaunch::Map(DWORD *pdwResult)
  831. {
  832. bool bOK = true;
  833. TCHAR szMapFile[MAX_PATH];
  834. TCHAR szNetwork[SYM_LEN]; szNetwork[0] = NULL;
  835. TCHAR szTShootProblem[SYM_LEN]; szTShootProblem[0] = NULL;
  836. bOK = CheckMapFile(m_szAppName, szMapFile, pdwResult);
  837. // bOK false at this point means either the registry setting is missing or the file
  838. // is not where the registry says it is. PdwResult has already been set in CheckMapFile.
  839. if (bOK && _tcscmp(m_szMapFile, szMapFile))
  840. {
  841. // The mapping file we desire is _not_ already loaded
  842. if (m_pMap)
  843. {
  844. // we were using a different mapping file. We have to get rid of it.
  845. delete m_pMap;
  846. }
  847. // else we weren't using a mapping file yet.
  848. m_pMap = new TSMapClient(szMapFile);
  849. if (TSL_OK != m_pMap->GetStatus())
  850. {
  851. *pdwResult = m_pMap->GetStatus();
  852. bOK = false;
  853. }
  854. else
  855. {
  856. // We've successfully init'd m_pMap on the basis of the new map file.
  857. // Indicate that it's loaded.
  858. _tcscpy(m_szMapFile, szMapFile);
  859. }
  860. }
  861. if (bOK)
  862. {
  863. DWORD dwRes;
  864. // Now perform mapping itself
  865. //
  866. dwRes = m_pMap->FromAppVerDevAndClassToTS(m_szAppName, m_szAppVersion,
  867. m_Item.m_szPNPDeviceID, m_Item.m_szGuidClass, m_szAppProblem,
  868. szNetwork, szTShootProblem);
  869. // As documented for TSMapRuntimeAbstract::FromAppVerDevAndClassToTS(), there are two
  870. // return values here which require that we check for further status details: TSL_OK
  871. // (which means we found a mapping, but doesn't rule out warnings) and
  872. // TSL_ERROR_NO_NETWORK (which means we didn't find a mapping, and is typically
  873. // accompanied by further clarifications).
  874. if (TSL_OK == dwRes || TSL_ERROR_NO_NETWORK == dwRes)
  875. {
  876. DWORD dwStatus;
  877. while (0 != (dwStatus = m_pMap->MoreStatus()))
  878. m_stkStatus.Push(dwStatus);
  879. }
  880. if (TSL_OK != dwRes)
  881. m_stkStatus.Push(dwRes); // save the precise error status
  882. if (TSLIsError(dwRes) )
  883. bOK = false;
  884. if (bOK)
  885. {
  886. // We have a network name.
  887. bOK = VerifyNetworkExists(szNetwork);
  888. }
  889. if (bOK)
  890. {
  891. // We have a network name and we've verified that the network exists.
  892. // Set the item's network and tshoot problem.
  893. m_Item.SetNetwork(szNetwork);
  894. m_Item.SetProblem(szTShootProblem);
  895. }
  896. else
  897. *pdwResult = TSL_ERROR_GENERAL;
  898. }
  899. return bOK;
  900. }