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.

1058 lines
27 KiB

  1. ////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997 Microsoft Corporation
  4. //
  5. // Module Name: certmap.cpp
  6. //
  7. // Abstract: IIS privider cert mapper object methods
  8. //
  9. // Author: Philippe Choquier (phillich) 10-Apr-1997
  10. //
  11. // History: Zeyong Xu borrowed the source code from ADSI object
  12. // (created by Philippe Choquier at 10-Apr-1997) at 20-Oct-1999
  13. //
  14. ///////////////////////////////////////////////////
  15. #include "iisprov.h"
  16. //
  17. // CCertMapperMethod
  18. //
  19. CCertMapperMethod::CCertMapperMethod(LPCWSTR pszMetabasePathIn)
  20. {
  21. m_hmd = NULL;
  22. HRESULT hr = CoCreateInstance(
  23. CLSID_MSAdminBase,
  24. NULL,
  25. CLSCTX_ALL,
  26. IID_IMSAdminBase,
  27. (void**)&m_pIABase
  28. );
  29. THROW_ON_ERROR(hr);
  30. Init(pszMetabasePathIn);
  31. }
  32. CCertMapperMethod::~CCertMapperMethod()
  33. {
  34. if ( m_pszMetabasePath )
  35. {
  36. free( m_pszMetabasePath );
  37. }
  38. if(m_pIABase)
  39. m_pIABase->Release();
  40. }
  41. //
  42. // CreateMapping(): Create a mapping entry
  43. //
  44. // Arguments:
  45. //
  46. // vCert - X.509 certificate
  47. // bstrNtAcct - NT acct to map to
  48. // bstrNtPwd - NT pwd
  49. // bstrName - friendly name for mapping entry
  50. // lEnabled - 1 to enable mapping entry, 0 to disable it
  51. //
  52. HRESULT
  53. CCertMapperMethod::CreateMapping(
  54. VARIANT vCert,
  55. BSTR bstrNtAcct,
  56. BSTR bstrNtPwd,
  57. BSTR bstrName,
  58. LONG lEnabled
  59. )
  60. {
  61. HRESULT hr;
  62. LPBYTE pbCert = NULL;
  63. DWORD cCert;
  64. LPSTR pszNtAcct = NULL;
  65. LPSTR pszNtPwd = NULL;
  66. LPSTR pszName = NULL;
  67. LPBYTE pRes;
  68. DWORD cRes;
  69. DWORD cName;
  70. DWORD cNtAcct;
  71. DWORD cNtPwd;
  72. WCHAR achIndex[32];
  73. VARIANT vOldAcct;
  74. VARIANT vOldCert;
  75. VARIANT vOldPwd;
  76. VARIANT vOldName;
  77. VARIANT vOldEnabledFlag;
  78. PCCERT_CONTEXT pcCert = NULL;
  79. //
  80. // Do some sanity checks on the cert
  81. //
  82. if ( SUCCEEDED( hr = GetStringFromVariant( &vCert,
  83. (LPSTR*)&pbCert,
  84. &cCert,
  85. FALSE ) ) )
  86. {
  87. //
  88. // try to construct a cert context
  89. //
  90. if ( !( pcCert = CertCreateCertificateContext( X509_ASN_ENCODING,
  91. pbCert,
  92. cCert ) ) )
  93. {
  94. //
  95. // If the decoding fails, GetLastError() returns an ASN1 decoding
  96. // error that is obtained by subtracting CRYPT_E_OSS_ERROR from the returned
  97. // error and looking in file asn1code.h for the actual error. To avoid the
  98. // cryptic ASN1 errors, we'll just return a general "invalid arg" error
  99. //
  100. hr = RETURNCODETOHRESULT( E_INVALIDARG );
  101. FreeString( (LPSTR) pbCert );
  102. return hr;
  103. }
  104. CertFreeCertificateContext( pcCert );
  105. }
  106. else
  107. {
  108. return hr;
  109. }
  110. //
  111. // check if we already have a mapping for this cert; if we do, we'll replace that mapping
  112. // with the new one
  113. //
  114. if ( SUCCEEDED( hr = GetMapping( IISMAPPER_LOCATE_BY_CERT,
  115. vCert,
  116. &vOldCert,
  117. &vOldAcct,
  118. &vOldPwd,
  119. &vOldName,
  120. &vOldEnabledFlag ) ) )
  121. {
  122. if ( FAILED( hr = SetName( IISMAPPER_LOCATE_BY_CERT,
  123. vCert,
  124. bstrName ) ) ||
  125. FAILED( hr = SetAcct( IISMAPPER_LOCATE_BY_CERT,
  126. vCert,
  127. bstrNtAcct ) ) ||
  128. FAILED( hr = SetPwd( IISMAPPER_LOCATE_BY_CERT,
  129. vCert,
  130. bstrNtPwd ) ) ||
  131. FAILED( hr = SetEnabled( IISMAPPER_LOCATE_BY_CERT,
  132. vCert,
  133. lEnabled ) ) )
  134. {
  135. hr; //NOP - Something failed
  136. }
  137. }
  138. //
  139. // New mapping
  140. //
  141. else if ( hr == RETURNCODETOHRESULT( ERROR_PATH_NOT_FOUND ) )
  142. {
  143. //
  144. // check mapping exists, create if not
  145. //
  146. hr = OpenMd( L"Cert11", METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ );
  147. if ( hr == RETURNCODETOHRESULT( ERROR_PATH_NOT_FOUND ) )
  148. {
  149. if ( SUCCEEDED( hr = OpenMd( L"",
  150. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  151. {
  152. hr = CreateMdObject( L"Cert11" );
  153. CloseMd( FALSE );
  154. // Reopen to the correct node.
  155. hr = OpenMd( L"Cert11", METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ );
  156. }
  157. }
  158. if ( FAILED( hr ) )
  159. {
  160. return hr;
  161. }
  162. //
  163. // adding mapping cert "0" means add @ end of list
  164. //
  165. if ( SUCCEEDED( hr = CreateMdObject( L"mappings/0" ) ) )
  166. {
  167. if ( SUCCEEDED( hr = GetMdData( L"", MD_NSEPM_ACCESS_CERT, DWORD_METADATA, &
  168. cRes, &pRes ) ) )
  169. {
  170. if ( cRes == sizeof(DWORD ) )
  171. {
  172. wsprintfW( achIndex, L"mappings/%u", *(LPDWORD)pRes );
  173. if ( FAILED( hr = GetStringFromBSTR( bstrNtAcct, &pszNtAcct, &cNtAcct ) ) ||
  174. FAILED( hr = GetStringFromBSTR( bstrNtPwd, &pszNtPwd, &cNtPwd ) ) ||
  175. FAILED( hr = GetStringFromBSTR( bstrName, &pszName, &cName ) ) ||
  176. FAILED( hr = SetMdData( achIndex, MD_MAPENABLED, DWORD_METADATA,
  177. sizeof(DWORD), (LPBYTE)&lEnabled ) ) ||
  178. FAILED( hr = SetMdData( achIndex, MD_MAPNAME, STRING_METADATA,
  179. cName, (LPBYTE)pszName ) ) ||
  180. FAILED( hr = SetMdData( achIndex, MD_MAPNTPWD, STRING_METADATA,
  181. cNtPwd, (LPBYTE)pszNtPwd ) ) ||
  182. FAILED( hr = SetMdData( achIndex, MD_MAPNTACCT, STRING_METADATA,
  183. cNtAcct, (LPBYTE)pszNtAcct ) ) ||
  184. FAILED( hr = SetMdData( achIndex, MD_MAPCERT, BINARY_METADATA,
  185. cCert, (LPBYTE)pbCert ) ) )
  186. {
  187. }
  188. }
  189. else
  190. {
  191. hr = E_FAIL;
  192. }
  193. }
  194. }
  195. }
  196. CloseMd( SUCCEEDED( hr ) );
  197. FreeString( (LPSTR)pbCert );
  198. FreeString( pszNtAcct );
  199. FreeString( pszNtPwd );
  200. FreeString( pszName );
  201. return hr;
  202. }
  203. //
  204. // GetMapping: Get a mapping entry using key
  205. //
  206. // Arguments:
  207. //
  208. // lMethod - method to use for access ( IISMAPPER_LOCATE_BY_* )
  209. // vKey - key to use to locate mapping
  210. // pvCert - X.509 certificate
  211. // pbstrNtAcct - NT acct to map to
  212. // pbstrNtPwd - NT pwd
  213. // pbstrName - friendly name for mapping entry
  214. // plEnabled - 1 to enable mapping entry, 0 to disable it
  215. //
  216. HRESULT
  217. CCertMapperMethod::GetMapping(
  218. LONG lMethod,
  219. VARIANT vKey,
  220. VARIANT* pvCert,
  221. VARIANT* pbstrNtAcct,
  222. VARIANT* pbstrNtPwd,
  223. VARIANT* pbstrName,
  224. VARIANT* plEnabled
  225. )
  226. {
  227. WCHAR achIndex[32];
  228. HRESULT hr;
  229. DWORD dwLen;
  230. LPBYTE pbData;
  231. VariantInit( pvCert );
  232. VariantInit( pbstrNtAcct );
  233. VariantInit( pbstrNtPwd );
  234. VariantInit( pbstrName );
  235. VariantInit( plEnabled );
  236. if ( SUCCEEDED( hr = OpenMd( L"Cert11",
  237. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  238. {
  239. if ( SUCCEEDED(hr = Locate( lMethod, vKey, achIndex )) )
  240. {
  241. if ( SUCCEEDED( hr = GetMdData( achIndex, MD_MAPCERT, BINARY_METADATA, &dwLen,
  242. &pbData ) ) )
  243. {
  244. hr = SetVariantAsByteArray( pvCert, dwLen, pbData );
  245. free( pbData );
  246. }
  247. else
  248. {
  249. CloseMd( FALSE );
  250. return hr;
  251. }
  252. if ( SUCCEEDED( hr = GetMdData( achIndex, MD_MAPNTACCT, STRING_METADATA, &dwLen,
  253. &pbData ) ) )
  254. {
  255. hr = SetVariantAsBSTR( pbstrNtAcct, dwLen, pbData );
  256. free( pbData );
  257. }
  258. else
  259. {
  260. CloseMd( FALSE );
  261. return hr;
  262. }
  263. if ( SUCCEEDED( hr = GetMdData( achIndex, MD_MAPNTPWD, STRING_METADATA, &dwLen,
  264. &pbData ) ) )
  265. {
  266. hr = SetVariantAsBSTR( pbstrNtPwd, dwLen, pbData );
  267. free( pbData );
  268. }
  269. else
  270. {
  271. CloseMd( FALSE );
  272. return hr;
  273. }
  274. if ( SUCCEEDED( hr = GetMdData( achIndex, MD_MAPNAME, STRING_METADATA, &dwLen,
  275. &pbData ) ) )
  276. {
  277. hr = SetVariantAsBSTR( pbstrName, dwLen, pbData );
  278. free( pbData );
  279. }
  280. else
  281. {
  282. CloseMd( FALSE );
  283. return hr;
  284. }
  285. if ( FAILED( hr = GetMdData( achIndex, MD_MAPENABLED, STRING_METADATA, &dwLen,
  286. &pbData ) ) )
  287. {
  288. SetVariantAsLong( plEnabled, FALSE );
  289. }
  290. else
  291. {
  292. SetVariantAsLong( plEnabled, *(LPDWORD)pbData );
  293. free( pbData );
  294. }
  295. }
  296. CloseMd( FALSE );
  297. }
  298. return hr;
  299. }
  300. //
  301. // Delete a mapping entry using key
  302. //
  303. HRESULT
  304. CCertMapperMethod::DeleteMapping(
  305. LONG lMethod,
  306. VARIANT vKey
  307. )
  308. {
  309. WCHAR achIndex[32];
  310. HRESULT hr;
  311. if ( SUCCEEDED( hr = OpenMd( L"Cert11",
  312. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  313. {
  314. if ( SUCCEEDED(hr = Locate( lMethod, vKey, achIndex )) )
  315. {
  316. hr = DeleteMdObject( achIndex );
  317. }
  318. CloseMd( TRUE );
  319. }
  320. return hr;
  321. }
  322. //
  323. // Set the enable flag on a mapping entry using key
  324. //
  325. HRESULT
  326. CCertMapperMethod::SetEnabled(
  327. LONG lMethod,
  328. VARIANT vKey,
  329. LONG lEnabled
  330. )
  331. {
  332. WCHAR achIndex[32];
  333. HRESULT hr;
  334. if ( SUCCEEDED( hr = OpenMd( L"Cert11",
  335. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  336. {
  337. if ( SUCCEEDED(hr = Locate( lMethod, vKey, achIndex )) )
  338. {
  339. hr = SetMdData( achIndex, MD_MAPENABLED, DWORD_METADATA, sizeof(DWORD), (LPBYTE)&lEnabled );
  340. }
  341. CloseMd( TRUE );
  342. }
  343. return hr;
  344. }
  345. //
  346. // Set the Name on a mapping entry using key
  347. //
  348. HRESULT CCertMapperMethod::SetName(
  349. LONG lMethod,
  350. VARIANT vKey,
  351. BSTR bstrName
  352. )
  353. {
  354. return SetString( lMethod, vKey, bstrName, MD_MAPNAME );
  355. }
  356. //
  357. // Set a string property on a mapping entry using key
  358. //
  359. HRESULT CCertMapperMethod::SetString(
  360. LONG lMethod,
  361. VARIANT vKey,
  362. BSTR bstrName,
  363. DWORD dwProp
  364. )
  365. {
  366. WCHAR achIndex[32];
  367. LPSTR pszName = NULL;
  368. HRESULT hr;
  369. DWORD dwLen;
  370. if ( FAILED( hr = GetStringFromBSTR( bstrName, &pszName, &dwLen, TRUE ) ) )
  371. {
  372. return hr;
  373. }
  374. if ( SUCCEEDED( hr = OpenMd( L"Cert11",
  375. METADATA_PERMISSION_WRITE|METADATA_PERMISSION_READ ) ) )
  376. {
  377. if ( SUCCEEDED(hr = Locate( lMethod, vKey, achIndex )) )
  378. {
  379. hr = SetMdData( achIndex, dwProp, STRING_METADATA, dwLen, (LPBYTE)pszName );
  380. }
  381. CloseMd( TRUE );
  382. }
  383. FreeString( pszName );
  384. return hr;
  385. }
  386. //
  387. // Set the Password on a mapping entry using key
  388. //
  389. HRESULT
  390. CCertMapperMethod::SetPwd(
  391. LONG lMethod,
  392. VARIANT vKey,
  393. BSTR bstrPwd
  394. )
  395. {
  396. return SetString( lMethod, vKey, bstrPwd, MD_MAPNTPWD );
  397. }
  398. //
  399. // Set the NT account name on a mapping entry using key
  400. //
  401. HRESULT
  402. CCertMapperMethod::SetAcct(
  403. LONG lMethod,
  404. VARIANT vKey,
  405. BSTR bstrAcct
  406. )
  407. {
  408. return SetString( lMethod, vKey, bstrAcct, MD_MAPNTACCT );
  409. }
  410. HRESULT
  411. CCertMapperMethod::OpenMd(
  412. LPWSTR pszOpenPath,
  413. DWORD dwPermission
  414. )
  415. {
  416. HRESULT hr;
  417. LPWSTR pszPath;
  418. UINT cL = wcslen( m_pszMetabasePath );
  419. pszPath = (LPWSTR)malloc( (wcslen(pszOpenPath) + 1 + cL + 1)*sizeof(WCHAR) );
  420. if ( pszPath == NULL )
  421. {
  422. return E_OUTOFMEMORY;
  423. }
  424. memcpy( pszPath, m_pszMetabasePath, cL * sizeof(WCHAR) );
  425. if ( cL && m_pszMetabasePath[cL-1] != L'/' && *pszOpenPath && *pszOpenPath != L'/' )
  426. {
  427. pszPath[cL++] = L'/';
  428. }
  429. wcscpy( pszPath + cL, pszOpenPath );
  430. hr = OpenAdminBaseKey(
  431. pszPath,
  432. dwPermission
  433. );
  434. free( pszPath );
  435. return hr;
  436. }
  437. HRESULT
  438. CCertMapperMethod::CloseMd(
  439. BOOL fSave
  440. )
  441. {
  442. CloseAdminBaseKey();
  443. m_hmd = NULL;
  444. if ( m_pIABase && fSave )
  445. {
  446. m_pIABase->SaveData();
  447. }
  448. return S_OK;
  449. }
  450. HRESULT
  451. CCertMapperMethod::DeleteMdObject(
  452. LPWSTR pszKey
  453. )
  454. {
  455. return m_pIABase->DeleteKey( m_hmd, pszKey );
  456. }
  457. HRESULT
  458. CCertMapperMethod::CreateMdObject(
  459. LPWSTR pszKey
  460. )
  461. {
  462. return m_pIABase->AddKey( m_hmd, pszKey );
  463. }
  464. HRESULT
  465. CCertMapperMethod::SetMdData(
  466. LPWSTR achIndex,
  467. DWORD dwProp,
  468. DWORD dwDataType,
  469. DWORD dwDataLen,
  470. LPBYTE pbData
  471. )
  472. {
  473. METADATA_RECORD md;
  474. md.dwMDDataLen = dwDataLen;
  475. md.dwMDDataType = dwDataType;
  476. md.dwMDIdentifier = dwProp;
  477. md.dwMDAttributes = (dwProp == MD_MAPPWD) ? METADATA_SECURE : 0;
  478. md.pbMDData = pbData;
  479. return m_pIABase->SetData( m_hmd, achIndex, &md );
  480. }
  481. HRESULT
  482. CCertMapperMethod::GetMdData(
  483. LPWSTR achIndex,
  484. DWORD dwProp,
  485. DWORD dwDataType,
  486. LPDWORD pdwDataLen,
  487. LPBYTE* ppbData
  488. )
  489. {
  490. HRESULT hr;
  491. METADATA_RECORD md;
  492. DWORD dwRequired;
  493. md.dwMDDataLen = 0;
  494. md.dwMDDataType = dwDataType;
  495. md.dwMDIdentifier = dwProp;
  496. md.dwMDAttributes = 0;
  497. md.pbMDData = NULL;
  498. if ( FAILED(hr = m_pIABase->GetData( m_hmd, achIndex, &md, &dwRequired )) )
  499. {
  500. if ( hr == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER) )
  501. {
  502. if ( (*ppbData = (LPBYTE)malloc(dwRequired)) == NULL )
  503. {
  504. return E_OUTOFMEMORY;
  505. }
  506. md.pbMDData = *ppbData;
  507. md.dwMDDataLen = dwRequired;
  508. hr = m_pIABase->GetData( m_hmd, achIndex, &md, &dwRequired );
  509. *pdwDataLen = md.dwMDDataLen;
  510. }
  511. }
  512. else
  513. {
  514. *pdwDataLen = 0;
  515. *ppbData = NULL;
  516. }
  517. return hr;
  518. }
  519. //
  520. // Locate a mapping entry based on key
  521. // OpenMd() must be called 1st
  522. //
  523. HRESULT
  524. CCertMapperMethod::Locate(
  525. LONG lMethod,
  526. VARIANT vKey,
  527. LPWSTR pszResKey
  528. )
  529. {
  530. HRESULT hr;
  531. LPSTR pV = NULL;
  532. DWORD cV;
  533. DWORD dwProp;
  534. LPSTR pRes;
  535. DWORD cRes;
  536. BOOL fAddDelim = TRUE;
  537. //
  538. // determine method
  539. //
  540. switch ( lMethod )
  541. {
  542. case IISMAPPER_LOCATE_BY_CERT:
  543. dwProp = MD_NSEPM_ACCESS_CERT;
  544. fAddDelim = FALSE;
  545. break;
  546. case IISMAPPER_LOCATE_BY_NAME:
  547. dwProp = MD_NSEPM_ACCESS_NAME;
  548. break;
  549. case IISMAPPER_LOCATE_BY_ACCT:
  550. dwProp = MD_NSEPM_ACCESS_ACCOUNT;
  551. break;
  552. case IISMAPPER_LOCATE_BY_INDEX:
  553. if ( SUCCEEDED( hr = GetStringFromVariant( &vKey, &pV, &cV, TRUE ) ) )
  554. {
  555. wsprintfW( pszResKey, L"mappings/%s", pV );
  556. }
  557. FreeString( pV );
  558. return hr;
  559. default:
  560. return E_FAIL;
  561. }
  562. //
  563. // get ptr to data
  564. //
  565. if ( SUCCEEDED( hr = GetStringFromVariant( &vKey, &pV, &cV, fAddDelim ) ) )
  566. {
  567. //
  568. // set search prop, get result
  569. //
  570. if ( SUCCEEDED( hr = SetMdData( L"", dwProp, BINARY_METADATA, cV, (LPBYTE)pV ) ) )
  571. {
  572. if ( SUCCEEDED( hr = GetMdData( L"", dwProp, DWORD_METADATA, &cRes, (LPBYTE*)&pRes ) ) )
  573. {
  574. if ( cRes == sizeof(DWORD ) )
  575. {
  576. wsprintfW( pszResKey, L"mappings/%u", *(LPDWORD)pRes );
  577. }
  578. else
  579. {
  580. hr = E_FAIL;
  581. }
  582. free( pRes );
  583. }
  584. }
  585. }
  586. FreeString( pV );
  587. return hr;
  588. }
  589. //
  590. // GetStringFromBSTR: Allocate string buffer from BSTR
  591. //
  592. // Arguments:
  593. //
  594. // bstr - bstr to convert from
  595. // psz - updated with ptr to buffer, to be freed with FreeString()
  596. // pdwLen - updated with strlen(string), incremented by 1 if fAddDelimInCount is TRUE
  597. // fAddDelimInCount - TRUE to increment *pdwLen
  598. //
  599. HRESULT CCertMapperMethod::GetStringFromBSTR(
  600. BSTR bstr,
  601. LPSTR* psz,
  602. LPDWORD pdwLen,
  603. BOOL fAddDelimInCount
  604. )
  605. {
  606. UINT cch = SysStringLen(bstr);
  607. UINT cchT;
  608. // include NULL terminator
  609. *pdwLen = cch + (fAddDelimInCount ? 1 : 0);
  610. CHAR *szNew = (CHAR*)malloc((2 * cch) + 1); // * 2 for worst case DBCS string
  611. if (szNew == NULL)
  612. {
  613. return E_OUTOFMEMORY;
  614. }
  615. cchT = WideCharToMultiByte(CP_ACP, 0, bstr, cch + 1, szNew, (2 * cch) + 1, NULL, NULL);
  616. *psz = szNew;
  617. return NOERROR;
  618. }
  619. //
  620. // GetStringFromVariant: Allocate string buffer from BSTR
  621. //
  622. // Arguments:
  623. //
  624. // pVar - variant to convert from. Recognizes BSTR, VT_ARRAY|VT_UI1, ByRef or ByVal
  625. // psz - updated with ptr to buffer, to be freed with FreeString()
  626. // pdwLen - updated with size of input, incremented by 1 if fAddDelimInCount is TRUE
  627. // fAddDelimInCount - TRUE to increment *pdwLen
  628. //
  629. HRESULT CCertMapperMethod::GetStringFromVariant(
  630. VARIANT* pVar,
  631. LPSTR* psz,
  632. LPDWORD pdwLen,
  633. BOOL fAddDelim
  634. )
  635. {
  636. LPBYTE pbV;
  637. UINT cV;
  638. HRESULT hr;
  639. WORD vt = V_VT(pVar);
  640. BOOL fByRef = FALSE;
  641. VARIANT vOut;
  642. VariantInit( &vOut );
  643. if ( vt & VT_BYREF )
  644. {
  645. vt &= ~VT_BYREF;
  646. fByRef = TRUE;
  647. }
  648. // if pVar is BSTR, convert to multibytes
  649. if ( vt == VT_VARIANT )
  650. {
  651. pVar = (VARIANT*)V_BSTR(pVar);
  652. vt = V_VT(pVar);
  653. if ( fByRef = vt & VT_BYREF )
  654. {
  655. vt &= ~VT_BYREF;
  656. }
  657. }
  658. if ( vt == VT_BSTR )
  659. {
  660. hr = GetStringFromBSTR(
  661. fByRef ? *(BSTR*)V_BSTR(pVar) : V_BSTR(pVar),
  662. psz,
  663. pdwLen,
  664. fAddDelim
  665. );
  666. }
  667. else if( vt == (VT_ARRAY | VT_UI1) )
  668. {
  669. long lBound, uBound, lItem;
  670. BYTE bValue;
  671. SAFEARRAY* pSafeArray;
  672. // array of VT_UI1 (probably OctetString)
  673. pSafeArray = fByRef ? *(SAFEARRAY**)V_BSTR(pVar) : V_ARRAY( pVar );
  674. hr = SafeArrayGetLBound(pSafeArray, 1, &lBound);
  675. hr = SafeArrayGetUBound(pSafeArray, 1, &uBound);
  676. cV = uBound - lBound + 1;
  677. if ( !(pbV = (LPBYTE)malloc(cV)) )
  678. {
  679. hr = E_OUTOFMEMORY;
  680. VariantClear( &vOut );
  681. return hr;
  682. }
  683. hr = S_OK;
  684. for( lItem = lBound; lItem <= uBound ; lItem++ )
  685. {
  686. hr = SafeArrayGetElement( pSafeArray, &lItem, &bValue );
  687. if( FAILED( hr ) )
  688. {
  689. break;
  690. }
  691. pbV[lItem-lBound] = bValue;
  692. }
  693. *psz = (LPSTR)pbV;
  694. *pdwLen = cV;
  695. }
  696. else if( vt == (VT_ARRAY | VT_VARIANT) )
  697. {
  698. long lBound, uBound, lItem;
  699. VARIANT vValue;
  700. BYTE bValue;
  701. SAFEARRAY* pSafeArray;
  702. // array of VT_VARIANT (probably VT_I4 )
  703. pSafeArray = fByRef ? *(SAFEARRAY**)V_BSTR(pVar) : V_ARRAY( pVar );
  704. hr = SafeArrayGetLBound(pSafeArray, 1, &lBound);
  705. hr = SafeArrayGetUBound(pSafeArray, 1, &uBound);
  706. cV = uBound - lBound + 1;
  707. if ( !(pbV = (LPBYTE)malloc(cV)) )
  708. {
  709. hr = E_OUTOFMEMORY;
  710. VariantClear( &vOut );
  711. return hr;
  712. }
  713. hr = S_OK;
  714. for( lItem = lBound; lItem <= uBound ; lItem++ )
  715. {
  716. hr = SafeArrayGetElement( pSafeArray, &lItem, &vValue );
  717. if( FAILED( hr ) )
  718. {
  719. break;
  720. }
  721. if ( V_VT(&vValue) == VT_UI1 )
  722. {
  723. bValue = V_UI1(&vValue);
  724. }
  725. else if ( V_VT(&vValue) == VT_I2 )
  726. {
  727. bValue = (BYTE)V_I2(&vValue);
  728. }
  729. else if ( V_VT(&vValue) == VT_I4 )
  730. {
  731. bValue = (BYTE)V_I4(&vValue);
  732. }
  733. else
  734. {
  735. bValue = 0;
  736. }
  737. pbV[lItem-lBound] = bValue;
  738. }
  739. *psz = (LPSTR)pbV;
  740. *pdwLen = cV;
  741. }
  742. else
  743. {
  744. hr = E_FAIL;
  745. }
  746. VariantClear( &vOut );
  747. return hr;
  748. }
  749. VOID CCertMapperMethod::FreeString(
  750. LPSTR psz
  751. )
  752. {
  753. if ( psz )
  754. {
  755. free( psz );
  756. }
  757. }
  758. HRESULT CCertMapperMethod::SetBSTR(
  759. BSTR* pbstrRet,
  760. DWORD cch,
  761. LPBYTE sz
  762. )
  763. {
  764. BSTR bstrRet;
  765. if (sz == NULL)
  766. {
  767. *pbstrRet = NULL;
  768. return(NOERROR);
  769. }
  770. // Allocate a string of the desired length
  771. // SysAllocStringLen allocates enough room for unicode characters plus a null
  772. // Given a NULL string it will just allocate the space
  773. bstrRet = SysAllocStringLen(NULL, cch);
  774. if (bstrRet == NULL)
  775. {
  776. return(E_OUTOFMEMORY);
  777. }
  778. // If we were given "", we will have cch=0. return the empty bstr
  779. // otherwise, really copy/convert the string
  780. // NOTE we pass -1 as 4th parameter of MultiByteToWideChar for DBCS support
  781. if (cch != 0)
  782. {
  783. UINT cchTemp = 0;
  784. if (MultiByteToWideChar(CP_ACP, 0, (LPSTR)sz, -1, bstrRet, cch+1) == 0)
  785. {
  786. return(HRESULT_FROM_WIN32(GetLastError()));
  787. }
  788. // If there are some DBCS characters in the sz(Input), then, the character count of BSTR(DWORD) is
  789. // already set to cch(strlen(sz)) in SysAllocStringLen(NULL, cch), we cannot change the count,
  790. // and later call of SysStringLen(bstr) always returns the number of characters specified in the
  791. // cch parameter at allocation time. Bad, because one DBCS character(2 bytes) will convert
  792. // to one UNICODE character(2 bytes), not 2 UNICODE characters(4 bytes).
  793. // Example: For input sz contains only one DBCS character, we want to see SysStringLen(bstr)
  794. // = 1, not 2.
  795. bstrRet[cch] = 0;
  796. cchTemp = wcslen(bstrRet);
  797. if (cchTemp < cch)
  798. {
  799. BSTR bstrTemp = SysAllocString(bstrRet);
  800. SysFreeString(bstrRet);
  801. bstrRet = bstrTemp;
  802. cch = cchTemp;
  803. }
  804. }
  805. bstrRet[cch] = 0;
  806. *pbstrRet = bstrRet;
  807. return(NOERROR);
  808. }
  809. HRESULT CCertMapperMethod::Init(
  810. LPCWSTR pszMetabasePath
  811. )
  812. {
  813. UINT cL;
  814. cL = wcslen( pszMetabasePath );
  815. while ( cL && pszMetabasePath[cL-1] != L'/' && pszMetabasePath[cL-1] != L'\\' )
  816. {
  817. --cL;
  818. }
  819. if ( m_pszMetabasePath = (LPWSTR)malloc( cL*sizeof(WCHAR) + sizeof(L"<nsepm>") ) )
  820. {
  821. memcpy( m_pszMetabasePath, pszMetabasePath, cL * sizeof(WCHAR) );
  822. memcpy( m_pszMetabasePath + cL, L"<nsepm>", sizeof(L"<nsepm>") );
  823. }
  824. else
  825. {
  826. return E_OUTOFMEMORY;
  827. }
  828. return S_OK;
  829. }
  830. HRESULT CCertMapperMethod::SetVariantAsByteArray(
  831. VARIANT* pvarReturn,
  832. DWORD cbLen,
  833. LPBYTE pbIn
  834. )
  835. {
  836. SAFEARRAYBOUND rgsabound[1];
  837. BYTE * pbData = NULL;
  838. // Set the variant type of the output parameter
  839. V_VT(pvarReturn) = VT_ARRAY|VT_UI1;
  840. V_ARRAY(pvarReturn) = NULL;
  841. // Allocate a SafeArray for the data
  842. rgsabound[0].lLbound = 0;
  843. rgsabound[0].cElements = cbLen;
  844. V_ARRAY(pvarReturn) = SafeArrayCreate(VT_UI1, 1, rgsabound);
  845. if (V_ARRAY(pvarReturn) == NULL)
  846. {
  847. return E_OUTOFMEMORY;
  848. }
  849. if (FAILED(SafeArrayAccessData(V_ARRAY(pvarReturn), (void **) &pbData)))
  850. {
  851. return E_UNEXPECTED;
  852. }
  853. memcpy(pbData, pbIn, cbLen );
  854. SafeArrayUnaccessData(V_ARRAY(pvarReturn));
  855. return NOERROR;
  856. }
  857. HRESULT CCertMapperMethod::SetVariantAsBSTR(
  858. VARIANT* pvarReturn,
  859. DWORD cbLen,
  860. LPBYTE pbIn
  861. )
  862. {
  863. V_VT(pvarReturn) = VT_BSTR;
  864. return SetBSTR( &V_BSTR(pvarReturn), cbLen, pbIn );
  865. }
  866. HRESULT CCertMapperMethod::SetVariantAsLong(
  867. VARIANT* pvarReturn,
  868. DWORD dwV
  869. )
  870. {
  871. V_VT(pvarReturn) = VT_I4;
  872. V_I4(pvarReturn) = dwV;
  873. return S_OK;
  874. }
  875. HRESULT CCertMapperMethod::OpenAdminBaseKey(
  876. LPWSTR pszPathName,
  877. DWORD dwAccessType
  878. )
  879. {
  880. if(m_hmd)
  881. CloseAdminBaseKey();
  882. HRESULT t_hr = m_pIABase->OpenKey(
  883. METADATA_MASTER_ROOT_HANDLE,
  884. pszPathName,
  885. dwAccessType,
  886. METABASE_TIMEOUT, // 5 seconds
  887. &m_hmd
  888. );
  889. if(t_hr == ERROR_PATH_BUSY) // retry one time
  890. t_hr = m_pIABase->OpenKey(
  891. METADATA_MASTER_ROOT_HANDLE,
  892. pszPathName,
  893. dwAccessType,
  894. METABASE_TIMEOUT, // 5 seconds
  895. &m_hmd
  896. );
  897. if(FAILED(t_hr))
  898. m_hmd = NULL;
  899. return t_hr;
  900. }
  901. VOID CCertMapperMethod::CloseAdminBaseKey()
  902. {
  903. if(m_hmd && m_pIABase)
  904. {
  905. m_pIABase->CloseKey(m_hmd);
  906. m_hmd = NULL;
  907. }
  908. }