⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rasreg.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*****************************************************************************
* 
*
*   @doc EX_RAS
*
*   Date: 11/18/95
*
*   @topic RasPhoneBook |
*       This file implments the ras functions used to access the
*       registry based Ras PhoneBook.
*
*       Functions Included are :
*
*       <f RasEnumEntries>
*       <f RasGetEntryDevConfig>
*       <f RasGetEntryDialParams>
*       <f RasGetEntryProperties>
*       <f RasRenameEntry>
*       <f RasSetEntryDevConfig>
*       <f RasSetEntryDialParams>
*       <f RasSetEntryProperties>
*       <f RasValidateEntryName>
*       <f RasDeleteEntry>
*
*/

/* ----------------------------------------------------------------
*
*   Things to be done.
*
*   1)  Create a numeric based key value, then store the name
*       as the default value.  This makes the rename function
*       trivial (and safe).
*   2)  Update Autodoc for all functions
*   3)  Add Device Info
*
*
*
---------------------------------------------------------------- */



//  Include Files

#include "windows.h"
#include "tchar.h"
#include "memory.h"

#include "rasxport.h"
#include "raserror.h"
#include "unimodem.h"
#include "netui.h"

#include "cxport.h"
#include "protocol.h"
#include "ppp.h"
#include "mac.h"
#include "md5.h"
#include "crypt.h"
#include "wincrypt.h"
#include "cred.h"


static BOOL
ValidateStringLength(
	IN PCWSTR wstr,
	IN DWORD  ccMin,
	IN DWORD  ccMax)
//
//  Return TRUE if wstr contains between ccMin and ccMax characters, inclusive.
//  Return FALSE if wstr contains fewer than ccMin or more than ccMax characters.
//
{
	DWORD ccStr = 0;

	while (TRUE)
	{
		if (*wstr++ == L'\0')
			break;
		ccStr++;
		if (ccStr > ccMax)
			break;
	}

	return ccMin <= ccStr && ccStr <= ccMax;
}

TCHAR szDummyPassword[] = TEXT("****************");


static void
RasCredentialsMakeKey(
	IN  LPRASDIALPARAMS pRasDialParams,
	OUT PWSTR           wszKeyName)
//
//  Form the key name string "PPP_<szEntryName>".
//
{
	ASSERT(wcslen(pRasDialParams->szEntryName) <= RAS_MaxEntryName);

	wcscpy(wszKeyName, L"PPP_");
	wcscat(wszKeyName, pRasDialParams->szEntryName);
}

static void
RasCredentialsMakeUser(
	IN  LPRASDIALPARAMS pRasDialParams,
	OUT PWSTR           wszUserName)
//
//  Form the username string "[<domain>\]<user>".
//
{
	ASSERT(wcslen(pRasDialParams->szDomain) <= DNLEN);
	ASSERT(wcslen(pRasDialParams->szUserName) <= UNLEN);

	wszUserName[0] = 0;

	if (pRasDialParams->szDomain[0])
	{
		wsprintf(wszUserName, L"%s\\", pRasDialParams->szDomain);
	}
	wcscat(wszUserName, pRasDialParams->szUserName);

	ASSERT(wcslen(wszUserName) <= UNLEN + 1 + DNLEN + 1);
}

static DWORD
RasCredentialsWrite(
	IN  LPRASDIALPARAMS pRasDialParams,
	IN  BOOL            bDeletePassword)
//
// Save the domain/username/password in the credentials database using
// the keyname PPP_<szRasEntryName>.
//
{
	CRED  cred;
	WCHAR wszKeyName[4 + RAS_MaxEntryName + 1];
	WCHAR wszUserName[DNLEN + 1 + UNLEN + 1];
	DWORD dwResult;
	BOOL  bUpdateExistingCredentials = FALSE;
	DWORD dwFlags = CRED_FLAG_UPDATE_USER | CRED_FLAG_UPDATE_BLOB | CRED_FLAG_UPDATE_FLAGS;

	RasCredentialsMakeKey(pRasDialParams, wszKeyName);
	RasCredentialsMakeUser(pRasDialParams, wszUserName);

	// Set up the credential
	// We want credentials to be persisted across soft reset and cold (assuming registry persistence) resets.
	cred.dwVersion = CRED_VER_1;
	cred.dwType = CRED_TYPE_PLAINTEXT_PASSWORD;
	cred.wszTarget = wszKeyName;
	cred.dwTargetLen = wcslen(wszKeyName) + 1;
	cred.dwFlags = CRED_FLAG_PERSIST;
	cred.wszUser = wszUserName;
	cred.dwUserLen = wcslen(wszUserName) + 1;
	if (bDeletePassword)
	{
		cred.pBlob = NULL;
		cred.dwBlobSize = 0;
	}
	else if (0 == _tcscmp(pRasDialParams->szPassword, szDummyPassword))
	{
		// The password is the dummy password ("********"), returned by a prior
		// call to RasGetEntryDialParams.
		// This means that we want to leave the existing password as-is.
		bUpdateExistingCredentials = TRUE;
		dwFlags &= ~CRED_FLAG_UPDATE_BLOB;
	}
	else
	{
		// A real password has been specified.
		cred.pBlob = (PBYTE)(pRasDialParams->szPassword);
		cred.dwBlobSize = sizeof(WCHAR) * (wcslen(pRasDialParams->szPassword) + 1);
	}

	if (bUpdateExistingCredentials)
	{
		dwResult = CredUpdate(wszKeyName, wcslen(wszKeyName) + 1, CRED_TYPE_PLAINTEXT_PASSWORD, &cred, dwFlags);
	}
	else
	{
		// Write the credential
		dwResult = CredWrite(&cred, 0);
	}

	return dwResult;
}

static DWORD
RasCredentialsRead(
	IN OUT  LPRASDIALPARAMS pRasDialParams,
	IN      BOOL            bOnlyRetrievePassword,
	   OUT  PBOOL           pbRetrievedPassword)
//
// Read the domain/username/password from the credentials database using
// the keyname PPP_<szRasEntryName>.
//
{
	PCRED pCred = NULL;
	WCHAR wszKeyName[4 + RAS_MaxEntryName + 1];
	PWSTR pwszUserName,
		  pwszSeparator;
	DWORD dwResult;

	if (pbRetrievedPassword)
		*pbRetrievedPassword = FALSE;
	RasCredentialsMakeKey(pRasDialParams, wszKeyName);

	// Read the credential matching the requested target
	// If there is no exact target match, then we dont want default/implicit default creds to be returned
	dwResult = CredRead(wszKeyName, wcslen(wszKeyName) + 1, CRED_TYPE_PLAINTEXT_PASSWORD, CRED_FLAG_NO_DEFAULT|CRED_FLAG_NO_IMPLICIT_DEFAULT, &pCred);

	if (ERROR_SUCCESS != dwResult)
	{
	}
	else if (NULL == pCred)
	{
		dwResult = ERROR_NOT_FOUND;
	}
	else
	{
		if (FALSE == bOnlyRetrievePassword)
		{
			// Convert pCred at wszUser into domain and username.

			memset(pRasDialParams->szDomain, 0, sizeof(pRasDialParams->szDomain));

			pwszUserName = pCred->wszUser;
			pwszSeparator = wcschr(pCred->wszUser, L'\\');
			if (pwszSeparator)
			{
				// Extract the domain
				if (pwszSeparator - pwszUserName > DNLEN)
				{
					dwResult = ERROR_INSUFFICIENT_BUFFER;
				}
				else
				{
					memcpy(pRasDialParams->szDomain, pwszUserName, sizeof(WCHAR) * (pwszSeparator - pwszUserName));
				}

				// Username follows the separator
				pwszUserName = pwszSeparator + 1;
			}

			if (wcslen(pwszUserName) > UNLEN)
			{
				dwResult = ERROR_INSUFFICIENT_BUFFER;
			}
			else
			{
				wcscpy(pRasDialParams->szUserName, pwszUserName);
			}
		}

		SecureZeroMemory(pRasDialParams->szPassword, sizeof(pRasDialParams->szPassword));

		if (NULL == pCred->pBlob || 0 == pCred->dwBlobSize)
		{
			// No password stored in the blob.
		}
		else if ((pCred->dwBlobSize / sizeof(WCHAR)) > PWLEN)
		{
			dwResult = ERROR_INSUFFICIENT_BUFFER;
		}
		else
		{
			if (pbRetrievedPassword)
				*pbRetrievedPassword = TRUE;

			wcsncpy(pRasDialParams->szPassword, (PWSTR)pCred->pBlob, PWLEN + 1);
			pRasDialParams->szPassword[PWLEN] = 0;
		}
		CredFree((PBYTE)pCred);
	}
	return dwResult;
}

static DWORD
RasCredentialsDelete(
	IN LPRASDIALPARAMS pRasDialParams)
{
	WCHAR wszKeyName[RAS_MaxEntryName + 10];
	DWORD dwResult;

	RasCredentialsMakeKey(pRasDialParams, wszKeyName);
	dwResult = CredDelete(wszKeyName, wcslen(wszKeyName) + 1, CRED_TYPE_PLAINTEXT_PASSWORD, 0);

	return dwResult;
}

#define COUNTOF(array) (sizeof(array) / sizeof(array[0]))

DWORD
OpenRasEntryKey(
    IN  LPCTSTR  szPhonebook,
    IN  LPCTSTR  szEntry,
    OUT PHKEY    phKey)
{
    WCHAR   KeyName[128];
    DWORD   dwResult;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+OpenRasEntryKey %s\n"), szEntry ? szEntry : TEXT("NULL")));

    if (NULL != szPhonebook)
    {
        // We only support the system/registry phonebook.
        DEBUGMSG (ZONE_RAS, (TEXT(" OpenRasEntryKey: ERROR-Phonebook is NOT NULL\n")));
        dwResult = ERROR_CANNOT_OPEN_PHONEBOOK;
    }
    else 
    {
        dwResult = RaspCheckEntryName(szEntry);
        if (dwResult == ERROR_SUCCESS)
        {
            StringCchPrintfW(KeyName, COUNTOF(KeyName), L"%s\\%s", RASBOOK_KEY, szEntry);
            DEBUGMSG(ZONE_RAS, (TEXT(" OpenRasEntryKey '%s'\n"), KeyName));
            dwResult = RegOpenKeyEx (HKEY_CURRENT_USER, KeyName, 0, KEY_ALL_ACCESS, phKey);
            if (dwResult != ERROR_SUCCESS)
                dwResult = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY;
        }
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-OpenRasEntryKey result=%d\n"), dwResult));

    return dwResult;
}

DWORD
CreateRasEntryKey(
    IN  LPCTSTR  szPhonebook,
    IN  LPCTSTR  szEntry,
    OUT PHKEY    phKey)
{
    WCHAR   KeyName[128];
    DWORD   dwResult,
            dwDisp;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+CreateRasEntryKey %s\n"), szEntry ? szEntry : TEXT("NULL")));

    if (NULL != szPhonebook)
    {
        // We only support the system/registry phonebook.
        DEBUGMSG (ZONE_RAS, (TEXT(" CreateRasEntryKey: ERROR-Phonebook is NOT NULL\n")));
        dwResult = ERROR_CANNOT_OPEN_PHONEBOOK;
    }
    else 
    {
        dwResult = RaspCheckEntryName(szEntry);
        if (dwResult == ERROR_SUCCESS)
        {
            StringCchPrintfW(KeyName, COUNTOF(KeyName), L"%s\\%s", RASBOOK_KEY, szEntry);
            DEBUGMSG(ZONE_RAS, (TEXT(" CreateRasEntryKey '%s'\n"), KeyName));

            dwResult = RegCreateKeyEx(HKEY_CURRENT_USER, KeyName, 0, NULL,
                              REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
                              phKey, &dwDisp);

            if (dwResult != ERROR_SUCCESS)
                dwResult = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY;
        }
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-CreateRasEntryKey result=%d\n"), dwResult));

    return dwResult;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -