|
|
//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: grputils.cxx
//
// Contents: NetWare compatible GroupCollection Enumeration Code
//
// History: 22-Mar-96 t-ptam (PatrickT) migrated from KrishnaG for NetWare
//----------------------------------------------------------------------------
#include "nwcompat.hxx"
#pragma hdrstop
COMPUTER_GROUP_MEMBER CompMember;
//
// This assumes that addr is an LPBYTE type.
//
#define WORD_ALIGN_DOWN(addr) \
addr = ((LPBYTE)((UINT_PTR)addr & ~1))
DWORD ComputerGrpMemberStrings[]= { FIELD_OFFSET(COMPUTER_GROUP_MEMBER, Parent), FIELD_OFFSET(COMPUTER_GROUP_MEMBER, Computer), FIELD_OFFSET(COMPUTER_GROUP_MEMBER, Name), 0xFFFFFFFF };
DECLARE_INFOLEVEL(GrpUt) DECLARE_DEBUG(GrpUt) #define GrpUtDebugOut(x) GrpUtInlineDebugOut x
//----------------------------------------------------------------------------
//
// Function: NWCOMPATComputerGroupOpen
//
// Synopsis: This function opens a handle to a INI_COMP_GROUP structure.
//
//----------------------------------------------------------------------------
BOOL NWCOMPATComputerGroupOpen( LPWSTR szComputerName, LPWSTR szGroupName, PHANDLE phGroup ) { WCHAR szTempBuffer[MAX_PATH]; PINI_COMP_GROUP pIniCompGrp; HRESULT hr = S_OK;
if (!phGroup) { return(FALSE); }
pIniCompGrp = (PINI_COMP_GROUP)AllocADsMem( sizeof(INI_COMP_GROUP) ); if (!pIniCompGrp) { return(FALSE); }
//
// Fill structure's fields.
//
if (!(pIniCompGrp->szComputerName = AllocADsStr(szComputerName))){ goto error; }
if (!(pIniCompGrp->szGroupName = AllocADsStr(szGroupName))){ goto error; }
hr = NWApiGetBinderyHandle( &pIniCompGrp->_hConn, szComputerName ); BAIL_ON_FAILURE(hr);
//
// Return
//
*phGroup = (HANDLE)pIniCompGrp;
return(TRUE);
error: if (pIniCompGrp) { FreeIniCompGroup(pIniCompGrp); }
*phGroup = NULL;
return(FALSE); }
//----------------------------------------------------------------------------
//
// Function: NWCOMPATComputerGroupEnum
//
// Synopsis: This function returns a buffer which contains all the binding
// informations for the requested number of objects without any
// references.
// It returns TRUE iff dwReturned = dwRequested.
//
//----------------------------------------------------------------------------
BOOL NWCOMPATComputerGroupEnum( HANDLE hGroup, DWORD dwRequested, LPBYTE * ppBuffer, PDWORD pdwReturned ) { LPCOMPUTER_GROUP_MEMBER * ppGroupMembers = NULL; DWORD i = 0; BOOL dwRet = FALSE; DWORD dwReturned = 0; DWORD dwSize = 0; LPCOMPUTER_GROUP_MEMBER pBuffer = NULL; LPBYTE pEnd = NULL;
//
// Allocate buffer for the number of requested members.
//
ppGroupMembers = (LPCOMPUTER_GROUP_MEMBER *)AllocADsMem( sizeof(LPCOMPUTER_GROUP_MEMBER)* dwRequested ); if (!ppGroupMembers) { return(FALSE); }
//
// Fill in ppGroupMembers one by one.
//
for (i = 0; i < dwRequested; i++) {
dwRet = NWCOMPATComputerGroupGetObject( hGroup, &ppGroupMembers[i] ); if (!dwRet) { break; } }
if (dwRet) { dwReturned = i;
//
// Determine actual size of ppGroupMembers[], ie. since each string in
// COMPUTER_GROUP_MEMBER have a different length, a buffer that is going
// to contain all the data without any references is unknown.
//
dwRet = ComputeComputerGroupDataSize( ppGroupMembers, dwReturned, &dwSize );
pBuffer = (LPCOMPUTER_GROUP_MEMBER)AllocADsMem( dwSize ); if (!pBuffer) { goto error; }
pEnd = (LPBYTE)((LPBYTE)(pBuffer) + dwSize);
//
// Put data into pBuffer, starting from the end.
//
for (i = 0; i < dwReturned; i++) {
pEnd = CopyIniCompGroupToCompGroup( ppGroupMembers[i], (LPBYTE)(pBuffer + i), pEnd ); }
//
// Clean up.
//
for (i = 0; i < dwReturned; i++ ) { FreeIntCompGroup(*(ppGroupMembers + i)); }
//
// Return values.
//
*ppBuffer = (LPBYTE)pBuffer; *pdwReturned = dwReturned; }
FreeADsMem(ppGroupMembers);
if (dwReturned == dwRequested){ return(TRUE); }else { return(FALSE); }
error: for (i = 0; i < dwReturned; i++ ) { FreeIntCompGroup(*(ppGroupMembers + i)); } FreeADsMem(ppGroupMembers); return(FALSE); }
//----------------------------------------------------------------------------
//
// Function: NWCOMPATComputerGroupGetObject
//
// Synopsis: This function returns binding information of a user (group member)
// object one by one. In its first call, it builds a buffer that
// contains all the UserID of the group members. Then, and in
// subsequent calls, this UserID is translated into a user name.
//
//----------------------------------------------------------------------------
BOOL NWCOMPATComputerGroupGetObject( HANDLE hGroup, LPCOMPUTER_GROUP_MEMBER * ppGroupMember ) { BOOL dwRet = FALSE; DWORD dwUserID = 0; HRESULT hr = S_OK; PINI_COMP_GROUP pIniCompGrp = (PINI_COMP_GROUP)hGroup;
//
// Fill buffer with User ID. NetWare returns all UserID in one call.
//
if (!pIniCompGrp->_pBuffer) {
pIniCompGrp->_dwCurrentObject = 0;
hr = NWApiGroupGetMembers( pIniCompGrp->_hConn, pIniCompGrp->szGroupName, &(pIniCompGrp->_pBuffer) ); BAIL_ON_FAILURE(hr); }
//
// Build one group member.
//
dwUserID = *((LPDWORD)pIniCompGrp->_pBuffer + pIniCompGrp->_dwCurrentObject);
if (dwUserID != 0x0000) {
dwRet = BuildComputerGroupMember( hGroup, dwUserID, ppGroupMember ); if (!dwRet) { goto error; }
pIniCompGrp->_dwCurrentObject++;
return(TRUE); }
error:
return(FALSE); }
//----------------------------------------------------------------------------
//
// Function: NWCOMPATComputerGroupClose
//
// Synopsis: Wrapper of FreeIniCompGroup.
//
//----------------------------------------------------------------------------
BOOL NWCOMPATComputerGroupClose( HANDLE hGroup ) { PINI_COMP_GROUP pIniCompGrp = (PINI_COMP_GROUP)hGroup;
if (pIniCompGrp) { FreeIniCompGroup(pIniCompGrp); } return(TRUE); }
//----------------------------------------------------------------------------
//
// Function: FreeIniCompGroup
//
// Synopsis: Free an INI_COMP_GROUP structure.
//
//----------------------------------------------------------------------------
void FreeIniCompGroup( PINI_COMP_GROUP pIniCompGrp ) { HRESULT hr = S_OK;
if (pIniCompGrp) {
if (pIniCompGrp->szComputerName) { FreeADsStr(pIniCompGrp->szComputerName); }
if (pIniCompGrp->szGroupName) { FreeADsStr(pIniCompGrp->szGroupName); }
if (pIniCompGrp->_pBuffer) { FreeADsMem(pIniCompGrp->_pBuffer); }
if (pIniCompGrp->_hConn) { hr = NWApiReleaseBinderyHandle(pIniCompGrp->_hConn); }
FreeADsMem(pIniCompGrp); }
return; }
//----------------------------------------------------------------------------
//
// Function: FreeIntCompGroup
//
// Synopsis: Free a COMPUTER_GROUP_MEMBER structure.
//
//----------------------------------------------------------------------------
void FreeIntCompGroup( LPCOMPUTER_GROUP_MEMBER pCompGroupMember ) { if (pCompGroupMember) {
if (pCompGroupMember->Parent) { FreeADsStr(pCompGroupMember->Parent); }
if (pCompGroupMember->Computer) { FreeADsStr(pCompGroupMember->Computer); }
if (pCompGroupMember->Name) { FreeADsStr(pCompGroupMember->Name); }
FreeADsMem(pCompGroupMember); }
return; }
//----------------------------------------------------------------------------
//
// Function: ComputeComputerGroupDataSize
//
// Synopsis: Calculate the size of a buffer that is going to store the data in
// ppGroupMembers without any references.
//
//----------------------------------------------------------------------------
BOOL ComputeComputerGroupDataSize( LPCOMPUTER_GROUP_MEMBER * ppGroupMembers, DWORD dwReturned, PDWORD pdwSize ) {
DWORD i = 0; DWORD cb = 0; LPCOMPUTER_GROUP_MEMBER pMember = NULL;
for (i = 0; i < dwReturned; i++) {
pMember = *(ppGroupMembers + i);
cb += sizeof(COMPUTER_GROUP_MEMBER);
if (pMember->Parent) { cb += wcslen(pMember->Parent)*sizeof(WCHAR) + sizeof(WCHAR); }
if (pMember->Computer) { cb += wcslen(pMember->Computer)*sizeof(WCHAR) + sizeof(WCHAR); }
if (pMember->Name) { cb += wcslen(pMember->Name)*sizeof(WCHAR) + sizeof(WCHAR); } }
*pdwSize = cb; return(TRUE); }
//------------------------------------------------------------------------------
//
// Function: CopyIniCompGroupToCompGroup
//
// Synopsis: Pack referenced data (string) into a buffer without any reference.
//
//------------------------------------------------------------------------------
LPBYTE CopyIniCompGroupToCompGroup( LPCOMPUTER_GROUP_MEMBER pIntCompGrp, LPBYTE pExtCompGrp, LPBYTE pEnd ) { LPWSTR SourceStrings[sizeof(COMPUTER_GROUP_MEMBER)/sizeof(LPWSTR)]; LPWSTR *pSourceStrings = SourceStrings; LPCOMPUTER_GROUP_MEMBER pCompGrpMember = (LPCOMPUTER_GROUP_MEMBER)pExtCompGrp;
memset(SourceStrings, 0, sizeof(COMPUTER_GROUP_MEMBER)); *pSourceStrings++ = pIntCompGrp->Parent; *pSourceStrings++ = pIntCompGrp->Computer; *pSourceStrings++ = pIntCompGrp->Name;
pEnd = PackStrings( SourceStrings, pExtCompGrp, ComputerGrpMemberStrings, pEnd );
pCompGrpMember->Type = pIntCompGrp->Type;
return pEnd; }
//----------------------------------------------------------------------------
//
// Function: BuildComputerGroupMember
//
// Synopsis: Put binding information of a group member into ppGroupMember.
//
//----------------------------------------------------------------------------
BOOL BuildComputerGroupMember( HANDLE hGroup, DWORD dwUserID, LPCOMPUTER_GROUP_MEMBER * ppGroupMember ) { DWORD dwTempUserID = dwUserID; HRESULT hr = S_OK; LPCOMPUTER_GROUP_MEMBER pGroupMember = NULL; LPINI_COMP_GROUP pGroup = (LPINI_COMP_GROUP)hGroup; WCHAR szADsParent[MAX_PATH];
//
// Allocate one COMPUTER_GROUP_MEMBER.
//
pGroupMember = (LPCOMPUTER_GROUP_MEMBER)AllocADsMem( sizeof(COMPUTER_GROUP_MEMBER) ); if (!pGroupMember) { return(FALSE); }
//
// Fill structure's fields.
//
pGroupMember->Type = NWCOMPAT_USER_ID;
wsprintf( szADsParent, L"%s://%s", szProviderName, pGroup->szComputerName ); pGroupMember->Parent = AllocADsStr(szADsParent);
pGroupMember->Computer = AllocADsStr(pGroup->szComputerName);
hr = NWApiGetObjectName( pGroup->_hConn, dwTempUserID, &pGroupMember->Name ); BAIL_ON_FAILURE(hr);
//
// Return.
//
*ppGroupMember = pGroupMember; return(TRUE);
error:
if (pGroupMember) {
if (pGroupMember->Parent) FreeADsStr(pGroupMember->Parent);
if (pGroupMember->Computer) FreeADsStr(pGroupMember->Computer);
FreeADsMem(pGroupMember); }
return(FALSE); }
//----------------------------------------------------------------------------
//
// Function: PackStrings
//
// Synopsis:
//
//----------------------------------------------------------------------------
LPBYTE PackStrings( LPWSTR *pSource, LPBYTE pDest, DWORD *DestOffsets, LPBYTE pEnd ) { DWORD cbStr; WORD_ALIGN_DOWN(pEnd);
while (*DestOffsets != -1) { if (*pSource) { cbStr = wcslen(*pSource)*sizeof(WCHAR) + sizeof(WCHAR); pEnd -= cbStr; CopyMemory( pEnd, *pSource, cbStr); *(LPWSTR *)(pDest+*DestOffsets) = (LPWSTR)pEnd; } else { *(LPWSTR *)(pDest+*DestOffsets)=0; } pSource++; DestOffsets++; } return pEnd; }
|