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.
 
 
 
 
 
 

588 lines
14 KiB

/* Copyright (c) 1992, Microsoft Corporation, all rights reserved
**
** util.c
** Remote Access External APIs
** Utility routines
**
** 10/12/92 Steve Cobb
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <debug.h> // Trace and assert
#include <rasman.h>
#include <rasapip.h>
#include <pbk.h>
#define EAP_CUSTOM_KEY 0x43424431
typedef struct _EAP_CUSTOM_DATA
{
DWORD dwSignature;
DWORD dwCustomAuthKey;
DWORD dwSize;
BYTE abdata[1];
} EAP_CUSTOM_DATA;
BOOL IsRouterPhonebook(LPCTSTR pszPhonebook)
{
const TCHAR *psz;
BOOL fRouter = FALSE;
if(NULL == pszPhonebook)
{
goto done;
}
psz = pszPhonebook + lstrlen(pszPhonebook);
//
// Seek back to the beginning of the filename
//
while(psz != pszPhonebook)
{
if(TEXT('\\') == *psz)
{
break;
}
psz--;
}
if(TEXT('\\') == *psz)
{
psz += 1;
}
TRACE1("IsRouterPhonebook: pbk=%ws", psz);
//For whistler 524726
fRouter = ( CSTR_EQUAL == CompareString(
LOCALE_INVARIANT,
NORM_IGNORECASE,
TEXT("router.pbk"),
-1,
psz,
-1
)
);
done:
return fRouter;
}
BOOL
DwIsDefaultConnection(
IN PWCHAR pszEntryName)
{
DWORD dwErr = NO_ERROR, dwCb = 0, dwCount = 1;
RASAUTODIALENTRYW adEntry;
INT iCmp;
// Validate parameters
//
if (!pszEntryName)
{
return FALSE;
}
// Initialze
//
ZeroMemory(&adEntry, sizeof(adEntry));
dwCb = adEntry.dwSize = sizeof(adEntry);
dwErr = RasGetAutodialAddressW(
NULL,
NULL,
&adEntry,
&dwCb,
&dwCount);
if (dwErr != NO_ERROR)
{
return FALSE;
}
iCmp = _wcsnicmp(
adEntry.szEntry,
pszEntryName,
sizeof(adEntry.szEntry) / sizeof(WCHAR));
return (0 == iCmp);
}
DWORD
DwPbentryToDetails(
IN PBENTRY* pEntry,
IN LPCWSTR pszPhonebookPath,
IN BOOL fIsAllUsersPbk,
OUT RASENUMENTRYDETAILS* pDetails)
{
DWORD dwErr = NO_ERROR;
DTLNODE *pdtlnode;
PBLINK *pLink;
pDetails->dwSize = sizeof(RASENUMENTRYDETAILS);
pDetails->dwType = pEntry->dwType;
pDetails->fShowMonitorIconInTaskBar =
pEntry->fShowMonitorIconInTaskBar;
if(pEntry->pGuid)
{
pDetails->guidId = *pEntry->pGuid;
}
//For .Net 587396
lstrcpynW(pDetails->szEntryName,
pEntry->pszEntryName,
RASAPIP_MAX_ENTRY_NAME+1);
pDetails->dwFlags = (fIsAllUsersPbk) ? REN_AllUsers : REN_User;
if(pszPhonebookPath)
{
lstrcpynW(pDetails->szPhonebookPath,
pszPhonebookPath,
MAX_PATH + 1);
}
else
{
pDetails->szPhonebookPath[0] = L'\0';
}
//
// Get the devicename associated with the first
// link in the list of entries associated with
// this entry
//
pDetails->szDeviceName[0] = TEXT('\0');
pDetails->szPhoneNumber[0] = TEXT('\0');
pdtlnode = (DTLNODE *)
DtlGetFirstNode(pEntry->pdtllistLinks);
if(pdtlnode)
{
pLink = (PBLINK *) DtlGetData(pdtlnode);
if( (NULL != pLink)
&& (pLink->pbport.pszDevice))
{
pDetails->rdt = RdtFromPbdt(
pLink->pbport.pbdevicetype,
pLink->pbport.dwFlags);
if(RAS_DEVICE_CLASS(pDetails->rdt) == RDT_Tunnel)
{
(void) DwGetVpnDeviceName(
pEntry->dwVpnStrategy,
pLink->pbport.pszDevice,
pDetails->szDeviceName);
}
else
{
lstrcpy(pDetails->szDeviceName,
pLink->pbport.pszDevice);
}
}
// XP 351412
//
// Populate the phone number as well
//
if( (NULL != pLink)
&& (pLink->pdtllistPhones))
{
DTLNODE* pnodeNum = DtlGetFirstNode(pLink->pdtllistPhones);
PBPHONE* pPhone = NULL;
if (NULL != pnodeNum)
{
pPhone = DtlGetData(pnodeNum);
if ((NULL != pPhone) && (NULL != pPhone->pszPhoneNumber))
{
lstrcpyn(
pDetails->szPhoneNumber,
pPhone->pszPhoneNumber,
RAS_MaxPhoneNumber);
}
}
}
}
// Mark whether this is the default connection
// XP 286752
//
if (DwIsDefaultConnection(pEntry->pszEntryName))
{
pDetails->dwFlagsPriv |= REED_F_Default;
}
return dwErr;
}
DWORD
DwSendRasNotification(
IN RASEVENTTYPE Type,
IN PBENTRY* pEntry,
IN LPCTSTR pszPhonebookPath,
IN HANDLE hData) // Extra Type-specific info
{
RASEVENT RasEvent;
DWORD dwErr = ERROR_SUCCESS;
ZeroMemory((PBYTE) &RasEvent, sizeof(RASEVENT));
RasEvent.Type = Type;
//
// Ignore the notification if this is a router interface
//
if(IsRouterPhonebook(pszPhonebookPath))
{
goto done;
}
switch(Type)
{
case ENTRY_ADDED:
case ENTRY_MODIFIED:
case ENTRY_AUTODIAL:
{
BOOL fAllUsers = TRUE;
if (NULL != pszPhonebookPath)
{
fAllUsers = IsPublicPhonebook(pszPhonebookPath);
}
DwPbentryToDetails(
pEntry,
pszPhonebookPath,
fAllUsers,
&(RasEvent.Details)
);
break;
}
case ENTRY_DELETED:
case ENTRY_RENAMED:
{
if(NULL != pEntry->pGuid)
{
RasEvent.guidId = *pEntry->pGuid;
}
if(ENTRY_RENAMED == Type)
{
lstrcpy(RasEvent.pszwNewName,
pEntry->pszEntryName);
}
break;
}
default:
{
#if DBG
ASSERT(FALSE);
#endif
goto done;
}
}
dwErr = RasSendNotification(&RasEvent);
done:
return dwErr;
}
DWORD
DwGetCustomAuthData(PBENTRY *pEntry,
DWORD *pcbCustomAuthData,
PBYTE *ppCustomAuthData)
{
DWORD retcode = SUCCESS;
DWORD cbOffset = 0;
EAP_CUSTOM_DATA *pCustomData = NULL;
ASSERT(NULL != pcbCustomAuthData);
ASSERT(NULL != ppCustomAuthData);
ASSERT(NULL != pEntry);
*pcbCustomAuthData = 0;
*ppCustomAuthData = NULL;
//
// first check to see if we understand the format of the
// eap blob stored in the phonebook
//
if(NULL == pEntry->pCustomAuthData)
{
goto done;
}
if( (sizeof(DWORD) > pEntry->cbCustomAuthData)
|| ((*((DWORD *) pEntry->pCustomAuthData)) != EAP_CUSTOM_KEY))
{
Free(pEntry->pCustomAuthData);
pEntry->pCustomAuthData = NULL;
pEntry->cbCustomAuthData = 0;
goto done;
}
//
// Loop through the blob and return the blob corresponding
// to the eap type of the entry
//
while(cbOffset < pEntry->cbCustomAuthData)
{
pCustomData = (EAP_CUSTOM_DATA *)
((PBYTE) pEntry->pCustomAuthData + cbOffset);
if( (sizeof(DWORD) > (pEntry->cbCustomAuthData - cbOffset))
|| ((*((DWORD *) pEntry->pCustomAuthData)) != EAP_CUSTOM_KEY))
{
//
// The data is corrupt. Blow away the data.
// should we return an error?
//
Free(pEntry->pCustomAuthData);
pEntry->pCustomAuthData = NULL;
pEntry->cbCustomAuthData = 0;
TRACE("GetCustomAuthdata: data is corrupt");
goto done;
}
if(pCustomData->dwCustomAuthKey == pEntry->dwCustomAuthKey)
{
break;
}
cbOffset += sizeof(EAP_CUSTOM_DATA) + pCustomData->dwSize;
}
if(cbOffset < pEntry->cbCustomAuthData)
{
*pcbCustomAuthData = pCustomData->dwSize;
*ppCustomAuthData = pCustomData->abdata;
}
done:
return retcode;
}
DWORD
DwSetCustomAuthData(PBENTRY *pEntry,
DWORD cbCustomAuthData,
PBYTE pCustomAuthData)
{
DWORD retcode = SUCCESS;
DWORD cbOffset = 0;
EAP_CUSTOM_DATA *pCustomData = NULL;
DWORD dwSize;
PBYTE pNewCustomAuthData;
ASSERT(NULL != pEntry);
if(NULL != pEntry->pCustomAuthData)
{
if( (sizeof(DWORD) > pEntry->cbCustomAuthData)
|| ((*((DWORD *) pEntry->pCustomAuthData)) != EAP_CUSTOM_KEY))
{
Free(pEntry->pCustomAuthData);
pEntry->pCustomAuthData = NULL;
pEntry->cbCustomAuthData = 0;
}
}
//
// Find the old Eap Data
//
while(cbOffset < pEntry->cbCustomAuthData)
{
pCustomData = (EAP_CUSTOM_DATA *)
((PBYTE)pEntry->pCustomAuthData + cbOffset);
if( (sizeof(DWORD) > (pEntry->cbCustomAuthData - cbOffset))
|| ((*((DWORD *) pEntry->pCustomAuthData)) != EAP_CUSTOM_KEY))
{
//
// The data is corrupt. Blow away the data.
// should we return an error?
//
Free(pEntry->pCustomAuthData);
pEntry->pCustomAuthData = NULL;
pEntry->cbCustomAuthData = 0;
TRACE("SetCustomAuthData: data is corrupt!");
break;
}
if(pCustomData->dwCustomAuthKey == pEntry->dwCustomAuthKey)
{
break;
}
cbOffset += (sizeof(EAP_CUSTOM_DATA) + pCustomData->dwSize);
}
//
// Prefast warning
//
if( (NULL != pCustomData)
&& (cbOffset < pEntry->cbCustomAuthData))
{
dwSize = sizeof(EAP_CUSTOM_DATA) + pCustomData->dwSize;
ASSERT(pEntry->cbCustomAuthData >= (cbOffset + dwSize));
MoveMemory(pEntry->pCustomAuthData + cbOffset,
pEntry->pCustomAuthData
+ cbOffset + dwSize,
pEntry->cbCustomAuthData - cbOffset - dwSize);
pEntry->cbCustomAuthData -= dwSize;
}
if(0 == pEntry->cbCustomAuthData)
{
Free0(pEntry->pCustomAuthData);
pEntry->pCustomAuthData = NULL;
}
if( (0 == cbCustomAuthData)
|| (NULL == pCustomAuthData))
{
goto done;
}
dwSize = cbCustomAuthData
+ pEntry->cbCustomAuthData
+ sizeof(EAP_CUSTOM_DATA);
pNewCustomAuthData = Malloc(dwSize);
if(NULL == pNewCustomAuthData)
{
retcode = E_OUTOFMEMORY;
goto done;
}
ZeroMemory(pNewCustomAuthData, dwSize);
CopyMemory(pNewCustomAuthData,
pEntry->pCustomAuthData,
pEntry->cbCustomAuthData);
pCustomData = (EAP_CUSTOM_DATA *) (pNewCustomAuthData
+ pEntry->cbCustomAuthData);
pCustomData->dwSignature = EAP_CUSTOM_KEY;
pCustomData->dwCustomAuthKey = pEntry->dwCustomAuthKey;
pCustomData->dwSize = cbCustomAuthData;
CopyMemory(pCustomData->abdata,
pCustomAuthData,
cbCustomAuthData);
pEntry->cbCustomAuthData = dwSize;
if(NULL != pEntry->pCustomAuthData)
{
Free(pEntry->pCustomAuthData);
}
pEntry->pCustomAuthData = pNewCustomAuthData;
done:
return retcode;
}
DWORD
DwGetVpnDeviceName(
DWORD dwVpnStrategy,
WCHAR *pszDeviceDefault,
WCHAR *pszDeviceName)
{
DWORD dwErr = ERROR_SUCCESS, dwType;
CHAR szDeviceName[MAX_DEVICE_NAME];
// Figure out the device name we're interested in
// discovering.
//
dwType = RDT_Tunnel_L2tp;
switch (dwVpnStrategy)
{
case VS_Default:
case VS_L2tpFirst:
case VS_L2tpOnly:
dwType = RDT_Tunnel_L2tp;
break;
case VS_PptpFirst:
case VS_PptpOnly:
dwType = RDT_Tunnel_Pptp;
break;
}
TRACE1("RasGetDeviceName(rdt=%d)...", dwType);
dwErr = RasGetDeviceNameW(
dwType,
pszDeviceName);
TRACE1("RasGetDeviceName. 0x%x", dwErr);
if(ERROR_SUCCESS != dwErr)
{
dwErr = ERROR_SUCCESS;
// We can't determine from rasman -- use the phonebook
// value if possible
//
if (NULL != pszDeviceDefault)
{
lstrcpyn(
pszDeviceName,
pszDeviceDefault,
RASAPIP_MAX_DEVICE_NAME);
}
}
return dwErr;
}
BOOL
IsServerOS ( )
{
BOOL fServerOS = TRUE; //Default
//Check to see if the OS is server - Data Center, Server, Advanced Server
OSVERSIONINFOEX stOsvEx;
ZeroMemory( &stOsvEx, sizeof(stOsvEx) );
stOsvEx.dwOSVersionInfoSize = sizeof(stOsvEx);
GetVersionEx((LPOSVERSIONINFO)&stOsvEx);
if ( stOsvEx.wProductType == VER_NT_WORKSTATION )
fServerOS = FALSE;
return fServerOS;
}