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.

1095 lines
27 KiB

  1. /*++
  2. Copyright (C) 1995-2001 Microsoft Corporation
  3. Module Name:
  4. GENERAL.CPP
  5. Abstract:
  6. Containes some general purpose classes
  7. which are of use to serveral providers.
  8. Specifically, this contains the code for
  9. the classes used to cache open handles and
  10. the classes used to parse the mapping strings.
  11. History:
  12. a-davj 11-Nov-95 Created.
  13. --*/
  14. #include "precomp.h"
  15. //***************************************************************************
  16. //
  17. // CEntry::CEntry()
  18. //
  19. // DESCRIPTION:
  20. //
  21. // Constructor.
  22. //
  23. //***************************************************************************
  24. CEntry::CEntry()
  25. {
  26. hHandle = NULL;
  27. sPath.Empty();
  28. }
  29. //***************************************************************************
  30. //
  31. // CEntry::~CEntry()
  32. //
  33. // DESCRIPTION:
  34. //
  35. // Destructor.
  36. //
  37. //***************************************************************************
  38. CEntry::~CEntry()
  39. {
  40. sPath.Empty();
  41. }
  42. //***************************************************************************
  43. //
  44. // CHandleCache::~CHandleCache
  45. //
  46. // DESCRIPTION:
  47. //
  48. // Destructor.
  49. //
  50. //***************************************************************************
  51. CHandleCache::~CHandleCache()
  52. {
  53. Delete(0);
  54. }
  55. //***************************************************************************
  56. //
  57. // CHandleCache::lAddToList
  58. //
  59. // DESCRIPTION:
  60. //
  61. // Adds an entry to the handle list.
  62. //
  63. //
  64. // PARAMETERS:
  65. //
  66. // pAdd Name that will be used to retrieve the handle
  67. // hAdd handle to be added
  68. //
  69. // RETURN VALUE:
  70. //
  71. // S_OK all is well.
  72. // WBEM_E_OUT_OF_MEMORY out of memory
  73. //
  74. //***************************************************************************
  75. long int CHandleCache::lAddToList(
  76. IN const TCHAR * pAdd,
  77. IN HANDLE hAdd)
  78. {
  79. CEntry * pNew = new CEntry();
  80. if(pNew == NULL)
  81. return WBEM_E_OUT_OF_MEMORY;
  82. pNew->hHandle = hAdd;
  83. pNew->sPath = pAdd;
  84. if(CFlexArray::no_error != List.Add(pNew))
  85. return WBEM_E_OUT_OF_MEMORY;
  86. return S_OK;
  87. }
  88. //***************************************************************************
  89. //
  90. // CHandleCache::lGetNumMatch
  91. //
  92. // DESCRIPTION:
  93. //
  94. // Returns the number of entries which match the path tokens. For example,
  95. // the path might be HKEY_LOCAL_MACHINE, hardware, description, xyz, and
  96. // if the tokens, were, HKEY_LOCAL_MACHINE, hardware, devicemap, xyz then a
  97. // two would be returned since the first two parts matched.
  98. //
  99. // PARAMETERS:
  100. //
  101. // iEntry Entry to start checking at
  102. // iToken Token to start checking
  103. // Path This object supplies the tokens to be checked.
  104. //
  105. // RETURN VALUE:
  106. //
  107. // see description.
  108. //
  109. //***************************************************************************
  110. long int CHandleCache::lGetNumMatch(
  111. IN int iEntry,
  112. IN int iToken,
  113. IN CProvObj & Path)
  114. {
  115. int iMatch = 0;
  116. for(;iEntry < List.Size() && iToken < Path.iGetNumTokens();
  117. iEntry++, iToken++, iMatch++)
  118. {
  119. CEntry * pCurr = (CEntry *)List.GetAt(iEntry);
  120. TString sTemp = Path.sGetFullToken(iToken);
  121. if(lstrcmpi(pCurr->sPath,sTemp))
  122. break;
  123. }
  124. return iMatch;
  125. }
  126. //***************************************************************************
  127. //
  128. // CHandleCache::Delete
  129. //
  130. // DESCRIPTION:
  131. //
  132. // Empties all or part of the cache.
  133. //
  134. // PARAMETERS:
  135. //
  136. // lStart Indicates first element to delete. To empty entire cache,
  137. // a zero should be entered.
  138. //
  139. //***************************************************************************
  140. void CHandleCache::Delete(
  141. IN long int lStart)
  142. {
  143. int iCurr;
  144. for(iCurr = List.Size()-1; iCurr >= lStart; iCurr--)
  145. {
  146. CEntry * pCurr = (CEntry *)List.GetAt(iCurr);
  147. delete pCurr;
  148. List.RemoveAt(iCurr);
  149. }
  150. }
  151. //***************************************************************************
  152. //
  153. // CHandleCache::hGetHandle
  154. //
  155. // DESCRIPTION:
  156. //
  157. // Gets a handle.
  158. //
  159. // PARAMETERS:
  160. //
  161. // lIndex Indicates which handle to get. 0 is the first.
  162. //
  163. // RETURN VALUE:
  164. // handle retuested, NULL only if bad index is entered.
  165. //
  166. //***************************************************************************
  167. HANDLE CHandleCache::hGetHandle(
  168. IN long int lIndex)
  169. {
  170. if(lIndex < List.Size())
  171. {
  172. CEntry * pCurr = (CEntry *)List.GetAt(lIndex);
  173. if(pCurr)
  174. return pCurr->hHandle;
  175. }
  176. return NULL;
  177. }
  178. //***************************************************************************
  179. //
  180. // CHandleCache::sGetString
  181. //
  182. // DESCRIPTION:
  183. //
  184. // Gets the string associated with a cache entry.
  185. //
  186. // PARAMETERS:
  187. //
  188. // lIndex Index in cache, 0 is the first element.
  189. //
  190. // RETURN VALUE:
  191. //
  192. // Returns a pointer to the string. NULL if bad index.
  193. //
  194. //***************************************************************************
  195. const TCHAR * CHandleCache::sGetString(
  196. IN long int lIndex)
  197. {
  198. if(lIndex < List.Size()) {
  199. CEntry * pCurr = (CEntry *)List.GetAt(lIndex);
  200. if(pCurr)
  201. return pCurr->sPath;
  202. }
  203. return NULL;
  204. }
  205. //***************************************************************************
  206. //
  207. // CToken::CToken
  208. //
  209. // DESCRIPTION:
  210. //
  211. // constructor.
  212. //
  213. // PARAMETERS:
  214. //
  215. // cpStart String to be parsed.
  216. // cDelim Token delimeter.
  217. // bUsesEscapes If true, then need to look for special characters
  218. //
  219. //***************************************************************************
  220. #define MAX_TEMP 150
  221. CToken::CToken(
  222. IN const TCHAR * cpStart,
  223. IN const OLECHAR cDelim,
  224. bool bUsesEscapes)
  225. {
  226. const TCHAR * cpCurr; //atoi
  227. iOriginalLength = -1;
  228. TString *psExp;
  229. int iNumQuote;
  230. BOOL bLastWasEsc, bInExp, bInString;
  231. bLastWasEsc = bInExp = bInString = FALSE;
  232. // Before doing an elaborate parse, first check for the simple case where there
  233. // are no quotes, escapes, commas, etc
  234. bool bGotSpecialChar = false;
  235. for(cpCurr = cpStart; *cpCurr && *cpCurr != cDelim; cpCurr++)
  236. {
  237. if(*cpCurr == ESC || *cpCurr == '\"' || *cpCurr == '(')
  238. bGotSpecialChar = true;
  239. }
  240. if(!bUsesEscapes || cDelim != MAIN_DELIM || *cpCurr == cDelim || !bGotSpecialChar)
  241. {
  242. // Simple case do it quickly
  243. iOriginalLength = cpCurr - cpStart;
  244. if(iOriginalLength < MAX_TEMP)
  245. {
  246. TCHAR tcTemp[MAX_TEMP];
  247. lstrcpyn(tcTemp, cpStart, iOriginalLength + 1);
  248. sFullData = tcTemp;
  249. sData = tcTemp;
  250. if(*cpCurr)
  251. iOriginalLength++;
  252. return;
  253. }
  254. }
  255. for(cpCurr = cpStart; *cpCurr; cpCurr++) {
  256. // check if end of token
  257. if(*cpCurr == cDelim && !bLastWasEsc) {
  258. cpCurr++;
  259. break;
  260. }
  261. // full data stores everything. Check if character
  262. // is the escape which means that the following
  263. // character should be interpreted as a literal
  264. sFullData += *cpCurr;
  265. if(*cpCurr == ESC && !bLastWasEsc) {
  266. bLastWasEsc = TRUE;
  267. continue;
  268. }
  269. // tokens can include indexs of the form
  270. // (xxx) or ("xxx"). If an index is detected,
  271. // then store the characters between () separately
  272. if((*cpCurr == '(' && !bInExp && !bLastWasEsc)||
  273. (*cpCurr == ',' && bInExp && !bLastWasEsc)) {
  274. // start of index expression. Allocate a new
  275. // string to store it and store the string
  276. // in the expression collection.
  277. psExp = new (TString);
  278. if(psExp) {
  279. Expressions.Add((CObject *)psExp);
  280. bInExp = TRUE;
  281. iNumQuote = 0;
  282. }
  283. }
  284. else if(*cpCurr == ')' && bInExp && !bInString && !bLastWasEsc)
  285. bInExp = FALSE; // end of index expression
  286. else if (*cpCurr == '\"' && bInExp && !bLastWasEsc) {
  287. iNumQuote++;
  288. if(iNumQuote == 1) {
  289. bInString = TRUE;
  290. *psExp += *cpCurr;
  291. }
  292. else if(iNumQuote == 2)
  293. bInString = FALSE;
  294. else
  295. return;
  296. }
  297. else if (bInExp)
  298. *psExp += *cpCurr;
  299. else
  300. sData += *cpCurr;
  301. bLastWasEsc = FALSE;
  302. }
  303. if(bInString || bInExp)
  304. return; // got junk!!!
  305. iOriginalLength = cpCurr - cpStart;
  306. return;
  307. }
  308. //***************************************************************************
  309. //
  310. // CToken::~CToken
  311. //
  312. // DESCRIPTION:
  313. //
  314. // Destructor.
  315. //
  316. //***************************************************************************
  317. CToken::~CToken()
  318. {
  319. int iCnt;
  320. TString * pCurr;
  321. for (iCnt = 0; iCnt < Expressions.Size(); iCnt++) {
  322. pCurr = (TString *)Expressions.GetAt(iCnt);
  323. delete pCurr;
  324. }
  325. Expressions.Empty();
  326. sData.Empty();
  327. sFullData.Empty();
  328. }
  329. //***************************************************************************
  330. //
  331. // CToken::iConvOprand
  332. //
  333. // DESCRIPTION:
  334. //
  335. // Converts the characters in a string into an integer.
  336. //
  337. // PARAMETERS:
  338. //
  339. // tpCurr String to be converted.
  340. // iArray Not used anymore.
  341. // dwValue where the result is set.
  342. //
  343. // RETURN VALUE:
  344. //
  345. // Number of digits converted.
  346. //
  347. //***************************************************************************
  348. long int CToken::iConvOprand(
  349. IN const TCHAR * tpCurr,
  350. IN int iArray,
  351. OUT long int & dwValue)
  352. {
  353. TString sTemp;
  354. long int iRet = 0;
  355. // Build up a string containing
  356. // all characters upto the first non didgit
  357. for(;*tpCurr; tpCurr++)
  358. if(wbem_iswdigit(*tpCurr))
  359. {
  360. sTemp += *tpCurr;
  361. iRet++;
  362. }
  363. else
  364. break;
  365. // Convert and return the length
  366. dwValue = _wtoi(sTemp);
  367. return iRet;
  368. }
  369. //***************************************************************************
  370. //
  371. // CToken::GetIntExp
  372. //
  373. // DESCRIPTION:
  374. //
  375. // Converts the expression into an integer. The expression
  376. // can only be made up of integers, '+', '-' and a special
  377. // character ('#' as of now)for substituting iArray. Examples,
  378. // (23) (#+3) (#-4)
  379. //
  380. // PARAMETERS:
  381. //
  382. // iExp which integer to retrieve in the case where you have 2,5,8
  383. // iArray Not used anymore
  384. //
  385. // RETURN VALUE:
  386. //
  387. // -1 if error.
  388. //
  389. //***************************************************************************
  390. long int CToken::GetIntExp(int iExp,int iArray)
  391. {
  392. TString * psTest;
  393. TString sNoBlanks;
  394. TCHAR const * tpCurr;
  395. long int lOpSize;
  396. int iCnt;
  397. long int lAccum = 0, lOperand;
  398. TCHAR tUnary = ' ';
  399. TCHAR tBinary = '+';
  400. BOOL bNeedOperator = FALSE; // Start off needing operand
  401. // Do some intial check such as making sure the expression
  402. // exists and that it isnt a string expression
  403. if(Expressions.Size() <= iExp)
  404. return -1;
  405. if(IsExpString(iExp))
  406. return -1;
  407. psTest = (TString *)Expressions.GetAt(iExp);
  408. if(psTest == NULL) {
  409. return -1;
  410. }
  411. // Get rid of any blanks
  412. for(iCnt = 0; iCnt < psTest->Length(); iCnt++)
  413. if(psTest->GetAt(iCnt) != ' ')
  414. sNoBlanks += psTest->GetAt(iCnt);
  415. // Evalate the expression
  416. for(tpCurr = sNoBlanks; *tpCurr; tpCurr++)
  417. {
  418. if(*tpCurr == '+' || *tpCurr == '-')
  419. {
  420. // got an operator. Note that if an operator is not needed,
  421. // such as before the first operand, then it must be a unary
  422. // operator. Only one unary operator in a row is valid.
  423. if(bNeedOperator)
  424. {
  425. tBinary = *tpCurr;
  426. bNeedOperator = FALSE;
  427. }
  428. else
  429. {
  430. if(tUnary != ' ') // Gratuitous unary operator
  431. return -1;
  432. tUnary = *tpCurr;
  433. }
  434. }
  435. else
  436. {
  437. // got an operand
  438. if(bNeedOperator) // Gratuitous unary operand
  439. return -1;
  440. lOpSize = iConvOprand(tpCurr,iArray,lOperand);
  441. if(lOpSize > 1)
  442. tpCurr += lOpSize-1;
  443. if(tUnary == '-')
  444. lOperand = -lOperand;
  445. if(tBinary == '+')
  446. lAccum = lAccum + lOperand;
  447. else
  448. lAccum = lAccum - lOperand;
  449. bNeedOperator = TRUE;
  450. tUnary = ' ';
  451. }
  452. }
  453. return lAccum;
  454. }
  455. //***************************************************************************
  456. //
  457. // CToken::GetStringExp
  458. //
  459. // DESCRIPTION:
  460. //
  461. // Returns a string expression.
  462. //
  463. // PARAMETERS:
  464. //
  465. // iExp Which string to use when they are separated by commans
  466. //
  467. // RETURN VALUE:
  468. //
  469. // Pointer to string, NULL if iExp is bogus.
  470. //
  471. //***************************************************************************
  472. TCHAR const * CToken::GetStringExp(
  473. IN int iExp)
  474. {
  475. TString * psTest;
  476. TCHAR const * tp;
  477. // start by making sure expression exists.
  478. if(Expressions.Size() <= iExp)
  479. return NULL;
  480. psTest = (TString *)Expressions.GetAt(iExp);
  481. if(psTest != NULL)
  482. {
  483. int iIndex;
  484. iIndex = psTest->Find('\"');
  485. if(iIndex != -1)
  486. {
  487. // All is well. Return a pointer one passed
  488. // the initial \" whose only purpose is to
  489. // indicate that this is a string expression.
  490. tp = *psTest;
  491. return tp + iIndex + 1;
  492. }
  493. }
  494. return NULL;
  495. }
  496. //***************************************************************************
  497. //
  498. // CToken::IsExpString
  499. //
  500. // DESCRIPTION:
  501. //
  502. // Tests if the token contains a string
  503. //
  504. // PARAMETERS:
  505. //
  506. // iExp Indicates which substring for when the strings are divided
  507. // by commas
  508. //
  509. // RETURN VALUE:
  510. // Returns true if the expression is a string.
  511. //
  512. //***************************************************************************
  513. BOOL CToken::IsExpString(int iExp)
  514. {
  515. TString * psTest;
  516. // make sure that the expression exists.
  517. if(Expressions.Size() <= iExp)
  518. return FALSE;
  519. psTest = (TString *)Expressions.GetAt(iExp);
  520. if(psTest != NULL) {
  521. int iIndex;
  522. // String expressions always contain at least one \"
  523. iIndex = psTest->Find('\"');
  524. if(iIndex != -1)
  525. return TRUE;
  526. }
  527. return FALSE;
  528. }
  529. //***************************************************************************
  530. //
  531. // CProvObj::CProvObj(const char * ProviderString,const TCHAR cDelim)
  532. //
  533. // DESCRIPTION:
  534. //
  535. // Constructor.
  536. //
  537. // PARAMETERS:
  538. //
  539. // ProviderString String passed from wbem
  540. // cDelim Token delimeter
  541. // bUsesEscapes True if we need to treat escapes in a special way.
  542. //
  543. //***************************************************************************
  544. #ifndef UNICODE
  545. CProvObj::CProvObj(
  546. IN const char * ProviderString,
  547. IN const TCHAR cDelim, bool bUsesEscapes)
  548. {
  549. m_bUsesEscapes = bUsesEscapes;
  550. Init(ProviderString,cDelim);
  551. return;
  552. }
  553. #endif
  554. //***************************************************************************
  555. //
  556. // CProvObj::CProvObj(const WCHAR * ProviderString,const TCHAR cDelim)
  557. //
  558. // DESCRIPTION:
  559. //
  560. // Constructor.
  561. //
  562. // PARAMETERS:
  563. //
  564. // ProviderString String passed from wbem
  565. // cDelim Token delimeter
  566. //
  567. //***************************************************************************
  568. CProvObj::CProvObj(
  569. IN const WCHAR * ProviderString,
  570. IN const TCHAR cDelim, bool bUsesEscapes)
  571. {
  572. m_bUsesEscapes = bUsesEscapes;
  573. #ifdef UNICODE
  574. Init(ProviderString,cDelim);
  575. #else
  576. char * pTemp = WideToNarrowA(ProviderString);
  577. if(pTemp == NULL)
  578. dwStatus = WBEM_E_FAILED;
  579. else {
  580. Init(pTemp,cDelim);
  581. delete pTemp;
  582. }
  583. #endif
  584. return;
  585. }
  586. //***************************************************************************
  587. //
  588. // void CProvObj::Init
  589. //
  590. // DESCRIPTION:
  591. //
  592. // Doest the acutal work for the various constructors.
  593. //
  594. // PARAMETERS:
  595. // ProviderString String passed from wbem
  596. // cDelim Token delimeter
  597. //
  598. //***************************************************************************
  599. void CProvObj::Init(
  600. IN const TCHAR * ProviderString,
  601. IN const TCHAR cDelim)
  602. {
  603. CToken * pNewToken;
  604. const TCHAR * cpCurr;
  605. m_cDelim = cDelim;
  606. // Create a list of tokens
  607. for(cpCurr = ProviderString; *cpCurr;cpCurr+=pNewToken->GetOrigLength())
  608. {
  609. int iRet = 0;
  610. pNewToken = new CToken(cpCurr,cDelim, m_bUsesEscapes);
  611. if(pNewToken)
  612. iRet = myTokens.Add(pNewToken);
  613. if(pNewToken == NULL || iRet != CFlexArray::no_error)
  614. {
  615. dwStatus = WBEM_E_OUT_OF_MEMORY;
  616. return;
  617. }
  618. if(pNewToken->GetOrigLength() == -1)
  619. {
  620. dwStatus = WBEM_E_INVALID_PARAMETER;
  621. return;
  622. }
  623. }
  624. dwStatus = WBEM_NO_ERROR;
  625. return;
  626. }
  627. //***************************************************************************
  628. //
  629. // CProvObj::Empty
  630. //
  631. // DESCRIPTION:
  632. //
  633. // frees up all the data
  634. //
  635. //***************************************************************************
  636. void CProvObj::Empty(void)
  637. {
  638. int iCnt;
  639. CToken * pCurr;
  640. for (iCnt = 0; iCnt < myTokens.Size(); iCnt++) {
  641. pCurr = (CToken *)myTokens.GetAt(iCnt);
  642. delete pCurr;
  643. }
  644. myTokens.Empty();
  645. }
  646. //***************************************************************************
  647. //
  648. // BOOL CProvObj::Update
  649. //
  650. // DESCRIPTION:
  651. //
  652. // Resets the value with a new provider string.
  653. //
  654. // PARAMETERS:
  655. //
  656. // pwcProvider New provider string
  657. //
  658. // RETURN VALUE:
  659. //
  660. // TRUE if ok.
  661. //***************************************************************************
  662. BOOL CProvObj::Update(
  663. IN WCHAR * pwcProvider)
  664. {
  665. // Do a quick check to see if the "fast" update can be used
  666. BOOL bComplex = FALSE;
  667. int iDelim = 0;
  668. WCHAR * pwcCurr;
  669. for(pwcCurr = pwcProvider; *pwcCurr; pwcCurr++)
  670. {
  671. if(*pwcCurr == m_cDelim)
  672. iDelim++;
  673. else if(*pwcCurr == ESC || *pwcCurr == L'\"' || *pwcCurr == L'(')
  674. {
  675. bComplex = TRUE;
  676. break;
  677. }
  678. }
  679. // If the number of tokens changed, or there is some embedded junk
  680. // just empty and retry.
  681. if(bComplex || iDelim != myTokens.Size()-1)
  682. {
  683. Empty();
  684. #ifdef UNICODE
  685. Init(pwcProvider,m_cDelim);
  686. #else
  687. char * pTemp = WideToNarrowA(pwcProvider);
  688. if(pTemp == NULL)
  689. return FALSE;
  690. Init(pTemp,m_cDelim);
  691. delete pTemp;
  692. #endif
  693. return TRUE;
  694. }
  695. // We can take the shortcut. Start by creating a TCHAR temp version
  696. int iLen = 2*wcslen(pwcProvider) + 1;
  697. TCHAR * pTemp = new TCHAR[iLen];
  698. if(pTemp == NULL)
  699. return FALSE;
  700. #ifdef UNICODE
  701. StringCchCopyW(pTemp, iLen,pwcProvider);
  702. #else
  703. wcstombs(pTemp, pwcProvider, iLen);
  704. #endif
  705. TCHAR * ptcCurr;
  706. TCHAR * pStart;
  707. BOOL bTheEnd = FALSE;
  708. iDelim = 0;
  709. for(pStart = ptcCurr = pTemp;!bTheEnd;ptcCurr++)
  710. {
  711. if(*ptcCurr == m_cDelim || *ptcCurr == NULL)
  712. {
  713. bTheEnd = (*ptcCurr == NULL);
  714. *ptcCurr = NULL;
  715. CToken * pToken = (CToken *)myTokens.GetAt(iDelim);
  716. if(pToken && lstrcmpi(pStart,pToken->sFullData))
  717. {
  718. pToken->sFullData = pStart;
  719. pToken->sData = pStart;
  720. }
  721. iDelim++;
  722. pStart = ptcCurr+1;
  723. }
  724. }
  725. delete pTemp;
  726. return TRUE;
  727. }
  728. //***************************************************************************
  729. //
  730. // CProvObj::GetTokenPointer
  731. //
  732. // DESCRIPTION:
  733. //
  734. // Gets a pointer to a token
  735. //
  736. // PARAMETERS:
  737. //
  738. // iToken Which token to get
  739. //
  740. // RETURN VALUE:
  741. //
  742. // pointer to token, or NULL if bad request.
  743. //
  744. //***************************************************************************
  745. CToken * CProvObj::GetTokenPointer(
  746. IN int iToken)
  747. {
  748. if(iToken >= myTokens.Size() || iToken < 0)
  749. return NULL;
  750. return (CToken *)myTokens.GetAt(iToken);
  751. }
  752. //***************************************************************************
  753. //
  754. // CProvObj::dwGetStatus
  755. //
  756. // DESCRIPTION:
  757. //
  758. // Gets status and also checks to make sure a minimum number of tokens
  759. // exist.
  760. //
  761. // PARAMETERS:
  762. //
  763. // iMin minimum number of tokens.
  764. //
  765. // RETURN VALUE:
  766. //
  767. // Returns S_OK if OK, WBEM_E_FAILED otherwise.
  768. //
  769. //***************************************************************************
  770. DWORD CProvObj::dwGetStatus(
  771. IN int iMin)
  772. {
  773. if(dwStatus)
  774. return dwStatus;
  775. else
  776. return (iMin <= myTokens.Size()) ? S_OK : WBEM_E_FAILED;
  777. }
  778. //***************************************************************************
  779. //
  780. // CProvObj::sGetToken
  781. //
  782. // DESCRIPTION:
  783. //
  784. // Gets a token. Note that the token will not include embleded "(stuff)"
  785. //
  786. // PARAMETERS:
  787. //
  788. // iToken which token to get
  789. //
  790. // RETURN VALUE:
  791. //
  792. // pointer to token, NULL if invalid argument
  793. //***************************************************************************
  794. const TCHAR * CProvObj::sGetToken(
  795. IN int iToken)
  796. {
  797. CToken * pCurr = GetTokenPointer(iToken);
  798. return (pCurr) ? pCurr->GetStringValue() : NULL;
  799. }
  800. //***************************************************************************
  801. //
  802. // const TCHAR * CProvObj::sGetFullToken
  803. //
  804. // DESCRIPTION:
  805. //
  806. // Gets a full and unadulterated token.
  807. //
  808. // PARAMETERS:
  809. //
  810. // iToken token to get
  811. //
  812. // RETURN VALUE:
  813. //
  814. // pointer to token, NULL if invalid argument
  815. //***************************************************************************
  816. const TCHAR * CProvObj::sGetFullToken(
  817. IN int iToken)
  818. {
  819. CToken * pCurr = GetTokenPointer(iToken);
  820. return (pCurr) ? pCurr->GetFullStringValue() : NULL;
  821. }
  822. //***************************************************************************
  823. //
  824. // const TCHAR * CProvObj::sGetStringExp
  825. //
  826. // DESCRIPTION:
  827. //
  828. // Gets a substring for a particular token
  829. //
  830. // PARAMETERS:
  831. //
  832. // iToken token to get
  833. // iExp substring to get
  834. //
  835. // RETURN VALUE:
  836. //
  837. // pointer to substring, NULL if invalid argument
  838. //***************************************************************************
  839. const TCHAR * CProvObj::sGetStringExp(
  840. IN int iToken,
  841. IN int iExp)
  842. {
  843. CToken * pCurr = GetTokenPointer(iToken);
  844. return (pCurr) ? pCurr->GetStringExp(iExp) : NULL;
  845. }
  846. //***************************************************************************
  847. //
  848. // long int CProvObj::iGetIntExp
  849. //
  850. // DESCRIPTION:
  851. //
  852. // For a particular token, gets the integer value of a substring.
  853. //
  854. // PARAMETERS:
  855. //
  856. // iToken token to get
  857. // iExp substring
  858. // iArray no longer used
  859. //
  860. // RETURN VALUE:
  861. //
  862. // int value, or -1 if bad argument
  863. //***************************************************************************
  864. long int CProvObj::iGetIntExp(
  865. IN int iToken,
  866. IN int iExp,
  867. IN int iArray)
  868. {
  869. CToken * pCurr = GetTokenPointer(iToken);
  870. return (pCurr) ? pCurr->GetIntExp(iExp,iArray) : -1;
  871. }
  872. //***************************************************************************
  873. //
  874. // BOOL CProvObj::IsExpString
  875. //
  876. // DESCRIPTION:
  877. //
  878. // Tests a substring to see if it is a string, or numeric
  879. //
  880. // PARAMETERS:
  881. //
  882. // iToken token to get
  883. // iExp substring
  884. //
  885. //
  886. // RETURN VALUE:
  887. //
  888. // True if arguments are valid and it is not numeric
  889. //***************************************************************************
  890. BOOL CProvObj::IsExpString(
  891. IN int iToken,
  892. IN int iExp)
  893. {
  894. CToken * pCurr = GetTokenPointer(iToken);
  895. return (pCurr) ? pCurr->IsExpString(iExp) : FALSE;
  896. }
  897. //***************************************************************************
  898. //
  899. // long int CProvObj::iGetNumExp
  900. //
  901. // DESCRIPTION:
  902. //
  903. // Gets the number of subexpressions
  904. //
  905. // PARAMETERS:
  906. //
  907. // iToken token to check
  908. //
  909. // RETURN VALUE:
  910. //
  911. // number of substrings (subexpressions) or -1 if invalid argument
  912. //***************************************************************************
  913. long int CProvObj::iGetNumExp(
  914. IN int iToken)
  915. {
  916. CToken * pCurr = GetTokenPointer(iToken);
  917. return (pCurr) ? pCurr->GetNumExp() : -1;
  918. }
  919. //***************************************************************************
  920. //
  921. // IWbemClassObject * GetNotifyObj
  922. //
  923. // DESCRIPTION:
  924. //
  925. // This utility is useful for setting notify objects
  926. // at the end of async calls.
  927. //
  928. // PARAMETERS:
  929. //
  930. // pServices pointer back into WBEM
  931. // lRet status code to set in notify object
  932. //
  933. // RETURN VALUE:
  934. //
  935. // Class object. Null if failure.
  936. //***************************************************************************
  937. IWbemClassObject * GetNotifyObj(
  938. IN IWbemServices * pServices,
  939. IN long lRet,
  940. IN IWbemContext *pCtx)
  941. {
  942. if(pServices == NULL)
  943. return NULL;
  944. IWbemClassObject * pInst = NULL;
  945. IWbemClassObject * pClass = NULL;
  946. SCODE sc = pServices->GetObject(L"__ExtendedStatus", 0, pCtx, &pClass, NULL);
  947. if(sc != S_OK)
  948. return NULL;
  949. sc = pClass->SpawnInstance(0, &pInst);
  950. pClass->Release();
  951. if(sc == S_OK && pInst)
  952. {
  953. VARIANT v;
  954. v.vt = VT_I4;
  955. v.lVal = lRet;
  956. sc = pInst->Put(L"StatusCode", 0, &v, 0);
  957. if(sc != S_OK)
  958. {
  959. pInst->Release();
  960. return NULL;
  961. }
  962. else
  963. return pInst;
  964. }
  965. return NULL;
  966. }