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.

2084 lines
50 KiB

  1. // This is a part of the ActiveX Template Library.
  2. // Copyright (C) 1996 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // ActiveX Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // ActiveX Template Library product.
  10. #ifndef __ATLBASE_H__
  11. #error atlimpl.cpp requires atlbase.h to be included first
  12. #endif
  13. const IID IID_IRegister = {0xCC118C81,0xB379,0x11CF,{0x84,0xE3,0x00,0xAA,0x00,0x21,0xF3,0x37}};
  14. const CLSID CLSID_Register = {0xCC118C85,0xB379,0x11CF,{0x84,0xE3,0x00,0xAA,0x00,0x21,0xF3,0x37}};
  15. #ifndef _ATL_NO_OLEAUT
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CComBSTR
  18. CComBSTR& CComBSTR::operator=(const CComBSTR& src)
  19. {
  20. if (m_str != src.m_str)
  21. {
  22. if (m_str)
  23. ::SysFreeString(m_str);
  24. m_str = src.Copy();
  25. }
  26. return *this;
  27. }
  28. CComBSTR& CComBSTR::operator=(LPCOLESTR pSrc)
  29. {
  30. if (m_str)
  31. ::SysFreeString(m_str);
  32. m_str = ::SysAllocString(pSrc);
  33. return *this;
  34. }
  35. #ifndef OLE2ANSI
  36. CComBSTR::CComBSTR(LPCSTR pSrc)
  37. {
  38. USES_CONVERSION;
  39. m_str = ::SysAllocString(A2COLE(pSrc));
  40. }
  41. CComBSTR::CComBSTR(int nSize, LPCSTR sz)
  42. {
  43. USES_CONVERSION;
  44. m_str = ::SysAllocStringLen(A2COLE(sz), nSize);
  45. }
  46. CComBSTR& CComBSTR::operator=(LPCSTR pSrc)
  47. {
  48. USES_CONVERSION;
  49. if (m_str)
  50. ::SysFreeString(m_str);
  51. m_str = ::SysAllocString(A2COLE(pSrc));
  52. return *this;
  53. }
  54. #endif
  55. /////////////////////////////////////////////////////////////////////////////
  56. // CComVariant
  57. #ifndef OLE2ANSI
  58. CComVariant::CComVariant(LPCSTR lpsz)
  59. {
  60. USES_CONVERSION;
  61. VariantInit(this);
  62. vt = VT_BSTR;
  63. bstrVal = ::SysAllocString(A2COLE(lpsz));
  64. }
  65. CComVariant& CComVariant::operator=(LPCSTR lpsz)
  66. {
  67. USES_CONVERSION;
  68. VariantClear(this);
  69. vt = VT_BSTR;
  70. bstrVal = ::SysAllocString(A2COLE(lpsz));
  71. return *this;
  72. }
  73. #endif
  74. #endif // !_ATL_NO_OLEAUT
  75. /////////////////////////////////////////////////////////////////////////////
  76. // Smart Pointer helpers
  77. IUnknown* WINAPI _AtlComPtrAssign(IUnknown** pp, IUnknown* lp)
  78. {
  79. if (lp != NULL)
  80. lp->AddRef();
  81. if (*pp)
  82. (*pp)->Release();
  83. *pp = lp;
  84. return lp;
  85. }
  86. IUnknown* WINAPI _AtlComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid)
  87. {
  88. IUnknown* pTemp = *pp;
  89. lp->QueryInterface(riid, (void**)pp);
  90. if (pTemp)
  91. pTemp->Release();
  92. return *pp;
  93. }
  94. /////////////////////////////////////////////////////////////////////////////
  95. // Inproc Marshaling helpers
  96. void WINAPI AtlFreeMarshalStream(IStream* pStream)
  97. {
  98. if (pStream != NULL)
  99. {
  100. CoReleaseMarshalData(pStream);
  101. pStream->Release();
  102. }
  103. }
  104. HRESULT WINAPI AtlMarshalPtrInProc(IUnknown* pUnk, const IID& iid, IStream** ppStream)
  105. {
  106. HRESULT hRes = CreateStreamOnHGlobal(NULL, TRUE, ppStream);
  107. if (SUCCEEDED(hRes))
  108. {
  109. hRes = CoMarshalInterface(*ppStream, iid,
  110. pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);
  111. if (FAILED(hRes))
  112. {
  113. (*ppStream)->Release();
  114. *ppStream = NULL;
  115. }
  116. }
  117. return hRes;
  118. }
  119. HRESULT WINAPI AtlUnmarshalPtr(IStream* pStream, const IID& iid, IUnknown** ppUnk)
  120. {
  121. *ppUnk = NULL;
  122. HRESULT hRes = E_INVALIDARG;
  123. if (pStream != NULL)
  124. {
  125. LARGE_INTEGER l;
  126. l.QuadPart = 0;
  127. pStream->Seek(l, STREAM_SEEK_SET, NULL);
  128. hRes = CoUnmarshalInterface(pStream, iid, (void**)ppUnk);
  129. }
  130. return hRes;
  131. }
  132. /////////////////////////////////////////////////////////////////////////////
  133. // Connection Point Helpers
  134. HRESULT AtlAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw)
  135. {
  136. CComPtr<IConnectionPointContainer> pCPC;
  137. CComPtr<IConnectionPoint> pCP;
  138. HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  139. if (SUCCEEDED(hRes))
  140. hRes = pCPC->FindConnectionPoint(iid, &pCP);
  141. if (SUCCEEDED(hRes))
  142. hRes = pCP->Advise(pUnk, pdw);
  143. return hRes;
  144. }
  145. HRESULT AtlUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw)
  146. {
  147. CComPtr<IConnectionPointContainer> pCPC;
  148. CComPtr<IConnectionPoint> pCP;
  149. HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
  150. if (SUCCEEDED(hRes))
  151. hRes = pCPC->FindConnectionPoint(iid, &pCP);
  152. if (SUCCEEDED(hRes))
  153. hRes = pCP->Unadvise(dw);
  154. return hRes;
  155. }
  156. #ifndef _ATL_NO_OLEAUT
  157. /////////////////////////////////////////////////////////////////////////////
  158. // CComTypeInfoHolder
  159. void CComTypeInfoHolder::AddRef()
  160. {
  161. _Module.m_csTypeInfoHolder.Lock();
  162. m_dwRef++;
  163. _Module.m_csTypeInfoHolder.Unlock();
  164. }
  165. void CComTypeInfoHolder::Release()
  166. {
  167. _Module.m_csTypeInfoHolder.Lock();
  168. if (--m_dwRef == 0)
  169. {
  170. if (m_pInfo != NULL)
  171. m_pInfo->Release();
  172. m_pInfo = NULL;
  173. }
  174. _Module.m_csTypeInfoHolder.Unlock();
  175. }
  176. HRESULT CComTypeInfoHolder::GetTI(LCID lcid, ITypeInfo** ppInfo)
  177. {
  178. //If this assert occurs then most likely didn't initialize properly
  179. _ASSERTE(m_plibid != NULL && m_pguid != NULL);
  180. _ASSERTE(ppInfo != NULL);
  181. *ppInfo = NULL;
  182. HRESULT hRes = E_FAIL;
  183. _Module.m_csTypeInfoHolder.Lock();
  184. if (m_pInfo == NULL)
  185. {
  186. ITypeLib* pTypeLib;
  187. hRes = LoadRegTypeLib(*m_plibid, m_wMajor, m_wMinor, lcid, &pTypeLib);
  188. if (SUCCEEDED(hRes))
  189. {
  190. ITypeInfo* pTypeInfo;
  191. hRes = pTypeLib->GetTypeInfoOfGuid(*m_pguid, &pTypeInfo);
  192. if (SUCCEEDED(hRes))
  193. m_pInfo = pTypeInfo;
  194. pTypeLib->Release();
  195. }
  196. }
  197. *ppInfo = m_pInfo;
  198. if (m_pInfo != NULL)
  199. {
  200. m_pInfo->AddRef();
  201. hRes = S_OK;
  202. }
  203. _Module.m_csTypeInfoHolder.Unlock();
  204. return hRes;
  205. }
  206. HRESULT CComTypeInfoHolder::GetTypeInfo(UINT /*itinfo*/, LCID lcid,
  207. ITypeInfo** pptinfo)
  208. {
  209. HRESULT hRes = E_POINTER;
  210. if (pptinfo != NULL)
  211. hRes = GetTI(lcid, pptinfo);
  212. return hRes;
  213. }
  214. HRESULT CComTypeInfoHolder::GetIDsOfNames(REFIID /*riid*/, LPOLESTR* rgszNames,
  215. UINT cNames, LCID lcid, DISPID* rgdispid)
  216. {
  217. ITypeInfo* pInfo;
  218. HRESULT hRes = GetTI(lcid, &pInfo);
  219. if (pInfo != NULL)
  220. {
  221. hRes = pInfo->GetIDsOfNames(rgszNames, cNames, rgdispid);
  222. pInfo->Release();
  223. }
  224. return hRes;
  225. }
  226. HRESULT CComTypeInfoHolder::Invoke(IDispatch* p, DISPID dispidMember, REFIID /*riid*/,
  227. LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
  228. EXCEPINFO* pexcepinfo, UINT* puArgErr)
  229. {
  230. SetErrorInfo(0, NULL);
  231. ITypeInfo* pInfo;
  232. HRESULT hRes = GetTI(lcid, &pInfo);
  233. if (pInfo != NULL)
  234. {
  235. hRes = pInfo->Invoke(p, dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
  236. pInfo->Release();
  237. }
  238. return hRes;
  239. }
  240. /////////////////////////////////////////////////////////////////////////////
  241. // IDispatch Error handling
  242. HRESULT WINAPI AtlReportError(const CLSID& clsid, UINT nID, const IID& iid,
  243. HRESULT hRes)
  244. {
  245. TCHAR szDesc[1024];
  246. szDesc[0] = NULL;
  247. // For a valid HRESULT the id should be in the range [0x0200, 0xffff]
  248. _ASSERTE((nID >= 0x0200 && nID <= 0xffff) || hRes != 0);
  249. if (LoadString(_Module.GetResourceInstance(), nID, szDesc, 1024) == 0)
  250. {
  251. _ASSERTE(FALSE);
  252. lstrcpy(szDesc, _T("Unknown Error"));
  253. }
  254. AtlReportError(clsid, szDesc, iid, hRes);
  255. if (hRes == 0)
  256. hRes = MAKE_HRESULT(3, FACILITY_ITF, nID);
  257. return hRes;
  258. }
  259. #ifndef OLE2ANSI
  260. HRESULT WINAPI AtlReportError(const CLSID& clsid, LPCSTR lpszDesc,
  261. const IID& iid, HRESULT hRes)
  262. {
  263. USES_CONVERSION;
  264. return AtlReportError(clsid, A2CW(lpszDesc), iid, hRes);
  265. }
  266. #endif
  267. HRESULT WINAPI AtlReportError(const CLSID& clsid, LPCOLESTR lpszDesc,
  268. const IID& iid, HRESULT hRes)
  269. {
  270. CComPtr<ICreateErrorInfo> pICEI;
  271. if (SUCCEEDED(CreateErrorInfo(&pICEI)))
  272. {
  273. CComPtr<IErrorInfo> pErrorInfo;
  274. pICEI->SetGUID(iid);
  275. LPOLESTR lpsz;
  276. ProgIDFromCLSID(clsid, &lpsz);
  277. if (lpsz != NULL)
  278. pICEI->SetSource(lpsz);
  279. CoTaskMemFree(lpsz);
  280. pICEI->SetDescription((LPOLESTR)lpszDesc);
  281. if (SUCCEEDED(pICEI->QueryInterface(IID_IErrorInfo, (void**)&pErrorInfo)))
  282. SetErrorInfo(0, pErrorInfo);
  283. }
  284. return (hRes == 0) ? DISP_E_EXCEPTION : hRes;
  285. }
  286. #endif // !_ATL_NO_OLEAUT
  287. /////////////////////////////////////////////////////////////////////////////
  288. // QI implementation
  289. #ifdef _ATL_DEBUG_QI
  290. #define _DUMPIID(iid, name, hr) DumpIID(iid, name, hr)
  291. #else
  292. #define _DUMPIID(iid, name, hr) hr
  293. #endif
  294. HRESULT WINAPI CComObjectRoot::InternalQueryInterface(void* pThis,
  295. const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
  296. {
  297. _ASSERTE(pThis != NULL);
  298. // First entry should be an offset (pFunc == 1)
  299. _ASSERTE(pEntries->pFunc == (_ATL_CREATORARGFUNC*)1);
  300. #ifdef _ATL_DEBUG_QI
  301. LPCTSTR pszClassName = (LPCTSTR) pEntries[-1].dw;
  302. #endif // _ATL_DEBUG_QI
  303. if (ppvObject == NULL)
  304. return _DUMPIID(iid, pszClassName, E_POINTER);
  305. *ppvObject = NULL;
  306. if (InlineIsEqualUnknown(iid)) // use first interface
  307. {
  308. IUnknown* pUnk = (IUnknown*)((INT_PTR)pThis+pEntries->dw);
  309. pUnk->AddRef();
  310. *ppvObject = pUnk;
  311. return _DUMPIID(iid, pszClassName, S_OK);
  312. }
  313. while (pEntries->pFunc != NULL)
  314. {
  315. BOOL bBlind = (pEntries->piid == NULL);
  316. if (bBlind || InlineIsEqualGUID(*(pEntries->piid), iid))
  317. {
  318. if (pEntries->pFunc == (_ATL_CREATORARGFUNC*)1) //offset
  319. {
  320. _ASSERTE(!bBlind);
  321. IUnknown* pUnk = (IUnknown*)((INT_PTR)pThis+pEntries->dw);
  322. pUnk->AddRef();
  323. *ppvObject = pUnk;
  324. return _DUMPIID(iid, pszClassName, S_OK);
  325. }
  326. else //actual function call
  327. {
  328. HRESULT hRes = pEntries->pFunc(pThis,
  329. iid, ppvObject, pEntries->dw);
  330. if (hRes == S_OK || (!bBlind && FAILED(hRes)))
  331. return _DUMPIID(iid, pszClassName, hRes);
  332. }
  333. }
  334. pEntries++;
  335. }
  336. return _DUMPIID(iid, pszClassName, E_NOINTERFACE);
  337. }
  338. #ifdef _ATL_DEBUG_QI
  339. HRESULT CComObjectRoot::DumpIID(REFIID iid, LPCTSTR pszClassName, HRESULT hr)
  340. {
  341. USES_CONVERSION;
  342. CRegKey key;
  343. TCHAR szName[100];
  344. DWORD dwType,dw = sizeof(szName);
  345. LPOLESTR pszGUID = NULL;
  346. StringFromCLSID(iid, &pszGUID);
  347. OutputDebugString(pszClassName);
  348. OutputDebugString(_T(" - "));
  349. // Attempt to find it in the interfaces section
  350. key.Open(HKEY_CLASSES_ROOT, _T("Interface"));
  351. if (key.Open(key, OLE2T(pszGUID)) == S_OK)
  352. {
  353. *szName = 0;
  354. RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw);
  355. OutputDebugString(szName);
  356. goto cleanup;
  357. }
  358. // Attempt to find it in the clsid section
  359. key.Open(HKEY_CLASSES_ROOT, _T("CLSID"));
  360. if (key.Open(key, OLE2T(pszGUID)) == S_OK)
  361. {
  362. *szName = 0;
  363. RegQueryValueEx(key.m_hKey, (LPTSTR)NULL, NULL, &dwType, (LPBYTE)szName, &dw);
  364. OutputDebugString(_T("(CLSID\?\?\?) "));
  365. OutputDebugString(szName);
  366. goto cleanup;
  367. }
  368. OutputDebugString(OLE2T(pszGUID));
  369. cleanup:
  370. if (hr != S_OK)
  371. OutputDebugString(_T(" - failed"));
  372. OutputDebugString(_T("\n"));
  373. CoTaskMemFree(pszGUID);
  374. return hr;
  375. }
  376. #endif
  377. HRESULT WINAPI CComObjectRoot::_Cache(void* pv, REFIID iid, void** ppvObject, DWORD dw)
  378. {
  379. HRESULT hRes = E_NOINTERFACE;
  380. _ATL_CACHEDATA* pcd = (_ATL_CACHEDATA*)(DWORD_PTR)dw; //$WIN64 dw --> __ptr64
  381. IUnknown** pp = (IUnknown**)((DWORD_PTR)pv + pcd->dwOffsetVar);
  382. if (*pp == NULL)
  383. {
  384. _ThreadModel::CriticalSection* pcs =
  385. (_ThreadModel::CriticalSection*)((INT_PTR)pv + pcd->dwOffsetCS);
  386. pcs->Lock();
  387. if (*pp == NULL)
  388. hRes = pcd->pFunc(pv, IID_IUnknown, (void**)pp);
  389. pcs->Unlock();
  390. }
  391. if (*pp != NULL)
  392. hRes = (*pp)->QueryInterface(iid, ppvObject);
  393. return hRes;
  394. }
  395. HRESULT WINAPI CComObjectRoot::_Creator(void* pv, REFIID iid, void** ppvObject, DWORD dw)
  396. {
  397. _ATL_CREATORDATA* pcd = (_ATL_CREATORDATA*)(DWORD_PTR)dw; //$WIN64 dw --> __ptr64
  398. return pcd->pFunc(pv, iid, ppvObject);
  399. }
  400. HRESULT WINAPI CComObjectRoot::_Delegate(void* pv, REFIID iid, void** ppvObject, DWORD dw)
  401. {
  402. HRESULT hRes = E_NOINTERFACE;
  403. IUnknown* p = *(IUnknown**)((DWORD_PTR)pv + dw);
  404. if (p != NULL)
  405. hRes = p->QueryInterface(iid, ppvObject);
  406. return hRes;
  407. }
  408. HRESULT WINAPI CComObjectRoot::_Chain(void* pv, REFIID iid, void** ppvObject, DWORD dw)
  409. {
  410. _ATL_CHAINDATA* pcd = (_ATL_CHAINDATA*)(DWORD_PTR)dw; //$WIN64 dw --> __ptr64
  411. void* p = (void*)((DWORD_PTR)pv + pcd->dwOffset);
  412. return InternalQueryInterface(p, pcd->pFunc(), iid, ppvObject);
  413. }
  414. /////////////////////////////////////////////////////////////////////////////
  415. // CComClassFactory
  416. STDMETHODIMP CComClassFactory::CreateInstance(LPUNKNOWN pUnkOuter,
  417. REFIID riid, void** ppvObj)
  418. {
  419. _ASSERTE(m_pfnCreateInstance != NULL);
  420. HRESULT hRes = E_POINTER;
  421. if (ppvObj != NULL)
  422. {
  423. *ppvObj = NULL;
  424. // can't ask for anything other than IUnknown when aggregating
  425. _ASSERTE((pUnkOuter == NULL) || InlineIsEqualUnknown(riid));
  426. if ((pUnkOuter != NULL) && !InlineIsEqualUnknown(riid))
  427. hRes = CLASS_E_NOAGGREGATION;
  428. else
  429. hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj);
  430. }
  431. return hRes;
  432. }
  433. STDMETHODIMP CComClassFactory::LockServer(BOOL fLock)
  434. {
  435. if (fLock)
  436. _Module.Lock();
  437. else
  438. _Module.Unlock();
  439. return S_OK;
  440. }
  441. STDMETHODIMP CComClassFactory2Base::LockServer(BOOL fLock)
  442. {
  443. if (fLock)
  444. _Module.Lock();
  445. else
  446. _Module.Unlock();
  447. return S_OK;
  448. }
  449. #ifndef _ATL_NO_CONNECTION_POINTS
  450. /////////////////////////////////////////////////////////////////////////////
  451. // Connection Points
  452. CComConnectionPointBase* CComConnectionPointContainerImpl::
  453. FindConnPoint(REFIID riid)
  454. {
  455. const _ATL_CONNMAP_ENTRY* pEntry = GetConnMap();
  456. while (pEntry->dwOffset != (DWORD)-1)
  457. {
  458. CComConnectionPointBase* pCP =
  459. (CComConnectionPointBase*)((INT_PTR)this+pEntry->dwOffset);
  460. if (InlineIsEqualGUID(riid, *pCP->GetIID()))
  461. return pCP;
  462. pEntry++;
  463. }
  464. return NULL;
  465. }
  466. void CComConnectionPointContainerImpl::InitCloneVector(
  467. CComConnectionPointBase** ppCP)
  468. {
  469. const _ATL_CONNMAP_ENTRY* pEntry = GetConnMap();
  470. while (pEntry->dwOffset != (DWORD)-1)
  471. {
  472. *ppCP = (CComConnectionPointBase*)((INT_PTR)this+pEntry->dwOffset);
  473. ppCP++;
  474. pEntry++;
  475. }
  476. }
  477. STDMETHODIMP CComConnectionPointContainerImpl::EnumConnectionPoints(
  478. IEnumConnectionPoints** ppEnum)
  479. {
  480. if (ppEnum == NULL)
  481. return E_POINTER;
  482. *ppEnum = NULL;
  483. CComEnumConnectionPoints* pEnum = NULL;
  484. ATLTRY(pEnum = new CComObject<CComEnumConnectionPoints>)
  485. if (pEnum == NULL)
  486. return E_OUTOFMEMORY;
  487. // count the entries in the map
  488. _ATL_CONNMAP_ENTRY* pEntry = (_ATL_CONNMAP_ENTRY*)GetConnMap();
  489. int nCPCount=0;
  490. while (pEntry->dwOffset != (DWORD)-1)
  491. {
  492. nCPCount++;
  493. pEntry++;
  494. }
  495. _ASSERTE(nCPCount > 0);
  496. // allocate an initialize a vector of connection point object pointers
  497. CComConnectionPointBase** ppCP = (CComConnectionPointBase**)alloca(sizeof(CComConnectionPointBase*)*nCPCount);
  498. InitCloneVector(ppCP);
  499. // copy the pointers: they will AddRef this object
  500. HRESULT hRes = pEnum->Init((IConnectionPoint**)&ppCP[0],
  501. (IConnectionPoint**)&ppCP[nCPCount], this, AtlFlagCopy);
  502. if (FAILED(hRes))
  503. {
  504. delete pEnum;
  505. return hRes;
  506. }
  507. hRes = pEnum->QueryInterface(IID_IEnumConnectionPoints, (void**)ppEnum);
  508. if (FAILED(hRes))
  509. delete pEnum;
  510. return hRes;
  511. }
  512. STDMETHODIMP CComConnectionPointContainerImpl::FindConnectionPoint(
  513. REFIID riid, IConnectionPoint** ppCP)
  514. {
  515. if (ppCP == NULL)
  516. return E_POINTER;
  517. *ppCP = NULL;
  518. HRESULT hRes = CONNECT_E_NOCONNECTION;
  519. CComConnectionPointBase* pCP = FindConnPoint(riid);
  520. if (pCP != NULL)
  521. {
  522. pCP->AddRef();
  523. *ppCP = pCP;
  524. hRes = S_OK;
  525. }
  526. return hRes;
  527. }
  528. BOOL CComDynamicArrayCONNECTDATA::Add(IUnknown* pUnk)
  529. {
  530. if (m_nSize == 0) // no connections
  531. {
  532. m_cd.pUnk = pUnk;
  533. m_cd.dwCookie = (DWORD)pUnk;
  534. m_nSize = 1;
  535. return TRUE;
  536. }
  537. else if (m_nSize == 1)
  538. {
  539. //create array
  540. m_pCD = (CONNECTDATA*)malloc(sizeof(CONNECTDATA)*_DEFAULT_VECTORLENGTH);
  541. memset(m_pCD, 0, sizeof(CONNECTDATA)*_DEFAULT_VECTORLENGTH);
  542. m_pCD[0] = m_cd;
  543. m_nSize = _DEFAULT_VECTORLENGTH;
  544. }
  545. for (CONNECTDATA* p = begin();p<end();p++)
  546. {
  547. if (p->pUnk == NULL)
  548. {
  549. p->pUnk = pUnk;
  550. p->dwCookie = (DWORD)pUnk;
  551. return TRUE;
  552. }
  553. }
  554. int nAlloc = m_nSize*2;
  555. m_pCD = (CONNECTDATA*)realloc(m_pCD, sizeof(CONNECTDATA)*nAlloc);
  556. memset(&m_pCD[m_nSize], 0, sizeof(CONNECTDATA)*m_nSize);
  557. m_pCD[m_nSize].pUnk = pUnk;
  558. m_pCD[m_nSize].dwCookie = (DWORD)pUnk;
  559. m_nSize = nAlloc;
  560. return TRUE;
  561. }
  562. BOOL CComDynamicArrayCONNECTDATA::Remove(DWORD dwCookie)
  563. {
  564. CONNECTDATA* p;
  565. if (dwCookie == NULL)
  566. return FALSE;
  567. if (m_nSize == 0)
  568. return FALSE;
  569. if (m_nSize == 1)
  570. {
  571. if (m_cd.dwCookie == dwCookie)
  572. {
  573. m_nSize = 0;
  574. return TRUE;
  575. }
  576. return FALSE;
  577. }
  578. for (p=begin();p<end();p++)
  579. {
  580. if (p->dwCookie == dwCookie)
  581. {
  582. p->pUnk = NULL;
  583. p->dwCookie = NULL;
  584. return TRUE;
  585. }
  586. }
  587. return FALSE;
  588. }
  589. STDMETHODIMP CComConnectionPointBase::GetConnectionInterface(IID* piid)
  590. {
  591. if (piid == NULL)
  592. return E_POINTER;
  593. *piid = *(IID*)GetIID();
  594. return S_OK;
  595. }
  596. STDMETHODIMP CComConnectionPointBase::GetConnectionPointContainer(IConnectionPointContainer** ppCPC)
  597. {
  598. if (ppCPC == NULL)
  599. return E_POINTER;
  600. _ASSERTE(m_pContainer != NULL);
  601. *ppCPC = m_pContainer;
  602. m_pContainer->AddRef();
  603. return S_OK;
  604. }
  605. #endif //!_ATL_NO_CONNECTION_POINTS
  606. /////////////////////////////////////////////////////////////////////////////
  607. // statics
  608. static UINT WINAPI AtlGetDirLen(LPCOLESTR lpszPathName)
  609. {
  610. _ASSERTE(lpszPathName != NULL);
  611. // always capture the complete file name including extension (if present)
  612. LPCOLESTR lpszTemp = lpszPathName;
  613. for (LPCOLESTR lpsz = lpszPathName; *lpsz != NULL; )
  614. {
  615. LPCOLESTR lp = CharNextO(lpsz);
  616. // remember last directory/drive separator
  617. if (*lpsz == OLESTR('\\') || *lpsz == OLESTR('/') || *lpsz == OLESTR(':'))
  618. lpszTemp = lp;
  619. lpsz = lp;
  620. }
  621. return (UINT)(lpszTemp-lpszPathName);
  622. }
  623. /////////////////////////////////////////////////////////////////////////////
  624. // Object Registry Support
  625. static HRESULT WINAPI AtlRegisterProgID(LPCTSTR lpszCLSID, LPCTSTR lpszProgID, LPCTSTR lpszUserDesc)
  626. {
  627. CRegKey keyProgID;
  628. LONG lRes = keyProgID.Create(HKEY_CLASSES_ROOT, lpszProgID);
  629. if (lRes == ERROR_SUCCESS)
  630. {
  631. keyProgID.SetValue(lpszUserDesc);
  632. keyProgID.SetKeyValue(_T("CLSID"), lpszCLSID);
  633. return S_OK;
  634. }
  635. return HRESULT_FROM_WIN32(lRes);
  636. }
  637. #ifndef _ATL_NO_OLEAUT
  638. HRESULT WINAPI CComModule::UpdateRegistryFromResource(UINT nResID, BOOL bRegister,
  639. struct _ATL_REGMAP_ENTRY* pMapEntries)
  640. {
  641. CComPtr<IRegister> p;
  642. HRESULT hRes = CoCreateInstance(CLSID_Register, NULL,
  643. CLSCTX_INPROC_SERVER, IID_IRegister, (void**)&p);
  644. if (SUCCEEDED(hRes))
  645. {
  646. TCHAR szModule[_MAX_PATH];
  647. GetModuleFileName(_Module.GetModuleInstance(), szModule, _MAX_PATH);
  648. p->AddReplacement(CComBSTR(OLESTR("Module")), CComBSTR(szModule));
  649. if (NULL != pMapEntries)
  650. {
  651. while (NULL != pMapEntries->szKey)
  652. {
  653. _ASSERTE(NULL != pMapEntries->szData);
  654. CComBSTR bstrKey(pMapEntries->szKey);
  655. CComBSTR bstrValue(pMapEntries->szData);
  656. p->AddReplacement(bstrKey, bstrValue);
  657. pMapEntries++;
  658. }
  659. }
  660. CComVariant varRes;
  661. varRes.vt = VT_I2;
  662. varRes.iVal = (short)nResID;
  663. CComVariant varReg(OLESTR("REGISTRY"));
  664. GetModuleFileName(_Module.GetRegistryResourceInstance(), szModule, _MAX_PATH);
  665. CComBSTR bstrModule = szModule;
  666. if (bRegister)
  667. {
  668. hRes = p->ResourceRegister(bstrModule, varRes, varReg);
  669. }
  670. else
  671. {
  672. hRes = p->ResourceUnregister(bstrModule, varRes, varReg);
  673. }
  674. }
  675. return hRes;
  676. }
  677. HRESULT WINAPI CComModule::UpdateRegistryFromResource(LPCTSTR lpszRes, BOOL bRegister,
  678. struct _ATL_REGMAP_ENTRY* pMapEntries)
  679. {
  680. CComPtr<IRegister> p;
  681. HRESULT hRes = CoCreateInstance(CLSID_Register, NULL,
  682. CLSCTX_INPROC_SERVER, IID_IRegister, (void**)&p);
  683. if (SUCCEEDED(hRes))
  684. {
  685. TCHAR szModule[_MAX_PATH];
  686. GetModuleFileName(_Module.GetModuleInstance(), szModule, _MAX_PATH);
  687. p->AddReplacement(CComBSTR(OLESTR("Module")), CComBSTR(szModule));
  688. if (NULL != pMapEntries)
  689. {
  690. while (NULL != pMapEntries->szKey)
  691. {
  692. _ASSERTE(NULL != pMapEntries->szData);
  693. CComBSTR bstrKey(pMapEntries->szKey);
  694. CComBSTR bstrValue(pMapEntries->szData);
  695. p->AddReplacement(bstrKey, bstrValue);
  696. pMapEntries++;
  697. }
  698. }
  699. CComVariant varRes(lpszRes);
  700. CComVariant varReg(OLESTR("REGISTRY"));
  701. GetModuleFileName(_Module.GetRegistryResourceInstance(), szModule, _MAX_PATH);
  702. CComBSTR bstrModule = szModule;
  703. if (bRegister)
  704. {
  705. hRes = p->ResourceRegister(bstrModule, varRes, varReg);
  706. }
  707. else
  708. {
  709. hRes = p->ResourceUnregister(bstrModule, varRes, varReg);
  710. }
  711. }
  712. return hRes;
  713. }
  714. #endif // !_ATL_NO_OLEAUT
  715. #ifdef _ATL_STATIC_REGISTRY
  716. // Statically linking to Registry Ponent
  717. HRESULT WINAPI CComModule::UpdateRegistryFromResourceS(UINT nResID, BOOL bRegister,
  718. struct _ATL_REGMAP_ENTRY* pMapEntries)
  719. {
  720. CRegObject ro;
  721. CRegException re;
  722. TCHAR szModule[_MAX_PATH];
  723. GetModuleFileName(_Module.GetModuleInstance(), szModule, _MAX_PATH);
  724. ro.AddReplacement(OLESTR("Module"), CComBSTR(szModule));
  725. if (NULL != pMapEntries)
  726. {
  727. while (NULL != pMapEntries->szKey)
  728. {
  729. _ASSERTE(NULL != pMapEntries->szData);
  730. ro.AddReplacement(CComBSTR(pMapEntries->szKey),
  731. CComBSTR(pMapEntries->szData));
  732. pMapEntries++;
  733. }
  734. }
  735. CComVariant varRes;
  736. varRes.vt = VT_I2;
  737. varRes.iVal = (short)nResID;
  738. CComVariant varReg(OLESTR("REGISTRY"));
  739. GetModuleFileName(_Module.GetRegistryResourceInstance(), szModule, _MAX_PATH);
  740. CComBSTR bstrModule = szModule;
  741. return (bRegister) ? ro.ResourceRegister(bstrModule, varRes, varReg, re) :
  742. ro.ResourceUnregister(bstrModule, varRes, varReg, re);
  743. }
  744. HRESULT WINAPI CComModule::UpdateRegistryFromResourceS(LPCTSTR lpszRes, BOOL bRegister,
  745. struct _ATL_REGMAP_ENTRY* pMapEntries)
  746. {
  747. CRegObject ro;
  748. CRegException re;
  749. TCHAR szModule[_MAX_PATH];
  750. GetModuleFileName(_Module.GetModuleInstance(), szModule, _MAX_PATH);
  751. ro.AddReplacement(OLESTR("Module"), CComBSTR(szModule));
  752. if (NULL != pMapEntries)
  753. {
  754. while (NULL != pMapEntries->szKey)
  755. {
  756. _ASSERTE(NULL != pMapEntries->szData);
  757. ro.AddReplacement(CComBSTR(pMapEntries->szKey),
  758. CComBSTR(pMapEntries->szData));
  759. pMapEntries++;
  760. }
  761. }
  762. CComVariant varRes(lpszRes);
  763. CComVariant varReg(OLESTR("REGISTRY"));
  764. GetModuleFileName(_Module.GetRegistryResourceInstance(), szModule, _MAX_PATH);
  765. CComBSTR bstrModule = szModule;
  766. return (bRegister) ? ro.ResourceRegister(bstrModule, varRes, varReg, re) :
  767. ro.ResourceUnregister(bstrModule, varRes, varReg, re);
  768. }
  769. #endif // _ATL_STATIC_REGISTRY
  770. #ifndef _ATL_NO_OLD_REGISTRY
  771. HRESULT WINAPI CComModule::UpdateRegistryClass(const CLSID& clsid, LPCTSTR lpszProgID,
  772. LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags, BOOL bRegister)
  773. {
  774. if (bRegister)
  775. {
  776. return RegisterClassHelper(clsid, lpszProgID, lpszVerIndProgID, nDescID,
  777. dwFlags);
  778. }
  779. else
  780. return UnregisterClassHelper(clsid, lpszProgID, lpszVerIndProgID);
  781. }
  782. HRESULT WINAPI CComModule::RegisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  783. LPCTSTR lpszVerIndProgID, UINT nDescID, DWORD dwFlags)
  784. {
  785. static const TCHAR szProgID[] = _T("ProgID");
  786. static const TCHAR szVIProgID[] = _T("VersionIndependentProgID");
  787. static const TCHAR szLS32[] = _T("LocalServer32");
  788. static const TCHAR szIPS32[] = _T("InprocServer32");
  789. static const TCHAR szThreadingModel[] = _T("ThreadingModel");
  790. static const TCHAR szAUTPRX32[] = _T("AUTPRX32.DLL");
  791. static const TCHAR szApartment[] = _T("Apartment");
  792. static const TCHAR szBoth[] = _T("both");
  793. USES_CONVERSION;
  794. HRESULT hRes = S_OK;
  795. TCHAR szDesc[256];
  796. LoadString(m_hInst, nDescID, szDesc, 256);
  797. TCHAR szModule[_MAX_PATH];
  798. GetModuleFileName(m_hInst, szModule, _MAX_PATH);
  799. LPOLESTR lpOleStr;
  800. StringFromCLSID(clsid, &lpOleStr);
  801. LPTSTR lpsz = OLE2T(lpOleStr);
  802. if(lpsz == NULL)
  803. {
  804. if(lpOleStr)CoTaskMemFree(lpOleStr);
  805. return E_OUTOFMEMORY;
  806. }
  807. hRes = AtlRegisterProgID(lpsz, lpszProgID, szDesc);
  808. if (hRes == S_OK)
  809. hRes = AtlRegisterProgID(lpsz, lpszVerIndProgID, szDesc);
  810. LONG lRes = ERROR_SUCCESS;
  811. if (hRes == S_OK)
  812. {
  813. CRegKey key;
  814. LONG lRes = key.Open(HKEY_CLASSES_ROOT, _T("CLSID"));
  815. if (lRes == ERROR_SUCCESS)
  816. {
  817. lRes = key.Create(key, lpsz);
  818. if (lRes == ERROR_SUCCESS)
  819. {
  820. key.SetValue(szDesc);
  821. key.SetKeyValue(szProgID, lpszProgID);
  822. key.SetKeyValue(szVIProgID, lpszVerIndProgID);
  823. if ((m_hInst == NULL) || (m_hInst == GetModuleHandle(NULL))) // register as EXE
  824. key.SetKeyValue(szLS32, szModule);
  825. else
  826. {
  827. key.SetKeyValue(szIPS32, (dwFlags & AUTPRXFLAG) ? szAUTPRX32 : szModule);
  828. LPCTSTR lpszModel = (dwFlags & THREADFLAGS_BOTH) ? szBoth :
  829. (dwFlags & THREADFLAGS_APARTMENT) ? szApartment : NULL;
  830. if (lpszModel != NULL)
  831. key.SetKeyValue(szIPS32, lpszModel, szThreadingModel);
  832. }
  833. }
  834. }
  835. }
  836. CoTaskMemFree(lpOleStr);
  837. if (lRes != ERROR_SUCCESS)
  838. hRes = HRESULT_FROM_WIN32(lRes);
  839. return hRes;
  840. }
  841. HRESULT WINAPI CComModule::UnregisterClassHelper(const CLSID& clsid, LPCTSTR lpszProgID,
  842. LPCTSTR lpszVerIndProgID)
  843. {
  844. USES_CONVERSION;
  845. CRegKey key;
  846. key.Attach(HKEY_CLASSES_ROOT);
  847. key.RecurseDeleteKey(lpszProgID);
  848. key.RecurseDeleteKey(lpszVerIndProgID);
  849. LPOLESTR lpOleStr;
  850. StringFromCLSID(clsid, &lpOleStr);
  851. LPTSTR lpsz = OLE2T(lpOleStr);
  852. if (key.Open(key, _T("CLSID")) == ERROR_SUCCESS)
  853. key.RecurseDeleteKey(lpsz);
  854. CoTaskMemFree(lpOleStr);
  855. return S_OK;
  856. }
  857. #endif // _ATL_NO_OLD_REGISTRY
  858. #ifndef _ATL_NO_OLEAUT
  859. /////////////////////////////////////////////////////////////////////////////
  860. // TypeLib Support
  861. HRESULT CComModule::RegisterTypeLib(LPCTSTR lpszIndex)
  862. {
  863. USES_CONVERSION;
  864. _ASSERTE(m_hInst != NULL);
  865. TCHAR szModule[_MAX_PATH+10];
  866. OLECHAR szDir[_MAX_PATH];
  867. szModule[0] = 0;
  868. GetModuleFileName(GetTypeLibInstance(), szModule, _MAX_PATH);
  869. if (lpszIndex != NULL)
  870. lstrcat(szModule, lpszIndex);
  871. ITypeLib* pTypeLib;
  872. LPOLESTR lpszModule = T2OLE(szModule);
  873. HRESULT hr = LoadTypeLib(lpszModule, &pTypeLib);
  874. if (!SUCCEEDED(hr))
  875. {
  876. // typelib not in module, try <module>.tlb instead
  877. LPTSTR lpszExt = NULL;
  878. LPTSTR lpsz;
  879. for (lpsz = szModule; *lpsz != NULL; lpsz = CharNext(lpsz))
  880. {
  881. if (*lpsz == _T('.'))
  882. lpszExt = lpsz;
  883. }
  884. if (lpszExt == NULL)
  885. lpszExt = lpsz;
  886. lstrcpy(lpszExt, _T(".tlb"));
  887. lpszModule = T2OLE(szModule);
  888. hr = LoadTypeLib(lpszModule, &pTypeLib);
  889. }
  890. if (SUCCEEDED(hr))
  891. {
  892. ocscpy(szDir, lpszModule);
  893. szDir[AtlGetDirLen(szDir)] = 0;
  894. hr = ::RegisterTypeLib(pTypeLib, lpszModule, szDir);
  895. }
  896. if (pTypeLib != NULL)
  897. pTypeLib->Release();
  898. return hr;
  899. }
  900. #endif // !_ATL_NO_OLEAUT
  901. /////////////////////////////////////////////////////////////////////////////
  902. // CRegKey
  903. LONG CRegKey::Close()
  904. {
  905. LONG lRes = ERROR_SUCCESS;
  906. if (m_hKey != NULL)
  907. {
  908. lRes = RegCloseKey(m_hKey);
  909. m_hKey = NULL;
  910. }
  911. return lRes;
  912. }
  913. LONG CRegKey::Create(HKEY hKeyParent, LPCTSTR lpszKeyName,
  914. LPTSTR lpszClass, DWORD dwOptions, REGSAM samDesired,
  915. LPSECURITY_ATTRIBUTES lpSecAttr, LPDWORD lpdwDisposition)
  916. {
  917. _ASSERTE(hKeyParent != NULL);
  918. DWORD dw;
  919. HKEY hKey = NULL;
  920. LONG lRes = RegCreateKeyEx(hKeyParent, lpszKeyName, 0,
  921. lpszClass, dwOptions, samDesired, lpSecAttr, &hKey, &dw);
  922. if (lpdwDisposition != NULL)
  923. *lpdwDisposition = dw;
  924. if (lRes == ERROR_SUCCESS)
  925. {
  926. lRes = Close();
  927. m_hKey = hKey;
  928. }
  929. return lRes;
  930. }
  931. LONG CRegKey::Open(HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired)
  932. {
  933. _ASSERTE(hKeyParent != NULL);
  934. HKEY hKey = NULL;
  935. LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyName, 0, samDesired, &hKey);
  936. if (lRes == ERROR_SUCCESS)
  937. {
  938. lRes = Close();
  939. _ASSERTE(lRes == ERROR_SUCCESS);
  940. m_hKey = hKey;
  941. }
  942. return lRes;
  943. }
  944. LONG CRegKey::QueryValue(DWORD& dwValue, LPCTSTR lpszValueName)
  945. {
  946. DWORD dwType = NULL;
  947. DWORD dwCount = sizeof(DWORD);
  948. LONG lRes = RegQueryValueEx(m_hKey, (LPTSTR)lpszValueName, NULL, &dwType,
  949. (LPBYTE)&dwValue, &dwCount);
  950. _ASSERTE((lRes!=ERROR_SUCCESS) || (dwType == REG_DWORD));
  951. _ASSERTE((lRes!=ERROR_SUCCESS) || (dwCount == sizeof(DWORD)));
  952. return lRes;
  953. }
  954. LONG WINAPI CRegKey::SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName)
  955. {
  956. _ASSERTE(lpszValue != NULL);
  957. CRegKey key;
  958. LONG lRes = key.Create(hKeyParent, lpszKeyName);
  959. if (lRes == ERROR_SUCCESS)
  960. lRes = key.SetValue(lpszValue, lpszValueName);
  961. return lRes;
  962. }
  963. LONG CRegKey::SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName)
  964. {
  965. _ASSERTE(lpszValue != NULL);
  966. CRegKey key;
  967. LONG lRes = key.Create(m_hKey, lpszKeyName);
  968. if (lRes == ERROR_SUCCESS)
  969. lRes = key.SetValue(lpszValue, lpszValueName);
  970. return lRes;
  971. }
  972. //RecurseDeleteKey is necessary because on NT RegDeleteKey doesn't work if the
  973. //specified key has subkeys
  974. LONG CRegKey::RecurseDeleteKey(LPCTSTR lpszKey)
  975. {
  976. CRegKey key;
  977. LONG lRes = key.Open(m_hKey, lpszKey);
  978. if (lRes != ERROR_SUCCESS)
  979. return lRes;
  980. FILETIME time;
  981. TCHAR szBuffer[256];
  982. DWORD dwSize = 256;
  983. while (RegEnumKeyEx(key.m_hKey, 0, szBuffer, &dwSize, NULL, NULL, NULL,
  984. &time)==ERROR_SUCCESS)
  985. {
  986. lRes = key.RecurseDeleteKey(szBuffer);
  987. if (lRes != ERROR_SUCCESS)
  988. return lRes;
  989. dwSize = 256;
  990. }
  991. key.Close();
  992. return DeleteSubKey(lpszKey);
  993. }
  994. #ifndef _ATL_NO_SECURITY
  995. CSecurityDescriptor::CSecurityDescriptor()
  996. {
  997. m_pSD = NULL;
  998. m_pOwner = NULL;
  999. m_pGroup = NULL;
  1000. m_pDACL = NULL;
  1001. m_pSACL= NULL;
  1002. }
  1003. CSecurityDescriptor::~CSecurityDescriptor()
  1004. {
  1005. if (m_pSD)
  1006. delete m_pSD;
  1007. if (m_pOwner)
  1008. free(m_pOwner);
  1009. if (m_pGroup)
  1010. free(m_pGroup);
  1011. if (m_pDACL)
  1012. free(m_pDACL);
  1013. if (m_pSACL)
  1014. free(m_pSACL);
  1015. }
  1016. HRESULT CSecurityDescriptor::Initialize()
  1017. {
  1018. if (m_pSD)
  1019. {
  1020. delete m_pSD;
  1021. m_pSD = NULL;
  1022. }
  1023. if (m_pOwner)
  1024. {
  1025. free(m_pOwner);
  1026. m_pOwner = NULL;
  1027. }
  1028. if (m_pGroup)
  1029. {
  1030. free(m_pGroup);
  1031. m_pGroup = NULL;
  1032. }
  1033. if (m_pDACL)
  1034. {
  1035. free(m_pDACL);
  1036. m_pDACL = NULL;
  1037. }
  1038. if (m_pSACL)
  1039. {
  1040. free(m_pSACL);
  1041. m_pSACL = NULL;
  1042. }
  1043. m_pSD = new SECURITY_DESCRIPTOR;
  1044. if (!m_pSD)
  1045. return E_OUTOFMEMORY;
  1046. if (!InitializeSecurityDescriptor(m_pSD, SECURITY_DESCRIPTOR_REVISION))
  1047. {
  1048. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  1049. delete m_pSD;
  1050. m_pSD = NULL;
  1051. _ASSERTE(FALSE);
  1052. return hr;
  1053. }
  1054. // Set the DACL to allow EVERYONE
  1055. SetSecurityDescriptorDacl(m_pSD, TRUE, NULL, FALSE);
  1056. return S_OK;
  1057. }
  1058. HRESULT CSecurityDescriptor::InitializeFromProcessToken(BOOL bDefaulted)
  1059. {
  1060. PSID pUserSid;
  1061. PSID pGroupSid;
  1062. HRESULT hr;
  1063. Initialize();
  1064. hr = GetProcessSids(&pUserSid, &pGroupSid);
  1065. if (FAILED(hr))
  1066. return hr;
  1067. hr = SetOwner(pUserSid, bDefaulted);
  1068. if (FAILED(hr))
  1069. return hr;
  1070. hr = SetGroup(pGroupSid, bDefaulted);
  1071. if (FAILED(hr))
  1072. return hr;
  1073. return S_OK;
  1074. }
  1075. HRESULT CSecurityDescriptor::InitializeFromThreadToken(BOOL bDefaulted, BOOL bRevertToProcessToken)
  1076. {
  1077. PSID pUserSid;
  1078. PSID pGroupSid;
  1079. HRESULT hr;
  1080. Initialize();
  1081. hr = GetThreadSids(&pUserSid, &pGroupSid);
  1082. if (HRESULT_CODE(hr) == ERROR_NO_TOKEN && bRevertToProcessToken)
  1083. hr = GetProcessSids(&pUserSid, &pGroupSid);
  1084. if (FAILED(hr))
  1085. return hr;
  1086. hr = SetOwner(pUserSid, bDefaulted);
  1087. if (FAILED(hr))
  1088. return hr;
  1089. hr = SetGroup(pGroupSid, bDefaulted);
  1090. if (FAILED(hr))
  1091. return hr;
  1092. return S_OK;
  1093. }
  1094. HRESULT CSecurityDescriptor::SetOwner(PSID pOwnerSid, BOOL bDefaulted)
  1095. {
  1096. _ASSERTE(m_pSD);
  1097. // Mark the SD as having no owner
  1098. if (!SetSecurityDescriptorOwner(m_pSD, NULL, bDefaulted))
  1099. {
  1100. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  1101. _ASSERTE(FALSE);
  1102. return hr;
  1103. }
  1104. if (m_pOwner)
  1105. {
  1106. free(m_pOwner);
  1107. m_pOwner = NULL;
  1108. }
  1109. // If they asked for no owner don't do the copy
  1110. if (pOwnerSid == NULL)
  1111. return S_OK;
  1112. // Make a copy of the Sid for the return value
  1113. DWORD dwSize = GetLengthSid(pOwnerSid);
  1114. m_pOwner = (PSID) malloc(dwSize);
  1115. if (!m_pOwner)
  1116. {
  1117. // Insufficient memory to allocate Sid
  1118. _ASSERTE(FALSE);
  1119. return E_OUTOFMEMORY;
  1120. }
  1121. if (!CopySid(dwSize, m_pOwner, pOwnerSid))
  1122. {
  1123. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  1124. _ASSERTE(FALSE);
  1125. free(m_pOwner);
  1126. m_pOwner = NULL;
  1127. return hr;
  1128. }
  1129. _ASSERTE(IsValidSid(m_pOwner));
  1130. if (!SetSecurityDescriptorOwner(m_pSD, m_pOwner, bDefaulted))
  1131. {
  1132. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  1133. _ASSERTE(FALSE);
  1134. free(m_pOwner);
  1135. m_pOwner = NULL;
  1136. return hr;
  1137. }
  1138. return S_OK;
  1139. }
  1140. HRESULT CSecurityDescriptor::SetGroup(PSID pGroupSid, BOOL bDefaulted)
  1141. {
  1142. _ASSERTE(m_pSD);
  1143. // Mark the SD as having no Group
  1144. if (!SetSecurityDescriptorGroup(m_pSD, NULL, bDefaulted))
  1145. {
  1146. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  1147. _ASSERTE(FALSE);
  1148. return hr;
  1149. }
  1150. if (m_pGroup)
  1151. {
  1152. free(m_pGroup);
  1153. m_pGroup = NULL;
  1154. }
  1155. // If they asked for no Group don't do the copy
  1156. if (pGroupSid == NULL)
  1157. return S_OK;
  1158. // Make a copy of the Sid for the return value
  1159. DWORD dwSize = GetLengthSid(pGroupSid);
  1160. m_pGroup = (PSID) malloc(dwSize);
  1161. if (!m_pGroup)
  1162. {
  1163. // Insufficient memory to allocate Sid
  1164. _ASSERTE(FALSE);
  1165. return E_OUTOFMEMORY;
  1166. }
  1167. if (!CopySid(dwSize, m_pGroup, pGroupSid))
  1168. {
  1169. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  1170. _ASSERTE(FALSE);
  1171. free(m_pGroup);
  1172. m_pGroup = NULL;
  1173. return hr;
  1174. }
  1175. _ASSERTE(IsValidSid(m_pGroup));
  1176. if (!SetSecurityDescriptorGroup(m_pSD, m_pGroup, bDefaulted))
  1177. {
  1178. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  1179. _ASSERTE(FALSE);
  1180. free(m_pGroup);
  1181. m_pGroup = NULL;
  1182. return hr;
  1183. }
  1184. return S_OK;
  1185. }
  1186. HRESULT CSecurityDescriptor::Allow(LPCTSTR pszPrincipal, DWORD dwAccessMask)
  1187. {
  1188. HRESULT hr = AddAccessAllowedACEToACL(&m_pDACL, pszPrincipal, dwAccessMask);
  1189. if (SUCCEEDED(hr))
  1190. SetSecurityDescriptorDacl(m_pSD, TRUE, m_pDACL, FALSE);
  1191. return hr;
  1192. }
  1193. HRESULT CSecurityDescriptor::Deny(LPCTSTR pszPrincipal, DWORD dwAccessMask)
  1194. {
  1195. HRESULT hr = AddAccessDeniedACEToACL(&m_pDACL, pszPrincipal, dwAccessMask);
  1196. if (SUCCEEDED(hr))
  1197. SetSecurityDescriptorDacl(m_pSD, TRUE, m_pDACL, FALSE);
  1198. return hr;
  1199. }
  1200. HRESULT CSecurityDescriptor::Revoke(LPCTSTR pszPrincipal)
  1201. {
  1202. HRESULT hr = RemovePrincipalFromACL(m_pDACL, pszPrincipal);
  1203. if (SUCCEEDED(hr))
  1204. SetSecurityDescriptorDacl(m_pSD, TRUE, m_pDACL, FALSE);
  1205. return hr;
  1206. }
  1207. HRESULT CSecurityDescriptor::GetProcessSids(PSID* ppUserSid, PSID* ppGroupSid)
  1208. {
  1209. BOOL bRes;
  1210. HRESULT hr;
  1211. HANDLE hToken = NULL;
  1212. if (ppUserSid)
  1213. *ppUserSid = NULL;
  1214. if (ppGroupSid)
  1215. *ppGroupSid = NULL;
  1216. bRes = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
  1217. if (!bRes)
  1218. {
  1219. // Couldn't open process token
  1220. hr = HRESULT_FROM_WIN32(GetLastError());
  1221. _ASSERTE(FALSE);
  1222. return hr;
  1223. }
  1224. hr = GetTokenSids(hToken, ppUserSid, ppGroupSid);
  1225. return hr;
  1226. }
  1227. HRESULT CSecurityDescriptor::GetThreadSids(PSID* ppUserSid, PSID* ppGroupSid, BOOL bOpenAsSelf)
  1228. {
  1229. BOOL bRes;
  1230. HRESULT hr;
  1231. HANDLE hToken = NULL;
  1232. if (ppUserSid)
  1233. *ppUserSid = NULL;
  1234. if (ppGroupSid)
  1235. *ppGroupSid = NULL;
  1236. bRes = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, bOpenAsSelf, &hToken);
  1237. if (!bRes)
  1238. {
  1239. // Couldn't open thread token
  1240. hr = HRESULT_FROM_WIN32(GetLastError());
  1241. return hr;
  1242. }
  1243. hr = GetTokenSids(hToken, ppUserSid, ppGroupSid);
  1244. return hr;
  1245. }
  1246. HRESULT CSecurityDescriptor::GetTokenSids(HANDLE hToken, PSID* ppUserSid, PSID* ppGroupSid)
  1247. {
  1248. DWORD dwSize;
  1249. HRESULT hr;
  1250. PTOKEN_USER ptkUser = NULL;
  1251. PTOKEN_PRIMARY_GROUP ptkGroup = NULL;
  1252. if (ppUserSid)
  1253. *ppUserSid = NULL;
  1254. if (ppGroupSid)
  1255. *ppGroupSid = NULL;
  1256. if (ppUserSid)
  1257. {
  1258. // Get length required for TokenUser by specifying buffer length of 0
  1259. GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
  1260. hr = GetLastError();
  1261. if (hr != ERROR_INSUFFICIENT_BUFFER)
  1262. {
  1263. // Expected ERROR_INSUFFICIENT_BUFFER
  1264. _ASSERTE(FALSE);
  1265. hr = HRESULT_FROM_WIN32(hr);
  1266. goto failed;
  1267. }
  1268. ptkUser = (TOKEN_USER*) malloc(dwSize);
  1269. if (!ptkUser)
  1270. {
  1271. // Insufficient memory to allocate TOKEN_USER
  1272. _ASSERTE(FALSE);
  1273. hr = E_OUTOFMEMORY;
  1274. goto failed;
  1275. }
  1276. // Get Sid of process token.
  1277. if (!GetTokenInformation(hToken, TokenUser, ptkUser, dwSize, &dwSize))
  1278. {
  1279. // Couldn't get user info
  1280. hr = HRESULT_FROM_WIN32(GetLastError());
  1281. _ASSERTE(FALSE);
  1282. goto failed;
  1283. }
  1284. // Make a copy of the Sid for the return value
  1285. dwSize = GetLengthSid(ptkUser->User.Sid);
  1286. PSID pSid = (PSID) malloc(dwSize);
  1287. if (!pSid)
  1288. {
  1289. // Insufficient memory to allocate Sid
  1290. _ASSERTE(FALSE);
  1291. hr = E_OUTOFMEMORY;
  1292. goto failed;
  1293. }
  1294. if (!CopySid(dwSize, pSid, ptkUser->User.Sid))
  1295. {
  1296. hr = HRESULT_FROM_WIN32(GetLastError());
  1297. _ASSERTE(FALSE);
  1298. goto failed;
  1299. }
  1300. _ASSERTE(IsValidSid(pSid));
  1301. *ppUserSid = pSid;
  1302. free(ptkUser);
  1303. }
  1304. if (ppGroupSid)
  1305. {
  1306. // Get length required for TokenPrimaryGroup by specifying buffer length of 0
  1307. GetTokenInformation(hToken, TokenPrimaryGroup, NULL, 0, &dwSize);
  1308. hr = GetLastError();
  1309. if (hr != ERROR_INSUFFICIENT_BUFFER)
  1310. {
  1311. // Expected ERROR_INSUFFICIENT_BUFFER
  1312. _ASSERTE(FALSE);
  1313. hr = HRESULT_FROM_WIN32(hr);
  1314. goto failed;
  1315. }
  1316. ptkGroup = (TOKEN_PRIMARY_GROUP*) malloc(dwSize);
  1317. if (!ptkGroup)
  1318. {
  1319. // Insufficient memory to allocate TOKEN_USER
  1320. _ASSERTE(FALSE);
  1321. hr = E_OUTOFMEMORY;
  1322. goto failed;
  1323. }
  1324. // Get Sid of process token.
  1325. if (!GetTokenInformation(hToken, TokenPrimaryGroup, ptkGroup, dwSize, &dwSize))
  1326. {
  1327. // Couldn't get user info
  1328. hr = HRESULT_FROM_WIN32(GetLastError());
  1329. _ASSERTE(FALSE);
  1330. goto failed;
  1331. }
  1332. // Make a copy of the Sid for the return value
  1333. dwSize = GetLengthSid(ptkGroup->PrimaryGroup);
  1334. PSID pSid = (PSID) malloc(dwSize);
  1335. if (!pSid)
  1336. {
  1337. // Insufficient memory to allocate Sid
  1338. _ASSERTE(FALSE);
  1339. hr = E_OUTOFMEMORY;
  1340. goto failed;
  1341. }
  1342. if (!CopySid(dwSize, pSid, ptkGroup->PrimaryGroup))
  1343. {
  1344. hr = HRESULT_FROM_WIN32(GetLastError());
  1345. _ASSERTE(FALSE);
  1346. goto failed;
  1347. }
  1348. _ASSERTE(IsValidSid(pSid));
  1349. *ppGroupSid = pSid;
  1350. free(ptkGroup);
  1351. }
  1352. return S_OK;
  1353. failed:
  1354. if (ptkUser)
  1355. free(ptkUser);
  1356. if (ptkGroup)
  1357. free (ptkGroup);
  1358. return hr;
  1359. }
  1360. HRESULT CSecurityDescriptor::GetCurrentUserSID(PSID *ppSid)
  1361. {
  1362. HANDLE tkHandle;
  1363. if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tkHandle))
  1364. {
  1365. TOKEN_USER *tkUser;
  1366. DWORD tkSize;
  1367. DWORD sidLength;
  1368. // Call to get size information for alloc
  1369. GetTokenInformation(tkHandle, TokenUser, NULL, 0, &tkSize);
  1370. tkUser = (TOKEN_USER *) malloc(tkSize);
  1371. // Now make the real call
  1372. if (GetTokenInformation(tkHandle, TokenUser, tkUser, tkSize, &tkSize))
  1373. {
  1374. sidLength = GetLengthSid(tkUser->User.Sid);
  1375. *ppSid = (PSID) malloc(sidLength);
  1376. memcpy(*ppSid, tkUser->User.Sid, sidLength);
  1377. CloseHandle(tkHandle);
  1378. free(tkUser);
  1379. return S_OK;
  1380. }
  1381. else
  1382. {
  1383. free(tkUser);
  1384. return HRESULT_FROM_WIN32(GetLastError());
  1385. }
  1386. }
  1387. return HRESULT_FROM_WIN32(GetLastError());
  1388. }
  1389. HRESULT CSecurityDescriptor::GetPrincipalSID(LPCTSTR pszPrincipal, PSID *ppSid)
  1390. {
  1391. HRESULT hr;
  1392. LPTSTR pszRefDomain = NULL;
  1393. DWORD dwDomainSize = 0;
  1394. DWORD dwSidSize = 0;
  1395. SID_NAME_USE snu;
  1396. // Call to get size info for alloc
  1397. LookupAccountName(NULL, pszPrincipal, *ppSid, &dwSidSize, pszRefDomain, &dwDomainSize, &snu);
  1398. hr = GetLastError();
  1399. if (hr != ERROR_INSUFFICIENT_BUFFER)
  1400. return HRESULT_FROM_WIN32(hr);
  1401. pszRefDomain = new TCHAR[dwDomainSize];
  1402. if (pszRefDomain == NULL)
  1403. return E_OUTOFMEMORY;
  1404. *ppSid = (PSID) malloc(dwSidSize);
  1405. if (*ppSid != NULL)
  1406. {
  1407. if (!LookupAccountName(NULL, pszPrincipal, *ppSid, &dwSidSize, pszRefDomain, &dwDomainSize, &snu))
  1408. {
  1409. free(*ppSid);
  1410. *ppSid = NULL;
  1411. delete[] pszRefDomain;
  1412. return HRESULT_FROM_WIN32(GetLastError());
  1413. }
  1414. delete[] pszRefDomain;
  1415. return S_OK;
  1416. }
  1417. delete[] pszRefDomain;
  1418. return E_OUTOFMEMORY;
  1419. }
  1420. HRESULT CSecurityDescriptor::Attach(PSECURITY_DESCRIPTOR pSelfRelativeSD)
  1421. {
  1422. PACL pDACL = NULL;
  1423. PACL pSACL = NULL;
  1424. BOOL bDACLPresent, bSACLPresent;
  1425. BOOL bDefaulted;
  1426. PACL m_pDACL = NULL;
  1427. ACCESS_ALLOWED_ACE* pACE;
  1428. HRESULT hr;
  1429. PSID pUserSid;
  1430. PSID pGroupSid;
  1431. hr = Initialize();
  1432. if(FAILED(hr))
  1433. return hr;
  1434. // get the existing DACL.
  1435. if (!GetSecurityDescriptorDacl(pSelfRelativeSD, &bDACLPresent, &pDACL, &bDefaulted))
  1436. goto failed;
  1437. if (bDACLPresent)
  1438. {
  1439. if (pDACL)
  1440. {
  1441. // allocate new DACL.
  1442. if (!(m_pDACL = (PACL) malloc(pDACL->AclSize)))
  1443. goto failed;
  1444. // initialize the DACL
  1445. if (!InitializeAcl(m_pDACL, pDACL->AclSize, ACL_REVISION))
  1446. goto failed;
  1447. // copy the ACES
  1448. for (int i = 0; i < pDACL->AceCount; i++)
  1449. {
  1450. if (!GetAce(pDACL, i, (void **)&pACE))
  1451. goto failed;
  1452. if (!AddAccessAllowedAce(m_pDACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart)))
  1453. goto failed;
  1454. }
  1455. if (!IsValidAcl(m_pDACL))
  1456. goto failed;
  1457. }
  1458. // set the DACL
  1459. if (!SetSecurityDescriptorDacl(m_pSD, m_pDACL ? TRUE : FALSE, m_pDACL, bDefaulted))
  1460. goto failed;
  1461. }
  1462. // get the existing SACL.
  1463. if (!GetSecurityDescriptorSacl(pSelfRelativeSD, &bSACLPresent, &pSACL, &bDefaulted))
  1464. goto failed;
  1465. if (bSACLPresent)
  1466. {
  1467. if (pSACL)
  1468. {
  1469. // allocate new SACL.
  1470. if (!(m_pSACL = (PACL) malloc(pSACL->AclSize)))
  1471. goto failed;
  1472. // initialize the SACL
  1473. if (!InitializeAcl(m_pSACL, pSACL->AclSize, ACL_REVISION))
  1474. goto failed;
  1475. // copy the ACES
  1476. for (int i = 0; i < pSACL->AceCount; i++)
  1477. {
  1478. if (!GetAce(pSACL, i, (void **)&pACE))
  1479. goto failed;
  1480. if (!AddAccessAllowedAce(m_pSACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart)))
  1481. goto failed;
  1482. }
  1483. if (!IsValidAcl(m_pSACL))
  1484. goto failed;
  1485. }
  1486. // set the SACL
  1487. if (!SetSecurityDescriptorSacl(m_pSD, m_pSACL ? TRUE : FALSE, m_pSACL, bDefaulted))
  1488. goto failed;
  1489. }
  1490. if (!GetSecurityDescriptorOwner(m_pSD, &pUserSid, &bDefaulted))
  1491. goto failed;
  1492. if (FAILED(SetOwner(pUserSid, bDefaulted)))
  1493. goto failed;
  1494. if (!GetSecurityDescriptorGroup(m_pSD, &pGroupSid, &bDefaulted))
  1495. goto failed;
  1496. if (FAILED(SetGroup(pGroupSid, bDefaulted)))
  1497. goto failed;
  1498. if (!IsValidSecurityDescriptor(m_pSD))
  1499. goto failed;
  1500. return hr;
  1501. failed:
  1502. if (m_pDACL)
  1503. free(m_pDACL);
  1504. if (m_pSD)
  1505. free(m_pSD);
  1506. return E_UNEXPECTED;
  1507. }
  1508. HRESULT CSecurityDescriptor::AttachObject(HANDLE hObject)
  1509. {
  1510. HRESULT hr;
  1511. DWORD dwSize = 0;
  1512. PSECURITY_DESCRIPTOR pSD = NULL;
  1513. GetKernelObjectSecurity(hObject, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
  1514. DACL_SECURITY_INFORMATION, pSD, 0, &dwSize);
  1515. hr = GetLastError();
  1516. if (hr != ERROR_INSUFFICIENT_BUFFER)
  1517. return HRESULT_FROM_WIN32(hr);
  1518. pSD = (PSECURITY_DESCRIPTOR) malloc(dwSize);
  1519. if (!GetKernelObjectSecurity(hObject, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
  1520. DACL_SECURITY_INFORMATION, pSD, dwSize, &dwSize))
  1521. {
  1522. hr = HRESULT_FROM_WIN32(GetLastError());
  1523. free(pSD);
  1524. return hr;
  1525. }
  1526. hr = Attach(pSD);
  1527. free(pSD);
  1528. return hr;
  1529. }
  1530. HRESULT CSecurityDescriptor::CopyACL(PACL pDest, PACL pSrc)
  1531. {
  1532. ACL_SIZE_INFORMATION aclSizeInfo;
  1533. LPVOID pAce;
  1534. ACE_HEADER *aceHeader;
  1535. if (pSrc == NULL)
  1536. return S_OK;
  1537. if (!GetAclInformation(pSrc, (LPVOID) &aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation))
  1538. return HRESULT_FROM_WIN32(GetLastError());
  1539. // Copy all of the ACEs to the new ACL
  1540. for (UINT i = 0; i < aclSizeInfo.AceCount; i++)
  1541. {
  1542. if (!GetAce(pSrc, i, &pAce))
  1543. return HRESULT_FROM_WIN32(GetLastError());
  1544. aceHeader = (ACE_HEADER *) pAce;
  1545. if (!AddAce(pDest, ACL_REVISION, 0xffffffff, pAce, aceHeader->AceSize))
  1546. return HRESULT_FROM_WIN32(GetLastError());
  1547. }
  1548. return S_OK;
  1549. }
  1550. HRESULT CSecurityDescriptor::AddAccessDeniedACEToACL(PACL *ppAcl, LPCTSTR pszPrincipal, DWORD dwAccessMask)
  1551. {
  1552. ACL_SIZE_INFORMATION aclSizeInfo;
  1553. int aclSize;
  1554. DWORD returnValue;
  1555. PSID principalSID;
  1556. PACL oldACL, newACL;
  1557. oldACL = *ppAcl;
  1558. returnValue = GetPrincipalSID(pszPrincipal, &principalSID);
  1559. if (FAILED(returnValue))
  1560. return returnValue;
  1561. aclSizeInfo.AclBytesInUse = 0;
  1562. if (*ppAcl != NULL)
  1563. GetAclInformation(oldACL, (LPVOID) &aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
  1564. aclSize = aclSizeInfo.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_DENIED_ACE) + GetLengthSid(principalSID) - sizeof(DWORD);
  1565. newACL = (PACL) new BYTE[aclSize];
  1566. if (!InitializeAcl(newACL, aclSize, ACL_REVISION))
  1567. {
  1568. free(principalSID);
  1569. return HRESULT_FROM_WIN32(GetLastError());
  1570. }
  1571. if (!AddAccessDeniedAce(newACL, ACL_REVISION2, dwAccessMask, principalSID))
  1572. {
  1573. free(principalSID);
  1574. return HRESULT_FROM_WIN32(GetLastError());
  1575. }
  1576. returnValue = CopyACL(newACL, oldACL);
  1577. if (FAILED(returnValue))
  1578. {
  1579. free(principalSID);
  1580. return returnValue;
  1581. }
  1582. *ppAcl = newACL;
  1583. if (oldACL != NULL)
  1584. free(oldACL);
  1585. free(principalSID);
  1586. return S_OK;
  1587. }
  1588. HRESULT CSecurityDescriptor::AddAccessAllowedACEToACL(PACL *ppAcl, LPCTSTR pszPrincipal, DWORD dwAccessMask)
  1589. {
  1590. ACL_SIZE_INFORMATION aclSizeInfo;
  1591. int aclSize;
  1592. DWORD returnValue;
  1593. PSID principalSID;
  1594. PACL oldACL, newACL;
  1595. oldACL = *ppAcl;
  1596. returnValue = GetPrincipalSID(pszPrincipal, &principalSID);
  1597. if (FAILED(returnValue))
  1598. return returnValue;
  1599. aclSizeInfo.AclBytesInUse = 0;
  1600. if (*ppAcl != NULL)
  1601. GetAclInformation(oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
  1602. aclSize = aclSizeInfo.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(principalSID) - sizeof(DWORD);
  1603. newACL = (PACL) new BYTE[aclSize];
  1604. if (!InitializeAcl(newACL, aclSize, ACL_REVISION))
  1605. {
  1606. free(principalSID);
  1607. return HRESULT_FROM_WIN32(GetLastError());
  1608. }
  1609. returnValue = CopyACL(newACL, oldACL);
  1610. if (FAILED(returnValue))
  1611. {
  1612. free(principalSID);
  1613. return returnValue;
  1614. }
  1615. if (!AddAccessAllowedAce(newACL, ACL_REVISION2, dwAccessMask, principalSID))
  1616. {
  1617. free(principalSID);
  1618. return HRESULT_FROM_WIN32(GetLastError());
  1619. }
  1620. *ppAcl = newACL;
  1621. if (oldACL != NULL)
  1622. free(oldACL);
  1623. free(principalSID);
  1624. return S_OK;
  1625. }
  1626. HRESULT CSecurityDescriptor::RemovePrincipalFromACL(PACL pAcl, LPCTSTR pszPrincipal)
  1627. {
  1628. ACL_SIZE_INFORMATION aclSizeInfo;
  1629. ULONG i;
  1630. LPVOID ace;
  1631. ACCESS_ALLOWED_ACE *accessAllowedAce;
  1632. ACCESS_DENIED_ACE *accessDeniedAce;
  1633. SYSTEM_AUDIT_ACE *systemAuditAce;
  1634. PSID principalSID;
  1635. DWORD returnValue;
  1636. ACE_HEADER *aceHeader;
  1637. returnValue = GetPrincipalSID(pszPrincipal, &principalSID);
  1638. if (FAILED(returnValue))
  1639. return returnValue;
  1640. GetAclInformation(pAcl, (LPVOID) &aclSizeInfo, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
  1641. for (i = 0; i < aclSizeInfo.AceCount; i++)
  1642. {
  1643. if (!GetAce(pAcl, i, &ace))
  1644. {
  1645. free(principalSID);
  1646. return HRESULT_FROM_WIN32(GetLastError());
  1647. }
  1648. aceHeader = (ACE_HEADER *) ace;
  1649. if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
  1650. {
  1651. accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace;
  1652. if (EqualSid(principalSID, (PSID) &accessAllowedAce->SidStart))
  1653. {
  1654. DeleteAce(pAcl, i);
  1655. free(principalSID);
  1656. return S_OK;
  1657. }
  1658. } else
  1659. if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE)
  1660. {
  1661. accessDeniedAce = (ACCESS_DENIED_ACE *) ace;
  1662. if (EqualSid(principalSID, (PSID) &accessDeniedAce->SidStart))
  1663. {
  1664. DeleteAce(pAcl, i);
  1665. free(principalSID);
  1666. return S_OK;
  1667. }
  1668. } else
  1669. if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE)
  1670. {
  1671. systemAuditAce = (SYSTEM_AUDIT_ACE *) ace;
  1672. if (EqualSid(principalSID, (PSID) &systemAuditAce->SidStart))
  1673. {
  1674. DeleteAce(pAcl, i);
  1675. free(principalSID);
  1676. return S_OK;
  1677. }
  1678. }
  1679. }
  1680. free(principalSID);
  1681. return S_OK;
  1682. }
  1683. HRESULT CSecurityDescriptor::SetPrivilege(LPCTSTR privilege, BOOL bEnable, HANDLE hToken)
  1684. {
  1685. HRESULT hr;
  1686. TOKEN_PRIVILEGES tpPrevious;
  1687. TOKEN_PRIVILEGES tp;
  1688. DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
  1689. LUID luid;
  1690. // if no token specified open process token
  1691. if (hToken == 0)
  1692. {
  1693. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  1694. {
  1695. hr = HRESULT_FROM_WIN32(GetLastError());
  1696. _ASSERTE(FALSE);
  1697. return hr;
  1698. }
  1699. }
  1700. if (!LookupPrivilegeValue(NULL, privilege, &luid ))
  1701. {
  1702. hr = HRESULT_FROM_WIN32(GetLastError());
  1703. _ASSERTE(FALSE);
  1704. return hr;
  1705. }
  1706. tp.PrivilegeCount = 1;
  1707. tp.Privileges[0].Luid = luid;
  1708. tp.Privileges[0].Attributes = 0;
  1709. if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &tpPrevious, &cbPrevious))
  1710. {
  1711. hr = HRESULT_FROM_WIN32(GetLastError());
  1712. _ASSERTE(FALSE);
  1713. return hr;
  1714. }
  1715. tpPrevious.PrivilegeCount = 1;
  1716. tpPrevious.Privileges[0].Luid = luid;
  1717. if (bEnable)
  1718. tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
  1719. else
  1720. tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED & tpPrevious.Privileges[0].Attributes);
  1721. if (!AdjustTokenPrivileges(hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL))
  1722. {
  1723. hr = HRESULT_FROM_WIN32(GetLastError());
  1724. _ASSERTE(FALSE);
  1725. return hr;
  1726. }
  1727. return S_OK;
  1728. }
  1729. #endif //_ATL_NO_SECURITY
  1730. #ifdef _DEBUG
  1731. #include <stdio.h>
  1732. #include <stdarg.h>
  1733. void _cdecl AtlTrace(LPCTSTR lpszFormat, ...)
  1734. {
  1735. va_list args;
  1736. va_start(args, lpszFormat);
  1737. int nBuf;
  1738. TCHAR szBuffer[512];
  1739. nBuf = wvsprintf(szBuffer, lpszFormat, args);
  1740. _ASSERTE(nBuf < sizeof(szBuffer));
  1741. OutputDebugString(szBuffer);
  1742. va_end(args);
  1743. }
  1744. #endif //_DEBUG
  1745. /////////////////////////////////////////////////////////////////////////////
  1746. // Minimize CRT
  1747. // Specify DllMain as EntryPoint
  1748. // Turn off exception handling
  1749. // Define _ATL_MIN_CRT
  1750. #ifdef _ATL_MIN_CRT
  1751. /////////////////////////////////////////////////////////////////////////////
  1752. // Heap Allocation
  1753. #ifndef _DEBUG
  1754. #ifndef _ATL_NO_FLTUSED
  1755. extern "C" const int _fltused = 0;
  1756. #endif
  1757. #ifndef USE_IERT
  1758. _CRTNOALIAS _CRTRESTRICT void* __cdecl malloc(size_t n)
  1759. {
  1760. if (_Module.m_hHeap == NULL)
  1761. {
  1762. _Module.m_hHeap = HeapCreate(0, 0, 0);
  1763. if (_Module.m_hHeap == NULL)
  1764. return NULL;
  1765. }
  1766. _ASSERTE(_Module.m_hHeap != NULL);
  1767. #ifdef _MALLOC_ZEROINIT
  1768. void* p = HeapAlloc(_Module.m_hHeap, 0, n);
  1769. if (p != NULL)
  1770. memset(p, 0, n);
  1771. return p;
  1772. #else
  1773. return HeapAlloc(_Module.m_hHeap, 0, n);
  1774. #endif
  1775. }
  1776. _CRTNOALIAS _CRTRESTRICT void* __cdecl calloc(size_t n, size_t s)
  1777. {
  1778. #ifdef _MALLOC_ZEROINIT
  1779. return malloc(n * s);
  1780. #else
  1781. void* p = malloc(n * s);
  1782. if (p != NULL)
  1783. memset(p, 0, n * s);
  1784. return p;
  1785. #endif
  1786. }
  1787. _CRTNOALIAS void __cdecl free(void* p)
  1788. {
  1789. _ASSERTE(_Module.m_hHeap != NULL);
  1790. if (p != NULL)
  1791. HeapFree(_Module.m_hHeap, 0, p);
  1792. }
  1793. #endif // USE_IERT
  1794. #if 0
  1795. _CRTNOALIAS _CRTRESTRICT void* __cdecl realloc(void* p, size_t n)
  1796. {
  1797. _ASSERTE(_Module.m_hHeap != NULL);
  1798. return (p == NULL) ? malloc(n) : HeapReAlloc(_Module.m_hHeap, 0, p, n);
  1799. }
  1800. #endif
  1801. #endif //_DEBUG
  1802. #if !defined(_DEBUG) || defined(USE_IERT)
  1803. #ifndef _MERGE_PROXYSTUB
  1804. int __cdecl _purecall()
  1805. {
  1806. #if DBG==1
  1807. DebugBreak();
  1808. #endif // DBG
  1809. return 0;
  1810. }
  1811. #endif // !_MERGE_PROXYSTUB
  1812. void* __cdecl operator new(size_t n)
  1813. {
  1814. return malloc(n);
  1815. }
  1816. void __cdecl operator delete(void* p)
  1817. {
  1818. free(p);
  1819. }
  1820. #endif //!defined(_DEBUG) || defined(USE_IERT)
  1821. #endif //_ATL_MIN_CRT