local with custom IAccessControl.cpp
上传用户:bjlvip
上传日期:2010-02-08
资源大小:744k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // local.cpp
  2. #define _WIN32_WINNT 0x0403
  3. #define _WIN32_DCOM
  4. #include <windows.h>
  5. #include <stdio.h>
  6. #include <iaccess.h>   // IAccessControl
  7. #include <iostream.h>  // For cout
  8. #include "registry.h"  // For registry functions
  9. #include "Component IAccessControlcomponent.h" // Generated by MIDL
  10. const IID IID_IAccessControl = {0xEEDD23E0,0x8410,0x11CE,{0xA1,0xC3,0x08,0x00,0x2B,0x2B,0x8D,0x8F}};
  11. long g_cComponents = 0;
  12. long g_cServerLocks = 0;
  13. HANDLE g_hEvent;
  14. class CMyAccessControl : public IAccessControl
  15. {
  16. public:
  17. // IUnknown
  18. ULONG __stdcall AddRef();
  19. ULONG __stdcall Release();
  20. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  21. // IAccessControl
  22. HRESULT __stdcall GrantAccessRights(PACTRL_ACCESSW pAccessList);
  23. HRESULT __stdcall SetAccessRights(PACTRL_ACCESSW pAccessList);
  24. HRESULT __stdcall SetOwner(PTRUSTEEW pOwner, PTRUSTEEW pGroup);
  25. HRESULT __stdcall RevokeAccessRights(LPWSTR lpProperty, ULONG cTrustees, TRUSTEEW prgTrusteesp[]);
  26. HRESULT __stdcall GetAllAccessRights(LPWSTR lpProperty, PACTRL_ACCESSW_ALLOCATE_ALL_NODES* ppAccessList, PTRUSTEEW* ppOwner, PTRUSTEEW* ppGroup);
  27. HRESULT __stdcall IsAccessAllowed(PTRUSTEEW pTrustee, LPWSTR lpProperty, ACCESS_RIGHTS AccessRights, BOOL* pfAccessAllowed);
  28. private:
  29. ULONG m_cRef;
  30. };
  31. HRESULT CMyAccessControl::GrantAccessRights(PACTRL_ACCESSW pAccessList)
  32. {
  33. return E_NOTIMPL;
  34. }
  35. HRESULT CMyAccessControl::SetAccessRights(PACTRL_ACCESSW pAccessList)
  36. {
  37. return E_NOTIMPL;
  38. }
  39. HRESULT CMyAccessControl::SetOwner(PTRUSTEEW pOwner, PTRUSTEEW pGroup)
  40. {
  41. return E_NOTIMPL;
  42. }
  43. HRESULT CMyAccessControl::RevokeAccessRights(LPWSTR lpProperty, ULONG cTrustees, TRUSTEEW prgTrusteesp[])
  44. {
  45. return E_NOTIMPL;
  46. }
  47. HRESULT CMyAccessControl::GetAllAccessRights(LPWSTR lpProperty, PACTRL_ACCESSW_ALLOCATE_ALL_NODES* ppAccessList, PTRUSTEEW* ppOwner, PTRUSTEEW* ppGroup)
  48. {
  49. return E_NOTIMPL;
  50. }
  51. HRESULT CMyAccessControl::IsAccessAllowed(PTRUSTEEW pTrustee, LPWSTR lpProperty, ACCESS_RIGHTS AccessRights, BOOL* pfAccessAllowed)
  52. {
  53. if(MessageBoxW(NULL, pTrustee->ptstrName, L"Grant permission?", MB_SERVICE_NOTIFICATION | MB_SETFOREGROUND | MB_YESNO) == IDYES)
  54. *pfAccessAllowed = TRUE;
  55. else
  56. *pfAccessAllowed = FALSE;
  57. return S_OK;
  58. }
  59. ULONG CMyAccessControl::AddRef()
  60. {
  61. return ++m_cRef;
  62. }
  63. ULONG CMyAccessControl::Release()
  64. {
  65. if(--m_cRef != 0)
  66. return m_cRef;
  67. delete this;
  68. return 0;
  69. }
  70. HRESULT CMyAccessControl::QueryInterface(REFIID riid, void** ppv)
  71. {
  72. if(riid == IID_IUnknown || riid == IID_IAccessControl)
  73. *ppv = reinterpret_cast<IUnknown*>(this);
  74. else 
  75. {
  76. *ppv = NULL;
  77. return E_NOINTERFACE;
  78. }
  79. AddRef();
  80. return S_OK;
  81. }
  82. class CInsideCOM : public ISum
  83. {
  84. public:
  85. // IUnknown
  86. ULONG __stdcall AddRef();
  87. ULONG __stdcall Release();
  88. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  89. // ISum
  90. HRESULT __stdcall Sum(int x, int y, int* retval);
  91. CInsideCOM() : m_cRef(1) { g_cComponents++; }
  92. ~CInsideCOM() { cout << "Component: CInsideCOM::~CInsideCOM()" << endl, g_cComponents--; }
  93. private:
  94. ULONG m_cRef;
  95. };
  96. ULONG CInsideCOM::AddRef()
  97. {
  98. cout << "Component: CInsideCOM::AddRef() m_cRef = " << m_cRef + 1 << endl;
  99. return ++m_cRef;
  100. }
  101. ULONG CInsideCOM::Release()
  102. {
  103. cout << "Component: CInsideCOM::Release() m_cRef = " << m_cRef - 1 << endl;
  104. if(--m_cRef != 0)
  105. return m_cRef;
  106. SetEvent(g_hEvent); // ADD THIS!!!
  107. delete this;
  108. return 0;
  109. }
  110. HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
  111. {
  112. if(riid == IID_IUnknown)
  113. {
  114. cout << "Component: CInsideCOM::QueryInterface() for IUnknown returning " << this << endl;
  115. *ppv = reinterpret_cast<IUnknown*>(this);
  116. }
  117. else if(riid == IID_ISum)
  118. {
  119. cout << "Component: CInsideCOM::QueryInterface() for ISum returning " << this << endl;
  120. *ppv = (ISum*)this;
  121. }
  122. else 
  123. {
  124. *ppv = NULL;
  125. return E_NOINTERFACE;
  126. }
  127. AddRef();
  128. return S_OK;
  129. }
  130. HRESULT CInsideCOM::Sum(int x, int y, int* retval)
  131. {
  132. HRESULT hr;
  133. IServerSecurity* pServerSecurity;
  134. hr = CoGetCallContext(IID_IServerSecurity, (void**)&pServerSecurity);
  135. if(FAILED(hr))
  136. cout << "CoGetCallContext failed" << endl;
  137. DWORD AuthnSvc;
  138. DWORD AuthzSvc;
  139. OLECHAR* ServerPrincNam;
  140. DWORD AuthnLevel;
  141. RPC_AUTHZ_HANDLE Privs;
  142. DWORD Capabilities;
  143. // AuthzSvc is ignored when using the RPC_C_AUTHN_WINNT authentication service.
  144. //                             RPC_C_AUTHN_WINNT, ignored,    Administrator, RPC_C_AUTHN_LEVEL_PKT, Thing4Administrator, EOAC_NONE
  145. hr = pServerSecurity->QueryBlanket(&AuthnSvc, &AuthzSvc, &ServerPrincNam, &AuthnLevel, NULL, &Privs, &Capabilities);
  146. //                                                                       impersonation level is never returned
  147. if(FAILED(hr))
  148. cout << "QueryBlanket failed" << endl;
  149. pServerSecurity->Release();
  150. switch(AuthnSvc)
  151. {
  152. case RPC_C_AUTHN_NONE:
  153. cout << "RPC_C_AUTHN_NONE ";
  154. break;
  155. case RPC_C_AUTHN_DCE_PRIVATE:
  156. cout << "RPC_C_AUTHN_DCE_PRIVATE ";
  157. break;
  158. case RPC_C_AUTHN_DCE_PUBLIC:
  159. cout << "RPC_C_AUTHN_DCE_PUBLIC ";
  160. break;
  161. case RPC_C_AUTHN_WINNT:
  162. cout << "RPC_C_AUTHN_WINNT ";
  163. break;
  164. case RPC_C_AUTHN_DEFAULT:
  165. cout << "RPC_C_AUTHN_DEFAULT ";
  166. break;
  167. }
  168. switch(AuthnSvc)
  169. {
  170. case RPC_C_AUTHZ_NONE:
  171. cout << "RPC_C_AUTHZ_NONE ";
  172. break;
  173. case RPC_C_AUTHZ_NAME:
  174. cout << "RPC_C_AUTHZ_NAME ";
  175. break;
  176. case RPC_C_AUTHZ_DCE:
  177. cout << "RPC_C_AUTHZ_DCE ";
  178. break;
  179. }
  180. wprintf(L"ServerPrincNam %sn", ServerPrincNam);
  181. switch(AuthnLevel)
  182. {
  183. case RPC_C_AUTHN_LEVEL_NONE:
  184. cout << "RPC_C_AUTHN_LEVEL_NONE ";
  185. break;
  186. case RPC_C_AUTHN_LEVEL_CONNECT:
  187. cout << "RPC_C_AUTHN_LEVEL_CONNECT ";
  188. break;
  189. case RPC_C_AUTHN_LEVEL_CALL:
  190. cout << "RPC_C_AUTHN_LEVEL_CALL ";
  191. break;
  192. case RPC_C_AUTHN_LEVEL_PKT:
  193. cout << "RPC_C_AUTHN_LEVEL_PKT ";
  194. break;
  195. case RPC_C_AUTHN_LEVEL_PKT_INTEGRITY:
  196. cout << "RPC_C_AUTHN_LEVEL_PKT_INTEGRITY ";
  197. break;
  198. case RPC_C_AUTHN_LEVEL_PKT_PRIVACY:
  199. cout << "RPC_C_AUTHN_LEVEL_PKT_PRIVACY ";
  200. break;
  201. }
  202. wprintf(L"Privs %sn", Privs);
  203. if(Capabilities == EOAC_NONE)
  204. cout << "EOAC_NONE" << endl;
  205. CoTaskMemFree(ServerPrincNam);
  206. cout << "Component: CInsideCOM::Sum() " << x << " + " << y << " = " << x + y << endl;
  207. *retval = x + y;
  208. return S_OK;
  209. }
  210. class CFactory : public IClassFactory
  211. {
  212. public:
  213. // IUnknown
  214. ULONG __stdcall AddRef();
  215. ULONG __stdcall Release();
  216. HRESULT __stdcall QueryInterface(REFIID riid, void** ppv);
  217. // IClassFactory
  218. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv);
  219. HRESULT __stdcall LockServer(BOOL bLock);
  220. CFactory() : m_cRef(1) { }
  221. ~CFactory() { }
  222. private:
  223. ULONG m_cRef;
  224. };
  225. ULONG CFactory::AddRef()
  226. {
  227. cout << "Component: CFactory::AddRef() m_cRef = " << m_cRef + 1 << endl;
  228. return ++m_cRef;
  229. }
  230. ULONG CFactory::Release()
  231. {
  232. cout << "Component: CFactory::Release() m_cRef = " << m_cRef - 1 << endl;
  233. if(--m_cRef != 0)
  234. return m_cRef;
  235. delete this;
  236. return 0;
  237. }
  238. HRESULT CFactory::QueryInterface(REFIID riid, void** ppv)
  239. {
  240. if((riid == IID_IUnknown) || (riid == IID_IClassFactory))
  241. {
  242. cout << "Component: CFactory::QueryInteface() for IUnknown or IClassFactory " << this << endl;
  243. *ppv = (IClassFactory*)this;
  244. }
  245. else
  246. {
  247. *ppv = NULL;
  248. return E_NOINTERFACE;
  249. }
  250. AddRef();
  251. return S_OK;
  252. }
  253. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID riid, void** ppv)
  254. {
  255. if(pUnknownOuter != NULL)
  256. return CLASS_E_NOAGGREGATION;
  257. CInsideCOM *pInsideCOM = new CInsideCOM;
  258. cout << "Component: CFactory::CreateInstance() " << pInsideCOM << endl;
  259. if(pInsideCOM == NULL)
  260. return E_OUTOFMEMORY;
  261. // QueryInterface probably for IID_IUNKNOWN
  262. HRESULT hr = pInsideCOM->QueryInterface(riid, ppv);
  263. pInsideCOM->Release();
  264. return hr;
  265. }
  266. HRESULT CFactory::LockServer(BOOL bLock)
  267. {
  268. if(bLock)
  269. g_cServerLocks++;
  270. else
  271. g_cServerLocks--;
  272. return S_OK;
  273. }
  274. void RegisterComponent()
  275. {
  276. ITypeLib* pTypeLib;
  277. LoadTypeLibEx(L"Component IAccessControl.exe", REGKIND_DEFAULT, &pTypeLib);
  278. pTypeLib->Release();
  279. RegisterServer("Component IAccessControl.exe", CLSID_InsideCOM, "Inside COM Sample #1", "Component.InsideCOM", "Component.InsideCOM.1", NULL);
  280. }
  281. void CommandLineParameters(int argc, char** argv)
  282. {
  283. RegisterComponent();
  284. if(argc < 2)
  285. {
  286. cout << "No parameter, but registered anyway" << endl;
  287. exit(false);
  288. }
  289. char* szToken = strtok(argv[1], "-/"); 
  290. if(_stricmp(szToken, "RegServer") == 0)
  291. {
  292. RegisterComponent();
  293. cout << "RegServer" << endl;
  294. exit(true);
  295. }
  296. if(_stricmp(szToken, "UnregServer") == 0)
  297. {
  298. UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  299. UnregisterServer(CLSID_InsideCOM, "Component.InsideCOM", "Component.InsideCOM.1");
  300. cout << "UnregServer" << endl;
  301. exit(true);
  302. }
  303. if(_stricmp(szToken, "Embedding") != 0)
  304. {
  305. cout << "Invalid parameter" << endl;
  306. exit(false);
  307. }
  308. }
  309. void main(int argc, char** argv)
  310. {
  311. HRESULT hr;
  312. CommandLineParameters(argc, argv);
  313. cout << "Component: CoInitializeEx()" << endl;
  314. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  315. if(FAILED(hr))
  316. cout << "CoInitializeEx Failed" << endl;
  317. CMyAccessControl ac;
  318. hr = CoInitializeSecurity(&ac, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IDENTIFY, 
  319. NULL, EOAC_ACCESS_CONTROL, NULL);
  320. if(FAILED(hr))
  321. {
  322. printf("CoInitializeSecurity Failed = %0xn", hr);
  323. exit(0);
  324. }
  325. IClassFactory *pClassFactory = new CFactory();
  326. cout << "Component: CoRegisterClassObject()" << endl;
  327. DWORD dwRegister;
  328. CoRegisterClassObject(CLSID_InsideCOM, pClassFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
  329. g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  330. WaitForSingleObject(g_hEvent, INFINITE);
  331. CoRevokeClassObject(dwRegister);
  332. pClassFactory->Release();
  333. CoUninitialize();
  334. }