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.

2241 lines
60 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1998.
  5. //
  6. // File: tstparam.cxx
  7. //
  8. // Synopsys: Test paramers container class implementation
  9. //
  10. // Classes: CTestParams, CParamNode
  11. //
  12. // Notes: The test parameter containers provide a layer of abstraction
  13. // above the particular ways to pass test parameters -
  14. // (command line, environment, registry...)
  15. //
  16. // History: 10-Sep-1998 georgis created
  17. //
  18. //---------------------------------------------------------------------------
  19. #include "srheader.hxx"
  20. #include <tstparam.hxx>
  21. // Private macros to avoid some easy mistakes
  22. #define RETURN(x) hr=x; goto ErrReturn;
  23. #define ENTER_SYNC \
  24. EnterCriticalSection(&m_sync); \
  25. bEnterSync=TRUE; \
  26. if (!m_bUsed) \
  27. { \
  28. m_bUsed=TRUE; \
  29. hr=NotifyOnFirstUse(); \
  30. if (S_OK!=hr) \
  31. { \
  32. RETURN(hr); \
  33. } \
  34. }
  35. #define LEAVE_SYNC \
  36. if (bEnterSync) \
  37. { \
  38. LeaveCriticalSection(&m_sync); \
  39. }
  40. //+--------------------------------------------------------------------------
  41. //
  42. // Function: CalculateHashValue
  43. //
  44. // Synopsys: Calculates hash value for asciiz string
  45. // (case insensitive)
  46. //
  47. // Parameters: pszName: the string
  48. //
  49. // Returns: the hash value (the first 4 characters are used)
  50. //
  51. // History: 29-Sep-1998 georgis Created
  52. //
  53. //---------------------------------------------------------------------------
  54. DWORD CalculateHashValue(LPCWSTR pwszName)
  55. {
  56. DH_ASSERT(NULL!=pwszName);
  57. DWORD dwLen=(DWORD)wcslen(pwszName);
  58. DWORD dwTemp=0;
  59. for (DWORD dwIndex=0; dwIndex<2; dwIndex++)
  60. {
  61. dwTemp<<=16;
  62. if (dwIndex<dwLen)
  63. {
  64. dwTemp|=towlower(pwszName[dwIndex]);
  65. }
  66. }
  67. return dwTemp;
  68. };
  69. //+--------------------------------------------------------------------------
  70. //
  71. // Function: Unicode2Escaped
  72. //
  73. // Synopsys: Converts Unicode string to escaped ascii string
  74. //
  75. // Parameters: [in] pwszString: the source unicode string
  76. // [out] ppszString: return the ptr to escaped ascii string here
  77. // [in] dwEscapeMode: Escape mode
  78. //
  79. // History: 10-Nov-1998 georgis Created
  80. //
  81. //---------------------------------------------------------------------------
  82. HRESULT Unicode2Escaped(
  83. LPCWSTR pwszString,
  84. char ** ppszString,
  85. DWORD dwEscapeMode)
  86. {
  87. HRESULT hr=S_OK;
  88. char * pszEscaped=NULL;
  89. char * pszDest=NULL;
  90. LPCWSTR pwszSrc=NULL;
  91. DWORD dwSize=0;
  92. BOOL bNeedEscape=FALSE;
  93. DH_VDATEPTROUT(ppszString,LPSTR);
  94. *ppszString=NULL;
  95. // if NULL passed, just return NULL
  96. if (NULL==pwszString)
  97. {
  98. return S_OK;
  99. }
  100. // Count the size needed for the escaped string
  101. dwSize=0;
  102. for (pwszSrc=pwszString; 0!=*pwszSrc; pwszSrc++)
  103. {
  104. if (ESCAPE_NOTNEEDED(*pwszSrc))
  105. {
  106. dwSize++;
  107. }
  108. else
  109. {
  110. bNeedEscape=TRUE;
  111. dwSize+=5; // $xxxx format
  112. }
  113. }
  114. // Allocate memory for the escaped string
  115. // Eventually put the prefix
  116. if ((ESCAPEMODE_PREFIX_ALWAYS==dwEscapeMode)||
  117. (ESCAPEMODE_PREFIX_IFCHANGED==dwEscapeMode)&&bNeedEscape)
  118. {
  119. pszEscaped=new char [dwSize+2]; // the ESCAPED_MARKER and ending 0
  120. DH_ABORTIF(NULL==pszEscaped,E_OUTOFMEMORY,TEXT("new"));
  121. pszDest=pszEscaped;
  122. *pszDest++=ESCAPED_MARKER;
  123. }
  124. else
  125. {
  126. pszEscaped=new char [dwSize+1]; // ending 0
  127. DH_ABORTIF(NULL==pszEscaped,E_OUTOFMEMORY,TEXT("new"));
  128. pszDest=pszEscaped;
  129. }
  130. // Translate
  131. for (pwszSrc=pwszString; 0!=*pwszSrc; pwszSrc++)
  132. {
  133. if (ESCAPE_NOTNEEDED(*pwszSrc))
  134. {
  135. *pszDest++=(char)*pwszSrc;
  136. }
  137. else
  138. {
  139. *pszDest++=ESCAPE_CHARACTER;
  140. sprintf(pszDest,"%04x",*pwszSrc);
  141. pszDest+=4;
  142. }
  143. }
  144. *pszDest=0;
  145. ErrReturn:
  146. if (S_OK==hr)
  147. {
  148. *ppszString=pszEscaped;
  149. }
  150. else
  151. {
  152. delete pszEscaped;
  153. }
  154. return hr;
  155. }
  156. //+--------------------------------------------------------------------------
  157. //
  158. // Function: Unicode2Escaped (unicode->unicode)
  159. //
  160. // Synopsys: Converts Unicode string to escaped ascii string
  161. //
  162. // Parameters: [in] pwszString: the source unicode string
  163. // [out] ppwszString: return the ptr to escaped ascii string here
  164. // [in] dwEscapeMode: Escape mode
  165. //
  166. // History: 10-Nov-1998 georgis Created
  167. //
  168. //---------------------------------------------------------------------------
  169. HRESULT Unicode2Escaped(
  170. LPCWSTR pwszString,
  171. LPWSTR* ppwszString,
  172. DWORD dwEscapeMode)
  173. {
  174. HRESULT hr=S_OK;
  175. char * pszEscaped=NULL;
  176. DH_VDATEPTROUT(ppwszString,LPWSTR);
  177. hr=Unicode2Escaped(pwszString,&pszEscaped,dwEscapeMode);
  178. if ((S_OK==hr)&&(NULL!=pszEscaped))
  179. {
  180. hr=CopyString(pszEscaped,ppwszString);
  181. }
  182. else
  183. {
  184. *ppwszString=NULL;
  185. }
  186. delete pszEscaped;
  187. return hr;
  188. }
  189. //+--------------------------------------------------------------------------
  190. //
  191. // Function: Escaped2Unicode
  192. //
  193. // Synopsys: Converts Unicode string to escaped ascii string
  194. //
  195. // Parameters: [in] pszEscaped: the source escaped ascii string
  196. // [out] ppwszString: return the ptr to unescaped unicode string
  197. // [in] dwEscapeMode: escape mode
  198. //
  199. // History: 10-Nov-1998 georgis Created
  200. //
  201. //---------------------------------------------------------------------------
  202. HRESULT Escaped2Unicode(
  203. const char * pszEscaped,
  204. LPWSTR *ppwszString,
  205. DWORD dwEscapeMode)
  206. {
  207. HRESULT hr=S_OK;
  208. LPWSTR pwszDest=NULL;
  209. LPWSTR pwszUnescaped=NULL;
  210. const char * pszSrc=NULL;
  211. DWORD dwSize=0;
  212. int iTemp=0;
  213. DH_VDATEPTROUT(ppwszString,LPWSTR);
  214. *ppwszString=NULL;
  215. // if NULL passed, just return NULL
  216. if (NULL==pszEscaped)
  217. {
  218. return S_OK;
  219. }
  220. // Check for the escaped string marker
  221. switch (dwEscapeMode)
  222. {
  223. case ESCAPEMODE_PREFIX_ALWAYS:
  224. DH_ABORTIF(ESCAPED_MARKER!=*pszEscaped,E_UNEXPECTED,
  225. TEXT("Bad escaped source string"));
  226. pszEscaped++;
  227. break;
  228. case ESCAPEMODE_PREFIX_IFCHANGED:
  229. if (ESCAPED_MARKER==*pszEscaped)
  230. {
  231. pszEscaped++;
  232. }
  233. break;
  234. case ESCAPEMODE_PREFIX_NEVER:
  235. break;
  236. default:
  237. hr=E_INVALIDARG;
  238. DH_HRCHECK_ABORT(hr,TEXT("Bad escape mode"));
  239. }
  240. // Count the size needed for the escaped string
  241. dwSize=0;
  242. for (pszSrc=pszEscaped; 0!=*pszSrc; pszSrc++)
  243. {
  244. if (ESCAPE_CHARACTER==*pszSrc)
  245. {
  246. pszSrc+=4;
  247. }
  248. else
  249. {
  250. DH_ABORTIF(!ESCAPE_NOTNEEDED(*pszSrc),E_UNEXPECTED,
  251. TEXT("Bad symbol in the escaped string"));
  252. }
  253. dwSize++;
  254. }
  255. // Allocate memory for the unescaped string
  256. pwszUnescaped=new WCHAR [dwSize+1];
  257. DH_ABORTIF(NULL==pwszUnescaped,E_OUTOFMEMORY,TEXT("new"));
  258. // Translate
  259. pwszDest=pwszUnescaped;
  260. for (pszSrc=pszEscaped; 0!=*pszSrc; pwszDest++)
  261. {
  262. if (ESCAPE_CHARACTER==*pszSrc)
  263. {
  264. pszSrc++;
  265. // sscanf can read hex, but the output buffer must be
  266. // unsigned integer of the default int size, which is more
  267. // then sizeof(wchar)
  268. sscanf(pszSrc,"%04x",&iTemp);
  269. *pwszDest=(WCHAR)iTemp;
  270. pszSrc+=4;
  271. }
  272. else
  273. {
  274. *pwszDest=(WCHAR)*pszSrc++;
  275. }
  276. }
  277. *pwszDest=0;
  278. ErrReturn:
  279. if (S_OK==hr)
  280. {
  281. *ppwszString=pwszUnescaped;
  282. }
  283. else
  284. {
  285. delete pwszUnescaped;
  286. }
  287. return hr;
  288. }
  289. //+--------------------------------------------------------------------------
  290. //
  291. // Function: Escaped2Unicode (unicode->unicode)
  292. //
  293. // Synopsys: Converts Unicode string to escaped ascii string
  294. //
  295. // Parameters: [in] pwszEscaped: the source escaped string (unicode)
  296. // [out] ppwszString: return the ptr to unescaped unicode string
  297. // [in] dwEscapeMode: escape mode
  298. //
  299. // History: 10-Nov-1998 georgis Created
  300. //
  301. //---------------------------------------------------------------------------
  302. HRESULT Escaped2Unicode(
  303. LPCWSTR pwszEscaped,
  304. LPWSTR *ppwszString,
  305. DWORD dwEscapeMode)
  306. {
  307. HRESULT hr=S_OK;
  308. char *pszTemp=NULL;
  309. DH_VDATEPTROUT(ppwszString,LPWSTR);
  310. if (NULL!=pwszEscaped)
  311. {
  312. hr=CopyString(pwszEscaped,&pszTemp);
  313. }
  314. if (S_OK==hr)
  315. {
  316. hr=Escaped2Unicode(pszTemp,ppwszString,dwEscapeMode);
  317. }
  318. else
  319. {
  320. *ppwszString=NULL;
  321. }
  322. delete pszTemp;
  323. return hr;
  324. }
  325. //+--------------------------------------------------------------------------
  326. //
  327. // Constructor: CParamNode::CParamNode
  328. //
  329. // Synopsys: Initializes the parameter node as empty
  330. //
  331. // Arguments: dwFlags: General param info : source,priority,used
  332. //
  333. // History: 29-Sep-1998 georgis Created
  334. //
  335. //---------------------------------------------------------------------------
  336. CParamNode::CParamNode(DWORD dwFlags)
  337. {
  338. m_dwFlags=dwFlags;
  339. m_pwszName=NULL;
  340. m_pwszValue=NULL;
  341. m_pNext=NULL;
  342. }
  343. //+--------------------------------------------------------------------------
  344. //
  345. // Destructor: CParamNode::~CParamNode
  346. //
  347. // Synopsys: Releases the resources used by the parameter node
  348. //
  349. // History: 29-Sep-1998 georgis Created
  350. //
  351. //---------------------------------------------------------------------------
  352. CParamNode::~CParamNode()
  353. {
  354. delete m_pwszName;
  355. delete m_pwszValue;
  356. }
  357. //+--------------------------------------------------------------------------
  358. //
  359. // Method: CParamNode::Init
  360. //
  361. // Synopsys: Allocates memory for parameter Name and Value
  362. //
  363. // Parameters: pszName: the parameter name
  364. // pszValue: the parameter value
  365. //
  366. // History: 29-Sep-1998 georgis Created
  367. //
  368. //---------------------------------------------------------------------------
  369. HRESULT CParamNode::Init(LPCWSTR pwszName, LPCWSTR pwszValue)
  370. {
  371. HRESULT hr=S_OK;
  372. DH_ASSERT(NULL!=pwszName);
  373. DH_ASSERT(NULL==m_pwszName); // ensure the object is empty
  374. hr=CopyString(pwszName,&m_pwszName);
  375. if (S_OK==hr)
  376. {
  377. m_dwHashValue=CalculateHashValue(pwszName);
  378. if (NULL!=pwszValue)
  379. {
  380. hr=CopyString(pwszValue,&m_pwszValue);
  381. }
  382. }
  383. return hr;
  384. }
  385. //+--------------------------------------------------------------------------
  386. //
  387. // Method: CParamNode::ChangeValue
  388. //
  389. // Synopsys: Changes the parameter value
  390. //
  391. // Parameters: pszValue: the parameter value
  392. // dwFlags: parameter info (source,usage,priority)
  393. //
  394. // History: 29-Sep-1998 georgis Created
  395. //
  396. //---------------------------------------------------------------------------
  397. HRESULT CParamNode::ChangeValue(LPCWSTR pwszValue, DWORD dwFlags)
  398. {
  399. HRESULT hr=S_OK;
  400. DH_ASSERT(dwFlags>0);
  401. // Ensure we don't override used parameters unless asked
  402. if (PARAMMASK_USAGE & m_dwFlags)
  403. {
  404. if ((dwFlags & PARAMFLAG_OVERRIDEUSED)&&
  405. !(PARAMMASK_USAGE & (m_dwFlags & ~dwFlags)))
  406. {
  407. RETURN(E_ACCESSDENIED); // Can't override this type of usage
  408. }
  409. }
  410. // Ensure we don't override higher priority parameters
  411. if ((dwFlags & PARAMMASK_PRIORITY) < (m_dwFlags & PARAMMASK_PRIORITY))
  412. {
  413. if (dwFlags & PARAMFLAG_MUSTSET)
  414. {
  415. RETURN(E_ACCESSDENIED);
  416. }
  417. else
  418. {
  419. RETURN(S_OK);
  420. }
  421. }
  422. m_dwFlags=dwFlags;
  423. delete m_pwszValue;
  424. m_pwszValue=NULL;
  425. if (NULL!=pwszValue)
  426. {
  427. hr=CopyString(pwszValue,&m_pwszValue);
  428. }
  429. ErrReturn:
  430. return hr;
  431. }
  432. //+--------------------------------------------------------------------------
  433. //
  434. // Constructor: CTestParams::CTestParams (public)
  435. //
  436. // Synopsys: Initializes the parameter container as empty
  437. //
  438. // History: 10-Sep-1998 georgis Created
  439. //
  440. //---------------------------------------------------------------------------
  441. CTestParams::CTestParams()
  442. {
  443. m_pParamsList=NULL;
  444. m_dwUsageInfo=PARAMUSAGE_GENERAL;
  445. m_bUsed=FALSE;
  446. InitializeCriticalSection(&m_sync);
  447. }
  448. //+--------------------------------------------------------------------------
  449. //
  450. // Destructor: CTestParams::~CTestParams (public)
  451. //
  452. // Synopsys: Releases the resources used by the parameter container object
  453. //
  454. // History: 15-Sep-1998 georgis Created
  455. //
  456. //---------------------------------------------------------------------------
  457. CTestParams::~CTestParams()
  458. {
  459. EnterCriticalSection(&m_sync);
  460. CParamNode *pNext=NULL;
  461. for (CParamNode *pNode=m_pParamsList;
  462. NULL!=pNode;
  463. pNode=pNext)
  464. {
  465. pNext=pNode->m_pNext;
  466. delete pNode;
  467. }
  468. DeleteCriticalSection(&m_sync);
  469. }
  470. //+--------------------------------------------------------------------------
  471. //
  472. // Method: CTestParams::GetParam (public, synchronized)
  473. //
  474. // Synopsys: Reads parameter of given name:format
  475. //
  476. // Arguments: pszName: The parameter definition string
  477. // pTarget: the addres of the variable which receives the result
  478. //
  479. // Returns: S_OK on success,
  480. // S_FALSE if the parameter is not present,
  481. // E_FAIL if the format given is incompatible with the param value
  482. // or HRESULT error code (E_INVALIDARG, E_OUTOFMEMORY)
  483. //
  484. // Notes: The parameter definition string must be in format name:format
  485. // where name is the name which identyfies the parameter and
  486. // format shows how to read this parameter.
  487. // E.g. "my_int:%i"
  488. //
  489. // Formats may be of two types:
  490. // 1) Any standard sscanf formats starting with %
  491. // E.g. %i %u %d %lx %s ...
  492. //
  493. // 2) Custom formats
  494. // bool - read BOOL (*pTarget is BOOL)
  495. // cstr - read constant string (*pTarget is const char*)
  496. // astr - heap allocated ascii string (*pTarget is char*)
  497. // tstr - heap allocated TCHAR string (*pTarget is LPTSTR)
  498. // olestr - heap allocated OLESTR string (*pTarget is LPOLESTR)
  499. //
  500. // For the heap allocated formats the string obtained is writable,
  501. // and the caller is responsible for deleting it.
  502. //
  503. // History: 09-Sep-1998 georgis Created
  504. //
  505. //---------------------------------------------------------------------------
  506. HRESULT CTestParams::GetParam(const char *pszName, void* pTarget)
  507. {
  508. HRESULT hr=S_OK;
  509. BOOL bEnterSync=FALSE;
  510. LPWSTR pwszTemp=NULL;
  511. LPWSTR pwszFormat=NULL;
  512. CParamNode *pPrev=NULL; // not used
  513. CParamNode *pNode=NULL;
  514. if ((NULL==pszName)||(NULL==pTarget))
  515. {
  516. RETURN(E_INVALIDARG);
  517. }
  518. hr=CopyString(pszName,&pwszTemp);
  519. if (S_OK!=hr)
  520. {
  521. RETURN(hr);
  522. }
  523. pwszFormat=wcschr(pwszTemp,L':');
  524. if (NULL==pwszFormat)
  525. {
  526. RETURN(E_INVALIDARG);
  527. }
  528. *pwszFormat++=0;
  529. ENTER_SYNC;
  530. pNode=FindParam(pwszTemp,&pPrev);
  531. // for BOOL we always succed, eventyally seting the parameter
  532. // to FALSE if the switch is not found or has value "FALSE"
  533. if (!_wcsicmp(PARAMFMT_BOOL,pwszFormat))
  534. {
  535. if ((NULL!=pNode)&&
  536. ((NULL==pNode->m_pwszValue)||_wcsicmp(L"FALSE",pNode->m_pwszValue)))
  537. {
  538. *(BOOL*)pTarget=TRUE;
  539. pNode->MarkAsUsed(m_dwUsageInfo);
  540. }
  541. else
  542. {
  543. *(BOOL*)pTarget=FALSE;
  544. }
  545. RETURN(S_OK);
  546. }
  547. if (NULL==pNode)
  548. {
  549. RETURN(S_FALSE); // Not found
  550. }
  551. else
  552. {
  553. pNode->MarkAsUsed(m_dwUsageInfo);
  554. }
  555. // Process standard sscanf formats
  556. if (L'%'==*pwszFormat)
  557. {
  558. if (NULL==pNode->m_pwszValue)
  559. {
  560. RETURN(E_FAIL); // Found, but has no value
  561. }
  562. if (0<swscanf(pNode->m_pwszValue,pwszFormat,pTarget))
  563. {
  564. RETURN(S_OK);
  565. }
  566. else
  567. {
  568. RETURN(E_FAIL); // sscanf failed - incompatible format
  569. }
  570. }
  571. else // custom format
  572. {
  573. hr=GetCustomFmtParam(pwszFormat,pNode->m_pwszValue,pTarget);
  574. RETURN(hr);
  575. }
  576. ErrReturn:
  577. LEAVE_SYNC;
  578. delete pwszTemp;
  579. return hr;
  580. }
  581. //+--------------------------------------------------------------------------
  582. //
  583. // Method: CTestParams::GetCustomFmtParam (private)
  584. //
  585. // Synopsys: Extracts custom format parameter
  586. //
  587. // Arguments: pszFormat: The custom format.
  588. // pszValue: The value as string
  589. // pTarget: the addres of the variable which receives the result
  590. //
  591. // Custom formats:
  592. // cstr - read constant string (*pTarget is const char*)
  593. // astr - heap allocated ascii string (*pTarget is char*)
  594. // tstr - heap allocated TCHAR string (*pTarget is LPTSTR)
  595. // olestr - heap allocated OLESTR string (*pTarget is LPOLESTR)
  596. //
  597. //
  598. // History: 10-Sep-1998 georgis Created
  599. //
  600. //---------------------------------------------------------------------------
  601. HRESULT CTestParams::GetCustomFmtParam(LPCWSTR pwszFormat, LPCWSTR pwszValue, void* pTarget)
  602. {
  603. HRESULT hr=S_OK;
  604. DH_ASSERT(NULL!=pwszFormat);
  605. DH_ASSERT(NULL!=pTarget);
  606. // ASCII, allocated in heap
  607. if (!wcscmp(PARAMFMT_ASTR,pwszFormat))
  608. {
  609. if (NULL!=pwszValue)
  610. {
  611. hr=CopyString(pwszValue,(char**)pTarget);
  612. RETURN(hr);
  613. }
  614. else
  615. {
  616. *(char**)pTarget=NULL;
  617. RETURN(E_FAIL);
  618. }
  619. }
  620. // TSTR allocated in heap
  621. if (!wcscmp(PARAMFMT_TSTR,pwszFormat))
  622. {
  623. if (NULL!=pwszValue)
  624. {
  625. hr=CopyString(pwszValue,(LPTSTR*)pTarget);
  626. RETURN(hr);
  627. }
  628. else
  629. {
  630. *(LPTSTR*)pTarget=NULL;
  631. RETURN(E_FAIL);
  632. }
  633. }
  634. // OLESTR allocated in heap
  635. if (!wcscmp(PARAMFMT_OLESTR,pwszFormat))
  636. {
  637. if (NULL!=pwszValue)
  638. {
  639. hr=CopyString(pwszValue,(LPOLESTR*)pTarget);
  640. RETURN(hr);
  641. }
  642. else
  643. {
  644. *(LPOLESTR*)pTarget=NULL;
  645. RETURN(E_FAIL);
  646. }
  647. }
  648. // Unknown type
  649. hr=E_FAIL;
  650. ErrReturn:
  651. return hr;
  652. }
  653. //+--------------------------------------------------------------------------
  654. //
  655. // Method: CTestParams::IsPresent (public, synchronized)
  656. //
  657. // Synopsys: Retruns TRUE if the parameter is present
  658. // and FALSE if not or error occurs
  659. //
  660. // Arguments: pszName: The parameter definition string
  661. //
  662. // Note: The preferred way to handle BOOL parameters is
  663. // using GETPARAM*("name:bool"), which enables parameters
  664. // to be overwriten by cmd line e.g.
  665. // registry: REG_SZ myparam (existing, value do not matter)
  666. // cmdline: /myparam:false
  667. // The result of GETPARAM("myparam:bool") is FALSE,
  668. // while IsPresent("myparam") will return TRUE,
  669. // with or without cmdline switch /myparam:false
  670. //
  671. // History: 19-Oct-1998 georgis Created
  672. //
  673. //---------------------------------------------------------------------------
  674. BOOL __cdecl CTestParams::IsPresent(const char *pszName, ...)
  675. {
  676. HRESULT hr=S_OK;
  677. BOOL bEnterSync=FALSE;
  678. LPWSTR pwszTemp=NULL;
  679. LPWSTR pwszFormat=NULL;
  680. CParamNode *pPrev=NULL; // not used
  681. CParamNode *pNode=NULL;
  682. if (NULL==pszName)
  683. {
  684. return FALSE;
  685. }
  686. // if the param definition string contains format,
  687. // extract name only
  688. if (S_OK!=CopyString(pszName,&pwszTemp))
  689. {
  690. return FALSE;
  691. }
  692. pwszFormat=wcschr(pwszTemp,L':');
  693. if (NULL!=pwszFormat)
  694. {
  695. *pwszFormat=0;
  696. }
  697. ENTER_SYNC;
  698. pNode=FindParam(pwszTemp,&pPrev);
  699. ErrReturn:
  700. LEAVE_SYNC;
  701. delete pwszTemp;
  702. return (NULL!=pNode);
  703. }
  704. //+--------------------------------------------------------------------------
  705. //
  706. // Method: CTestParams::SetParam (public)
  707. //
  708. // Synopsys: Sets the parameter of given name:format
  709. //
  710. // Arguments: pszName: The parameter definition string
  711. // pTarget: the addres of the variable containig the param value
  712. //
  713. // Returns: S_OK on success,
  714. // E_FAIL if the format given is incompatible with the param value
  715. // or HRESULT error code (E_INVALIDARG, E_OUTOFMEMORY)
  716. //
  717. // Notes: The parameter definition string must be in format name:format
  718. // where name is the name which identyfies the parameter and
  719. // format shows how to read this parameter.
  720. // E.g. "my_string:cstr"
  721. //
  722. // Formats may be of two types:
  723. // 1) Standard sscanf formats
  724. // Only formats
  725. // %s %d %i %x %ld %lx %u %lu %ld, and %I64* are supported
  726. //
  727. // 2) Custom formats
  728. // bool - read BOOL (*pTarget is BOOL)
  729. // cstr - read constant string (*pTarget is const char*)
  730. // astr - heap allocated ascii string (*pTarget is char*)
  731. // tstr - heap allocated TCHAR string (*pTarget is LPTSTR)
  732. // olestr - heap allocated OLESTR string (*pTarget is LPOLESTR)
  733. //
  734. // For the heap allocated formats the string obtained is writable,
  735. // and the caller is responsible for deleting it.
  736. //
  737. // History: 17-Sep-1998 georgis Created
  738. //
  739. //---------------------------------------------------------------------------
  740. HRESULT CTestParams::SetParam(const char *pszName, void* pTarget, DWORD dwFlags)
  741. {
  742. HRESULT hr=S_OK;
  743. LPWSTR pwszTempName=NULL;
  744. LPWSTR pwszFormat=NULL;
  745. if ((NULL==pszName)||(NULL==pTarget)||
  746. (0==(PARAMMASK_SOURCE & dwFlags)))
  747. {
  748. RETURN(E_INVALIDARG);
  749. }
  750. hr=CopyString((char*)pszName,&pwszTempName);
  751. if (S_OK!=hr)
  752. {
  753. RETURN(hr);
  754. }
  755. pwszFormat=wcschr(pwszTempName,L':');
  756. if (NULL==pwszFormat)
  757. {
  758. RETURN(E_INVALIDARG);
  759. }
  760. *pwszFormat++=0;
  761. hr=SetCustomFmtParam(pwszTempName,pwszFormat,pTarget,dwFlags);
  762. ErrReturn:
  763. delete pwszTempName;
  764. return hr;
  765. }
  766. //+--------------------------------------------------------------------------
  767. //
  768. // Method: CTestParams::SetCustomFmtParam (private)
  769. //
  770. // Synopsys: Adds custom format parameter
  771. //
  772. // Arguments: pszName: The parameter name
  773. // pszFormat: The custom format.
  774. // pTarget: the addres of the variable which contains the value
  775. //
  776. // Custom formats:
  777. // bool - BOOL (*pTarget is BOOL)
  778. // cstr - ascii string (*pTarget is char*)
  779. // tstr - TCHAR string (*pTarget is LPTSTR)
  780. // olestr - OLESTR string (*pTarget is LPOLESTR)
  781. //
  782. //
  783. // History: 17-Sep-1998 georgis Created
  784. //
  785. //---------------------------------------------------------------------------
  786. HRESULT CTestParams::SetCustomFmtParam(
  787. LPCWSTR pwszName,
  788. LPCWSTR pwszFormat,
  789. void* pTarget,
  790. DWORD dwFlags)
  791. {
  792. HRESULT hr=S_OK;
  793. DH_ASSERT(NULL!=pwszName);
  794. DH_ASSERT(NULL!=pwszFormat);
  795. DH_ASSERT(NULL!=pTarget);
  796. DH_ASSERT((PARAMMASK_SOURCE & dwFlags)>0);
  797. LPWSTR pwszTempValue=NULL;
  798. WCHAR wszTemp[21]; // enough to print even 64bit integers
  799. // BOOL
  800. if (!wcscmp(PARAMFMT_BOOL,pwszFormat))
  801. {
  802. if (*(BOOL*)pTarget)
  803. {
  804. hr=AddParam(pwszName,NULL,dwFlags);
  805. RETURN(hr);
  806. }
  807. else
  808. {
  809. hr=AddParam(pwszName,L"FALSE",dwFlags);
  810. RETURN(hr);
  811. }
  812. }
  813. // Int
  814. if (!_wcsicmp(L"%i",pwszFormat)||
  815. !_wcsicmp(L"%d",pwszFormat)||
  816. !_wcsicmp(L"%u",pwszFormat)||
  817. !_wcsicmp(L"%lu",pwszFormat)||
  818. !_wcsicmp(L"%lx",pwszFormat)||
  819. !_wcsicmp(L"%ld",pwszFormat)||
  820. !_wcsicmp(L"%x",pwszFormat))
  821. {
  822. if (1>swprintf(wszTemp,pwszFormat,*(long*)pTarget))
  823. {
  824. RETURN(E_FAIL);
  825. }
  826. hr=AddParam(pwszName,wszTemp,dwFlags);
  827. RETURN(hr);
  828. }
  829. // I64 values
  830. if (!_wcsnicmp(L"%I64",pwszFormat,4))
  831. {
  832. if (1>swprintf(wszTemp,pwszFormat,*(ULONGLONG*)pTarget))
  833. {
  834. RETURN(E_FAIL);
  835. }
  836. hr=AddParam(pwszName,wszTemp,dwFlags);
  837. RETURN(hr);
  838. }
  839. // CONST ASCII - just pass the pszValue as pointer
  840. if (!_wcsicmp(L"%s",pwszFormat))
  841. {
  842. hr=AddParam(pwszName,(LPCWSTR)pTarget,dwFlags);
  843. RETURN(hr);
  844. }
  845. // ASTR
  846. if (!wcscmp(PARAMFMT_ASTR,pwszFormat))
  847. {
  848. if (NULL!=*(char*)pTarget)
  849. {
  850. hr=CopyString((char*)pTarget,&pwszTempValue);
  851. }
  852. if (S_OK==hr)
  853. {
  854. hr=AddParam(pwszName,pwszTempValue,dwFlags);
  855. }
  856. RETURN(hr);
  857. }
  858. // TSTR
  859. if (!wcscmp(PARAMFMT_TSTR,pwszFormat))
  860. {
  861. if (NULL!=*(LPTSTR*)pTarget)
  862. {
  863. hr=CopyString((LPTSTR)pTarget,&pwszTempValue);
  864. }
  865. if (S_OK==hr)
  866. {
  867. hr=AddParam(pwszName,pwszTempValue,dwFlags);
  868. }
  869. RETURN(hr);
  870. }
  871. // OLESTR
  872. if (!_wcsicmp(PARAMFMT_OLESTR,pwszFormat))
  873. {
  874. if (NULL!=*(LPOLESTR*)pTarget)
  875. {
  876. hr=CopyString((LPOLESTR)pTarget,&pwszTempValue);
  877. }
  878. if (S_OK==hr)
  879. {
  880. hr=AddParam(pwszName,pwszTempValue,dwFlags);
  881. }
  882. RETURN(hr);
  883. }
  884. // Unknown type
  885. hr=E_INVALIDARG;
  886. ErrReturn:
  887. delete pwszTempValue;
  888. return hr;
  889. }
  890. //+--------------------------------------------------------------------------
  891. //
  892. // Method: CTestParams::FindParam (private)
  893. //
  894. // Synopsys: Finds given parameter in the list
  895. //
  896. // Arguments: pszName: Parameter name
  897. // ppPrev: if not NULL, retrun the previous node here on success
  898. //
  899. // Returns: Pointer to the parmeter node
  900. //
  901. // History: 29-Sep-1998 georgis Created
  902. //
  903. //---------------------------------------------------------------------------
  904. CParamNode* CTestParams::FindParam(LPCWSTR pwszName, CParamNode** ppPrev)
  905. {
  906. CParamNode *pNode=NULL;
  907. DH_ASSERT(NULL!=pwszName);
  908. DH_ASSERT(NULL!=ppPrev);
  909. DWORD dwHashValue=CalculateHashValue(pwszName);
  910. for (pNode=m_pParamsList;
  911. NULL!=pNode;
  912. *ppPrev=pNode, pNode=pNode->m_pNext)
  913. {
  914. if (dwHashValue>pNode->m_dwHashValue)
  915. {
  916. continue;
  917. }
  918. else if (dwHashValue<pNode->m_dwHashValue)
  919. {
  920. return NULL;
  921. }
  922. else // Equal hash values
  923. {
  924. int i=_wcsicmp(pwszName,pNode->m_pwszName);
  925. if (i>0)
  926. {
  927. continue;
  928. }
  929. else if (i<0)
  930. {
  931. return NULL;
  932. }
  933. else
  934. {
  935. return pNode;
  936. }
  937. }
  938. }
  939. return NULL;
  940. };
  941. //+--------------------------------------------------------------------------
  942. //
  943. // Method: CTestParams::AddParam (public, synchronized)
  944. //
  945. // Synopsys: Adds a parameter to the container
  946. //
  947. // Arguments: pszName: The parameter name
  948. // pszValue: The parameter value as string
  949. // dwFlags: Param info (source,priority,usage)
  950. //
  951. // Returns: S_OK on success,
  952. // or HRESULT error code (E_INVALIDARG, E_OUTOFMEMORY)
  953. //
  954. // History: 29-Sep-1998 georgis Created
  955. //
  956. //---------------------------------------------------------------------------
  957. HRESULT CTestParams::AddParam(
  958. LPCWSTR pwszName,
  959. LPCWSTR pwszValue,
  960. DWORD dwFlags,
  961. BOOL bWasQuoted)
  962. {
  963. HRESULT hr=S_OK;
  964. BOOL bEnterSync=FALSE;
  965. CParamNode *pPrev=NULL;
  966. CParamNode *pParam=NULL;
  967. LPWSTR pwszTemp=NULL;
  968. if ((NULL==pwszName)||(0==(PARAMMASK_SOURCE & dwFlags)))
  969. {
  970. RETURN(E_INVALIDARG);
  971. }
  972. if ((NULL!=pwszValue)&&
  973. (ESCAPED_MARKER==*pwszValue)&&
  974. (!bWasQuoted))
  975. {
  976. hr=Escaped2Unicode(pwszValue,&pwszTemp,ESCAPEMODE_PREFIX_ALWAYS);
  977. if (S_OK!=hr)
  978. {
  979. RETURN(hr);
  980. }
  981. pwszValue=pwszTemp;
  982. }
  983. ENTER_SYNC;
  984. pParam=FindParam(pwszName,&pPrev);
  985. if (NULL!=pParam) // The parameter is known => try to change the value
  986. {
  987. hr=pParam->ChangeValue(pwszValue,dwFlags);
  988. RETURN(hr);
  989. }
  990. else // new parameter
  991. {
  992. // Create and initialize new parameter node
  993. pParam=new CParamNode(dwFlags);
  994. if (NULL==pParam)
  995. {
  996. RETURN(E_OUTOFMEMORY);
  997. }
  998. hr=pParam->Init(pwszName,pwszValue);
  999. if (S_OK!=hr)
  1000. {
  1001. RETURN(hr);
  1002. }
  1003. // Insert in the list
  1004. if (NULL==pPrev)
  1005. {
  1006. // Add as first node
  1007. pParam->m_pNext=m_pParamsList;
  1008. m_pParamsList=pParam;
  1009. }
  1010. else
  1011. {
  1012. // Add after pPrev
  1013. pParam->m_pNext=pPrev->m_pNext;
  1014. pPrev->m_pNext=pParam;
  1015. }
  1016. RETURN(S_OK);
  1017. }
  1018. ErrReturn:
  1019. if (S_OK!=hr)
  1020. {
  1021. delete pParam;
  1022. }
  1023. else // Mark the repro info params as used
  1024. {
  1025. if (PARAMFLAG_REPROINFO & dwFlags)
  1026. {
  1027. pParam->MarkAsUsed(dwFlags);
  1028. }
  1029. }
  1030. LEAVE_SYNC;
  1031. delete pwszTemp;
  1032. return hr;
  1033. }
  1034. //+--------------------------------------------------------------------------
  1035. //
  1036. // Method: CTestParams::DeleteParam (public, synchronized)
  1037. //
  1038. // Synopsys: Deletes given arameter from the string table
  1039. //
  1040. // Arguments: pszName: Parameter name
  1041. //
  1042. // Returns: S_OK if the param was not found or successifully deleted
  1043. // or E_INVALIDARG
  1044. //
  1045. // Notes: Deleting parmeters do not cause reallocation of
  1046. // the string table to smaller size.
  1047. //
  1048. // History: 10-Sep-1998 georgis Created
  1049. //
  1050. //---------------------------------------------------------------------------
  1051. HRESULT CTestParams::DeleteParam(const char *pszName)
  1052. {
  1053. HRESULT hr=S_OK;
  1054. BOOL bEnterSync=FALSE;
  1055. CParamNode *pPrev=NULL;
  1056. CParamNode *pParam=NULL;
  1057. LPWSTR pwszName=NULL;
  1058. if (NULL==pszName)
  1059. {
  1060. RETURN(E_INVALIDARG);
  1061. }
  1062. hr=CopyString(pszName,&pwszName);
  1063. if (S_OK!=hr)
  1064. {
  1065. RETURN(hr);
  1066. }
  1067. ENTER_SYNC;
  1068. pParam=FindParam(pwszName, &pPrev);
  1069. if (NULL==pParam)
  1070. {
  1071. RETURN(S_OK); // the param is not present anyway
  1072. }
  1073. if (NULL==pPrev)
  1074. {
  1075. DH_ASSERT(m_pParamsList==pParam);
  1076. m_pParamsList=pParam->m_pNext;
  1077. }
  1078. else
  1079. {
  1080. pPrev->m_pNext=pParam->m_pNext;
  1081. }
  1082. ErrReturn:
  1083. delete pParam;
  1084. delete pwszName;
  1085. LEAVE_SYNC;
  1086. return hr;
  1087. }
  1088. //+--------------------------------------------------------------------------
  1089. //
  1090. // Method: CTestParams::ReadCommandLine (public)
  1091. //
  1092. // Synopsys: Reads all the swithes from the command line
  1093. // to the parameter container.
  1094. //
  1095. // Parameters: pszCommandLine: the command line
  1096. // or NULL => use GetCommandLine()
  1097. //
  1098. // Returns: S_OK on success or E_OUTOFMEMORY
  1099. //
  1100. // History: 10-Sep-1998 georgis Created
  1101. //
  1102. //---------------------------------------------------------------------------
  1103. HRESULT CTestParams::ReadCommandLine(LPCTSTR ptszCommandLine, DWORD dwFlags)
  1104. {
  1105. LPWSTR pwszCmdLine=NULL;
  1106. LPWSTR pwszName=NULL;
  1107. LPWSTR pwszValue=NULL;
  1108. LPWSTR pwszEnd=NULL;
  1109. HRESULT hr=S_OK;
  1110. BOOL bQuoted=FALSE;
  1111. // If the ptszCommandLine is not given use GetCommandLine
  1112. if (NULL!=ptszCommandLine)
  1113. {
  1114. hr=CopyString(ptszCommandLine,&pwszCmdLine);
  1115. if(S_OK!=hr)
  1116. {
  1117. RETURN(hr);
  1118. }
  1119. }
  1120. else
  1121. {
  1122. hr=CopyString(GetCommandLine(),&pwszCmdLine);
  1123. if(S_OK!=hr)
  1124. {
  1125. RETURN(hr);
  1126. }
  1127. }
  1128. // Loop for command line switches
  1129. pwszName=pwszCmdLine;
  1130. while ((NULL!=pwszName)&&(0!=*pwszName))
  1131. {
  1132. bQuoted=FALSE;
  1133. // Find switch begining with /
  1134. while ((0!=*pwszName)&&('/'!=*pwszName))
  1135. {
  1136. pwszName++;
  1137. }
  1138. if (0==*pwszName)
  1139. {
  1140. RETURN(S_OK);
  1141. }
  1142. // Find switch value
  1143. pwszValue=++pwszName;
  1144. while ((0!=*pwszValue)&&(' '!=*pwszValue)&&(':'!=*pwszValue))
  1145. {
  1146. pwszValue++;
  1147. }
  1148. switch (*pwszValue)
  1149. {
  1150. case 0: // we hit the end
  1151. pwszEnd=NULL;
  1152. pwszValue=NULL;
  1153. break;
  1154. case ' ': // parameter has no value
  1155. pwszEnd=pwszValue;
  1156. *pwszEnd++=0;
  1157. pwszValue=NULL;
  1158. break;
  1159. case ':': // parameter with value
  1160. *pwszValue++=0;
  1161. if ('"'!=*pwszValue) //string without spaces
  1162. {
  1163. pwszEnd=pwszValue;
  1164. while ((0!=*pwszEnd)&&(' '!=*pwszEnd))
  1165. {
  1166. pwszEnd++;
  1167. }
  1168. if (0!=*pwszEnd)
  1169. {
  1170. *pwszEnd++=0;
  1171. }
  1172. else
  1173. {
  1174. pwszEnd=NULL;
  1175. }
  1176. }
  1177. else // get quoted string
  1178. {
  1179. pwszEnd=++pwszValue;
  1180. while ((0!=*pwszEnd)&&('"'!=*pwszEnd))
  1181. {
  1182. pwszEnd++;
  1183. }
  1184. if ('"'==*pwszEnd)
  1185. {
  1186. *pwszEnd++=0;
  1187. bQuoted=TRUE;
  1188. break;
  1189. }
  1190. else // the string ended before the closing quote
  1191. {
  1192. RETURN(E_UNEXPECTED);
  1193. }
  1194. }
  1195. } // case end
  1196. hr=AddParam(pwszName,pwszValue,dwFlags,bQuoted);
  1197. if (S_OK!=hr)
  1198. {
  1199. RETURN(hr);
  1200. }
  1201. pwszName=pwszEnd;
  1202. }// parameter loop end
  1203. ErrReturn:
  1204. delete pwszCmdLine;
  1205. return hr;
  1206. };
  1207. //+--------------------------------------------------------------------------
  1208. //
  1209. // Method: CTestParams::ReadEnvironment (public)
  1210. //
  1211. // Synopsys: Copies all the environment vars to the parameter container.
  1212. //
  1213. // Returns: S_OK on success,
  1214. // or HRESULT error code (E_UNEXPECTED, E_OUTOFMEMORY)
  1215. //
  1216. // Note: The prefix should be always in upper case
  1217. //
  1218. // History: 10-Sep-1998 georgis Created
  1219. //
  1220. //---------------------------------------------------------------------------
  1221. HRESULT CTestParams::ReadEnvironment(LPCWSTR pwszPrefix, DWORD dwFlags)
  1222. {
  1223. HRESULT hr=S_OK;
  1224. LPWSTR pwszTemp=NULL;
  1225. LPWSTR pwszName=NULL;
  1226. LPWSTR pwszValue=NULL;
  1227. int i=0;
  1228. int iLen=0;
  1229. // HACK - call getenv so that the system will create environment
  1230. // which can be accessed using the _tenviron
  1231. _tgetenv(TEXT("COMPUTRNAME"));
  1232. if (NULL==_tenviron)
  1233. {
  1234. RETURN(E_UNEXPECTED);
  1235. }
  1236. // Prepare the prefix length
  1237. if (NULL!=pwszPrefix)
  1238. {
  1239. iLen=(int)wcslen(pwszPrefix);
  1240. }
  1241. for (i=0; NULL!=_tenviron[i]; i++)
  1242. {
  1243. hr=CopyString(_environ[i],&pwszTemp);
  1244. if (S_OK!=hr)
  1245. {
  1246. RETURN(hr);
  1247. }
  1248. pwszValue=wcschr(pwszTemp,L'=');
  1249. DH_ASSERT(NULL!=pwszValue)
  1250. *pwszValue++=0; // cut the param name, get the value
  1251. if ((NULL==pwszPrefix)|| // no prefix
  1252. (!_wcsnicmp(pwszPrefix,pwszTemp,iLen))) // prefix maches
  1253. {
  1254. pwszName=pwszTemp+iLen; // cut the prefix
  1255. hr=AddParam(pwszName,pwszValue,dwFlags);
  1256. if (S_OK!=hr)
  1257. {
  1258. RETURN(hr);
  1259. }
  1260. }
  1261. delete pwszTemp;
  1262. pwszTemp=NULL;
  1263. }
  1264. ErrReturn:
  1265. delete pwszTemp;
  1266. return hr;
  1267. }
  1268. //+--------------------------------------------------------------------------
  1269. //
  1270. // Method: CTestParams::ReadRegistry (public)
  1271. //
  1272. // Synopsys: Reads the string values in the given registry key
  1273. // to the parameter container
  1274. //
  1275. // Returns: S_OK on success,
  1276. // or HRESULT error code (E_INVALIDARG, E_OUTOFMEMORY)
  1277. //
  1278. // Note: All non-string values under this key are currently ignored,
  1279. // as well as all too large string.
  1280. //
  1281. // Returns: S_OK on success, or HRESULT error code
  1282. //
  1283. // History: 10-Sep-1998 georgis Created
  1284. //
  1285. //---------------------------------------------------------------------------
  1286. HRESULT CTestParams::ReadRegistry(HKEY hBaseKey, LPCTSTR ptszKeyName, DWORD dwFlags)
  1287. {
  1288. HRESULT hr=S_OK;
  1289. DWORD dwResult=ERROR_SUCCESS;
  1290. HKEY hKey=0;
  1291. TCHAR atszTempName[MAX_REGSTRLEN];
  1292. TCHAR atszTempValue[MAX_REGSTRLEN];
  1293. DWORD dwNameSize=0;
  1294. DWORD dwValueSize=0;
  1295. DWORD dwType=REG_SZ;
  1296. int i=0;
  1297. if ((0==hBaseKey)||(NULL==ptszKeyName))
  1298. {
  1299. RETURN(E_INVALIDARG);
  1300. }
  1301. dwResult=RegOpenKey(hBaseKey,ptszKeyName,&hKey);
  1302. if ((ERROR_SUCCESS!=dwResult)||(0==hKey))
  1303. {
  1304. RETURN(HRESULT_FROM_WIN32(dwResult));
  1305. }
  1306. // Loop for all the registry values
  1307. for (i=0; dwResult==ERROR_SUCCESS; i++)
  1308. {
  1309. dwNameSize = ARRAYSIZE(atszTempName);
  1310. dwValueSize = ARRAYSIZE(atszTempValue);
  1311. dwResult=RegEnumValue(
  1312. hKey,
  1313. i,
  1314. (LPTSTR)atszTempName,
  1315. &dwNameSize,
  1316. NULL,
  1317. &dwType,
  1318. (BYTE*)atszTempValue,
  1319. &dwValueSize);
  1320. if (ERROR_NO_MORE_ITEMS==dwResult)
  1321. {
  1322. RETURN(S_OK);
  1323. }
  1324. else if (ERROR_SUCCESS==dwResult)
  1325. {
  1326. // We won't take very big strings, or not strings
  1327. if ((dwType!=REG_SZ)||
  1328. (dwNameSize>=ARRAYSIZE(atszTempName))||
  1329. (dwValueSize>=ARRAYSIZE(atszTempValue)))
  1330. {
  1331. // BUGBUG: trace warning here
  1332. continue;
  1333. }
  1334. else
  1335. {
  1336. #ifndef UNICODE
  1337. WCHAR awszTempName[MAX_REGSTRLEN];
  1338. WCHAR awszTempValue[MAX_REGSTRLEN];
  1339. hr = CopyString(atszTempName,
  1340. awszTempName,
  1341. ARRAYSIZE(atszTempName)-1,
  1342. ARRAYSIZE(atszTempName)-1);
  1343. if (S_OK!=hr)
  1344. {
  1345. RETURN(hr);
  1346. }
  1347. hr = CopyString(atszTempValue,
  1348. awszTempValue,
  1349. ARRAYSIZE(atszTempValue)-1,
  1350. ARRAYSIZE(atszTempValue)-1);
  1351. if (S_OK!=hr)
  1352. {
  1353. RETURN(hr);
  1354. }
  1355. HRESULT hr=AddParam(
  1356. awszTempName,
  1357. awszTempValue,
  1358. dwFlags);
  1359. #else
  1360. HRESULT hr=AddParam(
  1361. atszTempName,
  1362. atszTempValue,
  1363. dwFlags);
  1364. #endif
  1365. if (S_OK!=hr)
  1366. {
  1367. RETURN(hr);
  1368. }
  1369. }
  1370. }
  1371. else if (ERROR_MORE_DATA==dwResult)
  1372. {
  1373. // BUGBUG:Trace warning here
  1374. continue; // acceptable error - proceed with other params
  1375. }
  1376. }
  1377. ErrReturn:
  1378. if (0!=hKey)
  1379. {
  1380. RegCloseKey(hKey);
  1381. }
  1382. return hr;
  1383. };
  1384. //+--------------------------------------------------------------------------
  1385. //
  1386. // Method: CTestParams::GetEnum (public, synchronized)
  1387. //
  1388. // Synopsis: Interprets parameter string value
  1389. // as enum DWORD.
  1390. //
  1391. // Parameters: pszSwitchName: the command line switch name.
  1392. // pdwValue: ptr to enum var which receives the result
  1393. // ... expected value names and values untill NULL
  1394. //
  1395. // Example: g_TestParams.GetParamAsEnum(
  1396. // "mode",
  1397. // &dwMode,
  1398. // "rw", STGM_READWRITE,
  1399. // "r", STGM_READ,
  1400. // "w", STGM_WRITE,
  1401. // NULL);
  1402. //
  1403. // Returns: S_OK on success HRESULT error code
  1404. //
  1405. // Note: If the parameter is not found the function succeeds and
  1406. // retruns the first option value in *pdwValue
  1407. //
  1408. // History: 15-Sep-1998 georgis Created
  1409. //
  1410. //---------------------------------------------------------------------------
  1411. HRESULT __cdecl CTestParams::GetEnum(const char *pszParamName, DWORD *pdwValue,...)
  1412. {
  1413. HRESULT hr=S_OK;
  1414. char * pszOption=NULL;
  1415. DWORD dwValue=0xabcdabcd;
  1416. BOOL bFound=FALSE;
  1417. BOOL bEnterSync=FALSE;
  1418. va_list ARGS;
  1419. CParamNode *pPrev=NULL; // not used
  1420. CParamNode *pNode=NULL;
  1421. char * pszTemp=NULL;
  1422. LPWSTR pwszName=NULL;
  1423. if ((NULL==pszParamName)||(NULL==pdwValue))
  1424. {
  1425. RETURN(E_INVALIDARG);
  1426. }
  1427. // copy the name as unicode
  1428. hr=CopyString(pszParamName,&pwszName);
  1429. if (S_OK!=hr)
  1430. {
  1431. RETURN(hr);
  1432. }
  1433. // Get the switch string value
  1434. ENTER_SYNC;
  1435. pNode=FindParam(pwszName,&pPrev);
  1436. if (NULL!=pNode)
  1437. {
  1438. pNode->MarkAsUsed(m_dwUsageInfo);
  1439. }
  1440. // Copy the value as ascii
  1441. if ((NULL!=pNode)&&(NULL!=pNode->m_pwszValue))
  1442. {
  1443. hr=CopyString(pNode->m_pwszValue,&pszTemp);
  1444. if (S_OK!=hr)
  1445. {
  1446. RETURN(hr);
  1447. }
  1448. }
  1449. // Loop for all expected values
  1450. va_start(ARGS,pdwValue);
  1451. pszOption=va_arg(ARGS,char*);
  1452. while(NULL!=pszOption)
  1453. {
  1454. dwValue=va_arg(ARGS,DWORD);
  1455. if ((NULL==pszTemp)||
  1456. (!_stricmp(pszTemp,pszOption)))
  1457. {
  1458. bFound=TRUE;
  1459. break;
  1460. }
  1461. pszOption=va_arg(ARGS,char*);
  1462. }
  1463. va_end(ARGS);
  1464. if (bFound)
  1465. {
  1466. *pdwValue=dwValue;
  1467. hr=S_OK;
  1468. }
  1469. else
  1470. {
  1471. hr=E_FAIL;
  1472. }
  1473. ErrReturn:
  1474. LEAVE_SYNC;
  1475. delete pwszName;
  1476. delete pszTemp;
  1477. return hr;
  1478. }
  1479. //+--------------------------------------------------------------------------
  1480. //
  1481. // Method: CTestParams::ClearUsage (public, synchronized)
  1482. //
  1483. // Synopsys: Clears usage specific flags
  1484. //
  1485. // Parameters: dwFlags: DWORD containing the usage flags to clear
  1486. // (all other bits are ignored)
  1487. //
  1488. // History: 30-Sep-1998 georgis Created
  1489. //
  1490. //---------------------------------------------------------------------------
  1491. void CTestParams::ClearUsage(DWORD dwFlags)
  1492. {
  1493. HRESULT hr=S_OK;
  1494. BOOL bEnterSync=FALSE;
  1495. CParamNode **pLinkPtr=&m_pParamsList;
  1496. CParamNode *pNode=m_pParamsList;
  1497. CParamNode *pNext=NULL;
  1498. ENTER_SYNC;
  1499. while (NULL!=pNode)
  1500. {
  1501. pNode->ClearUsage(dwFlags);
  1502. pNext=pNode->m_pNext;
  1503. // Clear "repro info" parameters which are out of scope
  1504. // (all the usage flags are cleared)
  1505. if ((PARAMFLAG_REPROINFO & pNode->m_dwFlags)&&
  1506. !(PARAMMASK_USAGE & pNode->m_dwFlags))
  1507. {
  1508. *pLinkPtr=pNext;
  1509. delete pNode;
  1510. }
  1511. else
  1512. {
  1513. pLinkPtr=&pNode->m_pNext;
  1514. }
  1515. pNode=pNext;
  1516. }
  1517. ErrReturn:
  1518. LEAVE_SYNC;
  1519. }
  1520. //+--------------------------------------------------------------------------
  1521. //
  1522. // Method: CTestParams::ChangeParamFlags (public, synchronized)
  1523. //
  1524. // Synopsys: Change parameter flags (all except usage marks)
  1525. //
  1526. // Parameters: dwFlags: DWORD containing the flags
  1527. // (usage bits are ignored)
  1528. //
  1529. // Note: This function may be used for changing priority
  1530. // of the parameters from given source
  1531. // e.g. ???.ChangeParam(
  1532. // PARAMFLAGS_CMDLINE,
  1533. // PARAMFLAGS_CMDLINE+1); // raise priority
  1534. //
  1535. // History: 30-Sep-1998 georgis Created
  1536. //
  1537. //---------------------------------------------------------------------------
  1538. HRESULT CTestParams::ChangeFlags(DWORD dwOldFlags, DWORD dwNewFlags)
  1539. {
  1540. HRESULT hr=S_OK;
  1541. BOOL bEnterSync=FALSE;
  1542. CParamNode *pNode=NULL;
  1543. if ((0==(PARAMMASK_SOURCE & dwOldFlags))||
  1544. (0==(PARAMMASK_SOURCE & dwNewFlags)))
  1545. {
  1546. RETURN(E_INVALIDARG);
  1547. }
  1548. ENTER_SYNC;
  1549. for (pNode=m_pParamsList;
  1550. NULL!=pNode;
  1551. pNode=pNode->m_pNext)
  1552. {
  1553. if (dwOldFlags==(pNode->m_dwFlags & ~PARAMMASK_SOURCE))
  1554. {
  1555. pNode->ChangeFlags(dwNewFlags);
  1556. }
  1557. }
  1558. ErrReturn:
  1559. LEAVE_SYNC;
  1560. return hr;
  1561. }
  1562. //+--------------------------------------------------------------------------
  1563. //
  1564. // Method: CTestParams::SaveParams (public, synchronized)
  1565. //
  1566. // Synopsys: Allocates a memory block and saves all the parameter info
  1567. //
  1568. // Arguments: *ppcBuffer:[out] the pointer to the buffer with all params
  1569. // *pdwSize: [out] the size of the buffer
  1570. // dwMask: [in] filter for parameters
  1571. //
  1572. // Notes: This method enables storing the set of parameters,
  1573. // or sending it to different process.
  1574. //
  1575. // The caller is responsible for deleting the table obtained.
  1576. //
  1577. // History: 30-Sep-1998 georgis Created
  1578. //
  1579. //---------------------------------------------------------------------------
  1580. HRESULT CTestParams::SaveParams(
  1581. char **ppcBuffer,
  1582. DWORD *pdwSize,
  1583. DWORD dwMask)
  1584. {
  1585. HRESULT hr=S_OK;
  1586. DWORD dwSize=0;
  1587. CParamNode *pNode=NULL;
  1588. BOOL bEnterSync=FALSE;
  1589. char *pcTemp=NULL;
  1590. if ((NULL==pdwSize)||(NULL==ppcBuffer))
  1591. {
  1592. RETURN(E_INVALIDARG);
  1593. }
  1594. *ppcBuffer=NULL;
  1595. *pdwSize=0;
  1596. ENTER_SYNC;
  1597. // Calculate the size needed
  1598. for (pNode=m_pParamsList; NULL!=pNode; pNode=pNode->m_pNext)
  1599. {
  1600. if (pNode->m_dwFlags & dwMask)
  1601. {
  1602. dwSize+=sizeof(DWORD)+((DWORD)wcslen(pNode->m_pwszName)+1)*sizeof(WCHAR);
  1603. if (NULL!=pNode->m_pwszValue)
  1604. {
  1605. dwSize+=((DWORD)wcslen(pNode->m_pwszValue)+1)*sizeof(WCHAR)+1; // mark 'y' + string
  1606. }
  1607. else
  1608. {
  1609. dwSize++; // mark 0
  1610. };
  1611. };
  1612. }
  1613. // Allocate a buffer
  1614. *ppcBuffer=new char[dwSize];
  1615. if (NULL==*ppcBuffer)
  1616. {
  1617. RETURN(E_OUTOFMEMORY);
  1618. }
  1619. memset(*ppcBuffer,0,dwSize);
  1620. // Copy all parameters
  1621. pcTemp=*ppcBuffer;
  1622. for (pNode=m_pParamsList; NULL!=pNode; pNode=pNode->m_pNext)
  1623. {
  1624. if (pNode->m_dwFlags & dwMask)
  1625. {
  1626. // Flags
  1627. *(DWORD*)(LPVOID)pcTemp=pNode->m_dwFlags;
  1628. pcTemp+=sizeof(DWORD);
  1629. // Name
  1630. wcscpy((LPWSTR)pcTemp,pNode->m_pwszName);
  1631. pcTemp+=(wcslen((LPWSTR)pcTemp)+1)*sizeof(WCHAR);
  1632. // Value
  1633. if (NULL!=pNode->m_pwszValue)
  1634. {
  1635. *pcTemp++='y'; // mark that we have a value
  1636. wcscpy((LPWSTR)pcTemp,pNode->m_pwszValue);
  1637. pcTemp+=(wcslen((LPWSTR)pcTemp)+1)*sizeof(WCHAR);
  1638. }
  1639. else
  1640. {
  1641. *pcTemp++=0; // mark that there is no value
  1642. }
  1643. }
  1644. }
  1645. *pdwSize=dwSize;
  1646. ErrReturn:
  1647. LEAVE_SYNC;
  1648. return hr;
  1649. }
  1650. //+--------------------------------------------------------------------------
  1651. //
  1652. // Method: CTestParams::LoadParams (public, synchronized)
  1653. //
  1654. // Synopsys: Loads the parameters from memory buffer obtained by
  1655. // the CTestParams::Save method
  1656. //
  1657. // Arguments: pcBuffer: [in] the pointer to the buffer with all params
  1658. // dwSize: [in] the size of the buffer
  1659. // dwChangeFlags:[in] if not 0, change all parameters flags
  1660. //
  1661. // Note: The CTestParams object will make a copy of the parameters
  1662. // and do not need the buffer anymore.
  1663. //
  1664. // History: 30-Sep-1998 georgis Created
  1665. //
  1666. //---------------------------------------------------------------------------
  1667. HRESULT CTestParams::LoadParams(
  1668. char *pcBuffer,
  1669. DWORD dwSize,
  1670. DWORD dwChangeFlags)
  1671. {
  1672. HRESULT hr=S_OK;
  1673. BOOL bEnterSync=FALSE;
  1674. char *pcTemp=pcBuffer;
  1675. char *pcEndPtr=pcBuffer+dwSize;
  1676. if ((0==dwSize)||(NULL==pcBuffer))
  1677. {
  1678. RETURN(E_INVALIDARG);
  1679. }
  1680. ENTER_SYNC;
  1681. while (pcTemp<pcEndPtr)
  1682. {
  1683. // extract Flags
  1684. DWORD dwFlags=*(DWORD*)(LPVOID)(pcTemp);
  1685. pcTemp+=sizeof(DWORD);
  1686. if (0!=dwChangeFlags)
  1687. {
  1688. // Change all flags except the usage
  1689. dwFlags=(dwFlags & PARAMMASK_USAGE) |
  1690. (dwChangeFlags & ~PARAMMASK_USAGE);
  1691. }
  1692. // extract Name
  1693. LPWSTR pwszName=(LPWSTR)pcTemp;
  1694. pcTemp+=(wcslen((LPWSTR)pcTemp)+1)*sizeof(WCHAR);
  1695. // extract Value
  1696. LPWSTR pwszValue=NULL;
  1697. if ('y'==*pcTemp)
  1698. {
  1699. pwszValue=(LPWSTR)++pcTemp;
  1700. pcTemp=(char*)pwszValue+(wcslen(pwszValue)+1)*sizeof(WCHAR);
  1701. }
  1702. else
  1703. {
  1704. pwszValue=NULL;
  1705. pcTemp++;
  1706. }
  1707. // Add this parameter
  1708. HRESULT hr=AddParam(pwszName,pwszValue,dwFlags);
  1709. if (S_OK!=hr)
  1710. {
  1711. RETURN(hr);
  1712. }
  1713. }
  1714. ErrReturn:
  1715. LEAVE_SYNC;
  1716. return hr;
  1717. }
  1718. //+--------------------------------------------------------------------------
  1719. //
  1720. // Method: CTestParams::GetReproLine (public, synchronized)
  1721. //
  1722. // Synopsys: Extracts repro line including all the parameters
  1723. // which mach the mask
  1724. //
  1725. // Parameters: dwFlags: the mask to filter parameters,
  1726. // default is PARAMMASK_USAGE.
  1727. // Use PARAMMASK_ALL to get all parameters
  1728. //
  1729. // The caller is responsible for deleting the table obtained.
  1730. //
  1731. // History: 01-Oct-1998 georgis Created
  1732. //
  1733. //---------------------------------------------------------------------------
  1734. HRESULT CTestParams::GetReproLine(LPWSTR *ppwszReproLine, DWORD dwFlags)
  1735. {
  1736. HRESULT hr=S_OK;
  1737. DWORD dwSize=1; // the ending 0 in the string
  1738. CParamNode *pNode=NULL;
  1739. BOOL bEnterSync=FALSE;
  1740. LPWSTR pwszBuffer=NULL;
  1741. LPWSTR pwszTemp=NULL;
  1742. if (NULL==ppwszReproLine)
  1743. {
  1744. RETURN(E_INVALIDARG);
  1745. }
  1746. ENTER_SYNC;
  1747. // Calculate the size needed
  1748. for (pNode=m_pParamsList; NULL!=pNode; pNode=pNode->m_pNext)
  1749. {
  1750. if (dwFlags & pNode->m_dwFlags)
  1751. {
  1752. dwSize+=(DWORD)wcslen(pNode->m_pwszName)+2; // the name, '/' and space
  1753. if (NULL!=pNode->m_pwszValue)
  1754. {
  1755. dwSize+=(DWORD)wcslen(pNode->m_pwszValue)+1; // ':' and value
  1756. }
  1757. }
  1758. }
  1759. if (0==dwSize)
  1760. {
  1761. hr=CopyString("",&pwszBuffer);
  1762. RETURN(hr);
  1763. }
  1764. // Allocate a buffer
  1765. pwszBuffer=new WCHAR[dwSize];
  1766. if (NULL==pwszBuffer)
  1767. {
  1768. RETURN(E_OUTOFMEMORY);
  1769. }
  1770. memset(pwszBuffer,0,dwSize*sizeof(WCHAR));
  1771. // Copy all parameters
  1772. pwszTemp=pwszBuffer;
  1773. for (pNode=m_pParamsList; NULL!=pNode; pNode=pNode->m_pNext)
  1774. {
  1775. if (dwFlags & pNode->m_dwFlags)
  1776. {
  1777. // Value
  1778. if (NULL!=pNode->m_pwszValue)
  1779. {
  1780. swprintf(pwszTemp,L"/%s:%s ",pNode->m_pwszName,pNode->m_pwszValue);
  1781. pwszTemp+=wcslen(pwszTemp); // point to the ending zero
  1782. }
  1783. else
  1784. {
  1785. // The parameter has no value (boolean switch)
  1786. swprintf(pwszTemp,L"/%s ",pNode->m_pwszName);
  1787. pwszTemp+=wcslen(pwszTemp); // point to the ending zero
  1788. };
  1789. }
  1790. }
  1791. ErrReturn:
  1792. LEAVE_SYNC;
  1793. if (S_OK==hr)
  1794. {
  1795. *ppwszReproLine=pwszBuffer;
  1796. }
  1797. else
  1798. {
  1799. delete pwszBuffer;
  1800. }
  1801. return hr;
  1802. }
  1803. //+--------------------------------------------------------------------------
  1804. //
  1805. // Method: CTestParams::GetReproLine (public, synchronized)
  1806. //
  1807. // Synopsys: Extracts repro line including all the parameters
  1808. // which mach the mask
  1809. //
  1810. // Parameters: dwFlags: the mask to filter parameters,
  1811. // default is PARAMMASK_USAGE.
  1812. // Use PARAMMASK_ALL to get all parameters
  1813. //
  1814. // The caller is responsible for deleting the table obtained.
  1815. //
  1816. // History: 01-Oct-1998 georgis Created
  1817. //
  1818. //---------------------------------------------------------------------------
  1819. HRESULT CTestParams::GetReproLine(char **ppszReproLine, DWORD dwFlags)
  1820. {
  1821. HRESULT hr=S_OK;
  1822. LPWSTR pwszTemp=NULL;
  1823. if (NULL==ppszReproLine)
  1824. {
  1825. RETURN(E_INVALIDARG);
  1826. }
  1827. hr=GetReproLine(&pwszTemp,dwFlags);
  1828. if (S_OK==hr)
  1829. {
  1830. if (NULL==pwszTemp)
  1831. {
  1832. *ppszReproLine=NULL;
  1833. }
  1834. else
  1835. {
  1836. hr=CopyString(pwszTemp,ppszReproLine);
  1837. }
  1838. }
  1839. ErrReturn:
  1840. delete pwszTemp;
  1841. return hr;
  1842. }
  1843. //+--------------------------------------------------------------------------
  1844. //
  1845. // Method: CTestParams::GetRange (public, synchronized)
  1846. //
  1847. // Synopsys: Gets the values treating the parameter as range min-max
  1848. //
  1849. //
  1850. // Parameters: pszParamName: [in] the parameter name
  1851. // pullMin,pullMin : [out] the range values
  1852. //
  1853. // Retruns: S_OK or HRESULT error code
  1854. //
  1855. // Note: The string value of the parameter should be "min-max"
  1856. // e.g. "10-20"
  1857. // If the parameter can't be found, or the string format is bad
  1858. // the values won't be chenged.
  1859. //
  1860. // History: 02-Oct-1998 georgis Created
  1861. //
  1862. //---------------------------------------------------------------------------
  1863. HRESULT CTestParams::GetRange(
  1864. const char *pszParamName,
  1865. ULONGLONG *pullMin,
  1866. ULONGLONG *pullMax)
  1867. {
  1868. HRESULT hr=S_OK;
  1869. BOOL bEnterSync=FALSE;
  1870. CParamNode *pPrev=NULL; // not used
  1871. CParamNode *pNode=NULL;
  1872. LPWSTR pwszMin=NULL;
  1873. LPWSTR pwszMax=NULL;
  1874. ULONGLONG ullMin=0;
  1875. ULONGLONG ullMax=0;
  1876. LPWSTR pwszName=NULL;
  1877. if ((NULL==pszParamName)||(NULL==pullMin)||(NULL==pullMax))
  1878. {
  1879. RETURN(E_INVALIDARG);
  1880. }
  1881. hr=CopyString(pszParamName,&pwszName);
  1882. if (S_OK!=hr)
  1883. {
  1884. RETURN(hr);
  1885. }
  1886. // Get the switch string value
  1887. ENTER_SYNC;
  1888. pNode=FindParam(pwszName,&pPrev);
  1889. if ((NULL==pNode)||(NULL==pNode->m_pwszValue))
  1890. {
  1891. RETURN(S_FALSE);
  1892. }
  1893. pwszMin = pNode->m_pwszValue;
  1894. pwszMax = pwszMin;
  1895. // Advance the maximum pointer past the dash delimeter after
  1896. while ((*pwszMax != 0) && (*pwszMax++ != '-'))
  1897. {
  1898. ;
  1899. }
  1900. #ifdef WINNT // only here we have functions to hangle 64bit integers
  1901. ullMin = _wtoi64(pwszMin);
  1902. ullMax = _wtoi64(pwszMax);
  1903. #else
  1904. // wtoi64 is not present in link libraries, ifdef this
  1905. // to avoid build break. BUGBUG param values >DWORD will be truncated!
  1906. ullMin = _wtol(pwszMin);
  1907. ullMax = _wtol(pwszMax);
  1908. #endif
  1909. if (0==*pwszMax) // only one value is given
  1910. {
  1911. ullMax=ullMin;
  1912. };
  1913. if (ullMin <= ullMax)
  1914. {
  1915. hr=S_OK;
  1916. *pullMin=ullMin;
  1917. *pullMax=ullMax;
  1918. }
  1919. else
  1920. {
  1921. hr=E_FAIL;
  1922. }
  1923. ErrReturn:
  1924. LEAVE_SYNC;
  1925. delete pwszName;
  1926. return hr;
  1927. };
  1928. //+--------------------------------------------------------------------------
  1929. //
  1930. // Method: CTestParams::GetRange (public, synchronized)
  1931. //
  1932. // Synopsys: Gets the values treating the parameter as range min-max
  1933. //
  1934. // Parameters: pszParamName: [in] the parameter name
  1935. // pulMin,pulMin : [out] the range values
  1936. //
  1937. // Retruns: S_OK or HRESULT error code
  1938. //
  1939. // Note: The string value of the parameter should be "min-max"
  1940. // e.g. "10-20"
  1941. // If the parameter can't be found, or the string format is bad
  1942. // the values won't be chenged.
  1943. //
  1944. // History: 02-Oct-1998 georgis Created
  1945. //
  1946. //---------------------------------------------------------------------------
  1947. HRESULT CTestParams::GetRange(
  1948. const char *pszParamName,
  1949. ULONG *pulMin,
  1950. ULONG *pulMax)
  1951. {
  1952. HRESULT hr=S_OK;
  1953. ULARGE_INTEGER uliMin;
  1954. ULARGE_INTEGER uliMax;
  1955. if ((NULL==pszParamName)||(NULL==pulMin)||(NULL==pulMax))
  1956. {
  1957. RETURN(E_INVALIDARG);
  1958. }
  1959. uliMin.QuadPart=0;
  1960. uliMax.QuadPart=0;
  1961. hr=GetRange(pszParamName,&uliMin.QuadPart,&uliMax.QuadPart);
  1962. if (S_OK==hr) // else leave the values in *pulMin and *pulMax untouched
  1963. {
  1964. DH_ASSERT(0==uliMin.HighPart);
  1965. *pulMin=uliMin.LowPart;
  1966. DH_ASSERT(0==uliMax.HighPart);
  1967. *pulMax=uliMax.LowPart;
  1968. }
  1969. ErrReturn:
  1970. return hr;
  1971. };
  1972. //************** CTOLESTG specific **************************
  1973. // Define the default global parameter container
  1974. CStgParams g_TestParams;
  1975. //+--------------------------------------------------------------------------
  1976. //
  1977. // Method: CStgParams::NotifyOnFirstUse (public)
  1978. //
  1979. // Synopsys: Reads all the common parameter sources for
  1980. // the CTOLESTG project
  1981. //
  1982. // Note: The cleaner way is to implement a single function,
  1983. // but we want to start using the CTestParams in the
  1984. // common code, without modifying each the main()
  1985. // for each of the existing suites (about 50 now)
  1986. //
  1987. // History: 23-Oct-1998 georgis Created
  1988. //
  1989. //---------------------------------------------------------------------------
  1990. HRESULT CStgParams::NotifyOnFirstUse()
  1991. {
  1992. HRESULT hr=S_OK;
  1993. HRESULT hr1=S_OK;
  1994. DWORD dwDumpMask=PARAMMASK_ALL;
  1995. // command line
  1996. hr1=ReadCommandLine();
  1997. if (S_OK!=hr1)
  1998. {
  1999. hr=hr1;
  2000. };
  2001. if (!GETPARAM_ISPRESENT(STG_CMDLINEONLY))
  2002. {
  2003. // HKEY_CURRENT_USER\Software\Microsoft\CTOLESTG
  2004. // is the switch is not present, act as if it was empty
  2005. hr1=ReadRegistry(
  2006. HKEY_CURRENT_USER,
  2007. TEXT("Software\\Microsoft\\CTOLESTG"));
  2008. // Environment
  2009. hr1=ReadEnvironment(L"STG_");
  2010. if (S_OK!=hr1)
  2011. {
  2012. hr=hr1;
  2013. };
  2014. } // if cmdline only
  2015. // Eventually dump all the parameters
  2016. if (GETPARAM_ISPRESENT(PARAMDUMP))
  2017. {
  2018. GETPARAM(PARAMDUMP,dwDumpMask);
  2019. }
  2020. return hr;
  2021. };