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.

500 lines
10 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cenumGroupCollection.cxx
  7. //
  8. // Contents: Windows NT 3.5 GroupCollection Enumeration Code
  9. //
  10. //
  11. //
  12. //
  13. //
  14. //
  15. // History:
  16. //----------------------------------------------------------------------------
  17. #include "winnt.hxx"
  18. #pragma hdrstop
  19. DOMAIN_GROUP_MEMBER DomMember;
  20. //
  21. // This assumes that addr is an LPBYTE type.
  22. //
  23. #define WORD_ALIGN_DOWN(addr) \
  24. addr = ((LPBYTE)((DWORD_PTR)addr & ~1))
  25. DWORD DomainGrpMemberStrings[]=
  26. {
  27. FIELD_OFFSET(DOMAIN_GROUP_MEMBER, Parent),
  28. FIELD_OFFSET(DOMAIN_GROUP_MEMBER, Computer),
  29. FIELD_OFFSET(DOMAIN_GROUP_MEMBER, Domain),
  30. FIELD_OFFSET(DOMAIN_GROUP_MEMBER, Name),
  31. 0xFFFFFFFF
  32. };
  33. BOOL
  34. WinNTGlobalGroupOpen(
  35. LPWSTR szDomainName,
  36. LPWSTR szComputerName,
  37. LPWSTR szGroupName,
  38. PHANDLE phGroup
  39. )
  40. {
  41. WCHAR szTempBuffer[MAX_PATH];
  42. PINI_DOM_GROUP pIniDomGrp;
  43. HRESULT hr;
  44. if (!phGroup) {
  45. return(FALSE);
  46. }
  47. pIniDomGrp = (PINI_DOM_GROUP)AllocADsMem(
  48. sizeof(INI_DOM_GROUP)
  49. );
  50. if (!pIniDomGrp) {
  51. return(FALSE);
  52. }
  53. hr = MakeUncName(
  54. szComputerName,
  55. szTempBuffer
  56. );
  57. BAIL_ON_FAILURE(hr);
  58. if (!(pIniDomGrp->szUncCompName = AllocADsStr(szTempBuffer))){
  59. goto error;
  60. }
  61. if (!(pIniDomGrp->szDomainName = AllocADsStr(szDomainName))) {
  62. goto error;
  63. }
  64. if (!(pIniDomGrp->szComputerName = AllocADsStr(szComputerName))){
  65. goto error;
  66. }
  67. if (!(pIniDomGrp->szGroupName = AllocADsStr(szGroupName))){
  68. goto error;
  69. }
  70. *phGroup = (HANDLE)pIniDomGrp;
  71. return(TRUE);
  72. error:
  73. if (pIniDomGrp) {
  74. FreeIniDomGroup(pIniDomGrp);
  75. }
  76. *phGroup = NULL;
  77. return(FALSE);
  78. }
  79. BOOL
  80. WinNTGlobalGroupEnum(
  81. HANDLE hGroup,
  82. DWORD dwRequested,
  83. LPBYTE * ppBuffer,
  84. PDWORD pdwReturned
  85. )
  86. {
  87. LPDOMAIN_GROUP_MEMBER * ppGroupMembers = NULL;
  88. DWORD i = 0;
  89. BOOL dwRet = FALSE;
  90. DWORD dwReturned = 0;
  91. DWORD dwSize = 0;
  92. LPDOMAIN_GROUP_MEMBER pBuffer = NULL;
  93. LPBYTE pEnd = NULL;
  94. DWORD dwError = 0;
  95. BOOL retVal = FALSE;
  96. ppGroupMembers = (LPDOMAIN_GROUP_MEMBER *)AllocADsMem(
  97. sizeof(LPDOMAIN_GROUP_MEMBER)* dwRequested
  98. );
  99. if (!ppGroupMembers) {
  100. return(FALSE);
  101. }
  102. for (i = 0; i < dwRequested; i++) {
  103. dwRet = WinNTGlobalGroupGetObject(
  104. hGroup,
  105. &ppGroupMembers[dwReturned]
  106. );
  107. if (!dwRet) {
  108. dwError = GetLastError();
  109. if (dwError == ERROR_INVALID_SID) {
  110. continue;
  111. }
  112. //
  113. // it was not because of a bad sid
  114. // so break out, nothing more can be done
  115. //
  116. break;
  117. }
  118. dwReturned++;
  119. }
  120. dwRet = ComputeGlobalGroupDataSize(
  121. ppGroupMembers,
  122. dwReturned,
  123. &dwSize
  124. );
  125. pBuffer = (LPDOMAIN_GROUP_MEMBER)AllocADsMem(
  126. dwSize
  127. );
  128. if (pBuffer) {
  129. retVal = TRUE;
  130. pEnd = (LPBYTE)((LPBYTE)(pBuffer) + dwSize);
  131. for (i = 0; i < dwReturned; i++) {
  132. pEnd = CopyIniDomGroupToDomGroup(
  133. ppGroupMembers[i],
  134. (LPBYTE)(pBuffer + i),
  135. pEnd
  136. );
  137. }
  138. }
  139. for (i = 0; i < dwReturned; i++ ) {
  140. FreeIntDomGroup(*(ppGroupMembers + i));
  141. }
  142. FreeADsMem(ppGroupMembers);
  143. //
  144. // This will be NULL if pBuffer alloc failed.
  145. //
  146. *ppBuffer = (LPBYTE)pBuffer;
  147. *pdwReturned = retVal ? dwReturned : 0;
  148. if (!retVal) {
  149. return(FALSE);
  150. }
  151. if (dwReturned == dwRequested){
  152. return(TRUE);
  153. }else {
  154. return(FALSE);
  155. }
  156. }
  157. BOOL
  158. WinNTGlobalGroupGetObject(
  159. HANDLE hGroup,
  160. LPDOMAIN_GROUP_MEMBER * ppGroupMember
  161. )
  162. {
  163. BOOL dwRet = FALSE;
  164. PINI_DOM_GROUP pIniDomGrp = (PINI_DOM_GROUP)hGroup;
  165. NET_API_STATUS nasStatus = 0;
  166. if ((!pIniDomGrp->_pBuffer) ||
  167. (pIniDomGrp->_dwCurrentObject == pIniDomGrp->_dwObjectReturned)) {
  168. if (pIniDomGrp->_bNoMore) {
  169. //
  170. // No more objects to return
  171. //
  172. return(FALSE);
  173. }
  174. if (pIniDomGrp->_pBuffer) {
  175. NetApiBufferFree(pIniDomGrp->_pBuffer);
  176. pIniDomGrp->_pBuffer = NULL;
  177. }
  178. pIniDomGrp->_dwObjectReturned = 0;
  179. pIniDomGrp->_dwCurrentObject = 0;
  180. pIniDomGrp->_dwTotalObjects = 0;
  181. nasStatus = NetGroupGetUsers(
  182. pIniDomGrp->szUncCompName,
  183. pIniDomGrp->szGroupName,
  184. 0,
  185. &pIniDomGrp->_pBuffer,
  186. MAX_PREFERRED_LENGTH,
  187. &pIniDomGrp->_dwObjectReturned,
  188. &pIniDomGrp->_dwTotalObjects,
  189. &pIniDomGrp->_dwResumeHandle
  190. );
  191. if ((nasStatus != ERROR_SUCCESS) && (nasStatus != ERROR_MORE_DATA)){
  192. SetLastError(nasStatus);
  193. return(FALSE);
  194. }
  195. if (nasStatus != ERROR_MORE_DATA) {
  196. pIniDomGrp->_bNoMore = TRUE;
  197. }
  198. //
  199. // If there are no more objects to return,
  200. // return FALSE
  201. //
  202. if (!pIniDomGrp->_dwObjectReturned) {
  203. return(FALSE);
  204. }
  205. }
  206. dwRet = BuildGlobalGroupMember(
  207. hGroup,
  208. (LPBYTE)((LPGROUP_USERS_INFO_0)pIniDomGrp->_pBuffer + pIniDomGrp->_dwCurrentObject),
  209. ppGroupMember
  210. );
  211. if (!dwRet) {
  212. SetLastError(ERROR_INVALID_SID);
  213. goto error;
  214. }
  215. pIniDomGrp->_dwCurrentObject++;
  216. return(TRUE);
  217. error:
  218. return(FALSE);
  219. }
  220. BOOL
  221. WinNTGlobalGroupClose(
  222. HANDLE hGroup
  223. )
  224. {
  225. PINI_DOM_GROUP pIniDomGrp = (PINI_DOM_GROUP)hGroup;
  226. if (pIniDomGrp) {
  227. FreeIniDomGroup(pIniDomGrp);
  228. }
  229. return(TRUE);
  230. }
  231. void
  232. FreeIniDomGroup(
  233. PINI_DOM_GROUP pIniDomGrp
  234. )
  235. {
  236. if (pIniDomGrp->szDomainName) {
  237. FreeADsStr(pIniDomGrp->szDomainName);
  238. }
  239. if (pIniDomGrp->szComputerName) {
  240. FreeADsStr(pIniDomGrp->szComputerName);
  241. }
  242. if (pIniDomGrp->szGroupName) {
  243. FreeADsStr(pIniDomGrp->szGroupName);
  244. }
  245. if (pIniDomGrp->szUncCompName) {
  246. FreeADsStr(pIniDomGrp->szUncCompName);
  247. }
  248. if (pIniDomGrp->_pBuffer) {
  249. NetApiBufferFree(pIniDomGrp->_pBuffer);
  250. }
  251. if (pIniDomGrp) {
  252. FreeADsMem(pIniDomGrp);
  253. }
  254. return;
  255. }
  256. void
  257. FreeIntDomGroup(
  258. LPDOMAIN_GROUP_MEMBER pCompGroupMember
  259. )
  260. {
  261. if (pCompGroupMember->Parent) {
  262. FreeADsMem(pCompGroupMember->Parent);
  263. }
  264. if (pCompGroupMember->Computer) {
  265. FreeADsStr(pCompGroupMember->Computer);
  266. }
  267. if (pCompGroupMember->Domain) {
  268. FreeADsStr(pCompGroupMember->Domain);
  269. }
  270. if (pCompGroupMember->Name) {
  271. FreeADsStr(pCompGroupMember->Name);
  272. }
  273. FreeADsMem(pCompGroupMember);
  274. }
  275. BOOL
  276. ComputeGlobalGroupDataSize(
  277. LPDOMAIN_GROUP_MEMBER * ppGroupMembers,
  278. DWORD dwReturned,
  279. PDWORD pdwSize
  280. )
  281. {
  282. DWORD i = 0;
  283. DWORD cb = 0;
  284. LPDOMAIN_GROUP_MEMBER pMember = NULL;
  285. for (i = 0; i < dwReturned; i++) {
  286. pMember = *(ppGroupMembers + i);
  287. cb += sizeof(DOMAIN_GROUP_MEMBER);
  288. if (pMember->Parent) {
  289. cb += wcslen(pMember->Parent)*sizeof(WCHAR) + sizeof(WCHAR);
  290. }
  291. if (pMember->Computer) {
  292. cb += wcslen(pMember->Computer)*sizeof(WCHAR) + sizeof(WCHAR);
  293. }
  294. if (pMember->Domain) {
  295. cb += wcslen(pMember->Domain)*sizeof(WCHAR) + sizeof(WCHAR);
  296. }
  297. if (pMember->Name) {
  298. cb += wcslen(pMember->Name)*sizeof(WCHAR) + sizeof(WCHAR);
  299. }
  300. }
  301. *pdwSize = cb;
  302. return(TRUE);
  303. }
  304. LPBYTE
  305. CopyIniDomGroupToDomGroup(
  306. LPDOMAIN_GROUP_MEMBER pIntDomGrp,
  307. LPBYTE pExtDomGrp,
  308. LPBYTE pEnd
  309. )
  310. {
  311. LPWSTR SourceStrings[sizeof(DOMAIN_GROUP_MEMBER)/sizeof(LPWSTR)];
  312. LPWSTR *pSourceStrings=SourceStrings;
  313. LPDOMAIN_GROUP_MEMBER pDomGrpMember = (LPDOMAIN_GROUP_MEMBER)pExtDomGrp;
  314. memset(SourceStrings, 0, sizeof(DOMAIN_GROUP_MEMBER));
  315. *pSourceStrings++ = pIntDomGrp->Parent;
  316. *pSourceStrings++ = pIntDomGrp->Computer;
  317. *pSourceStrings++ = pIntDomGrp->Domain;
  318. *pSourceStrings++ = pIntDomGrp->Name;
  319. pEnd = PackStrings(
  320. SourceStrings,
  321. pExtDomGrp,
  322. DomainGrpMemberStrings,
  323. pEnd
  324. );
  325. pDomGrpMember->Type = pIntDomGrp->Type;
  326. return pEnd;
  327. }
  328. BOOL
  329. BuildGlobalGroupMember(
  330. HANDLE hGroup,
  331. LPBYTE lpBuffer,
  332. LPDOMAIN_GROUP_MEMBER * ppGroupMember
  333. )
  334. {
  335. LPINI_DOM_GROUP pGroup = (LPINI_DOM_GROUP)hGroup;
  336. LPDOMAIN_GROUP_MEMBER pGroupMember = NULL;
  337. LPGROUP_USERS_INFO_0 pGrpMem = (LPGROUP_USERS_INFO_0)lpBuffer;
  338. WCHAR szADsParent[MAX_PATH];
  339. LPWSTR pMemberName = NULL;
  340. DWORD cblen = 0;
  341. pGroupMember = (LPDOMAIN_GROUP_MEMBER)AllocADsMem(
  342. sizeof(DOMAIN_GROUP_MEMBER)
  343. );
  344. if (!pGroupMember) {
  345. goto error;
  346. }
  347. pGroupMember->Name = AllocADsStr(pGrpMem->grui0_name);
  348. pGroupMember->Computer = AllocADsStr(pGroup->szComputerName);
  349. pGroupMember->Domain = AllocADsStr(pGroup->szDomainName);
  350. wsprintf(
  351. szADsParent,
  352. L"%s://%s",
  353. szProviderName,
  354. pGroup->szDomainName
  355. );
  356. pGroupMember->Parent = AllocADsStr(szADsParent);
  357. pGroupMember->ParentType = WINNT_DOMAIN_ID;
  358. pGroupMember->Type = WINNT_USER_ID;
  359. *ppGroupMember = pGroupMember;
  360. return(TRUE);
  361. error:
  362. if (pGroupMember) {
  363. FreeIntDomGroup(pGroupMember);
  364. }
  365. *ppGroupMember = NULL;
  366. return(FALSE);
  367. }