//--------------------------------------------------------------------------- // // 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)((DWORD)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, CCredentials &Credentials, 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, Credentials ); 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; } } dwReturned = i; if (!dwRet) { goto error; } else { // // 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->Parent = NULL; pGroupMember->Computer = NULL; pGroupMember->Type = NWCOMPAT_USER_ID; wsprintf( szADsParent, L"%s://%s", szProviderName, pGroup->szComputerName ); pGroupMember->Parent = AllocADsStr(szADsParent); if (!pGroupMember->Parent) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } pGroupMember->Computer = AllocADsStr(pGroup->szComputerName); if (!pGroupMember->Computer) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } 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; }