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.
836 lines
19 KiB
836 lines
19 KiB
/********************************************************************/
|
|
/** Copyright(c) 1995 Microsoft Corporation. **/
|
|
/********************************************************************/
|
|
|
|
//***
|
|
//
|
|
// Filename: creds.c
|
|
//
|
|
// Description: Routines for storing and retrieving user Lsa secret
|
|
// dial parameters.
|
|
//
|
|
//
|
|
// History: 11/02/95 Anthony Discolo created
|
|
// May 11,1995 NarenG modified for router.
|
|
//
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <ntlsa.h>
|
|
#include <ntmsv1_0.h>
|
|
#include <llinfo.h>
|
|
#include <rasman.h>
|
|
#include <raserror.h>
|
|
#include <mprerror.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define MPR_CREDENTIALS_KEY TEXT("MprCredentials%d")
|
|
|
|
#define MAX_REGISTRY_VALUE_LENGTH ((64*1024) - 1)
|
|
|
|
typedef struct _MPRPARAMSENTRY
|
|
{
|
|
LIST_ENTRY ListEntry;
|
|
WCHAR szPhoneBookEntryName[MAX_INTERFACE_NAME_LEN + 1];
|
|
WCHAR szUserName[UNLEN + 1];
|
|
WCHAR szPassword[PWLEN + 1];
|
|
WCHAR szDomain[DNLEN + 1];
|
|
|
|
} MPRPARAMSENTRY, *PMPRPARAMSENTRY;
|
|
|
|
//**
|
|
//
|
|
// Call: ReadDialParamsBlob
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD
|
|
ReadDialParamsBlob(
|
|
IN LPWSTR lpwsServer,
|
|
OUT PVOID *ppvData,
|
|
OUT LPDWORD lpdwSize
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
DWORD dwRetCode = NO_ERROR;
|
|
DWORD dwIndex;
|
|
DWORD dwSize = 0;
|
|
PVOID pvData = NULL;
|
|
PVOID pvNewData = NULL;
|
|
UNICODE_STRING unicodeKey;
|
|
UNICODE_STRING unicodeServer;
|
|
PUNICODE_STRING punicodeValue = NULL;
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
LSA_HANDLE hPolicy;
|
|
WCHAR wchKey[sizeof(MPR_CREDENTIALS_KEY) + 10 ];
|
|
|
|
//
|
|
// Initialize return value.
|
|
//
|
|
|
|
*ppvData = NULL;
|
|
*lpdwSize = 0;
|
|
|
|
//
|
|
// Open the LSA secret space for reading.
|
|
//
|
|
|
|
InitializeObjectAttributes( &objectAttributes, NULL, 0L, NULL, NULL );
|
|
|
|
RtlInitUnicodeString( &unicodeServer, lpwsServer );
|
|
|
|
status = LsaOpenPolicy( &unicodeServer,
|
|
&objectAttributes,
|
|
POLICY_READ,
|
|
&hPolicy );
|
|
|
|
if ( status != STATUS_SUCCESS )
|
|
{
|
|
return( LsaNtStatusToWinError( status ) );
|
|
}
|
|
|
|
for( dwIndex = 0; TRUE; dwIndex++ )
|
|
{
|
|
//
|
|
// Format the key string.
|
|
//
|
|
|
|
wsprintf( wchKey, MPR_CREDENTIALS_KEY, dwIndex );
|
|
|
|
RtlInitUnicodeString( &unicodeKey, wchKey );
|
|
|
|
//
|
|
// Get the value.
|
|
//
|
|
|
|
status = LsaRetrievePrivateData( hPolicy, &unicodeKey, &punicodeValue );
|
|
|
|
if ( status != STATUS_SUCCESS )
|
|
{
|
|
dwRetCode = LsaNtStatusToWinError( status );
|
|
|
|
if ( dwRetCode == ERROR_FILE_NOT_FOUND )
|
|
{
|
|
dwRetCode = NO_ERROR;
|
|
}
|
|
|
|
break;
|
|
}
|
|
if ( punicodeValue == NULL )
|
|
{
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Concatenate the strings.
|
|
//
|
|
|
|
pvNewData = LocalAlloc( LPTR, dwSize + punicodeValue->Length );
|
|
|
|
if ( pvNewData == NULL )
|
|
{
|
|
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
if ( pvData != NULL )
|
|
{
|
|
RtlCopyMemory( pvNewData, pvData, dwSize );
|
|
ZeroMemory( pvData, dwSize );
|
|
LocalFree( pvData );
|
|
pvData = NULL;
|
|
}
|
|
|
|
RtlCopyMemory( (PBYTE)pvNewData + dwSize,
|
|
punicodeValue->Buffer,
|
|
punicodeValue->Length );
|
|
|
|
pvData = pvNewData;
|
|
dwSize += punicodeValue->Length;
|
|
SecureZeroMemory(punicodeValue->Buffer, punicodeValue->Length);
|
|
LsaFreeMemory( punicodeValue );
|
|
punicodeValue = NULL;
|
|
}
|
|
|
|
LsaClose( hPolicy );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
if ( pvData != NULL )
|
|
{
|
|
ZeroMemory( pvData, dwSize );
|
|
LocalFree( pvData );
|
|
}
|
|
|
|
pvData = NULL;
|
|
dwSize = 0;
|
|
}
|
|
|
|
if ( punicodeValue != NULL )
|
|
{
|
|
LsaFreeMemory( punicodeValue );
|
|
}
|
|
|
|
*ppvData = pvData;
|
|
*lpdwSize = dwSize;
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: WriteDialParamsBlob
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD
|
|
WriteDialParamsBlob(
|
|
IN LPWSTR lpwsServer,
|
|
IN PVOID pvData,
|
|
IN DWORD dwcbData
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
DWORD dwIndex = 0;
|
|
DWORD dwRetCode = NO_ERROR;
|
|
DWORD dwcb = 0;
|
|
UNICODE_STRING unicodeKey, unicodeValue;
|
|
UNICODE_STRING unicodeServer;
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
LSA_HANDLE hPolicy;
|
|
WCHAR wchKey[sizeof(MPR_CREDENTIALS_KEY) + 10 ];
|
|
|
|
//
|
|
// Open the LSA secret space for writing.
|
|
//
|
|
|
|
InitializeObjectAttributes( &objectAttributes, NULL, 0L, NULL, NULL );
|
|
|
|
RtlInitUnicodeString( &unicodeServer, lpwsServer );
|
|
|
|
status = LsaOpenPolicy( &unicodeServer,
|
|
&objectAttributes,
|
|
POLICY_WRITE,
|
|
&hPolicy);
|
|
|
|
if (status != STATUS_SUCCESS)
|
|
{
|
|
return LsaNtStatusToWinError(status);
|
|
}
|
|
|
|
while( dwcbData )
|
|
{
|
|
//
|
|
// Format the key string.
|
|
//
|
|
|
|
wsprintf( wchKey, MPR_CREDENTIALS_KEY, dwIndex++ );
|
|
|
|
RtlInitUnicodeString( &unicodeKey, wchKey );
|
|
|
|
//
|
|
// Write some of the key.
|
|
//
|
|
|
|
dwcb = ( dwcbData > MAX_REGISTRY_VALUE_LENGTH )
|
|
? MAX_REGISTRY_VALUE_LENGTH
|
|
: dwcbData;
|
|
|
|
unicodeValue.Length = unicodeValue.MaximumLength = (USHORT)dwcb;
|
|
|
|
unicodeValue.Buffer = pvData;
|
|
|
|
status = LsaStorePrivateData( hPolicy, &unicodeKey, &unicodeValue );
|
|
|
|
if ( status != STATUS_SUCCESS )
|
|
{
|
|
dwRetCode = LsaNtStatusToWinError(status);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Move the pointer to the unwritten part
|
|
// of the value.
|
|
//
|
|
|
|
pvData = (PBYTE)pvData + dwcb;
|
|
|
|
dwcbData -= dwcb;
|
|
}
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
LsaClose( hPolicy );
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
//
|
|
// Delete any extra keys.
|
|
//
|
|
|
|
for (;;)
|
|
{
|
|
//
|
|
// Format the key string.
|
|
//
|
|
|
|
wsprintf( wchKey, MPR_CREDENTIALS_KEY, dwIndex++ );
|
|
|
|
RtlInitUnicodeString( &unicodeKey, wchKey );
|
|
|
|
//
|
|
// Delete the key.
|
|
//
|
|
|
|
status = LsaStorePrivateData( hPolicy, &unicodeKey, NULL );
|
|
|
|
if ( status != STATUS_SUCCESS )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
LsaClose( hPolicy );
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: DialParamsBlobToList
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description: Take a string read from the user's registry key and produce
|
|
// a list of MPRPARAMSENTRY structures. If one of the structures
|
|
// has the same dwUID field as the dwUID passed in, then this
|
|
// function returns a pointer to this structure.
|
|
//
|
|
// This string encodes the data for multiple MPRPARAMSENTRY
|
|
// structures. The format of an encoded MPRPARAMSENTRY is as
|
|
// follows:
|
|
//
|
|
// <szPhoneBookEntryName>\0<szUserName>\0<szPassword>\0<szDomain>\0
|
|
//
|
|
PMPRPARAMSENTRY
|
|
DialParamsBlobToList(
|
|
IN PVOID pvData,
|
|
IN LPWSTR lpwsPhoneBookEntryName,
|
|
OUT PLIST_ENTRY pHead
|
|
)
|
|
{
|
|
PWCHAR p;
|
|
PMPRPARAMSENTRY pParams, pFoundParams;
|
|
|
|
p = (PWCHAR)pvData;
|
|
|
|
pFoundParams = NULL;
|
|
|
|
for (;;)
|
|
{
|
|
pParams = LocalAlloc(LPTR, sizeof (MPRPARAMSENTRY));
|
|
|
|
if ( pParams == NULL )
|
|
{
|
|
break;
|
|
}
|
|
|
|
wcscpy( pParams->szPhoneBookEntryName, p );
|
|
|
|
if (_wcsicmp(pParams->szPhoneBookEntryName,lpwsPhoneBookEntryName) == 0)
|
|
{
|
|
pFoundParams = pParams;
|
|
}
|
|
while (*p) p++; p++;
|
|
|
|
wcscpy(pParams->szUserName, p);
|
|
while (*p) p++; p++;
|
|
|
|
wcscpy(pParams->szPassword, p);
|
|
while (*p) p++; p++;
|
|
|
|
wcscpy(pParams->szDomain, p);
|
|
while (*p) p++; p++;
|
|
|
|
InsertTailList(pHead, &pParams->ListEntry);
|
|
|
|
if (*p == L'\0') break;
|
|
}
|
|
|
|
return( pFoundParams );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: DialParamsListToBlob
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
PVOID
|
|
DialParamsListToBlob(
|
|
IN PLIST_ENTRY pHead,
|
|
OUT LPDWORD lpcb
|
|
)
|
|
{
|
|
DWORD dwcb, dwSize;
|
|
PVOID pvData;
|
|
PWCHAR p;
|
|
PLIST_ENTRY pEntry;
|
|
PMPRPARAMSENTRY pParams;
|
|
|
|
//
|
|
// Estimate a buffer size large enough to hold the new entry.
|
|
//
|
|
|
|
dwSize = *lpcb + sizeof (MPRPARAMSENTRY) + 32;
|
|
|
|
if ( ( pvData = LocalAlloc(LPTR, dwSize) ) == NULL )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// Enumerate the list and convert each entry back to a string.
|
|
//
|
|
|
|
dwSize = 0;
|
|
|
|
p = (PWCHAR)pvData;
|
|
|
|
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink )
|
|
{
|
|
pParams = CONTAINING_RECORD(pEntry, MPRPARAMSENTRY, ListEntry);
|
|
|
|
wcscpy(p, pParams->szPhoneBookEntryName);
|
|
dwcb = wcslen(pParams->szPhoneBookEntryName) + 1;
|
|
p += dwcb; dwSize += dwcb;
|
|
|
|
wcscpy(p, pParams->szUserName);
|
|
dwcb = wcslen(pParams->szUserName) + 1;
|
|
p += dwcb; dwSize += dwcb;
|
|
|
|
wcscpy(p, pParams->szPassword);
|
|
dwcb = wcslen(pParams->szPassword) + 1;
|
|
p += dwcb; dwSize += dwcb;
|
|
|
|
wcscpy(p, pParams->szDomain);
|
|
dwcb = wcslen(pParams->szDomain) + 1;
|
|
p += dwcb; dwSize += dwcb;
|
|
}
|
|
|
|
*p = L'\0';
|
|
dwSize++;
|
|
dwSize *= sizeof (WCHAR);
|
|
|
|
//
|
|
// Set the exact length here.
|
|
//
|
|
|
|
*lpcb = dwSize;
|
|
|
|
return( pvData );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: FreeParamsList
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description: Will free the list of structures.
|
|
//
|
|
VOID
|
|
FreeParamsList(
|
|
IN PLIST_ENTRY pHead
|
|
)
|
|
{
|
|
PLIST_ENTRY pEntry;
|
|
PMPRPARAMSENTRY pParams;
|
|
|
|
while( !IsListEmpty(pHead) )
|
|
{
|
|
pEntry = RemoveHeadList(pHead);
|
|
pParams = CONTAINING_RECORD(pEntry, MPRPARAMSENTRY, ListEntry);
|
|
SecureZeroMemory( pParams, sizeof( MPRPARAMSENTRY ) );
|
|
LocalFree(pParams);
|
|
}
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: RemoveCredentials
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD
|
|
RemoveCredentials(
|
|
IN LPWSTR lpwsInterfaceName,
|
|
IN LPVOID pvData,
|
|
IN OUT LPDWORD lpdwSize
|
|
)
|
|
{
|
|
PWCHAR pWalker = (PWCHAR)pvData;
|
|
DWORD dwIndex;
|
|
|
|
//
|
|
// There is no list to remove from.
|
|
//
|
|
|
|
if ( pvData == NULL )
|
|
{
|
|
return( ERROR_NO_SUCH_INTERFACE );
|
|
}
|
|
|
|
for (;;)
|
|
{
|
|
//
|
|
// If we found the interface we want to remove, we jump past it
|
|
//
|
|
|
|
if ( _wcsicmp( (LPWSTR)pWalker, lpwsInterfaceName ) == 0 )
|
|
{
|
|
PWCHAR pInterface = pWalker;
|
|
DWORD dwEntrySize = 0;
|
|
|
|
//
|
|
// Jump past the 4 fields.
|
|
//
|
|
|
|
for ( dwIndex = 0; dwIndex < 4; dwIndex++ )
|
|
{
|
|
while (*pWalker) pWalker++, dwEntrySize++;
|
|
|
|
pWalker++, dwEntrySize++;
|
|
}
|
|
|
|
//
|
|
// If this was the last entry in the list
|
|
//
|
|
|
|
if (*pWalker == L'\0')
|
|
{
|
|
ZeroMemory( pInterface, dwEntrySize );
|
|
}
|
|
else
|
|
{
|
|
CopyMemory( pInterface,
|
|
pWalker,
|
|
*lpdwSize - ( (PBYTE)pWalker - (PBYTE)pvData ) );
|
|
}
|
|
|
|
*lpdwSize -= dwEntrySize;
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Not found so skip over this entry
|
|
//
|
|
|
|
for ( dwIndex = 0; dwIndex < 4; dwIndex++ )
|
|
{
|
|
while (*pWalker) pWalker++; pWalker++;
|
|
}
|
|
}
|
|
|
|
if (*pWalker == L'\0') break;
|
|
}
|
|
|
|
return( ERROR_NO_SUCH_INTERFACE );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: MprAdminInterfaceSetCredentials
|
|
//
|
|
// Returns: NO_ERROR - success
|
|
// ERROR_INVALID_PARAMETER
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD APIENTRY
|
|
MprAdminInterfaceSetCredentialsInternal(
|
|
IN LPWSTR lpwsServer OPTIONAL,
|
|
IN LPWSTR lpwsInterfaceName,
|
|
IN LPWSTR lpwsUserName OPTIONAL,
|
|
IN LPWSTR lpwsDomainName OPTIONAL,
|
|
IN LPWSTR lpwsPassword OPTIONAL
|
|
)
|
|
{
|
|
DWORD dwRetCode;
|
|
DWORD dwSize;
|
|
PVOID pvData;
|
|
LIST_ENTRY paramList;
|
|
PMPRPARAMSENTRY pParams = NULL;
|
|
|
|
if ( lpwsInterfaceName == NULL )
|
|
{
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
if ( wcslen( lpwsInterfaceName ) > MAX_INTERFACE_NAME_LEN )
|
|
{
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
if ( lpwsUserName != NULL )
|
|
{
|
|
if ( wcslen( lpwsUserName ) > UNLEN )
|
|
{
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
}
|
|
|
|
if ( lpwsPassword != NULL )
|
|
{
|
|
if ( wcslen( lpwsPassword ) > PWLEN )
|
|
{
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
}
|
|
|
|
if ( lpwsDomainName != NULL )
|
|
{
|
|
if ( wcslen( lpwsDomainName ) > DNLEN )
|
|
{
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Read the existing dial params string from the registry.
|
|
//
|
|
|
|
dwRetCode = ReadDialParamsBlob( lpwsServer, &pvData, &dwSize );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
return( dwRetCode );
|
|
}
|
|
|
|
//
|
|
// If everything was NULL, we want to delete credentials for this interface
|
|
//
|
|
|
|
if ( ( lpwsUserName == NULL ) &&
|
|
( lpwsDomainName == NULL ) &&
|
|
( lpwsPassword == NULL ) )
|
|
{
|
|
dwRetCode = RemoveCredentials( lpwsInterfaceName, pvData, &dwSize );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
ZeroMemory ( pvData, dwSize );
|
|
LocalFree( pvData );
|
|
|
|
return( dwRetCode );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Parse the string into a list, and search for the phonebook entry.
|
|
//
|
|
|
|
InitializeListHead( ¶mList );
|
|
|
|
if ( pvData != NULL )
|
|
{
|
|
pParams = DialParamsBlobToList(pvData,lpwsInterfaceName,¶mList);
|
|
|
|
//
|
|
// We're done with pvData, so free it.
|
|
//
|
|
|
|
ZeroMemory ( pvData, dwSize );
|
|
|
|
LocalFree( pvData );
|
|
|
|
pvData = NULL;
|
|
}
|
|
|
|
//
|
|
// If there is no existing information for this entry, create a new one.
|
|
//
|
|
|
|
if ( pParams == NULL )
|
|
{
|
|
pParams = LocalAlloc(LPTR, sizeof (MPRPARAMSENTRY) );
|
|
|
|
if (pParams == NULL)
|
|
{
|
|
FreeParamsList( ¶mList );
|
|
|
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|
}
|
|
|
|
InsertTailList( ¶mList, &pParams->ListEntry );
|
|
}
|
|
|
|
//
|
|
// Set the new uid for the entry.
|
|
//
|
|
|
|
wcscpy( pParams->szPhoneBookEntryName, lpwsInterfaceName );
|
|
|
|
if ( lpwsUserName != NULL )
|
|
{
|
|
wcscpy( pParams->szUserName, lpwsUserName );
|
|
}
|
|
|
|
if ( lpwsPassword != NULL )
|
|
{
|
|
wcscpy( pParams->szPassword, lpwsPassword );
|
|
}
|
|
|
|
if ( lpwsDomainName != NULL )
|
|
{
|
|
wcscpy( pParams->szDomain, lpwsDomainName );
|
|
}
|
|
|
|
//
|
|
// Convert the new list back to a string, so we can store it back into
|
|
// the registry.
|
|
//
|
|
|
|
pvData = DialParamsListToBlob( ¶mList, &dwSize );
|
|
|
|
FreeParamsList( ¶mList );
|
|
|
|
if ( pvData == NULL )
|
|
{
|
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Write it back to the registry.
|
|
//
|
|
|
|
dwRetCode = WriteDialParamsBlob( lpwsServer, pvData, dwSize );
|
|
|
|
if ( pvData != NULL )
|
|
{
|
|
SecureZeroMemory( pvData, dwSize );
|
|
LocalFree( pvData );
|
|
}
|
|
|
|
return( dwRetCode );
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: MprAdminInterfaceGetCredentials
|
|
//
|
|
// Returns: NO_ERROR - success
|
|
// ERROR_INVALID_PARAMETER
|
|
//
|
|
// Description:
|
|
//
|
|
DWORD APIENTRY
|
|
MprAdminInterfaceGetCredentialsInternal(
|
|
IN LPWSTR lpwsServer OPTIONAL,
|
|
IN LPWSTR lpwsInterfaceName,
|
|
IN LPWSTR lpwsUserName OPTIONAL,
|
|
IN LPWSTR lpwsPassword OPTIONAL,
|
|
IN LPWSTR lpwsDomainName OPTIONAL
|
|
)
|
|
{
|
|
DWORD dwRetCode;
|
|
DWORD dwSize;
|
|
PVOID pvData;
|
|
LIST_ENTRY paramList;
|
|
PMPRPARAMSENTRY pParams = NULL;
|
|
|
|
if ( lpwsInterfaceName == NULL )
|
|
{
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
if ( ( lpwsUserName == NULL ) &&
|
|
( lpwsDomainName == NULL ) &&
|
|
( lpwsPassword == NULL ) )
|
|
{
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
//
|
|
// Read the existing dial params string from the registry.
|
|
//
|
|
|
|
dwRetCode = ReadDialParamsBlob( lpwsServer, &pvData, &dwSize );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
return( dwRetCode );
|
|
}
|
|
|
|
//
|
|
// Parse the string into a list, and search for the lpwsInterfaceName entry.
|
|
//
|
|
|
|
InitializeListHead( ¶mList );
|
|
|
|
if ( pvData != NULL )
|
|
{
|
|
pParams = DialParamsBlobToList( pvData, lpwsInterfaceName, ¶mList );
|
|
|
|
//
|
|
// We're done with pvData, so free it.
|
|
//
|
|
|
|
ZeroMemory( pvData, dwSize );
|
|
LocalFree( pvData );
|
|
}
|
|
|
|
//
|
|
// If the entry doesn't have any saved parameters, then return.
|
|
//
|
|
if ( pParams == NULL )
|
|
{
|
|
FreeParamsList( ¶mList );
|
|
|
|
return( ERROR_CANNOT_FIND_PHONEBOOK_ENTRY );
|
|
}
|
|
|
|
//
|
|
// Otherwise, copy the fields to the caller's buffer.
|
|
//
|
|
|
|
if ( lpwsUserName != NULL )
|
|
{
|
|
wcscpy( lpwsUserName, pParams->szUserName );
|
|
}
|
|
|
|
if ( lpwsPassword != NULL )
|
|
{
|
|
wcscpy( lpwsPassword, pParams->szPassword );
|
|
}
|
|
|
|
if ( lpwsDomainName != NULL )
|
|
{
|
|
wcscpy( lpwsDomainName, pParams->szDomain );
|
|
}
|
|
|
|
FreeParamsList( ¶mList );
|
|
|
|
return( NO_ERROR );
|
|
}
|