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.

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