Source code of Windows XP (NT5)
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.

607 lines
13 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cgroup.cxx
  7. //
  8. // Contents: Group object
  9. //
  10. // History: Jan-29-1996 t-ptam(PatrickT) Created.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "NWCOMPAT.hxx"
  14. #pragma hdrstop
  15. //
  16. // Class CNWCOMPATGroup
  17. //
  18. DEFINE_IDispatch_Implementation(CNWCOMPATGroup)
  19. DEFINE_IADs_TempImplementation(CNWCOMPATGroup)
  20. DEFINE_IADs_PutGetImplementation(CNWCOMPATGroup, GroupClass, gdwGroupTableSize)
  21. DEFINE_IADsPropertyList_Implementation(CNWCOMPATGroup, GroupClass, gdwGroupTableSize)
  22. //----------------------------------------------------------------------------
  23. //
  24. // Function: CNWCOMPATGroup::CNWCOMPATGroup
  25. //
  26. // Synopsis:
  27. //
  28. //----------------------------------------------------------------------------
  29. CNWCOMPATGroup::CNWCOMPATGroup():
  30. _pDispMgr(NULL),
  31. _pPropertyCache(NULL),
  32. _ParentType(0),
  33. _ServerName(NULL),
  34. _hConn(NULL)
  35. {
  36. ENLIST_TRACKING(CNWCOMPATGroup);
  37. }
  38. //----------------------------------------------------------------------------
  39. //
  40. // Function: CNWCOMPATGroup::CreateGroup
  41. //
  42. // Synopsis:
  43. //
  44. //----------------------------------------------------------------------------
  45. HRESULT
  46. CNWCOMPATGroup::CreateGroup(
  47. BSTR Parent,
  48. ULONG ParentType,
  49. BSTR ServerName,
  50. BSTR GroupName,
  51. CCredentials &Credentials,
  52. DWORD dwObjectState,
  53. REFIID riid,
  54. void **ppvObj
  55. )
  56. {
  57. CNWCOMPATGroup FAR * pGroup = NULL;
  58. HRESULT hr = S_OK;
  59. //
  60. // Allocate memory for a Group object.
  61. //
  62. hr = AllocateGroupObject(&pGroup);
  63. BAIL_ON_FAILURE(hr);
  64. //
  65. // Initialize group's core object.
  66. //
  67. hr = pGroup->InitializeCoreObject(
  68. Parent,
  69. GroupName,
  70. GROUP_CLASS_NAME,
  71. GROUP_SCHEMA_NAME,
  72. CLSID_NWCOMPATGroup,
  73. dwObjectState
  74. );
  75. BAIL_ON_FAILURE(hr);
  76. //
  77. // Save protected values.
  78. //
  79. hr = ADsAllocString( ServerName , &pGroup->_ServerName);
  80. BAIL_ON_FAILURE(hr);
  81. pGroup->_Credentials = Credentials;
  82. //
  83. // Get a handle to the bindery this object resides on.
  84. //
  85. hr = NWApiGetBinderyHandle(
  86. &pGroup->_hConn,
  87. pGroup->_ServerName,
  88. pGroup->_Credentials
  89. );
  90. BAIL_ON_FAILURE(hr);
  91. //
  92. // QueryInterface.
  93. //
  94. hr = pGroup->QueryInterface(riid, ppvObj);
  95. BAIL_ON_FAILURE(hr);
  96. pGroup->Release();
  97. //
  98. // Return.
  99. //
  100. RRETURN(hr);
  101. error:
  102. delete pGroup;
  103. NW_RRETURN_EXP_IF_ERR(hr);
  104. }
  105. //----------------------------------------------------------------------------
  106. //
  107. // Function: CNWCOMPATGroup::~CNWCOMPATGroup
  108. //
  109. // Synopsis:
  110. //
  111. //----------------------------------------------------------------------------
  112. CNWCOMPATGroup::~CNWCOMPATGroup( )
  113. {
  114. ADsFreeString(_ServerName);
  115. delete _pDispMgr;
  116. delete _pPropertyCache;
  117. if (_hConn)
  118. NWApiReleaseBinderyHandle(_hConn);
  119. }
  120. //----------------------------------------------------------------------------
  121. //
  122. // Function: CNWCOMPATGroup::QueryInterface
  123. //
  124. // Synopsis:
  125. //
  126. //----------------------------------------------------------------------------
  127. STDMETHODIMP
  128. CNWCOMPATGroup::QueryInterface(
  129. REFIID iid,
  130. LPVOID FAR* ppv
  131. )
  132. {
  133. if (ppv == NULL) {
  134. RRETURN(E_POINTER);
  135. }
  136. if (IsEqualIID(iid, IID_IUnknown))
  137. {
  138. *ppv = (IADsGroup FAR *) this;
  139. }
  140. else if (IsEqualIID(iid, IID_IADsGroup))
  141. {
  142. *ppv = (IADsGroup FAR *) this;
  143. }
  144. else if (IsEqualIID(iid, IID_IADs))
  145. {
  146. *ppv = (IADsGroup FAR *) this;
  147. }
  148. else if (IsEqualIID(iid, IID_IDispatch))
  149. {
  150. *ppv = (IADsGroup FAR *) this;
  151. }
  152. else if (IsEqualIID(iid, IID_ISupportErrorInfo))
  153. {
  154. *ppv = (ISupportErrorInfo FAR *) this;
  155. }
  156. else if (IsEqualIID(iid, IID_IADsPropertyList))
  157. {
  158. *ppv = (IADsPropertyList FAR *) this;
  159. }
  160. else
  161. {
  162. *ppv = NULL;
  163. return E_NOINTERFACE;
  164. }
  165. AddRef();
  166. return NOERROR;
  167. }
  168. /* ISupportErrorInfo method */
  169. STDMETHODIMP
  170. CNWCOMPATGroup::InterfaceSupportsErrorInfo(
  171. THIS_ REFIID riid
  172. )
  173. {
  174. if (IsEqualIID(riid, IID_IADs) ||
  175. IsEqualIID(riid, IID_IADsGroup) ||
  176. IsEqualIID(riid, IID_IADsPropertyList)) {
  177. RRETURN(S_OK);
  178. } else {
  179. RRETURN(S_FALSE);
  180. }
  181. }
  182. /* IADs methods */
  183. //----------------------------------------------------------------------------
  184. //
  185. // Function: CNWCOMPATGroup::SetInfo
  186. //
  187. // Synopsis:
  188. //
  189. //----------------------------------------------------------------------------
  190. STDMETHODIMP
  191. CNWCOMPATGroup::SetInfo(THIS)
  192. {
  193. HRESULT hr = S_OK;
  194. POBJECTINFO pObjectInfo = NULL;
  195. //
  196. // Bind an object to a real life resource if it is not bounded already.
  197. //
  198. if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  199. hr = BuildObjectInfo(
  200. _Parent,
  201. _Name,
  202. &pObjectInfo
  203. );
  204. BAIL_ON_FAILURE(hr);
  205. hr = NWApiCreateGroup(
  206. pObjectInfo,
  207. _Credentials
  208. );
  209. BAIL_ON_FAILURE(hr);
  210. SetObjectState(ADS_OBJECT_BOUND);
  211. }
  212. //
  213. // Persist changes.
  214. //
  215. hr = SetInfo(GROUP_WILD_CARD_ID);
  216. BAIL_ON_FAILURE(hr);
  217. error:
  218. if (pObjectInfo) {
  219. FreeObjectInfo(pObjectInfo);
  220. }
  221. NW_RRETURN_EXP_IF_ERR(hr);
  222. }
  223. //----------------------------------------------------------------------------
  224. //
  225. // Function: CNWCOMPATGroup::GetInfo
  226. //
  227. // Synopsis:
  228. //
  229. //----------------------------------------------------------------------------
  230. STDMETHODIMP
  231. CNWCOMPATGroup::GetInfo(THIS)
  232. {
  233. HRESULT hr = S_OK;
  234. _pPropertyCache->flushpropcache();
  235. hr = GetInfo(
  236. TRUE,
  237. GROUP_WILD_CARD_ID
  238. );
  239. NW_RRETURN_EXP_IF_ERR(hr);
  240. }
  241. /* IADsGroup methods */
  242. //----------------------------------------------------------------------------
  243. //
  244. // Function: CNWCOMPATGroup::AllocateGroupObject
  245. //
  246. // Synopsis:
  247. //
  248. //----------------------------------------------------------------------------
  249. HRESULT
  250. CNWCOMPATGroup::AllocateGroupObject(
  251. CNWCOMPATGroup ** ppGroup
  252. )
  253. {
  254. CNWCOMPATGroup FAR * pGroup = NULL;
  255. CNWCOMPATGroupGenInfo FAR * pGenInfo = NULL;
  256. CDispatchMgr FAR * pDispMgr = NULL;
  257. CPropertyCache FAR * pPropertyCache = NULL;
  258. HRESULT hr = S_OK;
  259. pGroup = new CNWCOMPATGroup();
  260. if (pGroup == NULL) {
  261. hr = E_OUTOFMEMORY;
  262. }
  263. BAIL_ON_FAILURE(hr);
  264. //
  265. // Create dispatch manager.
  266. //
  267. pDispMgr = new CDispatchMgr;
  268. if (pDispMgr == NULL) {
  269. hr = E_OUTOFMEMORY;
  270. }
  271. BAIL_ON_FAILURE(hr);
  272. //
  273. // Load type info.
  274. //
  275. hr = LoadTypeInfoEntry(
  276. pDispMgr,
  277. LIBID_ADs,
  278. IID_IADsGroup,
  279. (IADsGroup *)pGroup,
  280. DISPID_REGULAR
  281. );
  282. BAIL_ON_FAILURE(hr);
  283. hr = LoadTypeInfoEntry(
  284. pDispMgr,
  285. LIBID_ADs,
  286. IID_IADsContainer,
  287. (IADsContainer *)pGroup,
  288. DISPID_NEWENUM
  289. );
  290. BAIL_ON_FAILURE(hr);
  291. hr = LoadTypeInfoEntry(
  292. pDispMgr,
  293. LIBID_ADs,
  294. IID_IADsPropertyList,
  295. (IADsPropertyList *)pGroup,
  296. DISPID_VALUE
  297. );
  298. BAIL_ON_FAILURE(hr);
  299. hr = CPropertyCache::createpropertycache(
  300. GroupClass,
  301. gdwGroupTableSize,
  302. (CCoreADsObject *)pGroup,
  303. &pPropertyCache
  304. );
  305. BAIL_ON_FAILURE(hr);
  306. pGroup->_pPropertyCache = pPropertyCache;
  307. pGroup->_pDispMgr = pDispMgr;
  308. pGroup->_pGenInfo = pGenInfo;
  309. *ppGroup = pGroup;
  310. RRETURN(hr);
  311. error:
  312. delete pDispMgr;
  313. RRETURN(hr);
  314. }
  315. //----------------------------------------------------------------------------
  316. //
  317. // Function: CNWCOMPATGroup::SetInfo
  318. //
  319. // Synopsis:
  320. //
  321. //----------------------------------------------------------------------------
  322. STDMETHODIMP
  323. CNWCOMPATGroup::SetInfo(THIS_ DWORD dwPropertyID)
  324. {
  325. HRESULT hr = S_OK;
  326. //
  327. // Persist changes in cache.
  328. //
  329. hr = SetDescription(_hConn);
  330. if (hr == E_ADS_PROPERTY_NOT_FOUND) {
  331. // not a real failure, but a missing attrib
  332. // BUGBUG: should create if missing
  333. hr = S_OK;
  334. }
  335. BAIL_ON_FAILURE(hr);
  336. error:
  337. NW_RRETURN_EXP_IF_ERR(hr);
  338. }
  339. //----------------------------------------------------------------------------
  340. //
  341. // Function: CNWCOMPATGroup::SetDescription
  342. //
  343. // Synopsis:
  344. //
  345. //----------------------------------------------------------------------------
  346. HRESULT
  347. CNWCOMPATGroup::SetDescription(
  348. NWCONN_HANDLE hConn
  349. )
  350. {
  351. LPWSTR pszDescription = NULL;
  352. WCHAR szwData[MAX_FULLNAME_LEN +1];
  353. CHAR szData[MAX_FULLNAME_LEN + 1];
  354. HRESULT hr = S_OK;
  355. memset(szwData, 0, sizeof(WCHAR)*(MAX_FULLNAME_LEN +1));
  356. hr = GetLPTSTRPropertyFromCache(
  357. _pPropertyCache,
  358. TEXT("Description"),
  359. &pszDescription
  360. );
  361. if (SUCCEEDED(hr)) {
  362. //
  363. // Convert bstr in ANSI string.
  364. //
  365. wcsncpy(szwData, pszDescription, MAX_FULLNAME_LEN);
  366. UnicodeToAnsiString(
  367. szwData,
  368. szData,
  369. 0
  370. );
  371. //
  372. // Commit change.
  373. //
  374. hr = NWApiWriteProperty(
  375. hConn,
  376. _Name,
  377. OT_USER_GROUP,
  378. NW_PROP_IDENTIFICATION,
  379. (LPBYTE) szData
  380. );
  381. BAIL_ON_FAILURE(hr);
  382. }
  383. //
  384. // Not is modified, that's ok.
  385. // reset hr to S_OK
  386. hr = S_OK;
  387. error:
  388. if (pszDescription ) {
  389. FreeADsStr(pszDescription);
  390. }
  391. NW_RRETURN_EXP_IF_ERR(hr);
  392. }
  393. //----------------------------------------------------------------------------
  394. //
  395. // Function: CNWCOMPATGroup::GetInfo
  396. //
  397. // Synopsis:
  398. //
  399. //----------------------------------------------------------------------------
  400. STDMETHODIMP
  401. CNWCOMPATGroup::GetInfo(
  402. BOOL fExplicit,
  403. DWORD dwPropertyID
  404. )
  405. {
  406. HRESULT hr = S_OK;
  407. if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  408. NW_RRETURN_EXP_IF_ERR(E_ADS_OBJECT_UNBOUND);
  409. }
  410. //
  411. // Get property.
  412. //
  413. hr = GetProperty_Description(_hConn, fExplicit);
  414. if (hr == E_ADS_PROPERTY_NOT_FOUND) {
  415. // not a real failure, we ignore it and treat it as a missing attrib
  416. hr = S_OK;
  417. }
  418. BAIL_ON_FAILURE(hr);
  419. error:
  420. NW_RRETURN_EXP_IF_ERR(hr);
  421. }
  422. //----------------------------------------------------------------------------
  423. //
  424. // Function: CNWCOMPATGroup::GetProperty_Description
  425. //
  426. // Synopsis:
  427. //
  428. //----------------------------------------------------------------------------
  429. HRESULT
  430. CNWCOMPATGroup::GetProperty_Description(
  431. NWCONN_HANDLE hConn,
  432. BOOL fExplicit
  433. )
  434. {
  435. LPWSTR lpszFullName = NULL;
  436. CHAR szFullName[MAX_FULLNAME_LEN + 1];
  437. DWORD dwNumSegment = 0;
  438. HRESULT hr = S_OK;
  439. LP_RPLY_SGMT_LST lpReplySegment = NULL;
  440. LP_RPLY_SGMT_LST lpTemp = NULL; // Used by DELETE_LIST macro below
  441. //
  442. // Get IDENTIFICATIOIN. This property contains the full name of an object.
  443. // It is often used in place of "Description".
  444. //
  445. hr = NWApiGetProperty(
  446. _Name,
  447. NW_PROP_IDENTIFICATION,
  448. OT_USER_GROUP,
  449. hConn,
  450. &lpReplySegment,
  451. &dwNumSegment
  452. );
  453. //
  454. // There was a bug marked on this code because NWApiGetProperty would fail with
  455. // an error if the property didn't exist (raid #34833), and the temp patch was
  456. // simply to hide all errors and always return S_OK when GetProperty_Description
  457. // returned. Now NWApiGetProperty will return E_ADS_PROPERTY_NOT_FOUND.
  458. //
  459. BAIL_ON_FAILURE(hr);
  460. //
  461. // Convert result into a UNICODE string.
  462. //
  463. strcpy(szFullName, lpReplySegment->Segment);
  464. lpszFullName = (LPWSTR) AllocADsMem(
  465. (strlen(szFullName) + 1) * sizeof(WCHAR)
  466. );
  467. AnsiToUnicodeString(
  468. szFullName,
  469. lpszFullName,
  470. 0
  471. );
  472. //
  473. // Unmarshall.
  474. //
  475. hr = SetLPTSTRPropertyInCache(
  476. _pPropertyCache,
  477. TEXT("Description"),
  478. lpszFullName,
  479. fExplicit
  480. );
  481. BAIL_ON_FAILURE(hr);
  482. error:
  483. if (lpszFullName) {
  484. FreeADsMem(lpszFullName);
  485. }
  486. if (lpReplySegment) {
  487. DELETE_LIST(lpReplySegment);
  488. }
  489. RRETURN(hr);
  490. }