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.

566 lines
14 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: grputils.cxx
  7. //
  8. // Contents: NetWare compatible GroupCollection Enumeration Code
  9. //
  10. // History: 22-Mar-96 t-ptam (PatrickT) migrated from KrishnaG for NetWare
  11. //----------------------------------------------------------------------------
  12. #include "nwcompat.hxx"
  13. #pragma hdrstop
  14. COMPUTER_GROUP_MEMBER CompMember;
  15. //
  16. // This assumes that addr is an LPBYTE type.
  17. //
  18. #define WORD_ALIGN_DOWN(addr) \
  19. addr = ((LPBYTE)((UINT_PTR)addr & ~1))
  20. DWORD ComputerGrpMemberStrings[]=
  21. {
  22. FIELD_OFFSET(COMPUTER_GROUP_MEMBER, Parent),
  23. FIELD_OFFSET(COMPUTER_GROUP_MEMBER, Computer),
  24. FIELD_OFFSET(COMPUTER_GROUP_MEMBER, Name),
  25. 0xFFFFFFFF
  26. };
  27. DECLARE_INFOLEVEL(GrpUt)
  28. DECLARE_DEBUG(GrpUt)
  29. #define GrpUtDebugOut(x) GrpUtInlineDebugOut x
  30. //----------------------------------------------------------------------------
  31. //
  32. // Function: NWCOMPATComputerGroupOpen
  33. //
  34. // Synopsis: This function opens a handle to a INI_COMP_GROUP structure.
  35. //
  36. //----------------------------------------------------------------------------
  37. BOOL
  38. NWCOMPATComputerGroupOpen(
  39. LPWSTR szComputerName,
  40. LPWSTR szGroupName,
  41. PHANDLE phGroup
  42. )
  43. {
  44. WCHAR szTempBuffer[MAX_PATH];
  45. PINI_COMP_GROUP pIniCompGrp;
  46. HRESULT hr = S_OK;
  47. if (!phGroup) {
  48. return(FALSE);
  49. }
  50. pIniCompGrp = (PINI_COMP_GROUP)AllocADsMem(
  51. sizeof(INI_COMP_GROUP)
  52. );
  53. if (!pIniCompGrp) {
  54. return(FALSE);
  55. }
  56. //
  57. // Fill structure's fields.
  58. //
  59. if (!(pIniCompGrp->szComputerName = AllocADsStr(szComputerName))){
  60. goto error;
  61. }
  62. if (!(pIniCompGrp->szGroupName = AllocADsStr(szGroupName))){
  63. goto error;
  64. }
  65. hr = NWApiGetBinderyHandle(
  66. &pIniCompGrp->_hConn,
  67. szComputerName
  68. );
  69. BAIL_ON_FAILURE(hr);
  70. //
  71. // Return
  72. //
  73. *phGroup = (HANDLE)pIniCompGrp;
  74. return(TRUE);
  75. error:
  76. if (pIniCompGrp) {
  77. FreeIniCompGroup(pIniCompGrp);
  78. }
  79. *phGroup = NULL;
  80. return(FALSE);
  81. }
  82. //----------------------------------------------------------------------------
  83. //
  84. // Function: NWCOMPATComputerGroupEnum
  85. //
  86. // Synopsis: This function returns a buffer which contains all the binding
  87. // informations for the requested number of objects without any
  88. // references.
  89. // It returns TRUE iff dwReturned = dwRequested.
  90. //
  91. //----------------------------------------------------------------------------
  92. BOOL
  93. NWCOMPATComputerGroupEnum(
  94. HANDLE hGroup,
  95. DWORD dwRequested,
  96. LPBYTE * ppBuffer,
  97. PDWORD pdwReturned
  98. )
  99. {
  100. LPCOMPUTER_GROUP_MEMBER * ppGroupMembers = NULL;
  101. DWORD i = 0;
  102. BOOL dwRet = FALSE;
  103. DWORD dwReturned = 0;
  104. DWORD dwSize = 0;
  105. LPCOMPUTER_GROUP_MEMBER pBuffer = NULL;
  106. LPBYTE pEnd = NULL;
  107. //
  108. // Allocate buffer for the number of requested members.
  109. //
  110. ppGroupMembers = (LPCOMPUTER_GROUP_MEMBER *)AllocADsMem(
  111. sizeof(LPCOMPUTER_GROUP_MEMBER)* dwRequested
  112. );
  113. if (!ppGroupMembers) {
  114. return(FALSE);
  115. }
  116. //
  117. // Fill in ppGroupMembers one by one.
  118. //
  119. for (i = 0; i < dwRequested; i++) {
  120. dwRet = NWCOMPATComputerGroupGetObject(
  121. hGroup,
  122. &ppGroupMembers[i]
  123. );
  124. if (!dwRet) {
  125. break;
  126. }
  127. }
  128. if (dwRet) {
  129. dwReturned = i;
  130. //
  131. // Determine actual size of ppGroupMembers[], ie. since each string in
  132. // COMPUTER_GROUP_MEMBER have a different length, a buffer that is going
  133. // to contain all the data without any references is unknown.
  134. //
  135. dwRet = ComputeComputerGroupDataSize(
  136. ppGroupMembers,
  137. dwReturned,
  138. &dwSize
  139. );
  140. pBuffer = (LPCOMPUTER_GROUP_MEMBER)AllocADsMem(
  141. dwSize
  142. );
  143. if (!pBuffer) {
  144. goto error;
  145. }
  146. pEnd = (LPBYTE)((LPBYTE)(pBuffer) + dwSize);
  147. //
  148. // Put data into pBuffer, starting from the end.
  149. //
  150. for (i = 0; i < dwReturned; i++) {
  151. pEnd = CopyIniCompGroupToCompGroup(
  152. ppGroupMembers[i],
  153. (LPBYTE)(pBuffer + i),
  154. pEnd
  155. );
  156. }
  157. //
  158. // Clean up.
  159. //
  160. for (i = 0; i < dwReturned; i++ ) {
  161. FreeIntCompGroup(*(ppGroupMembers + i));
  162. }
  163. //
  164. // Return values.
  165. //
  166. *ppBuffer = (LPBYTE)pBuffer;
  167. *pdwReturned = dwReturned;
  168. }
  169. FreeADsMem(ppGroupMembers);
  170. if (dwReturned == dwRequested){
  171. return(TRUE);
  172. }else {
  173. return(FALSE);
  174. }
  175. error:
  176. for (i = 0; i < dwReturned; i++ ) {
  177. FreeIntCompGroup(*(ppGroupMembers + i));
  178. }
  179. FreeADsMem(ppGroupMembers);
  180. return(FALSE);
  181. }
  182. //----------------------------------------------------------------------------
  183. //
  184. // Function: NWCOMPATComputerGroupGetObject
  185. //
  186. // Synopsis: This function returns binding information of a user (group member)
  187. // object one by one. In its first call, it builds a buffer that
  188. // contains all the UserID of the group members. Then, and in
  189. // subsequent calls, this UserID is translated into a user name.
  190. //
  191. //----------------------------------------------------------------------------
  192. BOOL
  193. NWCOMPATComputerGroupGetObject(
  194. HANDLE hGroup,
  195. LPCOMPUTER_GROUP_MEMBER * ppGroupMember
  196. )
  197. {
  198. BOOL dwRet = FALSE;
  199. DWORD dwUserID = 0;
  200. HRESULT hr = S_OK;
  201. PINI_COMP_GROUP pIniCompGrp = (PINI_COMP_GROUP)hGroup;
  202. //
  203. // Fill buffer with User ID. NetWare returns all UserID in one call.
  204. //
  205. if (!pIniCompGrp->_pBuffer) {
  206. pIniCompGrp->_dwCurrentObject = 0;
  207. hr = NWApiGroupGetMembers(
  208. pIniCompGrp->_hConn,
  209. pIniCompGrp->szGroupName,
  210. &(pIniCompGrp->_pBuffer)
  211. );
  212. BAIL_ON_FAILURE(hr);
  213. }
  214. //
  215. // Build one group member.
  216. //
  217. dwUserID = *((LPDWORD)pIniCompGrp->_pBuffer + pIniCompGrp->_dwCurrentObject);
  218. if (dwUserID != 0x0000) {
  219. dwRet = BuildComputerGroupMember(
  220. hGroup,
  221. dwUserID,
  222. ppGroupMember
  223. );
  224. if (!dwRet) {
  225. goto error;
  226. }
  227. pIniCompGrp->_dwCurrentObject++;
  228. return(TRUE);
  229. }
  230. error:
  231. return(FALSE);
  232. }
  233. //----------------------------------------------------------------------------
  234. //
  235. // Function: NWCOMPATComputerGroupClose
  236. //
  237. // Synopsis: Wrapper of FreeIniCompGroup.
  238. //
  239. //----------------------------------------------------------------------------
  240. BOOL
  241. NWCOMPATComputerGroupClose(
  242. HANDLE hGroup
  243. )
  244. {
  245. PINI_COMP_GROUP pIniCompGrp = (PINI_COMP_GROUP)hGroup;
  246. if (pIniCompGrp) {
  247. FreeIniCompGroup(pIniCompGrp);
  248. }
  249. return(TRUE);
  250. }
  251. //----------------------------------------------------------------------------
  252. //
  253. // Function: FreeIniCompGroup
  254. //
  255. // Synopsis: Free an INI_COMP_GROUP structure.
  256. //
  257. //----------------------------------------------------------------------------
  258. void
  259. FreeIniCompGroup(
  260. PINI_COMP_GROUP pIniCompGrp
  261. )
  262. {
  263. HRESULT hr = S_OK;
  264. if (pIniCompGrp) {
  265. if (pIniCompGrp->szComputerName) {
  266. FreeADsStr(pIniCompGrp->szComputerName);
  267. }
  268. if (pIniCompGrp->szGroupName) {
  269. FreeADsStr(pIniCompGrp->szGroupName);
  270. }
  271. if (pIniCompGrp->_pBuffer) {
  272. FreeADsMem(pIniCompGrp->_pBuffer);
  273. }
  274. if (pIniCompGrp->_hConn) {
  275. hr = NWApiReleaseBinderyHandle(pIniCompGrp->_hConn);
  276. }
  277. FreeADsMem(pIniCompGrp);
  278. }
  279. return;
  280. }
  281. //----------------------------------------------------------------------------
  282. //
  283. // Function: FreeIntCompGroup
  284. //
  285. // Synopsis: Free a COMPUTER_GROUP_MEMBER structure.
  286. //
  287. //----------------------------------------------------------------------------
  288. void
  289. FreeIntCompGroup(
  290. LPCOMPUTER_GROUP_MEMBER pCompGroupMember
  291. )
  292. {
  293. if (pCompGroupMember) {
  294. if (pCompGroupMember->Parent) {
  295. FreeADsStr(pCompGroupMember->Parent);
  296. }
  297. if (pCompGroupMember->Computer) {
  298. FreeADsStr(pCompGroupMember->Computer);
  299. }
  300. if (pCompGroupMember->Name) {
  301. FreeADsStr(pCompGroupMember->Name);
  302. }
  303. FreeADsMem(pCompGroupMember);
  304. }
  305. return;
  306. }
  307. //----------------------------------------------------------------------------
  308. //
  309. // Function: ComputeComputerGroupDataSize
  310. //
  311. // Synopsis: Calculate the size of a buffer that is going to store the data in
  312. // ppGroupMembers without any references.
  313. //
  314. //----------------------------------------------------------------------------
  315. BOOL
  316. ComputeComputerGroupDataSize(
  317. LPCOMPUTER_GROUP_MEMBER * ppGroupMembers,
  318. DWORD dwReturned,
  319. PDWORD pdwSize
  320. )
  321. {
  322. DWORD i = 0;
  323. DWORD cb = 0;
  324. LPCOMPUTER_GROUP_MEMBER pMember = NULL;
  325. for (i = 0; i < dwReturned; i++) {
  326. pMember = *(ppGroupMembers + i);
  327. cb += sizeof(COMPUTER_GROUP_MEMBER);
  328. if (pMember->Parent) {
  329. cb += wcslen(pMember->Parent)*sizeof(WCHAR) + sizeof(WCHAR);
  330. }
  331. if (pMember->Computer) {
  332. cb += wcslen(pMember->Computer)*sizeof(WCHAR) + sizeof(WCHAR);
  333. }
  334. if (pMember->Name) {
  335. cb += wcslen(pMember->Name)*sizeof(WCHAR) + sizeof(WCHAR);
  336. }
  337. }
  338. *pdwSize = cb;
  339. return(TRUE);
  340. }
  341. //------------------------------------------------------------------------------
  342. //
  343. // Function: CopyIniCompGroupToCompGroup
  344. //
  345. // Synopsis: Pack referenced data (string) into a buffer without any reference.
  346. //
  347. //------------------------------------------------------------------------------
  348. LPBYTE
  349. CopyIniCompGroupToCompGroup(
  350. LPCOMPUTER_GROUP_MEMBER pIntCompGrp,
  351. LPBYTE pExtCompGrp,
  352. LPBYTE pEnd
  353. )
  354. {
  355. LPWSTR SourceStrings[sizeof(COMPUTER_GROUP_MEMBER)/sizeof(LPWSTR)];
  356. LPWSTR *pSourceStrings = SourceStrings;
  357. LPCOMPUTER_GROUP_MEMBER pCompGrpMember = (LPCOMPUTER_GROUP_MEMBER)pExtCompGrp;
  358. memset(SourceStrings, 0, sizeof(COMPUTER_GROUP_MEMBER));
  359. *pSourceStrings++ = pIntCompGrp->Parent;
  360. *pSourceStrings++ = pIntCompGrp->Computer;
  361. *pSourceStrings++ = pIntCompGrp->Name;
  362. pEnd = PackStrings(
  363. SourceStrings,
  364. pExtCompGrp,
  365. ComputerGrpMemberStrings,
  366. pEnd
  367. );
  368. pCompGrpMember->Type = pIntCompGrp->Type;
  369. return pEnd;
  370. }
  371. //----------------------------------------------------------------------------
  372. //
  373. // Function: BuildComputerGroupMember
  374. //
  375. // Synopsis: Put binding information of a group member into ppGroupMember.
  376. //
  377. //----------------------------------------------------------------------------
  378. BOOL
  379. BuildComputerGroupMember(
  380. HANDLE hGroup,
  381. DWORD dwUserID,
  382. LPCOMPUTER_GROUP_MEMBER * ppGroupMember
  383. )
  384. {
  385. DWORD dwTempUserID = dwUserID;
  386. HRESULT hr = S_OK;
  387. LPCOMPUTER_GROUP_MEMBER pGroupMember = NULL;
  388. LPINI_COMP_GROUP pGroup = (LPINI_COMP_GROUP)hGroup;
  389. WCHAR szADsParent[MAX_PATH];
  390. //
  391. // Allocate one COMPUTER_GROUP_MEMBER.
  392. //
  393. pGroupMember = (LPCOMPUTER_GROUP_MEMBER)AllocADsMem(
  394. sizeof(COMPUTER_GROUP_MEMBER)
  395. );
  396. if (!pGroupMember) {
  397. return(FALSE);
  398. }
  399. //
  400. // Fill structure's fields.
  401. //
  402. pGroupMember->Type = NWCOMPAT_USER_ID;
  403. wsprintf(
  404. szADsParent,
  405. L"%s://%s",
  406. szProviderName,
  407. pGroup->szComputerName
  408. );
  409. pGroupMember->Parent = AllocADsStr(szADsParent);
  410. pGroupMember->Computer = AllocADsStr(pGroup->szComputerName);
  411. hr = NWApiGetObjectName(
  412. pGroup->_hConn,
  413. dwTempUserID,
  414. &pGroupMember->Name
  415. );
  416. BAIL_ON_FAILURE(hr);
  417. //
  418. // Return.
  419. //
  420. *ppGroupMember = pGroupMember;
  421. return(TRUE);
  422. error:
  423. if (pGroupMember) {
  424. if (pGroupMember->Parent)
  425. FreeADsStr(pGroupMember->Parent);
  426. if (pGroupMember->Computer)
  427. FreeADsStr(pGroupMember->Computer);
  428. FreeADsMem(pGroupMember);
  429. }
  430. return(FALSE);
  431. }
  432. //----------------------------------------------------------------------------
  433. //
  434. // Function: PackStrings
  435. //
  436. // Synopsis:
  437. //
  438. //----------------------------------------------------------------------------
  439. LPBYTE
  440. PackStrings(
  441. LPWSTR *pSource,
  442. LPBYTE pDest,
  443. DWORD *DestOffsets,
  444. LPBYTE pEnd
  445. )
  446. {
  447. DWORD cbStr;
  448. WORD_ALIGN_DOWN(pEnd);
  449. while (*DestOffsets != -1) {
  450. if (*pSource) {
  451. cbStr = wcslen(*pSource)*sizeof(WCHAR) + sizeof(WCHAR);
  452. pEnd -= cbStr;
  453. CopyMemory( pEnd, *pSource, cbStr);
  454. *(LPWSTR *)(pDest+*DestOffsets) = (LPWSTR)pEnd;
  455. } else {
  456. *(LPWSTR *)(pDest+*DestOffsets)=0;
  457. }
  458. pSource++;
  459. DestOffsets++;
  460. }
  461. return pEnd;
  462. }