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.

824 lines
18 KiB

  1. /******************************************************************
  2. ConnShare.cpp-- Implementation of base class from which ConnectionToShare
  3. ConnectionToSession and Connection classes are derived
  4. // Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved
  5. *******************************************************************/
  6. #include "precomp.h"
  7. #include "connshare.h"
  8. /*****************************************************************************
  9. *
  10. * FUNCTION : CConnShare::CConnShare
  11. *
  12. * DESCRIPTION : Constructor
  13. *
  14. *****************************************************************************/
  15. CConnShare :: CConnShare ( )
  16. {
  17. }
  18. /*****************************************************************************
  19. *
  20. * FUNCTION : CConnShare::~CConnShare
  21. *
  22. * DESCRIPTION : Destructor
  23. *
  24. *****************************************************************************/
  25. CConnShare :: ~ CConnShare ( )
  26. {
  27. }
  28. #ifdef NTONLY
  29. /*****************************************************************************
  30. *
  31. * FUNCTION : CConnShare::GetNTShares
  32. *
  33. * DESCRIPTION : Enumerates all the Shares on NT
  34. *
  35. *****************************************************************************/
  36. HRESULT CConnShare :: GetNTShares ( CHStringArray &t_Shares )
  37. {
  38. HRESULT hRes = WBEM_S_NO_ERROR;
  39. NET_API_STATUS t_Status = NERR_Success;
  40. DWORD dwNoOfEntriesRead = 0;
  41. DWORD dwTotalEntries = 0;
  42. DWORD dwResumeHandle = 0;
  43. PSHARE_INFO_0 pBuf, pTempBuf;
  44. while ( true )
  45. {
  46. t_Status = NetShareEnum (
  47. NULL, //Server
  48. 0, //level
  49. (LPBYTE *) &pBuf,
  50. -1, // Preferred Max Length
  51. &dwNoOfEntriesRead,
  52. &dwTotalEntries,
  53. &dwResumeHandle
  54. );
  55. if (( t_Status == NERR_Success ) || (t_Status == ERROR_MORE_DATA))
  56. {
  57. try
  58. {
  59. pTempBuf = pBuf;
  60. for( DWORD i = 0; i < dwNoOfEntriesRead; i++, pTempBuf++ )
  61. {
  62. t_Shares.Add ( pTempBuf->shi0_netname );
  63. }
  64. }
  65. catch ( ... )
  66. {
  67. NetApiBufferFree( pBuf );
  68. pBuf = NULL;
  69. throw;
  70. }
  71. NetApiBufferFree( pBuf );
  72. pBuf = NULL;
  73. }
  74. if ( t_Status != ERROR_MORE_DATA )
  75. {
  76. if ( t_Status == NERR_Success )
  77. {
  78. hRes = WBEM_S_NO_ERROR;
  79. }
  80. else
  81. {
  82. if ( t_Status == ERROR_ACCESS_DENIED )
  83. {
  84. hRes = WBEM_E_ACCESS_DENIED;
  85. }
  86. else
  87. {
  88. if ( t_Status == ERROR_NOT_ENOUGH_MEMORY )
  89. {
  90. hRes = WBEM_E_OUT_OF_MEMORY;
  91. }
  92. else
  93. {
  94. hRes = WBEM_E_FAILED;
  95. }
  96. }
  97. }
  98. break;
  99. }
  100. }
  101. return hRes;
  102. }
  103. /*****************************************************************************
  104. *
  105. * FUNCTION : CConnShare::FindAndSetNTConnection
  106. *
  107. * DESCRIPTION : Finds the instance and if presnt does an appropriate operation.
  108. *
  109. *****************************************************************************/
  110. HRESULT CConnShare :: FindAndSetNTConnection (
  111. LPWSTR t_ShareName,
  112. LPCWSTR t_NetName,
  113. LPCWSTR t_UserName,
  114. DWORD dwPropertiesReq,
  115. CInstance *pInstance,
  116. DWORD eOperation
  117. )
  118. {
  119. HRESULT hRes = WBEM_S_NO_ERROR;
  120. NET_API_STATUS t_Status = NERR_Success;
  121. DWORD dwNoOfEntriesRead = 0;
  122. DWORD dwTotalConnections = 0;
  123. DWORD dwResumeHandle = 0;
  124. CONNECTION_INFO *pBuf = NULL;
  125. CONNECTION_INFO *pTempBuf = NULL;
  126. while ( true )
  127. {
  128. t_Status = NetConnectionEnum(
  129. NULL,
  130. t_ShareName, // ShareName
  131. 1,
  132. (LPBYTE *) &pBuf,
  133. -1,
  134. &dwNoOfEntriesRead,
  135. &dwTotalConnections,
  136. &dwResumeHandle
  137. );
  138. if ( ( ( t_Status == NERR_Success ) && ( dwNoOfEntriesRead == 0 ) ) ||
  139. ( ( t_Status != NERR_Success ) && ( t_Status != ERROR_MORE_DATA ) ) )
  140. {
  141. hRes = WBEM_E_NOT_FOUND;
  142. break;
  143. }
  144. try
  145. {
  146. pTempBuf = pBuf;
  147. BOOL bFound = FALSE;
  148. for ( DWORD dwConnIndex = 0 ; dwConnIndex < dwNoOfEntriesRead ; dwConnIndex ++, pTempBuf++ )
  149. {
  150. if ( pTempBuf->coni1_netname &&
  151. pTempBuf->coni1_username &&
  152. ( _wcsicmp ( t_NetName, pTempBuf->coni1_netname ) == 0 ) &&
  153. ( _wcsicmp (t_UserName, pTempBuf->coni1_username ) == 0 ) )
  154. {
  155. bFound = TRUE;
  156. break ;
  157. }
  158. }
  159. if ( bFound )
  160. {
  161. // We are not to free the buff in this loop, but free it after using this buffer
  162. break;
  163. }
  164. if ( t_Status != ERROR_MORE_DATA )
  165. {
  166. hRes = WBEM_E_NOT_FOUND;
  167. NetApiBufferFree ( pBuf );
  168. pBuf = NULL;
  169. break;
  170. }
  171. }
  172. catch ( ... )
  173. {
  174. NetApiBufferFree ( pBuf );
  175. pBuf = NULL;
  176. throw;
  177. }
  178. NetApiBufferFree ( pBuf );
  179. pBuf = NULL;
  180. }
  181. if ( SUCCEEDED ( hRes ) )
  182. {
  183. try
  184. {
  185. switch ( eOperation )
  186. {
  187. case Get: hRes = LoadInstance (
  188. pInstance,
  189. t_ShareName,
  190. t_NetName,
  191. pTempBuf,
  192. dwPropertiesReq
  193. );
  194. case NoOp: break; //do nothing
  195. default: hRes = WBEM_E_INVALID_PARAMETER; break;
  196. }
  197. }
  198. catch ( ... )
  199. {
  200. NetApiBufferFree( pBuf );
  201. pBuf = NULL;
  202. throw;
  203. }
  204. NetApiBufferFree( pBuf );
  205. pBuf = NULL;
  206. }
  207. return hRes;
  208. }
  209. #endif
  210. #if 0
  211. #ifdef WIN9XONLY
  212. /*****************************************************************************
  213. *
  214. * FUNCTION : CConnShare::Get9XShares
  215. *
  216. * DESCRIPTION : Enumerates all the Shares on WIN9X
  217. *
  218. *****************************************************************************/
  219. HRESULT CConnShare :: Get9XShares ( CHStringArray &t_Shares )
  220. {
  221. HRESULT hRes = WBEM_S_NO_ERROR;
  222. DWORD t_Status = NERR_Success;
  223. DWORD dwNoOfEntriesRead = 0;
  224. DWORD dwTotalEntries = 0;
  225. struct share_info_1* pBuf = NULL;
  226. struct share_info_1* pTmpBuf = NULL;
  227. DWORD dwBufferSize = MAX_ENTRIES * sizeof( struct share_info_0 );
  228. pBuf = ( struct share_info_1 *) malloc ( dwBufferSize );
  229. if ( pBuf != NULL )
  230. {
  231. try
  232. {
  233. t_Status = NetShareEnum (
  234. NULL,
  235. 1,
  236. (char FAR *)pBuf,
  237. ( unsigned short ) dwBufferSize,
  238. ( unsigned short *) &dwNoOfEntriesRead,
  239. ( unsigned short *) &dwTotalEntries
  240. );
  241. if ( dwNoOfEntriesRead > 0 )
  242. {
  243. pTmpBuf = pBuf;
  244. CHString t_NetName;
  245. for( DWORD i = 0; i < dwNoOfEntriesRead; i++, pTmpBuf++ )
  246. {
  247. t_NetName = pTmpBuf->shi1_netname;
  248. t_Shares.Add ( t_NetName );
  249. }
  250. }
  251. }
  252. catch ( ... )
  253. {
  254. free ( pBuf );
  255. pBuf = NULL;
  256. throw;
  257. }
  258. free ( pBuf );
  259. pBuf = NULL;
  260. }
  261. else
  262. {
  263. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  264. }
  265. if ( ( dwNoOfEntriesRead < dwTotalEntries ) || ( t_Status == ERROR_MORE_DATA ) )
  266. {
  267. DWORD oldENtriesRead = dwNoOfEntriesRead;
  268. pBuf = ( struct share_info_1 *) malloc ( dwTotalEntries );
  269. if ( pBuf != NULL )
  270. {
  271. try
  272. {
  273. t_Status = NetShareEnum (
  274. NULL,
  275. 1,
  276. (char FAR *)pBuf,
  277. ( unsigned short ) dwBufferSize,
  278. ( unsigned short *) &dwNoOfEntriesRead,
  279. ( unsigned short *) &dwTotalEntries
  280. );
  281. if ( t_Status == NERR_Success )
  282. {
  283. pTmpBuf = pBuf;
  284. CHString t_NetName;
  285. for( DWORD i = oldENtriesRead; i < dwNoOfEntriesRead; i++, pTmpBuf )
  286. {
  287. t_NetName = pTmpBuf->shi1_netname;
  288. t_Shares.Add ( t_NetName );
  289. }
  290. }
  291. else
  292. {
  293. hRes = WBEM_E_FAILED;
  294. }
  295. }
  296. catch ( ... )
  297. {
  298. free ( pBuf );
  299. pBuf = NULL;
  300. throw;
  301. }
  302. free ( pBuf );
  303. pBuf = NULL;
  304. }
  305. else
  306. {
  307. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  308. }
  309. }
  310. return hRes;
  311. }
  312. /*****************************************************************************
  313. *
  314. * FUNCTION : CConnShare::FindAndSet9XConnection
  315. *
  316. * DESCRIPTION : Finds the instance and if presnt does an appropriate operation.
  317. *
  318. *****************************************************************************/
  319. HRESULT CConnShare :: FindAndSet9XConnection (
  320. LPWSTR t_ShareName,
  321. LPCWSTR t_NetName,
  322. LPCWSTR t_UserName,
  323. DWORD dwPropertiesReq,
  324. CInstance *pInstance,
  325. DWORD eOperation
  326. )
  327. {
  328. HRESULT hRes = WBEM_S_NO_ERROR;
  329. NET_API_STATUS t_Status = NERR_Success;
  330. DWORD dwNoOfEntriesRead = 0;
  331. DWORD dwTotalConnections = 0;
  332. BOOL bFound = FALSE;
  333. CONNECTION_INFO * pBuf = NULL;
  334. CONNECTION_INFO * pTmpBuf = NULL;
  335. DWORD dwBufferSize = MAX_ENTRIES * sizeof( CONNECTION_INFO );
  336. pBuf = ( CONNECTION_INFO *) malloc(dwBufferSize);
  337. if ( pBuf != NULL )
  338. {
  339. try
  340. {
  341. t_Status = NetConnectionEnum(
  342. NULL,
  343. (char FAR *) ( t_ShareName ), // ShareName
  344. 1,
  345. (char *) pBuf,
  346. ( unsigned short )dwBufferSize,
  347. ( unsigned short *) &dwNoOfEntriesRead,
  348. ( unsigned short *) &dwTotalConnections
  349. );
  350. if ( dwNoOfEntriesRead > 0 )
  351. {
  352. pTmpBuf = pBuf;
  353. CHString t_TempNetNameStr, t_UserName ;
  354. for ( DWORD dwConnIndex = 0 ; dwConnIndex < dwNoOfEntriesRead ; dwConnIndex ++, pTmpBuf++ )
  355. {
  356. t_TempNetNameStr = pTmpBuf->coni1_netname;
  357. t_UserName = pTmpBuf->coni1_username;
  358. if ( ( _wcsicmp ( t_NetName, t_TempNetNameStr ) == 0 ) &&
  359. ( t_UserName.CompareNoCase ( t_UserName ) == 0 ) )
  360. {
  361. bFound = TRUE;
  362. break ;
  363. }
  364. }
  365. }
  366. }
  367. catch ( ... )
  368. {
  369. free ( pBuf );
  370. pBuf = NULL;
  371. throw;
  372. }
  373. if ( bFound == FALSE )
  374. {
  375. // if found is TRUE pBuf is not to be freed since the found entry is yet to be used
  376. free ( pBuf );
  377. pBuf = NULL;
  378. }
  379. }
  380. else
  381. {
  382. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  383. }
  384. if ( ! bFound && ( dwNoOfEntriesRead < dwTotalConnections ) && ( t_Status == ERROR_MORE_DATA ) )
  385. {
  386. DWORD dwOldNoOfEntries = dwNoOfEntriesRead;
  387. dwBufferSize = dwTotalConnections * sizeof( CONNECTION_INFO );
  388. pBuf = ( CONNECTION_INFO *) malloc(dwBufferSize);
  389. if ( pBuf != NULL )
  390. {
  391. try
  392. {
  393. t_Status = NetConnectionEnum(
  394. NULL,
  395. (char FAR *) ( t_ShareName ), // ShareName
  396. 1,
  397. (char *) pBuf,
  398. ( unsigned short )dwBufferSize,
  399. ( unsigned short *) &dwNoOfEntriesRead,
  400. ( unsigned short *) &dwTotalConnections
  401. );
  402. if ( dwNoOfEntriesRead > 0 )
  403. {
  404. pTmpBuf = pBuf;
  405. CHString t_TempNetNameStr, t_UserName;
  406. for ( DWORD dwConnIndex = dwOldNoOfEntries ; dwConnIndex < dwNoOfEntriesRead ; dwConnIndex ++, pTmpBuf++ )
  407. {
  408. t_TempNetNameStr = pTmpBuf->coni1_netname;
  409. t_UserName = pTmpBuf->coni1_username;
  410. if ( ( _wcsicmp ( t_NetName, t_TempNetNameStr ) == 0 ) &&
  411. ( _wcsicmp (t_UserName, t_UserName ) == 0 ) )
  412. {
  413. bFound = TRUE;
  414. break ;
  415. }
  416. }
  417. }
  418. }
  419. catch ( ... )
  420. {
  421. free ( pBuf );
  422. pBuf = NULL;
  423. throw;
  424. }
  425. if ( ! bFound )
  426. {
  427. // Free the buffer only if not found, otherwise it needs to be freed after using this found entry
  428. free ( pBuf );
  429. pBuf = NULL;
  430. }
  431. }
  432. else
  433. {
  434. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  435. }
  436. }
  437. if ( bFound == FALSE )
  438. {
  439. hRes = WBEM_E_NOT_FOUND;
  440. }
  441. if ( SUCCEEDED ( hRes ) )
  442. {
  443. try
  444. {
  445. switch ( eOperation )
  446. {
  447. case Get: hRes = LoadInstance (
  448. pInstance,
  449. t_ShareName,
  450. t_NetName,
  451. pTmpBuf,
  452. dwPropertiesReq
  453. );
  454. case NoOp: break; //do nothing
  455. default: hRes = WBEM_E_INVALID_PARAMETER; break;
  456. }
  457. }
  458. catch ( ... )
  459. {
  460. free( pBuf );
  461. pBuf = NULL;
  462. throw;
  463. }
  464. free( pBuf );
  465. pBuf = NULL;
  466. }
  467. return hRes;
  468. }
  469. #endif
  470. #endif // #if 0
  471. /*****************************************************************************
  472. *
  473. * FUNCTION : CConnShare::EnumConnectionInfo
  474. *
  475. * DESCRIPTION : Enumerates all the NT connections information
  476. *
  477. *****************************************************************************/
  478. HRESULT CConnShare :: EnumConnectionInfo (
  479. LPWSTR a_ComputerName,
  480. LPWSTR a_ShareName,
  481. MethodContext *pMethodContext,
  482. DWORD dwPropertiesReq
  483. )
  484. {
  485. HRESULT hRes = WBEM_S_NO_ERROR;
  486. if ( ( a_ComputerName[0] != L'\0' ) || ( a_ShareName[0] != L'\0' ) )
  487. {
  488. #ifdef NTONLY
  489. hRes = EnumNTConnectionsFromComputerToShare (
  490. a_ComputerName,
  491. a_ShareName,
  492. pMethodContext,
  493. dwPropertiesReq
  494. );
  495. #endif
  496. #if 0
  497. #ifdef WIN9XONLY
  498. hRes = Enum9XConnectionsFromComputerToShare (
  499. a_ComputerName,
  500. a_ShareName,
  501. pMethodContext,
  502. dwPropertiesReq
  503. );
  504. #endif
  505. #endif // #if 0
  506. }
  507. else
  508. if ( ( a_ComputerName[0] == L'\0' ) && ( a_ShareName[0] == L'\0' ) )
  509. {
  510. CHStringArray t_Shares;
  511. #ifdef NTONLY
  512. hRes = GetNTShares ( t_Shares );
  513. #endif
  514. #if 0
  515. #ifdef WIN9XONLY
  516. hRes = Get9XShares ( t_Shares );
  517. #endif
  518. #endif // #if 0
  519. if ( SUCCEEDED ( hRes ) )
  520. {
  521. for ( int i = 0; i < t_Shares.GetSize() ; i++ )
  522. {
  523. #ifdef NTONLY
  524. hRes = EnumNTConnectionsFromComputerToShare (
  525. a_ComputerName,
  526. t_Shares.GetAt ( i ).GetBuffer(0),
  527. pMethodContext,
  528. dwPropertiesReq
  529. );
  530. #endif
  531. #if 0
  532. #ifdef WIN9XONLY
  533. hRes = Enum9XConnectionsFromComputerToShare (
  534. a_ComputerName,
  535. t_Shares.GetAt ( i ),
  536. pMethodContext,
  537. dwPropertiesReq
  538. );
  539. #endif
  540. #endif // #if 0
  541. }
  542. }
  543. }
  544. return hRes;;
  545. }
  546. /*****************************************************************************
  547. *
  548. * FUNCTION : CConnShare::GetConnectionsKeyVal
  549. *
  550. * DESCRIPTION : Parsing the key to get Connection Key Value
  551. *
  552. *****************************************************************************/
  553. HRESULT CConnShare::GetConnectionsKeyVal (
  554. LPCWSTR a_Key,
  555. CHString &a_ComputerName,
  556. CHString &a_ShareName,
  557. CHString &a_UserName
  558. )
  559. {
  560. HRESULT hRes = WBEM_S_NO_ERROR;
  561. ParsedObjectPath *t_ObjPath;
  562. CObjectPathParser t_PathParser;
  563. DWORD dwAllKeys = 0;
  564. if ( t_PathParser.Parse( a_Key, &t_ObjPath ) == t_PathParser.NoError )
  565. {
  566. try
  567. {
  568. hRes = t_ObjPath->m_dwNumKeys != 3 ? WBEM_E_INVALID_PARAMETER : hRes;
  569. if ( SUCCEEDED ( hRes ) )
  570. {
  571. hRes = (t_ObjPath->m_pClass) && _wcsicmp ( t_ObjPath->m_pClass, PROVIDER_NAME_CONNECTION ) == 0 ? WBEM_S_NO_ERROR: WBEM_E_INVALID_PARAMETER;
  572. if ( SUCCEEDED ( hRes ) )
  573. {
  574. for ( int i = 0; i < 3; i++ )
  575. {
  576. if (V_VT(&t_ObjPath->m_paKeys[i]->m_vValue) == VT_BSTR)
  577. {
  578. if ( _wcsicmp ( t_ObjPath->m_paKeys[i]->m_pName, IDS_ComputerName ) == 0 )
  579. {
  580. a_ComputerName = t_ObjPath->m_paKeys[i]->m_vValue.bstrVal;
  581. dwAllKeys |= 1;
  582. }
  583. else
  584. if ( _wcsicmp ( t_ObjPath->m_paKeys[i]->m_pName, IDS_ShareName ) == 0 )
  585. {
  586. a_ShareName = t_ObjPath->m_paKeys[i]->m_vValue.bstrVal;
  587. dwAllKeys |= 2;
  588. }
  589. if ( _wcsicmp ( t_ObjPath->m_paKeys[i]->m_pName, IDS_UserName ) == 0 )
  590. {
  591. a_UserName = t_ObjPath->m_paKeys[i]->m_vValue.bstrVal;
  592. dwAllKeys |= 4;
  593. }
  594. }
  595. else
  596. {
  597. break;
  598. }
  599. }
  600. if ( dwAllKeys != 7 )
  601. {
  602. hRes = WBEM_E_INVALID_PARAMETER;
  603. }
  604. }
  605. else
  606. {
  607. hRes = WBEM_E_INVALID_PARAMETER;
  608. }
  609. }
  610. }
  611. catch ( ... )
  612. {
  613. delete t_ObjPath;
  614. throw;
  615. }
  616. delete t_ObjPath;
  617. }
  618. else
  619. {
  620. hRes = WBEM_E_INVALID_PARAMETER;
  621. }
  622. return hRes;
  623. }
  624. /*****************************************************************************
  625. *
  626. * FUNCTION : CConnShare::MakeObjectPath
  627. *
  628. * DESCRIPTION : Makes the Object Path Given given a class name, a key Name
  629. * and a key value
  630. *
  631. *****************************************************************************/
  632. HRESULT CConnShare::MakeObjectPath (
  633. LPWSTR &a_ObjPathString,
  634. LPCWSTR a_ClassName,
  635. LPCWSTR a_AttributeName,
  636. LPCWSTR a_AttributeVal
  637. )
  638. {
  639. HRESULT hRes = WBEM_S_NO_ERROR;
  640. ParsedObjectPath t_ObjPath;
  641. variant_t t_Path;
  642. t_Path = a_AttributeVal;
  643. hRes = t_ObjPath.SetClassName ( a_ClassName ) ? hRes : WBEM_E_INVALID_PARAMETER;
  644. if ( SUCCEEDED ( hRes ) )
  645. {
  646. hRes = t_ObjPath.AddKeyRef ( a_AttributeName, &t_Path ) ? hRes : WBEM_E_INVALID_PARAMETER;
  647. }
  648. if ( SUCCEEDED ( hRes ) )
  649. {
  650. CObjectPathParser t_PathParser;
  651. hRes = t_PathParser.Unparse( &t_ObjPath, &a_ObjPathString ) == t_PathParser.NoError ? hRes : WBEM_E_INVALID_PARAMETER;
  652. }
  653. return hRes;
  654. }
  655. /*****************************************************************************
  656. *
  657. * FUNCTION : CConnShare::AddToObjectPath
  658. *
  659. * DESCRIPTION : Adds a key name and a value to the existing Object path
  660. *
  661. *****************************************************************************/
  662. HRESULT CConnShare::AddToObjectPath (
  663. LPWSTR &a_ObjPathString,
  664. LPCWSTR a_AttributeName,
  665. LPCWSTR a_AttributeVal
  666. )
  667. {
  668. HRESULT hRes = WBEM_S_NO_ERROR;
  669. ParsedObjectPath *t_ObjPath;
  670. variant_t t_Path;
  671. CObjectPathParser t_PathParser;
  672. if ( t_PathParser.Parse( a_ObjPathString, &t_ObjPath ) == t_PathParser.NoError )
  673. {
  674. try
  675. {
  676. t_Path = a_AttributeVal;
  677. if ( t_ObjPath->AddKeyRef ( a_AttributeName, &t_Path ) )
  678. {
  679. // delete the oldpath string
  680. if ( a_ObjPathString != NULL )
  681. {
  682. delete [] a_ObjPathString;
  683. a_ObjPathString = NULL;
  684. }
  685. }
  686. else
  687. {
  688. hRes = WBEM_E_INVALID_PARAMETER;
  689. }
  690. hRes = t_PathParser.Unparse( t_ObjPath, &a_ObjPathString ) == t_PathParser.NoError ? hRes : WBEM_E_INVALID_PARAMETER;
  691. }
  692. catch ( ... )
  693. {
  694. delete t_ObjPath;
  695. throw;
  696. }
  697. delete t_ObjPath;
  698. }
  699. else
  700. {
  701. hRes = WBEM_E_INVALID_PARAMETER;
  702. }
  703. return hRes;
  704. }