957 lines
20 KiB
C
957 lines
20 KiB
C
/*++
|
|
|
|
Copyright (C) 1992-98 Microsft Corporation. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
dlparams.c
|
|
|
|
Abstract:
|
|
|
|
Routines for storing and retrieving user Lsa secret
|
|
dial parameters.
|
|
|
|
Author:
|
|
|
|
Gurdeep Singh Pall (gurdeep) 06-Jun-1997
|
|
|
|
Revision History:
|
|
|
|
Miscellaneous Modifications - raos 31-Dec-1997
|
|
|
|
--*/
|
|
|
|
#define RASMXS_DYNAMIC_LINK
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <ntlsa.h>
|
|
#include <ntmsv1_0.h>
|
|
#include <llinfo.h>
|
|
#include <rasman.h>
|
|
#include <lm.h>
|
|
#include <lmwksta.h>
|
|
#include <wanpub.h>
|
|
#include <raserror.h>
|
|
// #include <rasarp.h>
|
|
#include <media.h>
|
|
#include <device.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ntlsa.h>
|
|
|
|
#define MAX_REGISTRY_VALUE_LENGTH ((64*1024) - 1)
|
|
|
|
#define cszEapKeyRas TEXT("Software\\Microsoft\\RAS EAP\\UserEapInfo")
|
|
|
|
#define cszEapKeyRouter TEXT("Software\\Microsoft\\Router EAP\\IfEapInfo")
|
|
|
|
#define cszEapValue TEXT("EapInfo")
|
|
|
|
#define EAP_SIG 0x31504145
|
|
#define EAP_SIG_2 0x32504145
|
|
|
|
typedef struct _EAP_USER_INFO
|
|
{
|
|
DWORD dwSignature;
|
|
DWORD dwEapTypeId;
|
|
GUID Guid;
|
|
DWORD dwSize;
|
|
BYTE abdata[1];
|
|
} EAP_USER_INFO, *PEAP_USER_INFO;
|
|
|
|
typedef struct _EAP_USER_INFO_0
|
|
{
|
|
DWORD dwUID;
|
|
DWORD dwSize;
|
|
BYTE abdata[1];
|
|
} EAP_USER_INFO_0, *PEAP_USER_INFO_0;
|
|
|
|
|
|
DWORD
|
|
DwGetSidFromHtoken(
|
|
HANDLE hToken,
|
|
PWCHAR pszSid,
|
|
USHORT cbSid
|
|
)
|
|
{
|
|
DWORD cbNeeded, dwErr;
|
|
BOOL fThreadTokenOpened = FALSE;
|
|
|
|
UNICODE_STRING unicodeString;
|
|
|
|
TOKEN_USER *pUserToken = NULL;
|
|
|
|
if( (NULL == hToken)
|
|
|| (INVALID_HANDLE_VALUE == hToken))
|
|
{
|
|
fThreadTokenOpened = TRUE;
|
|
|
|
if (!OpenThreadToken(
|
|
GetCurrentThread(),
|
|
TOKEN_QUERY,
|
|
TRUE,
|
|
&hToken))
|
|
{
|
|
dwErr = GetLastError();
|
|
if (dwErr == ERROR_NO_TOKEN)
|
|
{
|
|
//
|
|
// This means we are not impersonating
|
|
// anyone. Instead, get the token out
|
|
// of the process.
|
|
//
|
|
if (!OpenProcessToken(
|
|
GetCurrentProcess(),
|
|
TOKEN_QUERY,
|
|
&hToken))
|
|
{
|
|
return GetLastError();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return dwErr;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Call GetTokenInformation once to determine
|
|
// the number of bytes needed.
|
|
//
|
|
cbNeeded = 0;
|
|
|
|
GetTokenInformation(hToken,
|
|
TokenUser,
|
|
NULL, 0,
|
|
&cbNeeded);
|
|
if (!cbNeeded)
|
|
{
|
|
dwErr = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Allocate the memory and call it again.
|
|
//
|
|
pUserToken = LocalAlloc(LPTR, cbNeeded);
|
|
|
|
if (pUserToken == NULL)
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
if (!GetTokenInformation(
|
|
hToken,
|
|
TokenUser,
|
|
pUserToken,
|
|
cbNeeded,
|
|
&cbNeeded))
|
|
{
|
|
dwErr = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Format the SID as a Unicode string.
|
|
//
|
|
unicodeString.Length = 0;
|
|
|
|
unicodeString.MaximumLength = cbSid;
|
|
|
|
unicodeString.Buffer = pszSid;
|
|
|
|
dwErr = RtlConvertSidToUnicodeString(
|
|
&unicodeString,
|
|
pUserToken->User.Sid,
|
|
FALSE);
|
|
|
|
done:
|
|
if (pUserToken != NULL)
|
|
{
|
|
LocalFree(pUserToken);
|
|
}
|
|
|
|
if ( (NULL != hToken)
|
|
&& (INVALID_HANDLE_VALUE != hToken)
|
|
&& fThreadTokenOpened)
|
|
{
|
|
CloseHandle(hToken);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
DWORD
|
|
GetUserSid(
|
|
IN PWCHAR pszSid,
|
|
IN USHORT cbSid
|
|
)
|
|
{
|
|
return DwGetSidFromHtoken(NULL,
|
|
pszSid,
|
|
cbSid);
|
|
}
|
|
|
|
LONG
|
|
lrGetEapKeyFromToken(HANDLE hToken,
|
|
HKEY *phkey)
|
|
{
|
|
LONG lr = ERROR_SUCCESS;
|
|
|
|
WCHAR szSid[260];
|
|
|
|
HKEY hkeyUser = NULL;
|
|
|
|
HKEY hkeyEap = NULL;
|
|
|
|
DWORD dwDisposition;
|
|
|
|
ASSERT(NULL != phkey);
|
|
|
|
//
|
|
// Get sid of the user from the htoken
|
|
//
|
|
lr = (LONG) DwGetSidFromHtoken(hToken,
|
|
szSid,
|
|
sizeof(szSid));
|
|
|
|
if(ERROR_SUCCESS != lr)
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Open the users registry key
|
|
//
|
|
lr = RegOpenKeyExW(HKEY_USERS,
|
|
szSid,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hkeyUser);
|
|
|
|
if(ERROR_SUCCESS != lr)
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Create the eap key if required.
|
|
//
|
|
lr = RegCreateKeyEx(hkeyUser,
|
|
cszEapKeyRas,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hkeyEap,
|
|
&dwDisposition);
|
|
|
|
if(ERROR_SUCCESS != lr)
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
|
|
done:
|
|
|
|
if(NULL != hkeyUser)
|
|
{
|
|
RegCloseKey(hkeyUser);
|
|
}
|
|
|
|
*phkey = hkeyEap;
|
|
|
|
return lr;
|
|
|
|
}
|
|
|
|
DWORD
|
|
DwUpgradeEapInfo(PBYTE *ppbInfo,
|
|
DWORD *pdwSize)
|
|
{
|
|
BYTE *pbInfo;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
EAP_USER_INFO UNALIGNED *pEapInfo;
|
|
DWORD dwSize;
|
|
DWORD dwRequiredSize = 0;
|
|
BYTE *pbNewInfo = NULL;
|
|
EAP_USER_INFO *pNewEapInfo;
|
|
|
|
if( (NULL == ppbInfo)
|
|
|| (NULL == pdwSize))
|
|
{
|
|
dwErr = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
dwSize = *pdwSize;
|
|
pbInfo = *ppbInfo;
|
|
pEapInfo = (EAP_USER_INFO *) pbInfo;
|
|
|
|
while((BYTE *) pEapInfo < pbInfo + dwSize)
|
|
{
|
|
dwRequiredSize += RASMAN_ALIGN8(
|
|
sizeof(EAP_USER_INFO)
|
|
+ pEapInfo->dwSize);
|
|
|
|
((PBYTE) pEapInfo) += (sizeof(EAP_USER_INFO)
|
|
+ pEapInfo->dwSize);
|
|
}
|
|
|
|
pbNewInfo = LocalAlloc(LPTR, dwRequiredSize);
|
|
|
|
if(NULL == pbNewInfo)
|
|
{
|
|
dwErr = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
pEapInfo = (EAP_USER_INFO *) pbInfo;
|
|
pNewEapInfo = (EAP_USER_INFO *) pbNewInfo;
|
|
|
|
while((BYTE *) pEapInfo < pbInfo + dwSize)
|
|
{
|
|
CopyMemory(
|
|
(BYTE *) pNewEapInfo,
|
|
(BYTE *) pEapInfo,
|
|
sizeof(EAP_USER_INFO) + pEapInfo->dwSize);
|
|
|
|
pNewEapInfo->dwSignature = EAP_SIG_2;
|
|
|
|
(BYTE *) pNewEapInfo += RASMAN_ALIGN8(sizeof(EAP_USER_INFO)
|
|
+ pEapInfo->dwSize);
|
|
|
|
(BYTE *) pEapInfo += (sizeof(EAP_USER_INFO) + pEapInfo->dwSize);
|
|
}
|
|
|
|
*ppbInfo = pbNewInfo;
|
|
*pdwSize = dwRequiredSize;
|
|
|
|
if(NULL != pbInfo)
|
|
{
|
|
LocalFree(pbInfo);
|
|
}
|
|
|
|
done:
|
|
return dwErr;
|
|
}
|
|
|
|
DWORD
|
|
DwGetEapInfo(HANDLE hToken,
|
|
BOOL fRouter,
|
|
PBYTE *ppbInfo,
|
|
DWORD *pdwSize,
|
|
HKEY *phkey
|
|
)
|
|
{
|
|
LONG lr = ERROR_SUCCESS;
|
|
|
|
HKEY hkey = NULL;
|
|
|
|
DWORD dwDisposition;
|
|
|
|
DWORD dwInfoSize = 0;
|
|
|
|
DWORD dwType;
|
|
|
|
PBYTE pbInfo = NULL;
|
|
|
|
if( (NULL == ppbInfo)
|
|
|| (NULL == pdwSize))
|
|
{
|
|
lr = (LONG) E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
if( (NULL != hToken)
|
|
&& (INVALID_HANDLE_VALUE != hToken)
|
|
&& !fRouter)
|
|
{
|
|
//
|
|
// If a valid token is passed then its most likely
|
|
// a service trying to open users registry. Get the
|
|
// sid of the user and open HKU in this case.
|
|
//
|
|
if(ERROR_SUCCESS != (lr = lrGetEapKeyFromToken(hToken,
|
|
&hkey)))
|
|
{
|
|
goto done;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Open the key. Create the key if its not present
|
|
//
|
|
if(ERROR_SUCCESS != (lr = RegCreateKeyEx(
|
|
(fRouter)
|
|
? HKEY_LOCAL_MACHINE
|
|
: HKEY_CURRENT_USER,
|
|
(fRouter)
|
|
? cszEapKeyRouter
|
|
: cszEapKeyRas,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hkey,
|
|
&dwDisposition)))
|
|
{
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Get size of the binary value. If the value is not
|
|
// found, return no information. This value will be
|
|
// set the first time we store any eap information.
|
|
//
|
|
if( (ERROR_SUCCESS != (lr = RegQueryValueEx(
|
|
hkey,
|
|
cszEapValue,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&dwInfoSize)))
|
|
&& (ERROR_SUCCESS != lr))
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
#if DBG
|
|
ASSERT(REG_BINARY == dwType);
|
|
#endif
|
|
|
|
//
|
|
// Allocate a buffer to hold the binary value
|
|
//
|
|
pbInfo = LocalAlloc(LPTR, dwInfoSize);
|
|
if(NULL == pbInfo)
|
|
{
|
|
lr = (LONG) GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Get the binary value
|
|
//
|
|
if(ERROR_SUCCESS != (lr = RegQueryValueEx(
|
|
hkey,
|
|
cszEapValue,
|
|
NULL,
|
|
&dwType,
|
|
pbInfo,
|
|
&dwInfoSize)))
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
done:
|
|
|
|
if(NULL != phkey)
|
|
{
|
|
*phkey = hkey;
|
|
}
|
|
else if (NULL != hkey)
|
|
{
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
if(NULL != ppbInfo)
|
|
{
|
|
*ppbInfo = pbInfo;
|
|
}
|
|
else if(NULL != pbInfo)
|
|
{
|
|
LocalFree(pbInfo);
|
|
}
|
|
|
|
if(NULL != pdwSize)
|
|
{
|
|
*pdwSize = dwInfoSize;
|
|
}
|
|
|
|
if(ERROR_FILE_NOT_FOUND == lr)
|
|
{
|
|
lr = ERROR_SUCCESS;
|
|
}
|
|
|
|
return (DWORD) lr;
|
|
}
|
|
|
|
DWORD
|
|
DwSetEapInfo(HKEY hkey,
|
|
PBYTE pbInfo,
|
|
DWORD dwSize)
|
|
{
|
|
LONG lr = ERROR_SUCCESS;
|
|
|
|
if(ERROR_SUCCESS != (lr = RegSetValueEx(
|
|
hkey,
|
|
cszEapValue,
|
|
0,
|
|
REG_BINARY,
|
|
pbInfo,
|
|
dwSize)))
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
done:
|
|
return (DWORD) lr;
|
|
}
|
|
|
|
DWORD
|
|
DwRemoveEapUserInfo(GUID *pGuid,
|
|
PBYTE pbInfo,
|
|
PDWORD pdwSize,
|
|
HKEY hkey,
|
|
BOOL fWrite,
|
|
DWORD dwEapTypeId)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
DWORD dwcb = 0;
|
|
|
|
EAP_USER_INFO *pEapInfo = (EAP_USER_INFO *) pbInfo;
|
|
|
|
DWORD dwNewSize;
|
|
|
|
DWORD dwSize = *pdwSize;
|
|
|
|
//
|
|
// Find the binary blob with the
|
|
// UID
|
|
//
|
|
while(dwcb < dwSize)
|
|
{
|
|
if( (0 == memcmp(
|
|
(PBYTE) pGuid,
|
|
(PBYTE) &pEapInfo->Guid,
|
|
sizeof(GUID)))
|
|
&& (dwEapTypeId == pEapInfo->dwEapTypeId))
|
|
{
|
|
break;
|
|
}
|
|
|
|
dwcb += RASMAN_ALIGN8((sizeof(EAP_USER_INFO) + pEapInfo->dwSize));
|
|
|
|
pEapInfo = (EAP_USER_INFO *) (pbInfo + dwcb);
|
|
}
|
|
|
|
if(dwcb >= dwSize)
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
#if DBG
|
|
ASSERT(dwSize >= dwcb
|
|
+ RASMAN_ALIGN8(pEapInfo->dwSize
|
|
+ sizeof(EAP_USER_INFO)));
|
|
#endif
|
|
|
|
dwNewSize = dwSize -
|
|
RASMAN_ALIGN8(pEapInfo->dwSize + sizeof(EAP_USER_INFO));
|
|
|
|
//
|
|
// Remove the info
|
|
//
|
|
MoveMemory(
|
|
pbInfo + dwcb,
|
|
pbInfo + dwcb
|
|
+ RASMAN_ALIGN8(sizeof(EAP_USER_INFO) + pEapInfo->dwSize),
|
|
dwSize - dwcb
|
|
- RASMAN_ALIGN8(sizeof(EAP_USER_INFO) + pEapInfo->dwSize));
|
|
|
|
if(fWrite)
|
|
{
|
|
|
|
dwErr = DwSetEapInfo(
|
|
hkey,
|
|
pbInfo,
|
|
dwNewSize);
|
|
}
|
|
else
|
|
{
|
|
*pdwSize = dwNewSize;
|
|
}
|
|
|
|
done:
|
|
return dwErr;
|
|
|
|
}
|
|
|
|
DWORD
|
|
DwReplaceEapUserInfo(GUID *pGuid,
|
|
PBYTE pbUserInfo,
|
|
DWORD dwUserInfo,
|
|
PBYTE pbInfo,
|
|
DWORD dwSize,
|
|
HKEY hkey,
|
|
DWORD dwEapTypeId)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
DWORD dwNewSize = dwSize;
|
|
|
|
PBYTE pbNewInfo = NULL;
|
|
|
|
EAP_USER_INFO UNALIGNED *pEapInfo;
|
|
|
|
if(NULL == pGuid)
|
|
{
|
|
ASSERT(FALSE);
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Remove the existing eap information corresponding
|
|
// to dwUID if any.
|
|
//
|
|
if(ERROR_SUCCESS != (dwErr = DwRemoveEapUserInfo(
|
|
pGuid,
|
|
pbInfo,
|
|
&dwNewSize,
|
|
hkey,
|
|
FALSE,
|
|
dwEapTypeId)))
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Local Alloc a new blob with enough space for the
|
|
// eap information of the new entry
|
|
//
|
|
pbNewInfo = LocalAlloc(LPTR,
|
|
dwNewSize
|
|
+ RASMAN_ALIGN8(sizeof(EAP_USER_INFO)
|
|
+ dwUserInfo));
|
|
|
|
if(NULL == pbNewInfo)
|
|
{
|
|
dwErr = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
RtlCopyMemory(
|
|
pbNewInfo,
|
|
pbInfo,
|
|
dwNewSize);
|
|
|
|
pEapInfo = (EAP_USER_INFO *) (pbNewInfo + dwNewSize);
|
|
pEapInfo->Guid = *pGuid;
|
|
pEapInfo->dwEapTypeId = dwEapTypeId;
|
|
pEapInfo->dwSize = dwUserInfo;
|
|
pEapInfo->dwSignature = EAP_SIG_2;
|
|
|
|
dwNewSize += RASMAN_ALIGN8((sizeof(EAP_USER_INFO) + dwUserInfo));
|
|
|
|
RtlCopyMemory(
|
|
pEapInfo->abdata,
|
|
pbUserInfo,
|
|
dwUserInfo);
|
|
|
|
dwErr = DwSetEapInfo(
|
|
hkey,
|
|
pbNewInfo,
|
|
dwNewSize);
|
|
|
|
done:
|
|
|
|
if(NULL != pbNewInfo)
|
|
{
|
|
LocalFree(pbNewInfo);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
DWORD
|
|
DwSetEapUserInfo(HANDLE hToken,
|
|
GUID *pGuid,
|
|
PBYTE pbUserInfo,
|
|
DWORD dwInfoSize,
|
|
BOOL fClear,
|
|
BOOL fRouter,
|
|
DWORD dwEapTypeId)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
PBYTE pbInfo = NULL;
|
|
|
|
DWORD dwSize = 0;
|
|
|
|
HKEY hkey = NULL;
|
|
|
|
if(NULL == pGuid)
|
|
{
|
|
ASSERT(FALSE);
|
|
goto done;
|
|
}
|
|
|
|
if(ERROR_SUCCESS != (dwErr = DwGetEapInfo(
|
|
hToken,
|
|
fRouter,
|
|
&pbInfo,
|
|
&dwSize,
|
|
&hkey)))
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
#if DBG
|
|
ASSERT(NULL != hkey);
|
|
#endif
|
|
|
|
//
|
|
// Check to see if the blob is one we recognize
|
|
//
|
|
if( !fClear
|
|
&& ( (sizeof(DWORD) > dwSize)
|
|
|| (((*((DWORD *) pbInfo)) != EAP_SIG))
|
|
&& ( (*((DWORD *) pbInfo)) != EAP_SIG_2)))
|
|
{
|
|
EAP_USER_INFO *pEapInfo;
|
|
|
|
//
|
|
// Upgrade?? How? We will just blow away all the old data.
|
|
//
|
|
pEapInfo = (EAP_USER_INFO *) LocalAlloc(LPTR,
|
|
RASMAN_ALIGN8(
|
|
sizeof(EAP_USER_INFO)
|
|
+ dwInfoSize));
|
|
|
|
if(NULL == pEapInfo)
|
|
{
|
|
dwErr = GetLastError();
|
|
goto done;
|
|
}
|
|
|
|
pEapInfo->Guid = *pGuid;
|
|
pEapInfo->dwEapTypeId = dwEapTypeId;
|
|
pEapInfo->dwSize = dwInfoSize;
|
|
pEapInfo->dwSignature = EAP_SIG_2;
|
|
|
|
RtlCopyMemory(
|
|
pEapInfo->abdata,
|
|
pbUserInfo,
|
|
dwInfoSize);
|
|
|
|
dwErr = DwSetEapInfo(hkey,
|
|
(PBYTE) pEapInfo,
|
|
RASMAN_ALIGN8(sizeof(EAP_USER_INFO)
|
|
+ dwInfoSize));
|
|
|
|
goto done;
|
|
}
|
|
else if ( (fClear)
|
|
&& ( (sizeof(DWORD) > dwSize)
|
|
|| (((*((DWORD *) pbInfo)) != EAP_SIG))
|
|
&& ( (*((DWORD *) pbInfo)) != EAP_SIG_2)))
|
|
{
|
|
//
|
|
// Blow away the old information
|
|
//
|
|
dwErr = RegDeleteValue(
|
|
hkey,
|
|
cszEapValue);
|
|
|
|
goto done;
|
|
}
|
|
|
|
if(*((DWORD *) pbInfo) == EAP_SIG)
|
|
{
|
|
//
|
|
// upgrade the blob so that its aligned
|
|
// at 8-byte boundaries
|
|
//
|
|
dwErr = DwUpgradeEapInfo(&pbInfo, &dwSize);
|
|
|
|
if(ERROR_SUCCESS != dwErr)
|
|
{
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
if(fClear)
|
|
{
|
|
dwErr = DwRemoveEapUserInfo(pGuid,
|
|
pbInfo,
|
|
&dwSize,
|
|
hkey,
|
|
TRUE,
|
|
dwEapTypeId);
|
|
}
|
|
else
|
|
{
|
|
dwErr = DwReplaceEapUserInfo(
|
|
pGuid,
|
|
pbUserInfo,
|
|
dwInfoSize,
|
|
pbInfo,
|
|
dwSize,
|
|
hkey,
|
|
dwEapTypeId);
|
|
}
|
|
|
|
done:
|
|
|
|
if(NULL != hkey)
|
|
{
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
|
|
if(NULL != pbInfo)
|
|
{
|
|
LocalFree(pbInfo);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
DWORD
|
|
DwGetEapUserInfo(HANDLE hToken,
|
|
PBYTE pbEapInfo,
|
|
DWORD *pdwInfoSize,
|
|
GUID *pGuid,
|
|
BOOL fRouter,
|
|
DWORD dwEapTypeId)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
PBYTE pbInfo = NULL;
|
|
|
|
DWORD dwSize;
|
|
|
|
DWORD dwcb = 0;
|
|
|
|
EAP_USER_INFO UNALIGNED *pEapUserInfo = NULL;
|
|
|
|
HKEY hkey = NULL;
|
|
|
|
if(NULL == pdwInfoSize)
|
|
{
|
|
dwErr = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
// *pdwInfoSize = 0;
|
|
|
|
if(NULL == pGuid)
|
|
{
|
|
ASSERT(FALSE);
|
|
*pdwInfoSize = 0;
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Get the binary blob from the registry
|
|
//
|
|
dwErr = DwGetEapInfo(hToken,
|
|
fRouter,
|
|
&pbInfo,
|
|
&dwSize,
|
|
&hkey);
|
|
|
|
if( (ERROR_SUCCESS != dwErr)
|
|
|| (0 == dwSize))
|
|
{
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Check to see if the blob is one we recognize
|
|
//
|
|
if( (sizeof(DWORD) > dwSize)
|
|
|| (((*((DWORD *) pbInfo)) != EAP_SIG)
|
|
&& ( (*((DWORD *) pbInfo)) != EAP_SIG_2)))
|
|
{
|
|
//
|
|
// Upgrade?? How? We will just blow away all the old data.
|
|
//
|
|
RegDeleteValue(hkey, cszEapValue);
|
|
|
|
*pdwInfoSize = 0;
|
|
goto done;
|
|
}
|
|
|
|
if(*((DWORD *) pbInfo) == EAP_SIG)
|
|
{
|
|
//
|
|
// Upgrade the blob so that its
|
|
// aligned correctly.
|
|
//
|
|
dwErr = DwUpgradeEapInfo(&pbInfo, &dwSize);
|
|
if(ERROR_SUCCESS != dwErr)
|
|
{
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Loop through the binary blob and look for the
|
|
// eap info corresponding to the UID passed in.
|
|
//
|
|
pEapUserInfo = (EAP_USER_INFO *) pbInfo;
|
|
|
|
while(dwcb < dwSize)
|
|
{
|
|
if( (0 == memcmp(
|
|
(PBYTE) pGuid,
|
|
(PBYTE) &pEapUserInfo->Guid,
|
|
sizeof(GUID)))
|
|
&& (dwEapTypeId == pEapUserInfo->dwEapTypeId))
|
|
{
|
|
break;
|
|
}
|
|
|
|
dwcb += RASMAN_ALIGN8((sizeof(EAP_USER_INFO)
|
|
+ pEapUserInfo->dwSize));
|
|
|
|
pEapUserInfo = (EAP_USER_INFO *) (pbInfo + dwcb);
|
|
}
|
|
|
|
if(dwcb >= dwSize)
|
|
{
|
|
*pdwInfoSize = 0;
|
|
goto done;
|
|
}
|
|
|
|
if( (NULL != pbEapInfo)
|
|
&& (*pdwInfoSize >= pEapUserInfo->dwSize))
|
|
{
|
|
RtlCopyMemory(pbEapInfo,
|
|
pEapUserInfo->abdata,
|
|
pEapUserInfo->dwSize);
|
|
}
|
|
else
|
|
{
|
|
dwErr = ERROR_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
*pdwInfoSize = pEapUserInfo->dwSize;
|
|
|
|
done:
|
|
|
|
if(NULL != pbInfo)
|
|
{
|
|
LocalFree(pbInfo);
|
|
}
|
|
|
|
if(NULL != hkey)
|
|
{
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|