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.

1805 lines
47 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. SecConLib.cpp
  5. Abstract:
  6. Implementation of:
  7. CSecConLib
  8. Author:
  9. Brent R. Midwood Apr-2002
  10. Revision History:
  11. --*/
  12. #include "secconlib.h"
  13. #include "debug.h"
  14. #include "iiscnfg.h"
  15. #define BAIL_ON_FAILURE(hr) if (FAILED(hr)) { goto done; }
  16. #define DEFAULT_TIMEOUT_VALUE 30000
  17. #define SEMICOLON_STRING L";"
  18. #define SEMICOLON_CHAR L';'
  19. #define COMMA_STRING L","
  20. #define COMMA_CHAR L','
  21. #define ZERO_STRING L"0"
  22. #define ZERO_CHAR L'0'
  23. #define ONE_STRING L"1"
  24. #define ONE_CHAR L'1'
  25. CSecConLib::CSecConLib()
  26. {
  27. m_bInit = false;
  28. }
  29. CSecConLib::CSecConLib(
  30. IMSAdminBase* pIABase)
  31. {
  32. SC_ASSERT(pIABase != NULL);
  33. m_spIABase = pIABase;
  34. m_bInit = true;
  35. }
  36. CSecConLib::~CSecConLib()
  37. {
  38. }
  39. HRESULT
  40. CSecConLib::InternalInitIfNecessary()
  41. {
  42. HRESULT hr = S_OK;
  43. CSafeLock csSafe(m_SafeCritSec);
  44. if(m_bInit)
  45. {
  46. return hr;
  47. }
  48. hr = csSafe.Lock();
  49. hr = HRESULT_FROM_WIN32(hr);
  50. if(FAILED(hr))
  51. {
  52. return hr;
  53. }
  54. if(!m_bInit)
  55. {
  56. hr = CoCreateInstance(
  57. CLSID_MSAdminBase,
  58. NULL,
  59. CLSCTX_ALL,
  60. IID_IMSAdminBase,
  61. (void**)&m_spIABase);
  62. if(FAILED(hr))
  63. {
  64. m_bInit = false;
  65. }
  66. else
  67. {
  68. m_bInit = true;
  69. }
  70. }
  71. csSafe.Unlock();
  72. return hr;
  73. }
  74. STDMETHODIMP CSecConLib::EnableApplication(
  75. /* [in] */ LPCWSTR wszApplication,
  76. /* [in] */ LPCWSTR wszPath)
  77. {
  78. DWORD dwAppNameSz = 0;
  79. WCHAR *pwszAppProp = NULL;
  80. DWORD dwAppPropSz = 0;
  81. HRESULT hr = S_OK;
  82. bool bFound = false;
  83. WCHAR *pTop = NULL;
  84. // compute arg length
  85. dwAppNameSz = (DWORD)wcslen(wszApplication);
  86. hr = InternalInitIfNecessary();
  87. if (FAILED(hr))
  88. {
  89. BAIL_ON_FAILURE(hr);
  90. }
  91. // get the current property value for applicationdep list
  92. hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
  93. BAIL_ON_FAILURE(hr);
  94. if (NULL == pwszAppProp)
  95. {
  96. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  97. }
  98. pTop = pwszAppProp;
  99. // go thru the apps one by one
  100. while (pwszAppProp[0])
  101. {
  102. DWORD dwTokSz = (DWORD)wcslen(pwszAppProp) + 1;
  103. // check to see if the app matches
  104. if (!_wcsnicmp(wszApplication, pwszAppProp, dwAppNameSz) &&
  105. pwszAppProp[dwAppNameSz] == SEMICOLON_CHAR)
  106. {
  107. bFound = true;
  108. WCHAR *pGroups = &pwszAppProp[dwAppNameSz + ((DWORD)sizeof(SEMICOLON_CHAR) / (DWORD)sizeof(WCHAR))];
  109. while (pGroups)
  110. {
  111. WCHAR *pTemp = wcschr(pGroups, COMMA_CHAR);
  112. if (pTemp)
  113. {
  114. *pTemp = 0; // replace comma w/ null
  115. }
  116. hr = EnableWebServiceExtension(pGroups, wszPath);
  117. BAIL_ON_FAILURE(hr);
  118. if (pTemp)
  119. {
  120. pGroups = pTemp + 1; // go past comma
  121. }
  122. else
  123. {
  124. pGroups = NULL;
  125. }
  126. }
  127. }
  128. pwszAppProp += dwTokSz; // go to the next part of the multisz
  129. }
  130. if (!bFound)
  131. {
  132. BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
  133. }
  134. done:
  135. if (pTop)
  136. {
  137. delete [] pTop;
  138. }
  139. return hr;
  140. }
  141. HRESULT CSecConLib::SetMultiSZPropVal(
  142. LPCWSTR wszPath,
  143. DWORD dwMetaId,
  144. WCHAR *pBuffer,
  145. DWORD dwBufSize)
  146. {
  147. HRESULT hr = S_OK;
  148. METADATA_RECORD mdrMDData;
  149. METADATA_HANDLE hObjHandle = NULL;
  150. hr = m_spIABase->OpenKey(
  151. METADATA_MASTER_ROOT_HANDLE,
  152. wszPath,
  153. METADATA_PERMISSION_WRITE,
  154. DEFAULT_TIMEOUT_VALUE,
  155. &hObjHandle
  156. );
  157. BAIL_ON_FAILURE(hr);
  158. if (!pBuffer)
  159. {
  160. hr = m_spIABase->DeleteData(
  161. hObjHandle,
  162. (LPWSTR)L"",
  163. dwMetaId,
  164. ALL_METADATA
  165. );
  166. BAIL_ON_FAILURE(hr);
  167. }
  168. else
  169. {
  170. MD_SET_DATA_RECORD(&mdrMDData,
  171. dwMetaId,
  172. METADATA_NO_ATTRIBUTES,
  173. IIS_MD_UT_SERVER,
  174. MULTISZ_METADATA,
  175. dwBufSize * sizeof(WCHAR),
  176. pBuffer);
  177. hr = m_spIABase->SetData(
  178. hObjHandle,
  179. L"",
  180. &mdrMDData
  181. );
  182. BAIL_ON_FAILURE(hr);
  183. }
  184. done:
  185. m_spIABase->CloseKey(hObjHandle);
  186. return hr;
  187. }
  188. HRESULT CSecConLib::GetMultiSZPropVal(
  189. LPCWSTR wszPath,
  190. DWORD dwMetaId,
  191. WCHAR **ppBuffer,
  192. DWORD *dwBufSize)
  193. {
  194. HRESULT hr = S_OK;
  195. DWORD dwBufferSize = 0;
  196. METADATA_RECORD mdrMDData;
  197. WCHAR *pBuffer = NULL;
  198. METADATA_HANDLE hObjHandle = NULL;
  199. hr = m_spIABase->OpenKey(
  200. METADATA_MASTER_ROOT_HANDLE,
  201. wszPath,
  202. METADATA_PERMISSION_READ,
  203. DEFAULT_TIMEOUT_VALUE,
  204. &hObjHandle
  205. );
  206. BAIL_ON_FAILURE(hr);
  207. MD_SET_DATA_RECORD(&mdrMDData,
  208. dwMetaId,
  209. METADATA_NO_ATTRIBUTES,
  210. IIS_MD_UT_SERVER,
  211. MULTISZ_METADATA,
  212. dwBufferSize,
  213. pBuffer);
  214. hr = m_spIABase->GetData(
  215. hObjHandle,
  216. L"",
  217. &mdrMDData,
  218. &dwBufferSize
  219. );
  220. if (dwBufferSize > 0)
  221. {
  222. *dwBufSize = dwBufferSize / sizeof(WCHAR);
  223. pBuffer = (WCHAR*) new BYTE[dwBufferSize];
  224. if (!pBuffer) {
  225. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  226. }
  227. MD_SET_DATA_RECORD(&mdrMDData,
  228. dwMetaId,
  229. METADATA_NO_ATTRIBUTES,
  230. IIS_MD_UT_SERVER,
  231. MULTISZ_METADATA,
  232. dwBufferSize,
  233. pBuffer);
  234. hr = m_spIABase->GetData(
  235. hObjHandle,
  236. L"",
  237. &mdrMDData,
  238. &dwBufferSize
  239. );
  240. }
  241. BAIL_ON_FAILURE(hr);
  242. *ppBuffer = pBuffer;
  243. hr = m_spIABase->CloseKey(hObjHandle);
  244. return hr;
  245. done:
  246. if (pBuffer) {
  247. delete [] pBuffer;
  248. }
  249. m_spIABase->CloseKey(hObjHandle);
  250. return hr;
  251. }
  252. STDMETHODIMP CSecConLib::RemoveApplication(
  253. /* [in] */ LPCWSTR wszApplication,
  254. /* [in] */ LPCWSTR wszPath)
  255. {
  256. DWORD dwAppNameSz = 0;
  257. WCHAR *pwszOrig = NULL;
  258. WCHAR *pTopOrig = NULL;
  259. WCHAR *pwszAppProp = NULL;
  260. DWORD dwAppPropSz = 0;
  261. HRESULT hr = S_OK;
  262. bool bFound = false;
  263. // compute arg length
  264. dwAppNameSz = (DWORD)wcslen(wszApplication);
  265. hr = InternalInitIfNecessary();
  266. if (FAILED(hr))
  267. {
  268. BAIL_ON_FAILURE(hr);
  269. }
  270. // get the current property value for applicationdep list
  271. hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
  272. BAIL_ON_FAILURE(hr);
  273. // remove the application
  274. // copy the property
  275. pwszOrig = new WCHAR[dwAppPropSz];
  276. pTopOrig = pwszOrig;
  277. if (!pwszOrig)
  278. {
  279. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  280. }
  281. memcpy(pwszOrig, pwszAppProp, dwAppPropSz * sizeof(WCHAR));
  282. dwAppPropSz = 1; //reset size to contain one for the last null
  283. WCHAR* pMidBuf = pwszAppProp;
  284. // copy the old apps one by one
  285. while (pwszOrig[0])
  286. {
  287. DWORD dwTokSz = (DWORD)wcslen(pwszOrig) + 1;
  288. // check to see if the app already exists
  289. if (!_wcsnicmp(wszApplication, pwszOrig, dwAppNameSz) &&
  290. pwszOrig[dwAppNameSz] == SEMICOLON_CHAR)
  291. {
  292. bFound = true;
  293. }
  294. else
  295. {
  296. // copy it in
  297. if (NULL == pMidBuf)
  298. {
  299. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  300. }
  301. wcscpy(pMidBuf, pwszOrig);
  302. pMidBuf += dwTokSz; // advance past null
  303. *pMidBuf = 0; // add the last null
  304. dwAppPropSz += dwTokSz;
  305. }
  306. pwszOrig += dwTokSz; // go to the next part of the multisz
  307. }
  308. if (!bFound)
  309. {
  310. BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
  311. }
  312. // set the new property value for property
  313. if (dwAppPropSz < 3)
  314. {
  315. // handle deleting the last one
  316. hr = SetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, NULL, 0);
  317. }
  318. else
  319. {
  320. hr = SetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, pwszAppProp, dwAppPropSz);
  321. }
  322. BAIL_ON_FAILURE(hr);
  323. done:
  324. if (pTopOrig)
  325. {
  326. delete [] pTopOrig;
  327. }
  328. if (pwszAppProp)
  329. {
  330. delete [] pwszAppProp;
  331. }
  332. return hr;
  333. }
  334. STDMETHODIMP CSecConLib::QueryGroupIDStatus(
  335. /* [in] */ LPCWSTR wszPath,
  336. /* [in] */ LPCWSTR wszGroupID,
  337. /* [out] */ WCHAR **pszBuffer, // MULTI_SZ - allocated in here, caller should delete
  338. /* [out] */ DWORD *pdwBufferSize) // length includes double null
  339. {
  340. WCHAR *pwszAppProp = NULL;
  341. DWORD dwAppPropSz = 0;
  342. WCHAR *pList = NULL;
  343. WCHAR *pTempList = NULL;
  344. DWORD dwListLen = 1; // one for the extra null at the end
  345. DWORD dwOldListLen = 1;
  346. HRESULT hr = S_OK;
  347. WCHAR *pTop = NULL;
  348. hr = InternalInitIfNecessary();
  349. if (FAILED(hr))
  350. {
  351. BAIL_ON_FAILURE(hr);
  352. }
  353. // get the current property value for applicationdep list
  354. hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
  355. BAIL_ON_FAILURE(hr);
  356. if (NULL == pwszAppProp)
  357. {
  358. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  359. }
  360. pTop = pwszAppProp;
  361. // iterate through the apps
  362. while (pwszAppProp[0])
  363. {
  364. // reset bFound
  365. bool bFound = false;
  366. WCHAR* pMidBuf = wcschr(pwszAppProp, SEMICOLON_CHAR);
  367. if (!pMidBuf)
  368. {
  369. BAIL_ON_FAILURE(hr = E_FAIL);
  370. }
  371. // null the semicolon and go past it
  372. *pMidBuf = 0;
  373. *pMidBuf++;
  374. // does this app have a dependency on the GroupID that got passed in?
  375. WCHAR* pGroupID = NULL;
  376. WCHAR* pGroups = new WCHAR[(DWORD)wcslen(pMidBuf) + 1];
  377. if (!pGroups)
  378. {
  379. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  380. }
  381. // copy in the GroupIDs
  382. wcscpy(pGroups, pMidBuf);
  383. // look at each GroupID
  384. pGroupID = wcstok(pGroups, COMMA_STRING);
  385. while (pGroupID && !bFound)
  386. {
  387. if (!wcscmp(pGroupID, wszGroupID))
  388. {
  389. bFound = true;
  390. }
  391. pGroupID = wcstok(NULL, COMMA_STRING);
  392. }
  393. if (pGroups)
  394. {
  395. delete [] pGroups;
  396. }
  397. // do we want to add this app to the list?
  398. if (bFound)
  399. {
  400. // allocate the memory
  401. dwListLen += (DWORD)wcslen(pwszAppProp) + 1; // for the null
  402. pTempList = new WCHAR[dwListLen];
  403. if (!pTempList)
  404. {
  405. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  406. }
  407. if (pList)
  408. {
  409. // copy the previous list
  410. memcpy(pTempList, pList, dwOldListLen * sizeof(WCHAR));
  411. delete [] pList;
  412. }
  413. // copy on the app name
  414. wcscpy(&pTempList[dwOldListLen - 1], pwszAppProp);
  415. pTempList[dwListLen-1] = 0;
  416. pTempList[dwListLen-2] = 0;
  417. pList = pTempList;
  418. dwOldListLen = dwListLen;
  419. }
  420. // now go to the next application
  421. pwszAppProp = pMidBuf + (DWORD)wcslen(pMidBuf) + 1;
  422. }
  423. *pszBuffer = pList;
  424. *pdwBufferSize = dwListLen;
  425. done:
  426. if (pTop)
  427. {
  428. delete [] pTop;
  429. }
  430. return hr;
  431. }
  432. STDMETHODIMP CSecConLib::ListApplications(
  433. /* [in] */ LPCWSTR wszPath,
  434. /* [out] */ WCHAR **pszBuffer, // MULTI_SZ - allocated in here, caller should delete
  435. /* [out] */ DWORD *pdwBufferSize) // length includes double null
  436. {
  437. WCHAR *pwszAppProp = NULL;
  438. DWORD dwAppPropSz = 0;
  439. WCHAR *pList = NULL;
  440. WCHAR *pTempList = NULL;
  441. DWORD dwListLen = 1; // one for the extra null at the end
  442. DWORD dwOldListLen = 1;
  443. HRESULT hr = S_OK;
  444. WCHAR *pTop = NULL;
  445. hr = InternalInitIfNecessary();
  446. if (FAILED(hr))
  447. {
  448. BAIL_ON_FAILURE(hr);
  449. }
  450. // get the current property value for applicationdep list
  451. hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
  452. BAIL_ON_FAILURE(hr);
  453. if (NULL == pwszAppProp)
  454. {
  455. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  456. }
  457. pTop = pwszAppProp;
  458. // iterate through the apps
  459. while (pwszAppProp[0])
  460. {
  461. WCHAR* pMidBuf = wcschr(pwszAppProp, SEMICOLON_CHAR);
  462. if (!pMidBuf)
  463. {
  464. BAIL_ON_FAILURE(hr = E_FAIL);
  465. }
  466. // null the semicolon and go past it
  467. *pMidBuf = 0;
  468. *pMidBuf++;
  469. // allocate the memory
  470. dwListLen += (DWORD)wcslen(pwszAppProp) + 1; // for the null
  471. pTempList = new WCHAR[dwListLen];
  472. if (!pTempList)
  473. {
  474. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  475. }
  476. if (pList)
  477. {
  478. // copy the previous list
  479. memcpy(pTempList, pList, dwOldListLen * sizeof(WCHAR));
  480. delete [] pList;
  481. }
  482. // copy on the app name
  483. wcscpy(&pTempList[dwOldListLen - 1], pwszAppProp);
  484. pTempList[dwListLen-1] = 0;
  485. pTempList[dwListLen-2] = 0;
  486. pList = pTempList;
  487. dwOldListLen = dwListLen;
  488. // now go to the next application
  489. pwszAppProp = pMidBuf + (DWORD)wcslen(pMidBuf) + 1;
  490. }
  491. if (!pList)
  492. {
  493. // make it a valid empty multisz
  494. dwListLen = 2;
  495. pList = new WCHAR[dwListLen];
  496. if (!pList)
  497. {
  498. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  499. }
  500. wmemset(pList, 0, dwListLen);
  501. }
  502. *pszBuffer = pList;
  503. *pdwBufferSize = dwListLen;
  504. done:
  505. if (pTop)
  506. {
  507. delete [] pTop;
  508. }
  509. return hr;
  510. }
  511. STDMETHODIMP CSecConLib::AddDependency(
  512. /* [in] */ LPCWSTR wszApplication,
  513. /* [in] */ LPCWSTR wszGroupID,
  514. /* [in] */ LPCWSTR wszPath)
  515. {
  516. WCHAR *pwszAppProp = NULL;
  517. WCHAR *pwszOrig = NULL;
  518. WCHAR *pwszTopOrig = NULL;
  519. DWORD dwAppPropSz = 0;
  520. DWORD dwAppNameSz = 0;
  521. DWORD dwGroupIDSz = 0;
  522. HRESULT hr = S_OK;
  523. bool bDone = false;
  524. // compute arg length
  525. dwAppNameSz = (DWORD)wcslen(wszApplication);
  526. dwGroupIDSz = (DWORD)wcslen(wszGroupID);
  527. hr = InternalInitIfNecessary();
  528. if (FAILED(hr))
  529. {
  530. BAIL_ON_FAILURE(hr);
  531. }
  532. // get the current property value for applicationdep list
  533. hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
  534. if (MD_ERROR_DATA_NOT_FOUND == hr)
  535. {
  536. // this is okay, we just need to create the property.
  537. hr = S_OK;
  538. dwAppPropSz = 0;
  539. }
  540. BAIL_ON_FAILURE(hr);
  541. // add the dependency
  542. if (!dwAppPropSz)
  543. {
  544. // create the property
  545. // size of the property = len(App) + 1(semicolon) + len(GID) + 2(double null MULTISZ)
  546. dwAppPropSz = dwAppNameSz + (DWORD)wcslen(SEMICOLON_STRING) + dwGroupIDSz + 2;
  547. // No Leak
  548. // pwszAppProp never got alloced since we didn't get any value back,
  549. // so no need to delete first...
  550. pwszAppProp = new WCHAR[dwAppPropSz];
  551. if (!pwszAppProp)
  552. {
  553. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  554. }
  555. wcscpy(pwszAppProp, wszApplication);
  556. wcscat(pwszAppProp, SEMICOLON_STRING);
  557. wcscat(pwszAppProp, wszGroupID);
  558. // add the double null
  559. pwszAppProp[dwAppPropSz-1] = 0;
  560. pwszAppProp[dwAppPropSz-2] = 0;
  561. }
  562. else
  563. {
  564. // property already exists
  565. // copy the property
  566. pwszOrig = new WCHAR[dwAppPropSz];
  567. pwszTopOrig = pwszOrig;
  568. if (!pwszOrig)
  569. {
  570. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  571. }
  572. memcpy(pwszOrig, pwszAppProp, dwAppPropSz * sizeof(WCHAR));
  573. // resize the new property to the biggest possible
  574. if (pwszAppProp)
  575. {
  576. delete [] pwszAppProp;
  577. }
  578. // max new size is old size + len(app) + 1(semicolon) + len(GID) + null
  579. dwAppPropSz = dwAppPropSz + dwAppNameSz + (DWORD)wcslen(SEMICOLON_STRING) +
  580. dwGroupIDSz + 1;
  581. pwszAppProp = new WCHAR[dwAppPropSz];
  582. if (!pwszAppProp)
  583. {
  584. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  585. }
  586. WCHAR* pMidBuf = pwszAppProp;
  587. // copy the old dependencies one by one
  588. while (pwszOrig[0])
  589. {
  590. wcscpy(pMidBuf, pwszOrig);
  591. // check to see if the app already exists
  592. if (!_wcsnicmp(wszApplication, pMidBuf, dwAppNameSz) &&
  593. pMidBuf[dwAppNameSz] == SEMICOLON_CHAR)
  594. {
  595. // since we're not adding the app, subtract the size of the app and trailing null
  596. dwAppPropSz = dwAppPropSz - dwAppNameSz - 1;
  597. // this is the correct app, so now look for the GroupID
  598. pMidBuf += dwAppNameSz + 1; // go to the first GroupID
  599. // need a temp copy, sinc wcstok modifies the string
  600. WCHAR* pTokTemp = new WCHAR[(DWORD)wcslen(pMidBuf) + 1];
  601. if (!pTokTemp)
  602. {
  603. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  604. }
  605. wcscpy(pTokTemp, pMidBuf);
  606. WCHAR* token = wcstok( pTokTemp, COMMA_STRING );
  607. while (token && !bDone)
  608. {
  609. if (!_wcsicmp(token, wszGroupID))
  610. {
  611. // we found the group ID, so the user is trying
  612. // to add a dependency that is already there
  613. if (pTokTemp)
  614. {
  615. delete [] pTokTemp;
  616. }
  617. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(ERROR_DUP_NAME));
  618. }
  619. token = wcstok( NULL, COMMA_STRING );
  620. }
  621. if (pTokTemp)
  622. {
  623. delete [] pTokTemp;
  624. }
  625. pMidBuf += (DWORD)wcslen(pMidBuf); // go to the null at the end of this part
  626. if (!bDone)
  627. {
  628. // we didn't find the GroupID, so add it
  629. wcscat(pMidBuf, COMMA_STRING);
  630. wcscat(pMidBuf, wszGroupID);
  631. pMidBuf += (DWORD)wcslen(pMidBuf); // go to the null at the end of this part
  632. bDone = true;
  633. }
  634. pMidBuf++; // go to the next char and make it a null
  635. pMidBuf[0] = 0;
  636. }
  637. else // no change here, move pMidBuf along...
  638. {
  639. pMidBuf += (DWORD)wcslen(pMidBuf) + 1; // go past the null
  640. }
  641. pwszOrig += (DWORD)wcslen(pwszOrig) + 1; // go to the next part of the multisz
  642. }
  643. if (!bDone)
  644. {
  645. // we didn't even find the application, so add both app & groupID
  646. wcscpy(pMidBuf, wszApplication);
  647. wcscat(pMidBuf, SEMICOLON_STRING);
  648. wcscat(pMidBuf, wszGroupID);
  649. pMidBuf[(DWORD)wcslen(pMidBuf)+1] = 0; // add the last null
  650. }
  651. }
  652. // set the new property value for property
  653. hr = SetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, pwszAppProp, dwAppPropSz);
  654. BAIL_ON_FAILURE(hr);
  655. done:
  656. if (pwszTopOrig)
  657. {
  658. delete [] pwszTopOrig;
  659. }
  660. if (pwszAppProp)
  661. {
  662. delete [] pwszAppProp;
  663. }
  664. return hr;
  665. }
  666. STDMETHODIMP CSecConLib::RemoveDependency(
  667. /* [in] */ LPCWSTR wszApplication,
  668. /* [in] */ LPCWSTR wszGroupID,
  669. /* [in] */ LPCWSTR wszPath)
  670. {
  671. HRESULT hr = S_OK;
  672. WCHAR *pwszOrig = NULL;
  673. WCHAR *pwszTopOrig = NULL;
  674. WCHAR *pwszAppProp = NULL;
  675. WCHAR *pStartStr = NULL;
  676. DWORD dwAppPropSz = 0;
  677. DWORD dwAppNameSz = 0;
  678. DWORD dwGroupIDSz = 0;
  679. bool bFound = false;
  680. bool bOtherGIDs = false;
  681. // compute arg length
  682. dwAppNameSz = (DWORD)wcslen(wszApplication);
  683. dwGroupIDSz = (DWORD)wcslen(wszGroupID);
  684. hr = InternalInitIfNecessary();
  685. if (FAILED(hr))
  686. {
  687. BAIL_ON_FAILURE(hr);
  688. }
  689. // get the current property value for applicationdep list
  690. hr = GetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, &pwszAppProp, &dwAppPropSz);
  691. BAIL_ON_FAILURE(hr);
  692. // remove the dependency
  693. // copy the property
  694. pwszOrig = new WCHAR[dwAppPropSz];
  695. pwszTopOrig = pwszOrig;
  696. if (!pwszOrig)
  697. {
  698. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  699. }
  700. memcpy(pwszOrig, pwszAppProp, dwAppPropSz * sizeof(WCHAR));
  701. WCHAR* pMidBuf = pwszAppProp;
  702. // copy the old dependencies one by one
  703. while (pwszOrig[0])
  704. {
  705. // check to see if the app already exists
  706. if (!_wcsnicmp(wszApplication, pwszOrig, dwAppNameSz) &&
  707. pwszOrig[dwAppNameSz] == SEMICOLON_CHAR)
  708. {
  709. pStartStr = pMidBuf;
  710. // this is the correct app, so now look for the GroupID
  711. pMidBuf += dwAppNameSz + 1; // go to the first GroupID
  712. // need a temp copy, sinc wcstok modifies the string
  713. WCHAR* pTokTemp = new WCHAR[(DWORD)wcslen(pMidBuf) + 1];
  714. if (!pTokTemp)
  715. {
  716. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  717. }
  718. wcscpy(pTokTemp, pMidBuf);
  719. WCHAR* token = wcstok( pTokTemp, COMMA_STRING );
  720. while (token)
  721. {
  722. if (bOtherGIDs)
  723. {
  724. wcscpy(pMidBuf, COMMA_STRING);
  725. pMidBuf += (DWORD)wcslen(pMidBuf);
  726. }
  727. if (!wcscmp(token, wszGroupID))
  728. {
  729. // we found the group ID
  730. bFound = true;
  731. // adjust the final length = no comma, no GID
  732. dwAppPropSz = dwAppPropSz - (DWORD)wcslen(COMMA_STRING) - dwGroupIDSz;
  733. if (bOtherGIDs)
  734. {
  735. // need to backup over the last comma we inserted
  736. pMidBuf -= (DWORD)wcslen(COMMA_STRING);
  737. *pMidBuf = 0;
  738. }
  739. }
  740. else
  741. {
  742. bOtherGIDs = true;
  743. wcscpy(pMidBuf, token);
  744. pMidBuf += (DWORD)wcslen(pMidBuf);
  745. }
  746. token = wcstok( NULL, COMMA_STRING );
  747. }
  748. if (pTokTemp)
  749. {
  750. delete [] pTokTemp;
  751. }
  752. if (!bOtherGIDs)
  753. {
  754. // deleted last dependency, so delete the app
  755. pMidBuf = pStartStr;
  756. dwAppPropSz = dwAppPropSz - dwAppNameSz - 1; // account for null
  757. }
  758. else
  759. {
  760. pMidBuf++;
  761. *pMidBuf = 0;
  762. }
  763. }
  764. else // no change here, move pMidBuf along...
  765. {
  766. if (NULL == pMidBuf)
  767. {
  768. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  769. }
  770. wcscpy(pMidBuf, pwszOrig); // copy the part without mods
  771. pMidBuf += (DWORD)wcslen(pMidBuf) + 1; // go past the null
  772. }
  773. pwszOrig += (DWORD)wcslen(pwszOrig) + 1; // go to the next part of the multisz
  774. }
  775. if (!bFound)
  776. {
  777. // user is trying to remove a non-existent dependency
  778. BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
  779. }
  780. *pMidBuf = 0;
  781. // set the new property value for property
  782. if (dwAppPropSz < 3)
  783. {
  784. // handle deleting the last one
  785. hr = SetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, NULL, 0);
  786. }
  787. else
  788. {
  789. hr = SetMultiSZPropVal(wszPath, MD_APP_DEPENDENCIES, pwszAppProp, dwAppPropSz);
  790. }
  791. BAIL_ON_FAILURE(hr);
  792. done:
  793. if (pwszTopOrig)
  794. {
  795. delete [] pwszTopOrig;
  796. }
  797. if (pwszAppProp)
  798. {
  799. delete [] pwszAppProp;
  800. }
  801. return hr;
  802. }
  803. STDMETHODIMP CSecConLib::EnableWebServiceExtension(
  804. /* [in] */ LPCWSTR wszExtension,
  805. /* [in] */ LPCWSTR wszPath)
  806. {
  807. HRESULT hr = S_OK;
  808. hr = InternalInitIfNecessary();
  809. if (FAILED(hr))
  810. {
  811. BAIL_ON_FAILURE(hr);
  812. }
  813. hr = StatusWServEx(true, wszExtension, wszPath);
  814. if (FAILED(hr))
  815. {
  816. BAIL_ON_FAILURE(hr);
  817. }
  818. done:
  819. return hr;
  820. }
  821. STDMETHODIMP CSecConLib::DisableWebServiceExtension(
  822. /* [in] */ LPCWSTR wszExtension,
  823. /* [in] */ LPCWSTR wszPath)
  824. {
  825. HRESULT hr = S_OK;
  826. hr = InternalInitIfNecessary();
  827. if (FAILED(hr))
  828. {
  829. BAIL_ON_FAILURE(hr);
  830. }
  831. hr = StatusWServEx(false, wszExtension, wszPath);
  832. if (FAILED(hr))
  833. {
  834. BAIL_ON_FAILURE(hr);
  835. }
  836. done:
  837. return hr;
  838. }
  839. STDMETHODIMP CSecConLib::ListWebServiceExtensions(
  840. /* [in] */ LPCWSTR wszPath,
  841. /* [out] */ WCHAR **pszBuffer, // MULTI_SZ - allocated in here, caller should delete
  842. /* [out] */ DWORD *pdwBufferSize) // length includes double null
  843. {
  844. WCHAR *pwszRListProp = NULL;
  845. DWORD dwRListPropSz = 0;
  846. WCHAR *pList = NULL;
  847. WCHAR *pTempList = NULL;
  848. DWORD dwListLen = 1; // one for the extra null at the end
  849. DWORD dwOldListLen = 1;
  850. HRESULT hr = S_OK;
  851. WCHAR *pTop = NULL;
  852. WCHAR *pMidBuf = NULL;
  853. bool bFound = false;
  854. bool bSpecial = false;
  855. hr = InternalInitIfNecessary();
  856. if (FAILED(hr))
  857. {
  858. BAIL_ON_FAILURE(hr);
  859. }
  860. // get the current property value for applicationdep list
  861. hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
  862. BAIL_ON_FAILURE(hr);
  863. if (NULL == pwszRListProp)
  864. {
  865. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  866. }
  867. pTop = pwszRListProp;
  868. // iterate through the files
  869. while (pwszRListProp[0])
  870. {
  871. // get to the group ID
  872. for (int i=0; i<3; i++)
  873. {
  874. pMidBuf = wcschr(pwszRListProp, COMMA_CHAR);
  875. if (!pMidBuf)
  876. {
  877. // don't fail. just treat this as a special case and break out
  878. bSpecial = true;
  879. pMidBuf = pwszRListProp;
  880. break;
  881. }
  882. // null the comma and go past it
  883. *pMidBuf = 0;
  884. *pMidBuf++;
  885. pwszRListProp = pMidBuf;
  886. }
  887. if (COMMA_CHAR == pMidBuf[0])
  888. {
  889. bSpecial = true;
  890. pMidBuf = pwszRListProp;
  891. }
  892. if (!bSpecial)
  893. {
  894. // now we're looking at the group ID
  895. pMidBuf = wcschr(pwszRListProp, COMMA_CHAR);
  896. // if we can't find the comma, just treat the whole thing as a GroupID
  897. // otherwise, the GroupID ends at the comma
  898. if (pMidBuf)
  899. {
  900. // null the comma and go past it
  901. *pMidBuf = 0;
  902. *pMidBuf++;
  903. }
  904. // check to see if the entry is in the list already
  905. WCHAR *pCheck = pList;
  906. while (pCheck && *pCheck)
  907. {
  908. if (!_wcsicmp(pCheck, pwszRListProp))
  909. {
  910. bFound = true;
  911. pCheck = NULL;
  912. }
  913. else
  914. {
  915. pCheck += (DWORD)wcslen(pCheck) + 1;
  916. }
  917. }
  918. if (!bFound)
  919. {
  920. // allocate the memory
  921. dwListLen += (DWORD)wcslen(pwszRListProp) + 1; // for the null
  922. pTempList = new WCHAR[dwListLen];
  923. if (!pTempList)
  924. {
  925. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  926. }
  927. if (pList)
  928. {
  929. // copy the previous list
  930. memcpy(pTempList, pList, dwOldListLen * sizeof(WCHAR));
  931. delete [] pList;
  932. }
  933. // copy on the file name
  934. wcscpy(&pTempList[dwOldListLen - 1], pwszRListProp);
  935. pTempList[dwListLen-1] = 0;
  936. pTempList[dwListLen-2] = 0;
  937. pList = pTempList;
  938. dwOldListLen = dwListLen;
  939. }
  940. }
  941. // now go to the next application
  942. pwszRListProp = pMidBuf + (DWORD)wcslen(pMidBuf) + 1;
  943. bFound = false;
  944. bSpecial = false;
  945. }
  946. if (!pList)
  947. {
  948. // make it a valid empty multisz
  949. dwListLen = 2;
  950. pList = new WCHAR[dwListLen];
  951. if (!pList)
  952. {
  953. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  954. }
  955. wmemset(pList, 0, dwListLen);
  956. }
  957. *pszBuffer = pList;
  958. *pdwBufferSize = dwListLen;
  959. done:
  960. if (pTop)
  961. {
  962. delete [] pTop;
  963. }
  964. return hr;
  965. }
  966. STDMETHODIMP CSecConLib::EnableExtensionFile(
  967. /* [in] */ LPCWSTR wszExFile,
  968. /* [in] */ LPCWSTR wszPath)
  969. {
  970. HRESULT hr = S_OK;
  971. hr = InternalInitIfNecessary();
  972. if (FAILED(hr))
  973. {
  974. BAIL_ON_FAILURE(hr);
  975. }
  976. hr = StatusExtensionFile(true, wszExFile, wszPath);
  977. if (FAILED(hr))
  978. {
  979. BAIL_ON_FAILURE(hr);
  980. }
  981. done:
  982. return hr;
  983. }
  984. STDMETHODIMP CSecConLib::DisableExtensionFile(
  985. /* [in] */ LPCWSTR wszExFile,
  986. /* [in] */ LPCWSTR wszPath)
  987. {
  988. HRESULT hr = S_OK;
  989. hr = InternalInitIfNecessary();
  990. if (FAILED(hr))
  991. {
  992. BAIL_ON_FAILURE(hr);
  993. }
  994. hr = StatusExtensionFile(false, wszExFile, wszPath);
  995. if (FAILED(hr))
  996. {
  997. BAIL_ON_FAILURE(hr);
  998. }
  999. done:
  1000. return hr;
  1001. }
  1002. HRESULT CSecConLib::StatusWServEx(
  1003. /* [in] */ bool bEnable,
  1004. /* [in] */ LPCWSTR wszWServEx,
  1005. /* [in] */ LPCWSTR wszPath)
  1006. {
  1007. WCHAR *pwszRListProp = NULL;
  1008. WCHAR *pTop = NULL;
  1009. DWORD dwRListPropSz = 0;
  1010. HRESULT hr = S_OK;
  1011. DWORD dwWServExSz = 0;
  1012. bool bFound = false;
  1013. // compute arg length
  1014. dwWServExSz = (DWORD)wcslen(wszWServEx);
  1015. // get the current property value for restriction list
  1016. hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
  1017. BAIL_ON_FAILURE(hr);
  1018. if (NULL == pwszRListProp)
  1019. {
  1020. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1021. }
  1022. pTop = pwszRListProp;
  1023. // look at the files one by one
  1024. while (pwszRListProp[0])
  1025. {
  1026. DWORD dwTokSz = (DWORD)wcslen(pwszRListProp) + 1;
  1027. WCHAR *pFileTemp = new WCHAR[dwTokSz];
  1028. WCHAR *pToken;
  1029. if (!pFileTemp)
  1030. {
  1031. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1032. }
  1033. // check to see if we're at the right group
  1034. wcscpy(pFileTemp, pwszRListProp);
  1035. pToken = wcstok( pFileTemp, COMMA_STRING );
  1036. // look at the group ID
  1037. for (int i=0; i<3; i++)
  1038. {
  1039. if (pToken)
  1040. {
  1041. pToken = wcstok( NULL, COMMA_STRING );
  1042. }
  1043. }
  1044. if (pToken && (!wcscmp(pToken, wszWServEx)))
  1045. {
  1046. bFound = true;
  1047. if (bEnable)
  1048. {
  1049. pwszRListProp[0] = ONE_CHAR;
  1050. }
  1051. else
  1052. {
  1053. pwszRListProp[0] = ZERO_CHAR;
  1054. }
  1055. }
  1056. pwszRListProp += dwTokSz; // go to the next part of the multisz
  1057. if (pFileTemp)
  1058. {
  1059. delete [] pFileTemp;
  1060. }
  1061. }
  1062. if (!bFound)
  1063. {
  1064. BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
  1065. }
  1066. // set the new property value for property
  1067. hr = SetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, pTop, dwRListPropSz);
  1068. BAIL_ON_FAILURE(hr);
  1069. done:
  1070. if (pTop)
  1071. {
  1072. delete [] pTop;
  1073. }
  1074. return hr;
  1075. }
  1076. HRESULT CSecConLib::StatusExtensionFile(
  1077. /* [in] */ bool bEnable,
  1078. /* [in] */ LPCWSTR wszExFile,
  1079. /* [in] */ LPCWSTR wszPath)
  1080. {
  1081. WCHAR *pwszRListProp = NULL;
  1082. WCHAR *pTop = NULL;
  1083. DWORD dwRListPropSz = 0;
  1084. HRESULT hr = S_OK;
  1085. DWORD dwFileNameSz = 0;
  1086. bool bFound = false;
  1087. // compute arg length
  1088. dwFileNameSz = (DWORD)wcslen(wszExFile);
  1089. // get the current property value for restriction list
  1090. hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
  1091. BAIL_ON_FAILURE(hr);
  1092. if (NULL == pwszRListProp)
  1093. {
  1094. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1095. }
  1096. pTop = pwszRListProp;
  1097. // look at the files one by one
  1098. while (pwszRListProp[0])
  1099. {
  1100. DWORD dwTokSz = (DWORD)wcslen(pwszRListProp) + 1;
  1101. // check to see if we're at the right file
  1102. // look past the bool(1) + comma(sizof_comma_char)
  1103. DWORD dwTemp = (DWORD)sizeof(COMMA_CHAR) / (DWORD)sizeof(WCHAR);
  1104. if ((!_wcsnicmp(wszExFile, &pwszRListProp[1 + dwTemp], dwFileNameSz)) &&
  1105. ((pwszRListProp[dwFileNameSz + dwTemp + 1] == COMMA_CHAR) ||
  1106. (pwszRListProp[dwFileNameSz + dwTemp + 1] == NULL)
  1107. )
  1108. )
  1109. {
  1110. bFound = true;
  1111. if (bEnable)
  1112. {
  1113. pwszRListProp[0] = ONE_CHAR;
  1114. }
  1115. else
  1116. {
  1117. pwszRListProp[0] = ZERO_CHAR;
  1118. }
  1119. }
  1120. pwszRListProp += dwTokSz; // go to the next part of the multisz
  1121. }
  1122. if (!bFound)
  1123. {
  1124. BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
  1125. }
  1126. // set the new property value for property
  1127. hr = SetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, pTop, dwRListPropSz);
  1128. BAIL_ON_FAILURE(hr);
  1129. done:
  1130. if (pTop)
  1131. {
  1132. delete [] pTop;
  1133. }
  1134. return hr;
  1135. }
  1136. STDMETHODIMP CSecConLib::AddExtensionFile(
  1137. /* [in] */ LPCWSTR bstrExtensionFile,
  1138. /* [in] */ bool bAccess,
  1139. /* [in] */ LPCWSTR bstrGroupID,
  1140. /* [in] */ bool bCanDelete,
  1141. /* [in] */ LPCWSTR bstrDescription,
  1142. /* [in] */ LPCWSTR wszPath)
  1143. {
  1144. HRESULT hr = S_OK;
  1145. WCHAR *pwszRListProp = NULL;
  1146. WCHAR *pwszOrig = NULL;
  1147. WCHAR *pwszTopOrig = NULL;
  1148. DWORD dwRListPropSz = 0;
  1149. DWORD dwFileNameSz = 0;
  1150. DWORD dwGroupIDSz = 0;
  1151. DWORD dwDescSz = 0;
  1152. // compute arg length
  1153. dwFileNameSz = (DWORD)wcslen(bstrExtensionFile);
  1154. dwGroupIDSz = (DWORD)wcslen(bstrGroupID);
  1155. dwDescSz = (DWORD)wcslen(bstrDescription);
  1156. hr = InternalInitIfNecessary();
  1157. if (FAILED(hr))
  1158. {
  1159. BAIL_ON_FAILURE(hr);
  1160. }
  1161. // get the current property value for restriction list
  1162. hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
  1163. if (MD_ERROR_DATA_NOT_FOUND == hr)
  1164. {
  1165. // this is okay, we just need to create the property.
  1166. hr = S_OK;
  1167. dwRListPropSz = 0;
  1168. }
  1169. BAIL_ON_FAILURE(hr);
  1170. if (!dwRListPropSz)
  1171. {
  1172. // create the property
  1173. // size of the property = 1(0 or 1) + 1(comma) + len(file) + 1(comma) + 1(0 or 1) +
  1174. // 1(comma) + len(GID) + 1(comma) + len(descr) + 2(double null MULTISZ)
  1175. dwRListPropSz = 1 + (DWORD)wcslen(COMMA_STRING) + dwFileNameSz + (DWORD)wcslen(COMMA_STRING) +
  1176. 1 + (DWORD)wcslen(COMMA_STRING) + dwGroupIDSz + (DWORD)wcslen(COMMA_STRING) + dwDescSz + 2;
  1177. // No Leak
  1178. // pwszRListProp never got alloced since we didn't get any value back,
  1179. // so no need to delete first...
  1180. pwszRListProp = new WCHAR[dwRListPropSz];
  1181. if (!pwszRListProp)
  1182. {
  1183. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1184. }
  1185. if (bAccess)
  1186. {
  1187. wcscpy(pwszRListProp, ONE_STRING);
  1188. }
  1189. else
  1190. {
  1191. wcscpy(pwszRListProp, ZERO_STRING);
  1192. }
  1193. wcscat(pwszRListProp, COMMA_STRING);
  1194. wcscat(pwszRListProp, bstrExtensionFile);
  1195. wcscat(pwszRListProp, COMMA_STRING);
  1196. if (bCanDelete)
  1197. {
  1198. wcscat(pwszRListProp, ONE_STRING);
  1199. }
  1200. else
  1201. {
  1202. wcscat(pwszRListProp, ZERO_STRING);
  1203. }
  1204. wcscat(pwszRListProp, COMMA_STRING);
  1205. wcscat(pwszRListProp, bstrGroupID);
  1206. wcscat(pwszRListProp, COMMA_STRING);
  1207. wcscat(pwszRListProp, bstrDescription);
  1208. // add the double null
  1209. pwszRListProp[dwRListPropSz-1] = 0;
  1210. pwszRListProp[dwRListPropSz-2] = 0;
  1211. }
  1212. else
  1213. {
  1214. // property already exists
  1215. // copy the property
  1216. pwszOrig = new WCHAR[dwRListPropSz];
  1217. pwszTopOrig = pwszOrig;
  1218. if (!pwszOrig)
  1219. {
  1220. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1221. }
  1222. memcpy(pwszOrig, pwszRListProp, dwRListPropSz * sizeof(WCHAR));
  1223. // resize the new property to the biggest possible
  1224. if (pwszRListProp)
  1225. {
  1226. delete [] pwszRListProp;
  1227. }
  1228. // max new size is old size + new stuff
  1229. // new stuff = 1(0 or 1) + 1(comma) + len(file) + 1(comma) + 1(0 or 1) +
  1230. // 1(comma) + len(GID) + 1(comma) + len(descr) + 1(null)
  1231. dwRListPropSz = dwRListPropSz +
  1232. 1 + (DWORD)wcslen(COMMA_STRING) + dwFileNameSz + (DWORD)wcslen(COMMA_STRING) +
  1233. 1 + (DWORD)wcslen(COMMA_STRING) + dwGroupIDSz + (DWORD)wcslen(COMMA_STRING) + dwDescSz + 1;
  1234. pwszRListProp = new WCHAR[dwRListPropSz];
  1235. if (!pwszRListProp)
  1236. {
  1237. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1238. }
  1239. WCHAR* pMidBuf = pwszRListProp;
  1240. // copy the old list entries one by one
  1241. while (pwszOrig[0])
  1242. {
  1243. wcscpy(pMidBuf, pwszOrig);
  1244. // skip over the #,
  1245. pMidBuf += 1 + (DWORD)wcslen(COMMA_STRING);
  1246. // check to see if the app already exists
  1247. if ((!_wcsnicmp(bstrExtensionFile, pMidBuf, dwFileNameSz)) &&
  1248. ((pMidBuf[dwFileNameSz] == COMMA_CHAR) ||
  1249. (pMidBuf[dwFileNameSz] == NULL)
  1250. )
  1251. )
  1252. {
  1253. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(ERROR_DUP_NAME));
  1254. }
  1255. pwszOrig += (DWORD)wcslen(pwszOrig) + 1; // go to the next part of the multisz
  1256. pMidBuf += (DWORD)wcslen(pMidBuf) + 1; // go past the null
  1257. }
  1258. // now copy the new file entry on
  1259. if (bAccess)
  1260. {
  1261. wcscpy(pMidBuf, ONE_STRING);
  1262. }
  1263. else
  1264. {
  1265. wcscpy(pMidBuf, ZERO_STRING);
  1266. }
  1267. wcscat(pMidBuf, COMMA_STRING);
  1268. wcscat(pMidBuf, bstrExtensionFile);
  1269. wcscat(pMidBuf, COMMA_STRING);
  1270. if (bCanDelete)
  1271. {
  1272. wcscat(pMidBuf, ONE_STRING);
  1273. }
  1274. else
  1275. {
  1276. wcscat(pMidBuf, ZERO_STRING);
  1277. }
  1278. wcscat(pMidBuf, COMMA_STRING);
  1279. wcscat(pMidBuf, bstrGroupID);
  1280. wcscat(pMidBuf, COMMA_STRING);
  1281. wcscat(pMidBuf, bstrDescription);
  1282. // add the last null
  1283. pMidBuf += (DWORD)wcslen(pMidBuf) + 1;
  1284. *pMidBuf = 0;
  1285. }
  1286. // set the new property value for property
  1287. hr = SetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, pwszRListProp, dwRListPropSz);
  1288. BAIL_ON_FAILURE(hr);
  1289. done:
  1290. if (pwszTopOrig)
  1291. {
  1292. delete [] pwszTopOrig;
  1293. }
  1294. if (pwszRListProp)
  1295. {
  1296. delete [] pwszRListProp;
  1297. }
  1298. return hr;
  1299. }
  1300. STDMETHODIMP CSecConLib::DeleteExtensionFileRecord(
  1301. /* [in] */ LPCWSTR wszExFile,
  1302. /* [in] */ LPCWSTR wszPath)
  1303. {
  1304. HRESULT hr = S_OK;
  1305. WCHAR *pwszRListProp = NULL;
  1306. WCHAR *pwszOrig = NULL;
  1307. WCHAR *pTopOrig = NULL;
  1308. DWORD dwRListPropSz = 0;
  1309. DWORD dwFileNameSz = 0;
  1310. bool bFound = false;
  1311. // compute arg length
  1312. dwFileNameSz = (DWORD)wcslen(wszExFile);
  1313. hr = InternalInitIfNecessary();
  1314. if (FAILED(hr))
  1315. {
  1316. BAIL_ON_FAILURE(hr);
  1317. }
  1318. // get the current property value for applicationdep list
  1319. hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
  1320. BAIL_ON_FAILURE(hr);
  1321. // remove the application
  1322. // copy the property
  1323. pwszOrig = new WCHAR[dwRListPropSz];
  1324. pTopOrig = pwszOrig;
  1325. if (!pwszOrig)
  1326. {
  1327. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1328. }
  1329. memcpy(pwszOrig, pwszRListProp, dwRListPropSz * sizeof(WCHAR));
  1330. dwRListPropSz = 1; //reset size to contain one for the last null
  1331. WCHAR* pMidBuf = pwszRListProp;
  1332. // copy the old apps one by one
  1333. while (pwszOrig[0])
  1334. {
  1335. DWORD dwTokSz = (DWORD)wcslen(pwszOrig) + 1;
  1336. // check to see if we're at the right file
  1337. // look past the bool(1) + comma(sizof_comma_char)
  1338. DWORD dwTemp = (DWORD)sizeof(COMMA_CHAR) / (DWORD)sizeof(WCHAR);
  1339. if (!_wcsnicmp(wszExFile, &pwszOrig[1 + dwTemp], dwFileNameSz) &&
  1340. pwszOrig[dwFileNameSz + dwTemp + 1] == COMMA_CHAR)
  1341. {
  1342. bFound = true;
  1343. // we don't want to do this... spec change in progress
  1344. // check if this is deletable or not - if not, bail with an error
  1345. //if (pwszOrig[dwFileNameSz + 1 + (2 * dwTemp)] == ZERO_CHAR)
  1346. //{
  1347. // BAIL_ON_FAILURE(hr = E_FAIL);
  1348. //}
  1349. }
  1350. else
  1351. {
  1352. // copy it in
  1353. wcscpy(pMidBuf, pwszOrig);
  1354. pMidBuf += dwTokSz; // advance past null
  1355. *pMidBuf = 0; // add the last null
  1356. dwRListPropSz += dwTokSz;
  1357. }
  1358. pwszOrig += dwTokSz; // go to the next part of the multisz
  1359. }
  1360. if (!bFound)
  1361. {
  1362. BAIL_ON_FAILURE(hr = MD_ERROR_DATA_NOT_FOUND);
  1363. }
  1364. // set the new property value for property
  1365. if (dwRListPropSz < 3)
  1366. {
  1367. // handle deleting the last one
  1368. hr = SetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, NULL, 0);
  1369. }
  1370. else
  1371. {
  1372. hr = SetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, pwszRListProp, dwRListPropSz);
  1373. }
  1374. BAIL_ON_FAILURE(hr);
  1375. done:
  1376. if (pTopOrig)
  1377. {
  1378. delete [] pTopOrig;
  1379. }
  1380. if (pwszRListProp)
  1381. {
  1382. delete [] pwszRListProp;
  1383. }
  1384. return hr;
  1385. }
  1386. STDMETHODIMP CSecConLib::ListExtensionFiles(
  1387. /* [in] */ LPCWSTR wszPath,
  1388. /* [out] */ WCHAR **pszBuffer, // MULTI_SZ - allocated in here, caller should delete
  1389. /* [out] */ DWORD *pdwBufferSize) // length includes double null
  1390. {
  1391. WCHAR *pwszRListProp = NULL;
  1392. DWORD dwRListPropSz = 0;
  1393. WCHAR *pList = NULL;
  1394. WCHAR *pTempList = NULL;
  1395. DWORD dwListLen = 1; // one for the extra null at the end
  1396. DWORD dwOldListLen = 1;
  1397. HRESULT hr = S_OK;
  1398. WCHAR *pTop = NULL;
  1399. hr = InternalInitIfNecessary();
  1400. if (FAILED(hr))
  1401. {
  1402. BAIL_ON_FAILURE(hr);
  1403. }
  1404. // get the current property value for applicationdep list
  1405. hr = GetMultiSZPropVal(wszPath, MD_WEB_SVC_EXT_RESTRICTION_LIST, &pwszRListProp, &dwRListPropSz);
  1406. BAIL_ON_FAILURE(hr);
  1407. if (NULL == pwszRListProp)
  1408. {
  1409. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1410. }
  1411. pTop = pwszRListProp;
  1412. // iterate through the files
  1413. while (pwszRListProp[0])
  1414. {
  1415. pwszRListProp += 1 + ((DWORD)sizeof(COMMA_CHAR)/(DWORD)sizeof(WCHAR));
  1416. WCHAR* pMidBuf = wcschr(pwszRListProp, COMMA_CHAR);
  1417. if (pMidBuf)
  1418. {
  1419. // null the comma and go past it
  1420. *pMidBuf = 0;
  1421. *pMidBuf++;
  1422. // allocate the memory
  1423. dwListLen += (DWORD)wcslen(pwszRListProp) + 1; // for the null
  1424. pTempList = new WCHAR[dwListLen];
  1425. if (!pTempList)
  1426. {
  1427. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1428. }
  1429. if (pList)
  1430. {
  1431. // copy the previous list
  1432. memcpy(pTempList, pList, dwOldListLen * sizeof(WCHAR));
  1433. delete [] pList;
  1434. }
  1435. // copy on the file name
  1436. wcscpy(&pTempList[dwOldListLen - 1], pwszRListProp);
  1437. pTempList[dwListLen-1] = 0;
  1438. pTempList[dwListLen-2] = 0;
  1439. pList = pTempList;
  1440. dwOldListLen = dwListLen;
  1441. }
  1442. else
  1443. {
  1444. pMidBuf = pwszRListProp + (DWORD)wcslen(pwszRListProp) + 1;
  1445. }
  1446. // now go to the next application
  1447. pwszRListProp = pMidBuf + (DWORD)wcslen(pMidBuf) + 1;
  1448. }
  1449. if (!pList)
  1450. {
  1451. // make it a valid empty multisz
  1452. dwListLen = 2;
  1453. pList = new WCHAR[dwListLen];
  1454. if (!pList)
  1455. {
  1456. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1457. }
  1458. wmemset(pList, 0, dwListLen);
  1459. }
  1460. *pszBuffer = pList;
  1461. *pdwBufferSize = dwListLen;
  1462. done:
  1463. if (pTop)
  1464. {
  1465. delete [] pTop;
  1466. }
  1467. return hr;
  1468. }