//--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1995 // // File: usrutils.cxx // // Contents: NetWare compatible UserCollection Enumeration Code // // History: 22-Mar-96 t-ptam (PatrickT) migrated from KrishnaG for NetWare //---------------------------------------------------------------------------- #include "nwcompat.hxx" #pragma hdrstop USER_GROUP_ENTRY UserGroupEntry; // // This assumes that addr is an LPBYTE type. // #define WORD_ALIGN_DOWN(addr) \ addr = ((LPBYTE)((DWORD)addr & ~1)) DWORD UserGrpEntryStrings[]= { FIELD_OFFSET(USER_GROUP_ENTRY, Parent), FIELD_OFFSET(USER_GROUP_ENTRY, Computer), FIELD_OFFSET(USER_GROUP_ENTRY, Name), 0xFFFFFFFF }; DECLARE_INFOLEVEL(UsrUt) DECLARE_DEBUG(UsrUt) #define UsrUtDebugOut(x) UsrUtInlineDebugOut x //---------------------------------------------------------------------------- // // Function: NWCOMPATComputerUserOpen // // Synopsis: This function opens a handle to a INI_COMP_USER structure. // //---------------------------------------------------------------------------- BOOL NWCOMPATComputerUserOpen( LPWSTR szComputerName, LPWSTR szGroupName, PHANDLE phUser ) { WCHAR szTempBuffer[MAX_PATH]; PINI_COMP_USER pIniCompUsr; HRESULT hr = S_OK; if (!phUser) { return(FALSE); } pIniCompUsr = (PINI_COMP_USER)AllocADsMem( sizeof(INI_COMP_USER) ); if (!pIniCompUsr) { return(FALSE); } // // Fill structure's fields. // if (!(pIniCompUsr->szComputerName = AllocADsStr(szComputerName))){ goto error; } if (!(pIniCompUsr->szGroupName = AllocADsStr(szGroupName))){ goto error; } hr = NWApiGetBinderyHandle( &pIniCompUsr->_hConn, szComputerName ); BAIL_ON_FAILURE(hr); // // Return // *phUser = (HANDLE)pIniCompUsr; return(TRUE); error: if (pIniCompUsr) { FreeIniCompUser(pIniCompUsr); } *phUser = NULL; return(FALSE); } //---------------------------------------------------------------------------- // // Function: NWCOMPATComputerUserEnum // // 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 NWCOMPATComputerUserEnum( HANDLE hUser, DWORD dwRequested, LPBYTE * ppBuffer, PDWORD pdwReturned ) { LPUSER_GROUP_ENTRY * ppUserMembers = NULL; DWORD i = 0; BOOL dwRet = FALSE; DWORD dwReturned = 0; DWORD dwSize = 0; LPUSER_GROUP_ENTRY pBuffer = NULL; LPBYTE pEnd = NULL; // // Allocate buffer for the number of requested members. // ppUserMembers = (LPUSER_GROUP_ENTRY *)AllocADsMem( sizeof(LPUSER_GROUP_ENTRY)* dwRequested ); if (!ppUserMembers) { return(FALSE); } // // Fill in ppUserMembers one by one. // for (i = 0; i < dwRequested; i++) { dwRet = NWCOMPATComputerUserGetObject( hUser, &ppUserMembers[i] ); if (!dwRet) { break; } } if (dwRet) { dwReturned = i; // // Determine actual size of ppUserMembers[], ie. since each string in // USER_GROUP_ENTRY have a different length, a buffer that is going // to contain all the data without any references is unknown. // dwRet = ComputeComputerUserDataSize( ppUserMembers, dwReturned, &dwSize ); pBuffer = (LPUSER_GROUP_ENTRY)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 = CopyIniCompUserToCompUser( ppUserMembers[i], (LPBYTE)(pBuffer + i), pEnd ); } // // Clean up. // for (i = 0; i < dwReturned; i++ ) { FreeIntCompUser(*(ppUserMembers + i)); } // // Return values. // *ppBuffer = (LPBYTE)pBuffer; *pdwReturned = dwReturned; } FreeADsMem(ppUserMembers); if (dwReturned == dwRequested){ return(TRUE); }else { return(FALSE); } error: for (i = 0; i < dwReturned; i++ ) { FreeIntCompUser(*(ppUserMembers + i)); } FreeADsMem(ppUserMembers); return(FALSE); } //---------------------------------------------------------------------------- // // Function: NWCOMPATComputerUserGetObject // // 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 NWCOMPATComputerUserGetObject( HANDLE hUser, LPUSER_GROUP_ENTRY * ppUserMember ) { BOOL dwRet = FALSE; DWORD dwGroupId = 0; HRESULT hr = S_OK; PINI_COMP_USER pIniCompUsr = (PINI_COMP_USER)hUser; // // Fill buffer with User ID. NetWare returns all UserID in one call. // if (!pIniCompUsr->_pBuffer) { pIniCompUsr->_dwCurrentObject = 0; hr = NWApiUserGetGroups( pIniCompUsr->_hConn, pIniCompUsr->szGroupName, &(pIniCompUsr->_pBuffer) ); BAIL_ON_FAILURE(hr); } // // Build one group member. // dwGroupId = *((LPDWORD)pIniCompUsr->_pBuffer + pIniCompUsr->_dwCurrentObject); if (dwGroupId != 0x0000) { dwRet = BuildComputerUserMember( hUser, dwGroupId, ppUserMember ); if (!dwRet) { goto error; } pIniCompUsr->_dwCurrentObject++; return(TRUE); } error: return(FALSE); } //---------------------------------------------------------------------------- // // Function: NWCOMPATComputerUserClose // // Synopsis: Wrapper of FreeIniCompUser. // //---------------------------------------------------------------------------- BOOL NWCOMPATComputerUserClose( HANDLE hUser ) { PINI_COMP_USER pIniCompUsr = (PINI_COMP_USER)hUser; if (pIniCompUsr) { FreeIniCompUser(pIniCompUsr); } return(TRUE); } //---------------------------------------------------------------------------- // // Function: FreeIniCompUser // // Synopsis: Free an INI_COMP_USER structure. // //---------------------------------------------------------------------------- void FreeIniCompUser( PINI_COMP_USER pIniCompUsr ) { HRESULT hr = S_OK; if (pIniCompUsr) { if (pIniCompUsr->szComputerName) { FreeADsStr(pIniCompUsr->szComputerName); } if (pIniCompUsr->szGroupName) { FreeADsStr(pIniCompUsr->szGroupName); } if (pIniCompUsr->_pBuffer) { FreeADsMem(pIniCompUsr->_pBuffer); } if (pIniCompUsr->_hConn) { hr = NWApiReleaseBinderyHandle(pIniCompUsr->_hConn); } FreeADsMem(pIniCompUsr); } return; } //---------------------------------------------------------------------------- // // Function: FreeIntCompUser // // Synopsis: Free a USER_GROUP_ENTRY structure. // //---------------------------------------------------------------------------- void FreeIntCompUser( LPUSER_GROUP_ENTRY pCompUserMember ) { if (pCompUserMember) { if (pCompUserMember->Parent) { FreeADsStr(pCompUserMember->Parent); } if (pCompUserMember->Computer) { FreeADsStr(pCompUserMember->Computer); } if (pCompUserMember->Name) { FreeADsStr(pCompUserMember->Name); } FreeADsMem(pCompUserMember); } return; } //---------------------------------------------------------------------------- // // Function: ComputeComputerUserDataSize // // Synopsis: Calculate the size of a buffer that is going to store the data in // ppUserMembers without any references. // //---------------------------------------------------------------------------- BOOL ComputeComputerUserDataSize( LPUSER_GROUP_ENTRY * ppUserMembers, DWORD dwReturned, PDWORD pdwSize ) { DWORD i = 0; DWORD cb = 0; LPUSER_GROUP_ENTRY pMember = NULL; for (i = 0; i < dwReturned; i++) { pMember = *(ppUserMembers + i); cb += sizeof(USER_GROUP_ENTRY); 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: CopyIniCompUserToCompUser // // Synopsis: Pack referenced data (string) into a buffer without any reference. // //------------------------------------------------------------------------------ LPBYTE CopyIniCompUserToCompUser( LPUSER_GROUP_ENTRY pIntCompGrp, LPBYTE pExtCompGrp, LPBYTE pEnd ) { LPWSTR SourceStrings[sizeof(USER_GROUP_ENTRY)/sizeof(LPWSTR)]; LPWSTR *pSourceStrings = SourceStrings; LPUSER_GROUP_ENTRY pCompGrpMember = (LPUSER_GROUP_ENTRY)pExtCompGrp; memset(SourceStrings, 0, sizeof(USER_GROUP_ENTRY)); *pSourceStrings++ = pIntCompGrp->Parent; *pSourceStrings++ = pIntCompGrp->Computer; *pSourceStrings++ = pIntCompGrp->Name; pEnd = PackStrings( SourceStrings, pExtCompGrp, UserGrpEntryStrings, pEnd ); pCompGrpMember->Type = pIntCompGrp->Type; return pEnd; } //---------------------------------------------------------------------------- // // Function: BuildComputerUserMember // // Synopsis: Put binding information of a group member into ppUserMember. // //---------------------------------------------------------------------------- BOOL BuildComputerUserMember( HANDLE hUser, DWORD dwGroupId, LPUSER_GROUP_ENTRY * ppUserMember ) { DWORD dwTempUserId = dwGroupId; HRESULT hr = S_OK; LPUSER_GROUP_ENTRY pUserMember = NULL; LPINI_COMP_USER pUser = (LPINI_COMP_USER)hUser; WCHAR szADsParent[MAX_PATH]; // // Allocate one USER_GROUP_ENTRY. // pUserMember = (LPUSER_GROUP_ENTRY)AllocADsMem( sizeof(USER_GROUP_ENTRY) ); if (!pUserMember) { return(FALSE); } // // Fill structure's fields. // pUserMember->Type = NWCOMPAT_USER_ID; wsprintf( szADsParent, L"%s://%s", szProviderName, pUser->szComputerName ); pUserMember->Parent = AllocADsStr(szADsParent); pUserMember->Computer = AllocADsStr(pUser->szComputerName); hr = NWApiGetObjectName( pUser->_hConn, dwTempUserId, &pUserMember->Name ); BAIL_ON_FAILURE(hr); // // Return. // *ppUserMember = pUserMember; return(TRUE); error: if (pUserMember) { if (pUserMember->Parent) FreeADsStr(pUserMember->Parent); if (pUserMember->Computer) FreeADsStr(pUserMember->Computer); FreeADsMem(pUserMember); } return(FALSE); }