Source code of Windows XP (NT5)
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.

740 lines
16 KiB

  1. //
  2. // MODULE: APGTSCFG.CPP
  3. //
  4. // PURPOSE: Old commment says "Reads in ini file configuration" but that's not what this does
  5. // >>> an up-to-date description would be nice.
  6. //
  7. // PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
  8. //
  9. // COMPANY: Saltmine Creative, Inc. (206)-633-4743 [email protected]
  10. //
  11. // AUTHOR: Roman Mach
  12. //
  13. // ORIGINAL DATE: 8-2-96
  14. //
  15. // NOTES:
  16. // 1. Based on Print Troubleshooter DLL
  17. //
  18. // Version Date By Comments
  19. //--------------------------------------------------------------------
  20. // V0.1 - RM Original
  21. // V0.2 6/4/97 RWM Local Version for Memphis
  22. // V0.3 04/09/98 JM/OK+ Local Version for NT5
  23. //
  24. //#include "windows.h"
  25. #include "stdafx.h"
  26. #include "time.h"
  27. #include "apgts.h"
  28. #include "ErrorEnums.h"
  29. #include "bnts.h"
  30. #include "BackupInfo.h"
  31. #include "cachegen.h"
  32. #include "apgtsinf.h"
  33. #include "apgtscmd.h"
  34. #include "apgtshtx.h"
  35. #include "apgtscls.h"
  36. #include "TSHOOT.h"
  37. #include <memory.h>
  38. #include "chmread.h"
  39. //
  40. //
  41. CDBLoadConfiguration::CDBLoadConfiguration()
  42. {
  43. m_cfg.api.pAPI = NULL;
  44. m_cfg.api.pTemplate = NULL;
  45. InitializeToDefaults();
  46. return;
  47. }
  48. VOID CDBLoadConfiguration::ResetTemplate()
  49. {
  50. delete m_cfg.api.pTemplate;
  51. m_cfg.api.pTemplate = new CHTMLInputTemplate(m_cfg.api.szFilepath[BNOFF_HTI]);
  52. m_cfg.api.pTemplate->Initialize(m_cfg.api.szResPath, m_cfg.api.strFile[BNOFF_HTI]);
  53. return;
  54. }
  55. //
  56. //
  57. CDBLoadConfiguration::CDBLoadConfiguration(HMODULE hModule, LPCTSTR szValue)
  58. {
  59. Initialize(hModule, szValue);
  60. return;
  61. }
  62. //
  63. //
  64. void CDBLoadConfiguration::Initialize(HMODULE hModule, LPCTSTR szValue)
  65. {
  66. DWORD dwRErr;
  67. TCHAR temp[MAXBUF];
  68. _tcscpy(temp,_T(""));
  69. // do all setting of variables in constructor!
  70. InitializeToDefaults();
  71. ProcessEventReg(hModule);
  72. CreatePaths(szValue);
  73. InitializeSingleResourceData(szValue);
  74. dwRErr = CreateApi(temp);
  75. if (dwRErr) {
  76. ReportWFEvent( _T("[apgtscfg]"), //Module Name
  77. _T("[CDBLoadConfiguration]"), //event
  78. _T("(A)"),
  79. temp,
  80. dwRErr );
  81. }
  82. }
  83. void CDBLoadConfiguration::SetValues(CHttpQuery &httpQ)
  84. {
  85. int value;
  86. BCache *pAPI = m_cfg.api.pAPI;
  87. if(pAPI)
  88. if (httpQ.GetValue1(value))
  89. pAPI->AddValue(value);
  90. return;
  91. }
  92. //
  93. //
  94. CDBLoadConfiguration::~CDBLoadConfiguration()
  95. {
  96. DWORD j;
  97. if (m_dwFilecount > 0)
  98. DestroyApi();
  99. if (m_cfg.pHandles != NULL) {
  100. for (j = 0; j < m_cfg.dwHandleCnt; j++)
  101. if (m_cfg.pHandles[j] != NULL)
  102. CloseHandle(m_cfg.pHandles[j]);
  103. delete [] m_cfg.pHandles;
  104. }
  105. }
  106. // Call in constructor only!
  107. //
  108. VOID CDBLoadConfiguration::InitializeToDefaults()
  109. {
  110. m_dwErr = 0;
  111. m_bncfgsz = MAXBNCFG;
  112. _tcscpy(m_szResourcePath, DEF_FULLRESOURCE);
  113. ClearCfg(0);
  114. m_cfg.pHandles = NULL;
  115. m_cfg.dwHandleCnt = 0;
  116. _tcscpy(m_nullstr, _T(""));
  117. m_dwFilecount = 0;
  118. }
  119. VOID CDBLoadConfiguration::InitializeSingleResourceData(LPCTSTR szValue)
  120. {
  121. LoadSingleTS(szValue);
  122. InitializeFileTimeList(); // I don't know that this is used.
  123. return;
  124. }
  125. //
  126. //
  127. VOID CDBLoadConfiguration::ProcessEventReg(HMODULE hModule)
  128. {
  129. HKEY hk;
  130. DWORD dwDisposition, dwType, dwValue, dwSize;
  131. TCHAR path[MAXBUF];
  132. BOOL bFixit = FALSE;
  133. // 1. check if have valid event info
  134. // 2. if not, create it as appropriate
  135. // check presence of event log info...
  136. _stprintf(path, _T("%s\\%s"), REG_EVT_PATH, REG_EVT_ITEM_STR);
  137. if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  138. path,
  139. 0,
  140. TS_REG_CLASS,
  141. REG_OPTION_NON_VOLATILE,
  142. KEY_READ | KEY_WRITE,
  143. NULL,
  144. &hk,
  145. &dwDisposition) == ERROR_SUCCESS) {
  146. if (dwDisposition == REG_CREATED_NEW_KEY) {
  147. // create entire registry layout for events
  148. CreateEvtMF(hk, hModule);
  149. CreateEvtTS(hk);
  150. }
  151. else {
  152. // now make sure all registry elements present
  153. dwSize = sizeof (path) - 1;
  154. if (RegQueryValueEx(hk,
  155. REG_EVT_MF,
  156. 0,
  157. &dwType,
  158. (LPBYTE) path,
  159. &dwSize) != ERROR_SUCCESS) {
  160. CreateEvtMF(hk, hModule);
  161. }
  162. dwSize = sizeof (DWORD);
  163. if (RegQueryValueEx(hk,
  164. REG_EVT_TS,
  165. 0,
  166. &dwType,
  167. (LPBYTE) &dwValue,
  168. &dwSize) != ERROR_SUCCESS) {
  169. CreateEvtTS(hk);
  170. }
  171. }
  172. RegCloseKey(hk);
  173. }
  174. }
  175. //
  176. //
  177. VOID CDBLoadConfiguration::CreateEvtMF(HKEY hk, HMODULE hModule)
  178. {
  179. TCHAR path[MAXBUF];
  180. DWORD len;
  181. if (hModule) {
  182. if ((len = GetModuleFileName(hModule, path, MAXBUF-1))!=0) {
  183. path[len] = _T('\0');
  184. if (RegSetValueEx( hk,
  185. REG_EVT_MF,
  186. 0,
  187. REG_EXPAND_SZ,
  188. (LPBYTE) path,
  189. len + sizeof(TCHAR)) == ERROR_SUCCESS) {
  190. }
  191. }
  192. }
  193. }
  194. //
  195. //
  196. VOID CDBLoadConfiguration::CreateEvtTS(HKEY hk)
  197. {
  198. DWORD dwData;
  199. dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
  200. EVENTLOG_INFORMATION_TYPE;
  201. if (RegSetValueEx( hk,
  202. REG_EVT_TS,
  203. 0,
  204. REG_DWORD,
  205. (LPBYTE) &dwData,
  206. sizeof(DWORD)) == ERROR_SUCCESS) {
  207. }
  208. }
  209. //
  210. // This may not actually be germane for Local Troubleshooter: probably
  211. // rather blindly carried over from Online TS.
  212. // m_dir (which gives us a list of desired files) must already be filled in with file names
  213. // & paths before this is called. this finishes initializing it.
  214. VOID CDBLoadConfiguration::InitializeFileTimeList()
  215. {
  216. HANDLE hSearch;
  217. DWORD j;
  218. // get a list of files we are interested in
  219. for (j=0;j<MAXBNFILES;j++) {
  220. m_dir.file[j].bExist = TRUE;
  221. m_dir.file[j].bChanged = FALSE;
  222. // only hti is independent
  223. if (j == BNOFF_HTI || j == BNOFF_BES)
  224. m_dir.file[j].bIndependent = TRUE;
  225. else
  226. m_dir.file[j].bIndependent = FALSE;
  227. hSearch = FindFirstFile(m_dir.file[j].szFilepath, &m_dir.file[j].FindData);
  228. if (hSearch == INVALID_HANDLE_VALUE) {
  229. // file not found usually
  230. m_dir.file[j].bExist = FALSE;
  231. }
  232. else {
  233. FindClose(hSearch);
  234. }
  235. }
  236. }
  237. //
  238. //
  239. VOID CDBLoadConfiguration::ClearCfg(DWORD off)
  240. {
  241. DWORD k;
  242. m_cfg.api.pAPI = NULL;
  243. m_cfg.api.pTemplate = NULL;
  244. m_cfg.api.waitcount = 0;
  245. for (k = 0; k < MAXBNFILES; k++)
  246. _tcscpy(m_cfg.api.szFilepath[k], _T(""));
  247. _tcscpy(m_cfg.api.type, _T(""));
  248. }
  249. // Bring content of DSC/HTI files for one troubleshooter into internal memory structures
  250. // OUTPUT *szErrInfo - info specific to error
  251. // RETURN 0 on success
  252. DWORD CDBLoadConfiguration::CreateApi(TCHAR *szErrInfo)
  253. {
  254. DWORD j;
  255. DWORD dwRErr = 0, dwIErr = 0, dwTErr = 0;
  256. // get api count and create new objects
  257. m_cfg.dwApiCnt = m_dwFilecount;
  258. // (The following comment sure looks like its carried over from Online TS and has little
  259. // relevance to Local TS. This routine probably involves a lot of overkill JM 3/98)
  260. // create new api and other files
  261. // once these go live we can destroy the others
  262. // provided there are no users using them
  263. // copy over list file info
  264. for (j = 0; j < MAXBNFILES; j++)
  265. {
  266. _tcscpy(m_cfg.api.szFilepath[j], m_dir.file[j].szFilepath);
  267. m_cfg.api.strFile[j] = m_dir.file[j].strFile;
  268. }
  269. _tcscpy(m_cfg.api.szResPath, m_dir.szResPath);
  270. _tcscpy(m_cfg.api.type, m_dir.type);
  271. if (NULL != m_cfg.api.pAPI)
  272. delete m_cfg.api.pAPI;
  273. if ((m_cfg.api.pAPI = new BCache( m_cfg.api.szFilepath[BNOFF_DSC],
  274. m_cfg.api.type,
  275. m_szResourcePath,
  276. m_cfg.api.strFile[BNOFF_DSC])) == NULL) {
  277. dwRErr = EV_GTS_ERROR_INFENGINE;
  278. }
  279. //
  280. dwTErr = m_cfg.api.pAPI->Initialize(/*m_cfg.pWordExcept*/);
  281. if (dwTErr) {
  282. dwIErr = dwTErr;
  283. _tcscpy(szErrInfo, m_cfg.api.szFilepath[BNOFF_DSC]);
  284. }
  285. if (NULL != m_cfg.api.pTemplate)
  286. delete m_cfg.api.pTemplate;
  287. if ((m_cfg.api.pTemplate = new CHTMLInputTemplate(m_cfg.api.szFilepath[BNOFF_HTI])) == NULL) {
  288. dwRErr = EV_GTS_ERROR_TEMPLATE_CREATE;
  289. }
  290. dwTErr = m_cfg.api.pTemplate->Initialize(m_cfg.api.szResPath, m_cfg.api.strFile[BNOFF_HTI]);
  291. if (dwTErr) {
  292. dwIErr = dwTErr;
  293. _tcscpy(szErrInfo, m_cfg.api.szFilepath[BNOFF_HTI]);
  294. }
  295. if (!dwRErr)
  296. if (dwIErr)
  297. dwRErr = dwIErr;
  298. return dwRErr;
  299. }
  300. //
  301. //
  302. VOID CDBLoadConfiguration::DestroyApi()
  303. {
  304. DWORD i;
  305. for (i=0;i<m_cfg.dwApiCnt;i++) {
  306. if (m_cfg.api.pAPI)
  307. delete m_cfg.api.pAPI;
  308. m_cfg.api.pAPI = NULL;
  309. if (m_cfg.api.pTemplate)
  310. delete m_cfg.api.pTemplate;
  311. m_cfg.api.pTemplate = NULL;
  312. }
  313. }
  314. //
  315. //
  316. BNCTL *CDBLoadConfiguration::GetAPI()
  317. {
  318. return &m_cfg;
  319. }
  320. //
  321. //
  322. BOOL CDBLoadConfiguration::FindAPIFromValue(BNCTL *currcfg,
  323. LPCTSTR type,
  324. CHTMLInputTemplate **pIT,
  325. /*CSearchForm **pBES,*/
  326. BCache **pAPI,
  327. DWORD *dwOff)
  328. {
  329. *pIT = currcfg->api.pTemplate;
  330. *pAPI = currcfg->api.pAPI;
  331. *dwOff = 0;
  332. return TRUE;
  333. }
  334. //
  335. //
  336. TCHAR *CDBLoadConfiguration::GetHtmFilePath(BNCTL *currcfg, DWORD i)
  337. {
  338. if (i >= currcfg->dwApiCnt)
  339. return m_nullstr;
  340. return currcfg->api.szFilepath[BNOFF_HTM];
  341. }
  342. //
  343. //
  344. TCHAR *CDBLoadConfiguration::GetBinFilePath(BNCTL *currcfg, DWORD i)
  345. {
  346. if (i >= currcfg->dwApiCnt)
  347. return m_nullstr;
  348. return currcfg->api.szFilepath[BNOFF_DSC];
  349. }
  350. //
  351. //
  352. TCHAR *CDBLoadConfiguration::GetHtiFilePath(BNCTL *currcfg, DWORD i)
  353. {
  354. if (i >= currcfg->dwApiCnt)
  355. return m_nullstr;
  356. return currcfg->api.szFilepath[BNOFF_HTI];
  357. }
  358. //
  359. //
  360. // RETURNS symbolic name of troubleshooter
  361. TCHAR *CDBLoadConfiguration::GetTagStr(BNCTL *currcfg, DWORD i)
  362. {
  363. if (i >= currcfg->dwApiCnt)
  364. return m_nullstr;
  365. return currcfg->api.type;
  366. }
  367. //
  368. //
  369. // RETURNS number of [instances of] troubleshooters. Probably a dubious inheritance from
  370. // Online TS: Local TS should have only one troubleshooting belief network.
  371. DWORD CDBLoadConfiguration::GetFileCount(BNCTL *currcfg)
  372. {
  373. return currcfg->dwApiCnt;
  374. }
  375. // Look in the registry for whether we are using DSC files or DSZ files.
  376. void CDBLoadConfiguration::GetDSCExtension(CString &strDSCExtension, LPCTSTR szValue)
  377. {
  378. HKEY hKey;
  379. CString strSubKey = TSREGKEY_TL;
  380. strSubKey += _T("\\");
  381. strSubKey += szValue;
  382. if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  383. strSubKey,
  384. NULL,
  385. KEY_READ,
  386. &hKey))
  387. {
  388. strDSCExtension = DSC_DEFAULT; // Default to DSZ
  389. return;
  390. }
  391. DWORD dwSize;
  392. DWORD dwType = REG_SZ;
  393. long lRes = RegQueryValueEx(hKey,
  394. TSLCL_FMAINEXT,
  395. NULL,
  396. &dwType,
  397. (BYTE *) strDSCExtension.GetBufferSetLength(10),
  398. &dwSize);
  399. strDSCExtension.ReleaseBuffer();
  400. if (ERROR_MORE_DATA == lRes)
  401. {
  402. lRes = RegQueryValueEx(hKey,
  403. TSLCL_FMAINEXT,
  404. NULL,
  405. &dwType,
  406. (BYTE *) strDSCExtension.GetBufferSetLength(dwSize + 2),
  407. &dwSize);
  408. strDSCExtension.ReleaseBuffer();
  409. if (ERROR_SUCCESS != lRes ||
  410. strDSCExtension.GetLength() < 1)
  411. {
  412. RegCloseKey(hKey);
  413. strDSCExtension = DSC_DEFAULT;
  414. return;
  415. }
  416. }
  417. else // ERROR_SUCCESS is true or false
  418. if (ERROR_SUCCESS != lRes || strDSCExtension.GetLength() < 1)
  419. {
  420. RegCloseKey(hKey);
  421. strDSCExtension = DSC_DEFAULT;
  422. return;
  423. }
  424. RegCloseKey(hKey);
  425. if (_T('.') != strDSCExtension.GetAt(0))
  426. strDSCExtension = _T('.') + strDSCExtension;
  427. return;
  428. }
  429. //
  430. // LoadSingleTS replaces ProcessLstFile when apgts is used in an
  431. // ActiveX or OLE control.
  432. VOID CDBLoadConfiguration::LoadSingleTS(LPCTSTR szValue)
  433. {
  434. CString strRefedDSCExtension = _T("");
  435. ASSERT(1 == MAXBNCFG);
  436. if (m_dwFilecount >= m_bncfgsz) {
  437. // need to reallocate space
  438. DWORD newdirsz = (m_bncfgsz + MAXBNCFG) * sizeof (BNDIRCFG);
  439. DWORD newcfgsz = (m_bncfgsz + MAXBNCFG) * sizeof (BNAPICFG);
  440. ASSERT(0 == m_bncfgsz);
  441. ClearCfg(m_bncfgsz);
  442. m_bncfgsz += MAXBNCFG;
  443. }
  444. GetDSCExtension(strRefedDSCExtension, szValue);
  445. // No matter if we are using CHM or not -
  446. // this path will be "..\..\network.htm".
  447. // We are not using it directly ANYWAY
  448. _stprintf(m_dir.file[BNOFF_HTM].szFilepath, _T("%s%s.htm"), m_szResourcePath,szValue);
  449. if (IsUsingCHM())
  450. {
  451. m_dir.file[BNOFF_DSC].strFile = CString(szValue) + strRefedDSCExtension;
  452. _stprintf(m_dir.file[BNOFF_DSC].szFilepath, _T("%s%s"), m_szResourcePath,(LPCTSTR)m_strCHM);
  453. }
  454. else
  455. {
  456. _stprintf(m_dir.file[BNOFF_DSC].szFilepath, _T("%s%s"), m_szResourcePath,szValue);
  457. _tcscat(m_dir.file[BNOFF_DSC].szFilepath, (LPCTSTR) strRefedDSCExtension);
  458. }
  459. if (IsUsingCHM())
  460. {
  461. m_dir.file[BNOFF_HTI].strFile = CString(szValue) + HTI_DEFAULT;
  462. _stprintf(m_dir.file[BNOFF_HTI].szFilepath, _T("%s%s"), m_szResourcePath,(LPCTSTR)m_strCHM);
  463. }
  464. else
  465. {
  466. _stprintf(m_dir.file[BNOFF_HTI].szFilepath, _T("%s%s.hti"), m_szResourcePath,szValue);
  467. }
  468. _stprintf(m_dir.file[BNOFF_BES].szFilepath, _T("%s%s.bes"), m_szResourcePath,szValue);
  469. _tcscpy(m_dir.szResPath, m_szResourcePath);
  470. _tcscpy(m_dir.type, szValue);
  471. m_dwFilecount++;
  472. ASSERT(1 == m_dwFilecount);
  473. return;
  474. }
  475. //
  476. //
  477. BOOL CDBLoadConfiguration::CreatePaths(LPCTSTR szNetwork)
  478. {
  479. int len;
  480. BOOL bDirChanged;
  481. // if reg entry not present, we need to add it
  482. bDirChanged = GetResourceDirFromReg(szNetwork);
  483. // a this point we are guaranteed to have len > 0 for each below
  484. // do our own validation (add backshash if not present)
  485. len = _tcslen(m_szResourcePath);
  486. if (len) {
  487. if (m_szResourcePath[len - 1] == _T('/'))
  488. m_szResourcePath[len - 1] = _T('\\');
  489. else if (m_szResourcePath[len-1] != _T('\\')) {
  490. m_szResourcePath[len] = _T('\\');
  491. m_szResourcePath[len+1] = _T('\0');
  492. }
  493. }
  494. return bDirChanged;
  495. }
  496. //
  497. //
  498. TCHAR *CDBLoadConfiguration::GetFullResource()
  499. {
  500. return (m_szResourcePath);
  501. }
  502. //
  503. //
  504. VOID CDBLoadConfiguration::GetVrootPath(TCHAR *tobuf)
  505. {
  506. _tcscpy(tobuf, _T(""));
  507. }
  508. // Find (or if it doesn't exist, create) a registry key giving path to resource directory.
  509. // if returns true, then directory is new or changed
  510. // if returns false, directory entry is same as before
  511. // Yet another case of something which maybe overkill, left over from Online TS.
  512. BOOL CDBLoadConfiguration::GetResourceDirFromReg(LPCTSTR szNetwork)
  513. {
  514. HKEY hknew;
  515. DWORD dwType, dwSize, dwDisposition, len;
  516. TCHAR buf1[MAXBUF], buf2[MAXBUF];
  517. BOOL bDirChanged = TRUE;
  518. LONG lErr;
  519. CString tmp;
  520. // search for "Path" value in SOFTWARE\Microsoft\TShoot\TroubleshooterList\Network
  521. if (::GetNetworkRelatedResourceDirFromReg(szNetwork, &tmp))
  522. {
  523. if (::IsNetworkRelatedResourceDirCHM(tmp))
  524. {
  525. m_strCHM = ::ExtractCHM(tmp);
  526. _tcscpy(m_szResourcePath, ::ExtractResourceDir(tmp));
  527. }
  528. else
  529. {
  530. _tcscpy(m_szResourcePath, tmp);
  531. }
  532. }
  533. else
  534. {
  535. // create key if not present
  536. if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  537. TSREGKEY_MAIN,
  538. 0,
  539. TS_REG_CLASS,
  540. REG_OPTION_NON_VOLATILE,
  541. KEY_READ | KEY_WRITE,
  542. NULL,
  543. &hknew,
  544. &dwDisposition) == ERROR_SUCCESS)
  545. {
  546. if (dwDisposition == REG_OPENED_EXISTING_KEY)
  547. {
  548. // Get the current key value.
  549. dwSize = MAXBUF - 1;
  550. dwType = REG_SZ;
  551. if ((lErr = RegQueryValueEx(hknew,
  552. FULLRESOURCE_STR,
  553. 0,
  554. &dwType,
  555. (LPBYTE) buf1,
  556. &dwSize)) == ERROR_SUCCESS)
  557. {
  558. if (dwType == REG_EXPAND_SZ || dwType == REG_SZ)
  559. {
  560. if (ExpandEnvironmentStrings(buf1, buf2, MAXBUF-1))
  561. {
  562. len = _tcslen(buf2);
  563. if (len)
  564. {
  565. if (buf2[len-1] != _T('\\'))
  566. {
  567. buf2[len] = _T('\\');
  568. buf2[len+1] = _T('\0');
  569. }
  570. }
  571. if (!_tcscmp(m_szResourcePath, buf2))
  572. bDirChanged = FALSE;
  573. else
  574. _tcscpy(m_szResourcePath, buf2);
  575. }
  576. else
  577. {
  578. ReportWFEvent( _T("[apgtscfg]"), //Module Name
  579. _T("[GetResourceDirFromReg]"), //event
  580. _T(""),
  581. _T(""),
  582. EV_GTS_ERROR_CANT_GET_RES_PATH );
  583. }
  584. }
  585. else
  586. {
  587. ReportWFEvent( _T("[apgtscfg]"), //Module Name
  588. _T("[GetResourceDirFromReg]"), //event
  589. _T(""),
  590. _T(""),
  591. EV_GTS_ERROR_CANT_GET_RES_PATH );
  592. }
  593. }
  594. else
  595. {
  596. _stprintf(buf1, _T("%ld"),lErr);
  597. ReportWFEvent( _T("[apgtscfg]"), //Module Name
  598. _T("[GetResourceDirFromReg]"), //event
  599. buf1,
  600. _T(""),
  601. EV_GTS_ERROR_CANT_OPEN_SFT_3 );
  602. }
  603. }
  604. else
  605. { // Created new key. Don't have any resources.
  606. _stprintf(buf1, _T("%ld"),ERROR_REGISTRY_IO_FAILED);
  607. ReportWFEvent( _T("[apgtscfg]"), //Module Name
  608. _T("[GetResourceDirFromReg]"), //event
  609. buf1,
  610. _T(""),
  611. EV_GTS_ERROR_CANT_GET_RES_PATH);
  612. }
  613. RegCloseKey(hknew);
  614. }
  615. else
  616. {
  617. ReportWFEvent( _T("[apgtscfg]"), //Module Name
  618. _T("[GetResourceDirFromReg]"), //event
  619. _T(""),
  620. _T(""),
  621. EV_GTS_ERROR_CANT_OPEN_SFT_2 );
  622. }
  623. }
  624. return bDirChanged;
  625. }
  626. //
  627. //
  628. VOID CDBLoadConfiguration::BackslashIt(TCHAR *str)
  629. {
  630. while (*str) {
  631. if (*str==_T('/'))
  632. *str=_T('\\');
  633. str = _tcsinc(str);
  634. }
  635. }
  636. VOID CDBLoadConfiguration::ResetNodes()
  637. {
  638. m_cfg.api.pAPI->ResetNodes();
  639. return;
  640. }
  641. bool CDBLoadConfiguration::IsUsingCHM()
  642. {
  643. return 0 != m_strCHM.GetLength();
  644. }