Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1170 lines
31 KiB

/*++ BUILD Version: 0000 // Increment this if a change has global effects
Copyright (c) 2000-2002 Microsoft Corporation
Module Name:
mmcmgmt.cpp
Abstract:
Source file module for MMC manipulation
Author:
Xiaohai Zhang (xzhang) 22-March-2000
Revision History:
--*/
#include <stdio.h>
#include "windows.h"
#include "objbase.h"
#include "tapi.h"
#include "mmcmgmt.h"
#include "error.h"
#include "tchar.h"
#include <locale.h>
#include <winnlsp.h>
///////////////////////////////////////////////////////////
//
// CMMCManagement implementation
//
///////////////////////////////////////////////////////////
HRESULT CMMCManagement::GetMMCData ()
{
HRESULT hr = S_OK;
DWORD dwAPIVersion = TAPI_CURRENT_VERSION;
DWORD dw, dw1, dw2;
LPDEVICEINFO pDeviceInfo;
TAPISERVERCONFIG cfg;
LINEPROVIDERLIST tapiProviderList = {0};
LPLINEPROVIDERENTRY pProvider;
AVAILABLEPROVIDERLIST tapiAvailProvList = {0};
LPAVAILABLEPROVIDERLIST pAvailProvList = NULL;
AVAILABLEPROVIDERENTRY *pAvailProv;
hr = MMCInitialize (
NULL, // Local computer
&m_hMmc, // HMMCAPP to return
&dwAPIVersion, // API version
NULL
);
if (FAILED(hr) || m_hMmc == NULL)
{
goto ExitHere;
}
// Mark MMC to be busy
cfg.dwTotalSize = sizeof(TAPISERVERCONFIG);
hr = MMCGetServerConfig (m_hMmc, &cfg);
if (FAILED(hr))
{
goto ExitHere;
}
cfg.dwFlags |= TAPISERVERCONFIGFLAGS_LOCKMMCWRITE;
hr = MMCSetServerConfig (m_hMmc, &cfg);
if (FAILED(hr))
{
goto ExitHere;
}
m_bMarkedBusy = TRUE;
// Get the DEVICEINFOLIST structure
m_pDeviceInfoList = (LPDEVICEINFOLIST) new BYTE[sizeof(DEVICEINFOLIST)];
if (m_pDeviceInfoList == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
m_pDeviceInfoList->dwTotalSize = sizeof(DEVICEINFOLIST);
hr = MMCGetLineInfo (
m_hMmc,
m_pDeviceInfoList
);
if (FAILED(hr))
{
goto ExitHere;
}
else if (m_pDeviceInfoList->dwNeededSize > m_pDeviceInfoList->dwTotalSize)
{
dw = m_pDeviceInfoList->dwNeededSize;
delete [] m_pDeviceInfoList;
m_pDeviceInfoList = (LPDEVICEINFOLIST) new BYTE[dw];
if (m_pDeviceInfoList == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
m_pDeviceInfoList->dwTotalSize = dw;
hr = MMCGetLineInfo (
m_hMmc,
m_pDeviceInfoList
);
if (FAILED(hr))
{
goto ExitHere;
}
}
if (m_pDeviceInfoList->dwNumDeviceInfoEntries == 0)
{
delete [] m_pDeviceInfoList;
if (m_hMmc)
{
cfg.dwFlags &= (~TAPISERVERCONFIGFLAGS_LOCKMMCWRITE);
cfg.dwFlags |= TAPISERVERCONFIGFLAGS_UNLOCKMMCWRITE;
MMCSetServerConfig (m_hMmc, &cfg);
m_bMarkedBusy = FALSE;
MMCShutdown (m_hMmc);
m_hMmc = NULL;
}
goto ExitHere;
}
// Build the user name tuple
m_pUserTuple =
new USERNAME_TUPLE[m_pDeviceInfoList->dwNumDeviceInfoEntries];
if (m_pUserTuple == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
pDeviceInfo = (LPDEVICEINFO)(((LPBYTE)m_pDeviceInfoList) +
m_pDeviceInfoList->dwDeviceInfoOffset);
for (dw = 0;
dw < m_pDeviceInfoList->dwNumDeviceInfoEntries;
++dw, ++pDeviceInfo)
{
if (pDeviceInfo->dwDomainUserNamesSize == 0)
{
m_pUserTuple[dw].pDomainUserNames = NULL;
m_pUserTuple[dw].pFriendlyUserNames = NULL;
}
else
{
m_pUserTuple[dw].pDomainUserNames =
(LPTSTR) new BYTE[pDeviceInfo->dwDomainUserNamesSize];
m_pUserTuple[dw].pFriendlyUserNames =
(LPTSTR) new BYTE[pDeviceInfo->dwFriendlyUserNamesSize];
if (m_pUserTuple[dw].pDomainUserNames == NULL ||
m_pUserTuple[dw].pFriendlyUserNames == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
memcpy (
m_pUserTuple[dw].pDomainUserNames,
(((LPBYTE)m_pDeviceInfoList) +
pDeviceInfo->dwDomainUserNamesOffset),
pDeviceInfo->dwDomainUserNamesSize
);
memcpy (
m_pUserTuple[dw].pFriendlyUserNames,
(((LPBYTE)m_pDeviceInfoList) +
pDeviceInfo->dwFriendlyUserNamesOffset),
pDeviceInfo->dwFriendlyUserNamesSize
);
}
}
// Get the provider list
tapiProviderList.dwTotalSize = sizeof(LINEPROVIDERLIST);
hr = MMCGetProviderList( m_hMmc, &tapiProviderList);
if (FAILED(hr))
{
goto ExitHere;
}
m_pProviderList = (LPLINEPROVIDERLIST) new BYTE[tapiProviderList.dwNeededSize];
if (NULL == m_pProviderList)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
memset(m_pProviderList, 0, tapiProviderList.dwNeededSize);
m_pProviderList->dwTotalSize = tapiProviderList.dwNeededSize;
hr = MMCGetProviderList( m_hMmc, m_pProviderList);
if (FAILED(hr) || !m_pProviderList->dwNumProviders)
{
goto ExitHere;
}
// Get the available providers
tapiAvailProvList.dwTotalSize = sizeof(LINEPROVIDERLIST);
hr = MMCGetAvailableProviders (m_hMmc, &tapiAvailProvList);
if (FAILED(hr))
{
goto ExitHere;
}
pAvailProvList = (LPAVAILABLEPROVIDERLIST) new BYTE[tapiAvailProvList.dwNeededSize];
if (NULL == pAvailProvList)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
memset(pAvailProvList, 0, tapiAvailProvList.dwNeededSize);
pAvailProvList->dwTotalSize = tapiAvailProvList.dwNeededSize;
hr = MMCGetAvailableProviders (m_hMmc, pAvailProvList);
if (FAILED(hr) || !pAvailProvList->dwNumProviderListEntries)
{
delete [] pAvailProvList;
goto ExitHere;
}
m_pProviderName = new LPTSTR[ m_pProviderList->dwNumProviders ];
if (NULL == m_pProviderName)
{
hr = TSECERR_NOMEM;
delete [] pAvailProvList;
goto ExitHere;
}
memset(m_pProviderName, 0, m_pProviderList->dwNumProviders * sizeof (LPTSTR) );
// find providers friendly name
LPTSTR szAvailProvFilename;
LPTSTR szProviderFilename;
LPTSTR szAvailProvFriendlyName;
pProvider = (LPLINEPROVIDERENTRY)
((LPBYTE) m_pProviderList + m_pProviderList->dwProviderListOffset);
for( dw1=0; dw1 < m_pProviderList->dwNumProviders; dw1++, pProvider++ )
{
szProviderFilename =
(LPTSTR) ((LPBYTE) m_pProviderList + pProvider->dwProviderFilenameOffset);
for ( dw2=0; dw2 < pAvailProvList->dwNumProviderListEntries; dw2++ )
{
pAvailProv = (LPAVAILABLEPROVIDERENTRY)
(( LPBYTE) pAvailProvList + pAvailProvList->dwProviderListOffset) + dw2;
szAvailProvFilename =
(LPTSTR) ((LPBYTE) pAvailProvList + pAvailProv->dwFileNameOffset);
if (_tcsicmp(szAvailProvFilename, szProviderFilename) == 0)
{
szAvailProvFriendlyName =
(LPTSTR) ((LPBYTE) pAvailProvList + pAvailProv->dwFriendlyNameOffset);
m_pProviderName[ dw1 ] = new TCHAR[ _tcslen( szAvailProvFriendlyName ) + 1 ];
if (m_pProviderName[ dw1 ])
{
_tcscpy( m_pProviderName[ dw1 ], szAvailProvFriendlyName );
}
break;
}
}
}
delete [] pAvailProvList;
ExitHere:
if (FAILED(hr))
{
FreeMMCData ();
}
return hr;
}
HRESULT CMMCManagement::FreeMMCData ()
{
DWORD dw;
if (m_pUserTuple && m_pDeviceInfoList)
{
for (dw = 0;
dw < m_pDeviceInfoList->dwNumDeviceInfoEntries;
++dw)
{
if (m_pUserTuple[dw].pDomainUserNames)
{
delete [] m_pUserTuple[dw].pDomainUserNames;
}
if (m_pUserTuple[dw].pFriendlyUserNames)
{
delete [] m_pUserTuple[dw].pFriendlyUserNames;
}
}
delete [] m_pUserTuple;
m_pUserTuple = NULL;
}
if (m_pDeviceInfoList)
{
delete [] m_pDeviceInfoList;
m_pDeviceInfoList = NULL;
}
if (m_pProviderList)
{
delete [] m_pProviderList;
m_pProviderList = NULL;
}
if (m_pProviderName)
{
for ( DWORD dw=0; dw < sizeof( m_pProviderName ) / sizeof(LPTSTR); dw++ )
{
if (m_pProviderName[ dw ])
{
delete [] m_pProviderName[ dw ];
}
}
delete [] m_pProviderName;
}
if (m_bMarkedBusy && m_hMmc)
{
TAPISERVERCONFIG cfg;
cfg.dwTotalSize = sizeof(TAPISERVERCONFIG);
if (S_OK == MMCGetServerConfig (m_hMmc, &cfg))
{
cfg.dwFlags |= TAPISERVERCONFIGFLAGS_UNLOCKMMCWRITE;
MMCSetServerConfig (m_hMmc, &cfg);
}
m_bMarkedBusy = FALSE;
}
if (m_hMmc)
{
MMCShutdown (m_hMmc);
m_hMmc = NULL;
}
return S_OK;
}
HRESULT CMMCManagement::RemoveLinesForUser (LPTSTR szDomainUser)
{
HRESULT hr = S_OK;
LPDWORD adwIndex = NULL;
DWORD dwNumEntries;
DWORD dw;
// Ensure we are properly initialized
if (m_hMmc == NULL)
{
goto ExitHere;
}
hr = FindEntriesForUser (szDomainUser, &adwIndex, &dwNumEntries);
if (hr)
{
goto ExitHere;
}
for (dw = 0; dw < dwNumEntries; ++dw)
{
hr = RemoveEntryForUser (
adwIndex[dw],
szDomainUser
);
if(FAILED(hr))
{
goto ExitHere;
}
}
ExitHere:
if (adwIndex)
{
delete [] adwIndex;
}
return hr;
}
HRESULT CMMCManagement::IsValidPID (
DWORD dwPermanentID
)
{
DWORD dwEntry;
return FindEntryFromPID (dwPermanentID, &dwEntry);
}
HRESULT CMMCManagement::IsValidAddress (
LPTSTR szAddr
)
{
DWORD dwEntry;
return FindEntryFromAddr (szAddr, &dwEntry);
}
HRESULT CMMCManagement::AddLinePIDForUser (
DWORD dwPermanentID,
LPTSTR szDomainUser,
LPTSTR szFriendlyName
)
{
HRESULT hr = S_OK;
DWORD dwEntry;
// Ensure we are properly initialized
if (m_hMmc == NULL)
{
goto ExitHere;
}
hr = FindEntryFromPID (dwPermanentID, &dwEntry);
if (hr)
{
goto ExitHere;
}
hr = AddEntryForUser (dwEntry, szDomainUser, szFriendlyName);
ExitHere:
return hr;
}
HRESULT CMMCManagement::AddLineAddrForUser (
LPTSTR szAddr,
LPTSTR szDomainUser,
LPTSTR szFriendlyName
)
{
HRESULT hr = S_OK;
DWORD dwEntry;
// Ensure we are properly initialized
if (m_hMmc == NULL)
{
goto ExitHere;
}
hr = FindEntryFromAddr (szAddr, &dwEntry);
if (hr)
{
goto ExitHere;
}
hr = AddEntryForUser (dwEntry, szDomainUser, szFriendlyName);
ExitHere:
return hr;
}
HRESULT CMMCManagement::RemoveLinePIDForUser (
DWORD dwPermanentID,
LPTSTR szDomainUser
)
{
HRESULT hr = S_OK;
DWORD dwEntry;
// Ensure we are properly initialized
if (m_hMmc == NULL)
{
goto ExitHere;
}
hr = FindEntryFromPID (dwPermanentID, &dwEntry);
if (hr)
{
goto ExitHere;
}
hr = RemoveEntryForUser (dwEntry, szDomainUser);
ExitHere:
return hr;
}
HRESULT CMMCManagement::RemoveLineAddrForUser (
LPTSTR szAddr,
LPTSTR szDomainUser
)
{
HRESULT hr = S_OK;
DWORD dwEntry;
// Ensure we are properly initialized
if (m_hMmc == NULL)
{
goto ExitHere;
}
hr = FindEntryFromAddr (szAddr, &dwEntry);
if (hr)
{
goto ExitHere;
}
hr = RemoveEntryForUser (dwEntry, szDomainUser);
ExitHere:
return hr;
}
BOOL CMMCManagement::IsDeviceLocalOnly (DWORD dwProviderID, DWORD dwDeviceID)
{
HRESULT hr;
DWORD dwFlags, dwDev;
if (m_pFuncGetDeviceFlags == NULL)
{
return TRUE;
}
hr = (*m_pFuncGetDeviceFlags)(
m_hMmc,
TRUE,
dwProviderID,
dwDeviceID,
&dwFlags,
&dwDev
);
if (hr || dwFlags & LINEDEVCAPFLAGS_LOCAL)
{
return TRUE;
}
else
{
return FALSE;
}
}
HRESULT CMMCManagement::FindEntryFromAddr (LPTSTR szAddr, DWORD * pdwIndex)
{
HRESULT hr = S_FALSE;
DWORD dw;
LPDEVICEINFO pDevInfo;
LPTSTR szAddr2;
pDevInfo = (LPDEVICEINFO) (((LPBYTE)m_pDeviceInfoList) +
m_pDeviceInfoList->dwDeviceInfoOffset);
for (dw = 0;
dw < m_pDeviceInfoList->dwNumDeviceInfoEntries;
++dw, ++pDevInfo)
{
szAddr2 = (LPTSTR)(((LPBYTE)m_pDeviceInfoList) +
pDevInfo->dwAddressesOffset);
while (*szAddr2)
{
if (_tcsicmp (szAddr, szAddr2) == 0)
{
if (IsDeviceLocalOnly (
pDevInfo->dwProviderID,
pDevInfo->dwPermanentDeviceID
))
{
hr = TSECERR_DEVLOCALONLY;
}
else
{
hr = S_OK;
*pdwIndex = dw;
}
goto ExitHere;
}
szAddr2 += _tcslen (szAddr2) + 1;
}
}
ExitHere:
return hr;
}
HRESULT CMMCManagement::FindEntryFromPID (DWORD dwPID, DWORD * pdwIndex)
{
HRESULT hr = S_FALSE;
DWORD dw;
LPDEVICEINFO pDevInfo;
pDevInfo = (LPDEVICEINFO) (((LPBYTE)m_pDeviceInfoList) +
m_pDeviceInfoList->dwDeviceInfoOffset);
for (dw = 0;
dw < m_pDeviceInfoList->dwNumDeviceInfoEntries;
++dw, ++pDevInfo)
{
if (dwPID == pDevInfo->dwPermanentDeviceID)
{
if (IsDeviceLocalOnly (
pDevInfo->dwProviderID,
pDevInfo->dwPermanentDeviceID
))
{
hr = TSECERR_DEVLOCALONLY;
}
else
{
*pdwIndex = dw;
hr = S_OK;
}
goto ExitHere;
}
}
ExitHere:
return hr;
}
HRESULT CMMCManagement::FindEntriesForUser (
LPTSTR szDomainUser,
LPDWORD * padwIndex,
DWORD * pdwNumEntries
)
{
HRESULT hr = S_OK;
DWORD dw;
LPTSTR szUsers;
LPDWORD adw;
*padwIndex = NULL;
*pdwNumEntries = 0;
for (dw = 0;
dw < m_pDeviceInfoList->dwNumDeviceInfoEntries;
++dw)
{
szUsers = m_pUserTuple[dw].pDomainUserNames;
while (szUsers && *szUsers)
{
if (_tcsicmp (szDomainUser, szUsers) == 0)
{
hr = S_OK;
adw = new DWORD[*pdwNumEntries + 1];
if (adw == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
if (*pdwNumEntries > 0)
{
memcpy (adw, *padwIndex, sizeof(DWORD) * (*pdwNumEntries));
}
if (*padwIndex)
{
delete [] (*padwIndex);
}
*padwIndex = adw;
adw[*pdwNumEntries] = dw;
*pdwNumEntries += 1;
}
szUsers += _tcslen (szUsers) + 1;
}
}
ExitHere:
if (FAILED(hr))
{
*pdwNumEntries = 0;
if (*padwIndex)
{
delete [] (*padwIndex);
}
}
else if (*pdwNumEntries == 0)
{
hr = S_FALSE;
}
return hr;
}
HRESULT CMMCManagement::AddEntryForUser (
DWORD dwIndex,
LPTSTR szDomainUser,
LPTSTR szFriendlyName
)
{
HRESULT hr = S_OK;
DWORD dwSize, dw;
LPTSTR szUsers, szNewUsers = NULL, szNewFriendlyNames = NULL;
if (dwIndex >= m_pDeviceInfoList->dwNumDeviceInfoEntries ||
szDomainUser[0] == 0 ||
szFriendlyName[0] == 0)
{
hr = S_FALSE;
goto ExitHere;
}
//
// Add szDomainUser into the user tuple
//
// Computer the existing domain user size and make sure
// this user is not there already
dwSize = 0;
szUsers = m_pUserTuple[dwIndex].pDomainUserNames;
while (szUsers && *szUsers)
{
if (_tcsicmp (szDomainUser, szUsers) == 0)
{
goto ExitHere;
}
dw = _tcslen (szUsers) + 1;
dwSize += dw;
szUsers += dw;
}
// Extra space for double zero terminating
dw = _tcslen (szDomainUser);
szNewUsers = new TCHAR[dwSize + dw + 2];
if (szNewUsers == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
// copy over the old domain users
if (dwSize > 0)
{
memcpy (
szNewUsers,
m_pUserTuple[dwIndex].pDomainUserNames,
dwSize * sizeof(TCHAR)
);
}
// Append the new domain user
memcpy (
szNewUsers + dwSize,
szDomainUser,
(dw + 1) * sizeof(TCHAR)
);
// double zero terminate and assign the data
szNewUsers[dwSize + dw + 1] = 0;
//
// Add the szFriendlyName into the user tuple
//
// Compute the existing friendly names size
dwSize = 0;
szUsers = m_pUserTuple[dwIndex].pFriendlyUserNames;
while (szUsers && *szUsers)
{
dw = _tcslen (szUsers) + 1;
dwSize += dw;
szUsers += dw;
}
// Extra space for double zero terminating
dw = _tcslen (szFriendlyName);
szNewFriendlyNames = new TCHAR[dwSize + dw + 2];
if (szNewFriendlyNames == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
// Copy over the old friendly names
if (dwSize > 0)
{
memcpy (
szNewFriendlyNames,
m_pUserTuple[dwIndex].pFriendlyUserNames,
dwSize * sizeof(TCHAR)
);
}
// Append the new friendly name
memcpy (
szNewFriendlyNames + dwSize,
szFriendlyName,
(dw + 1) * sizeof(TCHAR)
);
// Double zero terminate the friend names
szNewFriendlyNames[dwSize + dw + 1] = 0;
//
// Everything is fine, set the new data in
//
if (m_pUserTuple[dwIndex].pDomainUserNames)
{
delete [] m_pUserTuple[dwIndex].pDomainUserNames;
}
m_pUserTuple[dwIndex].pDomainUserNames = szNewUsers;
if (m_pUserTuple[dwIndex].pFriendlyUserNames)
{
delete [] m_pUserTuple[dwIndex].pFriendlyUserNames;
}
m_pUserTuple[dwIndex].pFriendlyUserNames = szNewFriendlyNames;
// Call WriteMMCEntry
hr = WriteMMCEntry (dwIndex);
ExitHere:
return hr;
}
HRESULT CMMCManagement::RemoveEntryForUser (
DWORD dwIndex,
LPTSTR szDomainUser
)
{
HRESULT hr = S_OK;
LPTSTR szLoc, szUsers;
DWORD dwLoc, dw, dwSize;
BOOL bFound;
if (dwIndex >= m_pDeviceInfoList->dwNumDeviceInfoEntries ||
szDomainUser[0] == 0)
{
hr = S_FALSE;
goto ExitHere;
}
// Locate the domain user and its index in the array
// of domain users
szUsers = m_pUserTuple[dwIndex].pDomainUserNames;
dwLoc = 0;
dwSize = 0;
bFound = FALSE;
while (szUsers && *szUsers)
{
dw = _tcslen (szUsers) + 1;
if (bFound)
{
dwSize += dw;
}
else
{
if (_tcsicmp (szDomainUser, szUsers) == 0)
{
bFound = TRUE;
szLoc = szUsers;
}
else
{
++dwLoc;
}
}
szUsers += dw;
}
if (!bFound)
{
goto ExitHere;
}
// Move down the pszDomainUserNames
if (dwSize > 0)
{
dw = _tcslen (szDomainUser);
// Memory copy includes the double zero terminator
memmove (szLoc, szLoc + dw + 1, (dwSize + 1) * sizeof(TCHAR));
}
else
{
// The is the last item, simple double zero terminate
*szLoc = 0;
}
// Now find corresponding friendly name based on dwLoc
szUsers = m_pUserTuple[dwIndex].pFriendlyUserNames;
while (szUsers && *szUsers && dwLoc > 0)
{
--dwLoc;
szUsers += _tcslen (szUsers) + 1;
}
// bail if not exist, otherwise, remember the location
if (szUsers == NULL || *szUsers == 0)
{
goto ExitHere;
}
szLoc = szUsers;
// Go to the next item
szUsers += _tcslen (szUsers) + 1;
// This is the last item
if (*szUsers == 0)
{
*szLoc = 0;
}
// Otherwise compute the remaining size to move
else
{
dwSize = 0;
while (*szUsers)
{
dw = _tcslen (szUsers) + 1;
dwSize += dw;
szUsers += dw;
}
// Compensate for the double zero terminating
dwSize++;
// Do the memory move
memmove (
szLoc,
szLoc + _tcslen (szLoc) + 1,
dwSize * sizeof(TCHAR)
);
}
// Call WriteMMCEntry
hr = WriteMMCEntry (dwIndex);
ExitHere:
return hr;
}
HRESULT CMMCManagement::WriteMMCEntry (DWORD dwIndex)
{
HRESULT hr = S_OK;
DWORD dwSize, dwSizeDU, dwSizeFU;
LPUSERNAME_TUPLE pUserTuple;
LPTSTR szUsers;
DWORD dw;
LPDEVICEINFOLIST pDevList = NULL;
LPDEVICEINFO pDevInfo, pDevInfoOld;
LPBYTE pDest;
if (dwIndex >= m_pDeviceInfoList->dwNumDeviceInfoEntries)
{
hr = S_FALSE;
goto ExitHere;
}
pUserTuple = m_pUserTuple + dwIndex;
// Computer domain user name size
dwSizeDU = 0;
if (pUserTuple->pDomainUserNames != NULL &&
*pUserTuple->pDomainUserNames != 0)
{
szUsers = pUserTuple->pDomainUserNames;
while (*szUsers)
{
dw = _tcslen (szUsers) + 1;
szUsers += dw;
dwSizeDU += dw;
}
dwSizeDU++; // double zero terminator
}
// Computer the friendly user name size
dwSizeFU = 0;
if (pUserTuple->pFriendlyUserNames != NULL &&
*pUserTuple->pFriendlyUserNames != 0)
{
szUsers = pUserTuple->pFriendlyUserNames;
while (*szUsers)
{
dw = _tcslen (szUsers) + 1;
szUsers += dw;
dwSizeFU += dw;
}
dwSizeFU++; // double zero terminator
}
// Computer the total size
dwSize = sizeof(DEVICEINFOLIST) + sizeof(DEVICEINFO) +
(dwSizeDU + dwSizeFU) * sizeof(TCHAR);
// Allocate the structure
pDevList = (LPDEVICEINFOLIST) new BYTE[dwSize];
if (pDevList == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
// Set the data member of DEVICEINFOLIST
pDevList->dwTotalSize = dwSize;
pDevList->dwNeededSize = dwSize;
pDevList->dwUsedSize = dwSize;
pDevList->dwNumDeviceInfoEntries = 1;
pDevList->dwDeviceInfoSize = sizeof(DEVICEINFO);
pDevList->dwDeviceInfoOffset = sizeof(DEVICEINFOLIST);
// Set the member of DEVICEINFO
pDevInfo = (LPDEVICEINFO)(((LPBYTE)pDevList) +
pDevList->dwDeviceInfoOffset);
pDevInfoOld = (LPDEVICEINFO)(((LPBYTE)m_pDeviceInfoList) +
m_pDeviceInfoList->dwDeviceInfoOffset) + dwIndex;
memset (pDevInfo, 0, sizeof(DEVICEINFO));
pDevInfo->dwPermanentDeviceID = pDevInfoOld->dwPermanentDeviceID;
pDevInfo->dwProviderID = pDevInfoOld->dwProviderID;
if (dwSizeDU > 0)
{
pDevInfo->dwDomainUserNamesSize = dwSizeDU * sizeof(TCHAR);
pDevInfo->dwDomainUserNamesOffset =
sizeof(DEVICEINFOLIST) + sizeof(DEVICEINFO);
pDest = ((LPBYTE)pDevList) + pDevInfo->dwDomainUserNamesOffset;
memcpy (
pDest,
pUserTuple->pDomainUserNames,
dwSizeDU * sizeof(TCHAR)
);
}
if (dwSizeFU)
{
pDevInfo->dwFriendlyUserNamesSize = dwSizeFU * sizeof(TCHAR);
pDevInfo->dwFriendlyUserNamesOffset =
pDevInfo->dwDomainUserNamesOffset + dwSizeDU * sizeof(TCHAR);
pDest = ((LPBYTE)pDevList) + pDevInfo->dwFriendlyUserNamesOffset;
memcpy (
pDest,
pUserTuple->pFriendlyUserNames,
dwSizeFU * sizeof(TCHAR)
);
}
hr = MMCSetLineInfo (
m_hMmc,
pDevList
);
ExitHere:
if (pDevList)
{
delete [] pDevList;
}
return hr;
}
HRESULT CMMCManagement::DisplayMMCData ()
{
HRESULT hr = S_OK;
LPDEVICEINFO pDeviceInfo;
DWORD * pdwIndex = NULL;
DWORD dwProviderId;
DWORD dwAddressCount,dw1,dw2;
LPLINEPROVIDERENTRY pProvider;
LPTSTR pUserName;
LPTSTR pAddress,
pAddressFirst,
pAddressLast;
UINT Codepage;
char achCodepage[12] = ".OCP";
if ( !m_pDeviceInfoList || !m_pDeviceInfoList->dwNumDeviceInfoEntries )
{
CIds IdsNoDevices (IDS_NODEVICES);
_tprintf ( IdsNoDevices.GetString () );
return hr;
}
//
// Build an index by provider ID
//
pdwIndex = new DWORD [ m_pDeviceInfoList->dwNumDeviceInfoEntries ];
if ( !pdwIndex )
{
hr = TSECERR_NOMEM;
return hr;
}
for ( dw1=0; dw1 < m_pDeviceInfoList->dwNumDeviceInfoEntries; dw1++ )
{
pdwIndex[ dw1 ] = dw1;
}
if (Codepage = GetConsoleOutputCP()) {
wsprintfA(achCodepage, ".%u", Codepage);
setlocale(LC_ALL, achCodepage);
}
else
{
setlocale (LC_COLLATE, achCodepage );
setlocale (LC_MONETARY, achCodepage );
setlocale (LC_NUMERIC, achCodepage );
setlocale (LC_TIME, achCodepage );
}
SetThreadUILanguage(0);
dw1 = 0;
while ( dw1 < m_pDeviceInfoList->dwNumDeviceInfoEntries )
{
pDeviceInfo = (LPDEVICEINFO)((LPBYTE)m_pDeviceInfoList +
m_pDeviceInfoList->dwDeviceInfoOffset) + pdwIndex[ dw1 ];
dwProviderId = pDeviceInfo->dwProviderID;
dw1++;
for ( dw2=dw1; dw2 < m_pDeviceInfoList->dwNumDeviceInfoEntries; dw2++ )
{
pDeviceInfo = (LPDEVICEINFO)((LPBYTE)m_pDeviceInfoList +
m_pDeviceInfoList->dwDeviceInfoOffset) + pdwIndex[ dw2 ];
if ( dwProviderId == pDeviceInfo->dwProviderID )
{
DWORD dwTemp = pdwIndex[ dw2 ];
pdwIndex[ dw2 ] = pdwIndex[ dw1 ];
pdwIndex[ dw1 ] = dwTemp;
dw1++;
}
}
}
//
// Display the device list
//
dw1 = 0;
while ( dw1 < m_pDeviceInfoList->dwNumDeviceInfoEntries )
{
pDeviceInfo = (LPDEVICEINFO)((LPBYTE)m_pDeviceInfoList +
m_pDeviceInfoList->dwDeviceInfoOffset) + pdwIndex[ dw1 ];
dwProviderId = pDeviceInfo->dwProviderID;
// find the provider entry
pProvider = (LPLINEPROVIDERENTRY) ((LPBYTE) m_pProviderList + m_pProviderList->dwProviderListOffset);
for( dw2=0; dw2 < m_pProviderList->dwNumProviders; dw2++, pProvider++ )
{
if ( dwProviderId == pProvider->dwPermanentProviderID )
{
break;
}
}
// display the provider name
if ( dw2 < m_pProviderList->dwNumProviders )
{
// provider entry found
_tprintf(
_T("\n%s\n"),
m_pProviderName[ dw2 ] ? m_pProviderName[ dw2 ] :
(LPTSTR)((LPBYTE) m_pProviderList + pProvider->dwProviderFilenameOffset)
);
}
else
{
CIds IdsProvider (IDS_PROVIDER);
_tprintf( IdsProvider.GetString(), dwProviderId );
}
// list devices / users for this provider
do
{
CIds IdsLine (IDS_LINE);
CIds IdsPermanentID (IDS_PID);
CIds IdsAddresses (IDS_ADDRESSES);
_tprintf( IdsLine.GetString(),
(LPTSTR)((LPBYTE)m_pDeviceInfoList + pDeviceInfo->dwDeviceNameOffset));
_tprintf( IdsPermanentID.GetString(), pDeviceInfo->dwPermanentDeviceID);
if ( pDeviceInfo->dwFriendlyUserNamesSize )
{
CIds IdsUsers (IDS_USERS);
_tprintf ( IdsUsers.GetString () );
pUserName = (LPTSTR) (((LPBYTE) m_pDeviceInfoList) +
pDeviceInfo->dwFriendlyUserNamesOffset);
while ( *pUserName != _T('\0') )
{
_tprintf( _T("\t\t\t%s\n"), pUserName );
pUserName += _tcslen (pUserName) + 1;
}
}
if ( pDeviceInfo->dwAddressesSize )
{
_tprintf( IdsAddresses.GetString() );
pAddress = (LPTSTR) (((LPBYTE) m_pDeviceInfoList) +
pDeviceInfo->dwAddressesOffset);
while ( *pAddress != _T('\0') )
{
_tprintf( _T("\t\t\t%s\n"), pAddress );
pAddress += _tcslen (pAddress) + 1;
}
}
dw1++;
pDeviceInfo++;
}
while ( dw1 < m_pDeviceInfoList->dwNumDeviceInfoEntries &&
pDeviceInfo->dwProviderID == dwProviderId );
}
return hr;
}