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.
4212 lines
122 KiB
4212 lines
122 KiB
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
rasmig.c
|
|
|
|
Abstract:
|
|
|
|
<abstract>
|
|
|
|
Author:
|
|
|
|
Calin Negreanu (calinn) 08 Mar 2000
|
|
|
|
Revision History:
|
|
|
|
<alias> <date> <comments>
|
|
|
|
--*/
|
|
|
|
//
|
|
// Includes
|
|
//
|
|
|
|
#include "pch.h"
|
|
#include "logmsg.h"
|
|
|
|
#include <ras.h>
|
|
#include <raserror.h>
|
|
|
|
#define DBG_RASMIG "RasMig"
|
|
#define SIZEOF_STRUCT(structname, uptomember) ((int)((LPBYTE)(&((structname*)0)->uptomember) - ((LPBYTE)((structname*)0))))
|
|
|
|
//
|
|
// Strings
|
|
//
|
|
|
|
#define S_RAS_POOL_NAME "RasConnection"
|
|
#define S_RAS_NAME TEXT("RasConnection")
|
|
#define S_PBKFILE_ATTRIBUTE TEXT("PbkFile")
|
|
#ifdef UNICODE
|
|
#define S_RASAPI_RASSETCREDENTIALS "RasSetCredentialsW"
|
|
#define S_RASAPI_RASDELETEENTRY "RasDeleteEntryW"
|
|
#else
|
|
#define S_RASAPI_RASSETCREDENTIALS "RasSetCredentialsA"
|
|
#define S_RASAPI_RASDELETEENTRY "RasDeleteEntryA"
|
|
#endif
|
|
|
|
//
|
|
// Constants
|
|
//
|
|
|
|
// None
|
|
|
|
//
|
|
// Macros
|
|
//
|
|
|
|
// None
|
|
|
|
//
|
|
// Types
|
|
//
|
|
|
|
// RAS api functions
|
|
|
|
typedef DWORD(WINAPI RASGETCREDENTIALSA)(
|
|
IN LPCSTR lpszPhonebook,
|
|
IN LPCSTR lpszEntry,
|
|
OUT LPRASCREDENTIALSA lpRasCredentials
|
|
);
|
|
typedef RASGETCREDENTIALSA *PRASGETCREDENTIALSA;
|
|
|
|
typedef DWORD(WINAPI RASSETCREDENTIALS)(
|
|
IN LPCTSTR lpszPhonebook,
|
|
IN LPCTSTR lpszEntry,
|
|
IN LPRASCREDENTIALS lpRasCredentials,
|
|
IN BOOL fClearCredentials
|
|
);
|
|
typedef RASSETCREDENTIALS *PRASSETCREDENTIALS;
|
|
|
|
typedef DWORD(WINAPI RASDELETEENTRY)(
|
|
IN LPCTSTR lpszPhonebook,
|
|
IN LPCTSTR lpszEntry
|
|
);
|
|
typedef RASDELETEENTRY *PRASDELETEENTRY;
|
|
|
|
typedef struct {
|
|
PCTSTR Pattern;
|
|
HASHTABLE_ENUM HashData;
|
|
} RAS_ENUM, *PRAS_ENUM;
|
|
|
|
//
|
|
// Globals
|
|
//
|
|
|
|
PMHANDLE g_RasPool = NULL;
|
|
HASHTABLE g_RasTable;
|
|
MIG_OBJECTTYPEID g_RasTypeId = 0;
|
|
static MIG_OBJECTTYPEID g_FileTypeId = 0;
|
|
MIG_ATTRIBUTEID g_PbkFileAttribute = 0;
|
|
BOOL g_AllowPbkRestore = FALSE;
|
|
GROWBUFFER g_RasConversionBuff = INIT_GROWBUFFER;
|
|
MIG_OBJECTSTRINGHANDLE g_Win9xPbkFile = NULL;
|
|
BOOL g_SrcOSNT4 = FALSE;
|
|
BOOL g_FirstRasPair = FALSE;
|
|
BOOL g_DelayRasOp = FALSE;
|
|
|
|
// RAS api functions
|
|
PRASGETCREDENTIALSA g_RasGetCredentialsA = NULL;
|
|
PRASSETCREDENTIALS g_RasSetCredentials = NULL;
|
|
PRASDELETEENTRY g_RasDeleteEntry = NULL;
|
|
|
|
//
|
|
// Macro expansion list
|
|
//
|
|
|
|
// None
|
|
|
|
//
|
|
// Private function prototypes
|
|
//
|
|
|
|
// None
|
|
|
|
//
|
|
// Macro expansion definition
|
|
//
|
|
|
|
// None
|
|
|
|
//
|
|
// Private prototypes
|
|
//
|
|
|
|
SGMENUMERATIONCALLBACK SgmRasConnectionsCallback;
|
|
VCMENUMERATIONCALLBACK VcmRasConnectionsCallback;
|
|
|
|
TYPE_ENUMFIRSTPHYSICALOBJECT EnumFirstRasConnection;
|
|
TYPE_ENUMNEXTPHYSICALOBJECT EnumNextRasConnection;
|
|
TYPE_ABORTENUMPHYSICALOBJECT AbortEnumRasConnection;
|
|
TYPE_CONVERTOBJECTTOMULTISZ ConvertRasConnectionToMultiSz;
|
|
TYPE_CONVERTMULTISZTOOBJECT ConvertMultiSzToRasConnection;
|
|
TYPE_GETNATIVEOBJECTNAME GetNativeRasConnectionName;
|
|
TYPE_ACQUIREPHYSICALOBJECT AcquireRasConnection;
|
|
TYPE_RELEASEPHYSICALOBJECT ReleaseRasConnection;
|
|
TYPE_DOESPHYSICALOBJECTEXIST DoesRasConnectionExist;
|
|
TYPE_REMOVEPHYSICALOBJECT RemoveRasConnection;
|
|
TYPE_CREATEPHYSICALOBJECT CreateRasConnection;
|
|
TYPE_CONVERTOBJECTCONTENTTOUNICODE ConvertRasConnectionContentToUnicode;
|
|
TYPE_CONVERTOBJECTCONTENTTOANSI ConvertRasConnectionContentToAnsi;
|
|
TYPE_FREECONVERTEDOBJECTCONTENT FreeConvertedRasConnectionContent;
|
|
MIG_OBJECTENUMCALLBACK PbkFilesCallback;
|
|
MIG_RESTORECALLBACK PbkRestoreCallback;
|
|
OPMFILTERCALLBACK FilterRasAutoFilter;
|
|
|
|
PCTSTR
|
|
pCreate9xPbkFile (
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// Code
|
|
//
|
|
|
|
BOOL
|
|
RasMigInitialize (
|
|
VOID
|
|
)
|
|
{
|
|
g_RasTable = HtAllocWithData (sizeof (PCTSTR));
|
|
if (!g_RasTable) {
|
|
return FALSE;
|
|
}
|
|
g_RasPool = PmCreateNamedPool (S_RAS_POOL_NAME);
|
|
if (!g_RasPool) {
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
RasMigTerminate (
|
|
VOID
|
|
)
|
|
{
|
|
HASHTABLE_ENUM e;
|
|
PCTSTR nativeName;
|
|
PCTSTR rasData = NULL;
|
|
|
|
if (g_Win9xPbkFile) {
|
|
nativeName = IsmGetNativeObjectName (
|
|
g_FileTypeId,
|
|
g_Win9xPbkFile
|
|
);
|
|
if (nativeName) {
|
|
DeleteFile (nativeName);
|
|
IsmReleaseMemory (nativeName);
|
|
}
|
|
IsmDestroyObjectHandle (g_Win9xPbkFile);
|
|
g_Win9xPbkFile = NULL;
|
|
}
|
|
|
|
GbFree (&g_RasConversionBuff);
|
|
|
|
if (g_RasTable) {
|
|
if (EnumFirstHashTableString (&e, g_RasTable)) {
|
|
do {
|
|
rasData = *(PCTSTR *)(e.ExtraData);
|
|
PmReleaseMemory (g_RasPool, rasData);
|
|
} while (EnumNextHashTableString (&e));
|
|
}
|
|
HtFree (g_RasTable);
|
|
g_RasTable = NULL;
|
|
}
|
|
|
|
if (g_RasPool) {
|
|
PmDestroyPool (g_RasPool);
|
|
g_RasPool = NULL;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
pLoadRasEntries (
|
|
BOOL LeftSide
|
|
)
|
|
{
|
|
HMODULE rasDll = NULL;
|
|
BOOL result = FALSE;
|
|
|
|
__try {
|
|
rasDll = LoadLibrary (TEXT("RASAPI32.DLL"));
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
rasDll = NULL;
|
|
}
|
|
if (rasDll) {
|
|
if (LeftSide) {
|
|
g_RasGetCredentialsA = (PRASGETCREDENTIALSA) GetProcAddress (rasDll, "RasGetCredentialsA");
|
|
} else {
|
|
g_RasSetCredentials = (PRASSETCREDENTIALS) GetProcAddress (rasDll, S_RASAPI_RASSETCREDENTIALS);
|
|
g_RasDeleteEntry = (PRASDELETEENTRY) GetProcAddress (rasDll, S_RASAPI_RASDELETEENTRY);
|
|
}
|
|
} else {
|
|
DEBUGMSG ((DBG_RASMIG, "RAS is not installed on this computer."));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
BOOL
|
|
pAddWin9xPbkObject (
|
|
VOID
|
|
)
|
|
{
|
|
g_Win9xPbkFile = pCreate9xPbkFile ();
|
|
|
|
return (g_Win9xPbkFile != NULL);
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
RasMigEtmInitialize (
|
|
IN MIG_PLATFORMTYPEID Platform,
|
|
IN PMIG_LOGCALLBACK LogCallback,
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
MIG_OSVERSIONINFO versionInfo;
|
|
TYPE_REGISTER rasConnTypeData;
|
|
|
|
LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
|
|
|
|
g_FileTypeId = MIG_FILE_TYPE;
|
|
|
|
ZeroMemory (&rasConnTypeData, sizeof (TYPE_REGISTER));
|
|
rasConnTypeData.Priority = PRIORITY_RASCONNECTION;
|
|
|
|
if (Platform == PLATFORM_SOURCE) {
|
|
rasConnTypeData.EnumFirstPhysicalObject = EnumFirstRasConnection;
|
|
rasConnTypeData.EnumNextPhysicalObject = EnumNextRasConnection;
|
|
rasConnTypeData.AbortEnumPhysicalObject = AbortEnumRasConnection;
|
|
rasConnTypeData.ConvertObjectToMultiSz = ConvertRasConnectionToMultiSz;
|
|
rasConnTypeData.ConvertMultiSzToObject = ConvertMultiSzToRasConnection;
|
|
rasConnTypeData.GetNativeObjectName = GetNativeRasConnectionName;
|
|
rasConnTypeData.AcquirePhysicalObject = AcquireRasConnection;
|
|
rasConnTypeData.ReleasePhysicalObject = ReleaseRasConnection;
|
|
rasConnTypeData.ConvertObjectContentToUnicode = ConvertRasConnectionContentToUnicode;
|
|
rasConnTypeData.ConvertObjectContentToAnsi = ConvertRasConnectionContentToAnsi;
|
|
rasConnTypeData.FreeConvertedObjectContent = FreeConvertedRasConnectionContent;
|
|
|
|
g_RasTypeId = IsmRegisterObjectType (
|
|
S_RAS_NAME,
|
|
TRUE,
|
|
FALSE,
|
|
&rasConnTypeData
|
|
);
|
|
|
|
pLoadRasEntries (TRUE);
|
|
if (IsmGetOsVersionInfo (Platform, &versionInfo)) {
|
|
if (versionInfo.OsType == OSTYPE_WINDOWS9X) {
|
|
// now it's time to convert registry into a PBK file
|
|
pAddWin9xPbkObject ();
|
|
}
|
|
if ((versionInfo.OsType == OSTYPE_WINDOWSNT) &&
|
|
(versionInfo.OsMajorVersion == OSMAJOR_WINNT4)
|
|
) {
|
|
g_SrcOSNT4 = TRUE;
|
|
}
|
|
}
|
|
} else {
|
|
rasConnTypeData.ConvertObjectToMultiSz = ConvertRasConnectionToMultiSz;
|
|
rasConnTypeData.ConvertMultiSzToObject = ConvertMultiSzToRasConnection;
|
|
rasConnTypeData.GetNativeObjectName = GetNativeRasConnectionName;
|
|
rasConnTypeData.DoesPhysicalObjectExist = DoesRasConnectionExist;
|
|
rasConnTypeData.RemovePhysicalObject = RemoveRasConnection;
|
|
rasConnTypeData.CreatePhysicalObject = CreateRasConnection;
|
|
rasConnTypeData.ConvertObjectContentToUnicode = ConvertRasConnectionContentToUnicode;
|
|
rasConnTypeData.ConvertObjectContentToAnsi = ConvertRasConnectionContentToAnsi;
|
|
rasConnTypeData.FreeConvertedObjectContent = FreeConvertedRasConnectionContent;
|
|
|
|
g_RasTypeId = IsmRegisterObjectType (
|
|
S_RAS_NAME,
|
|
TRUE,
|
|
FALSE,
|
|
&rasConnTypeData
|
|
);
|
|
pLoadRasEntries (FALSE);
|
|
if (IsmGetOsVersionInfo (Platform, &versionInfo)) {
|
|
if ((versionInfo.OsType == OSTYPE_WINDOWSNT) &&
|
|
(versionInfo.OsMajorVersion == OSMAJOR_WINNT4)
|
|
) {
|
|
g_SrcOSNT4 = TRUE;
|
|
}
|
|
}
|
|
}
|
|
MYASSERT (g_RasTypeId);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetNextRasConnection (
|
|
IN HANDLE PbkHandle
|
|
)
|
|
{
|
|
CHAR input = 0;
|
|
ULONGLONG beginPos = 0;
|
|
ULONGLONG endPos = 0;
|
|
ULONGLONG lastPos = 0;
|
|
PSTR resultTmp = NULL;
|
|
PTSTR result = NULL;
|
|
#ifdef UNICODE
|
|
WORD oldCodePage;
|
|
DWORD sizeW = 0;
|
|
PWSTR resultW = NULL;
|
|
#endif
|
|
|
|
while (TRUE) {
|
|
if (!BfReadFile (PbkHandle, (PBYTE)(&input), sizeof (CHAR))) {
|
|
break;
|
|
}
|
|
if (input == '[') {
|
|
if (!beginPos) {
|
|
BfGetFilePointer (PbkHandle, &beginPos);
|
|
}
|
|
}
|
|
if (input == ']') {
|
|
if (beginPos) {
|
|
if (!endPos) {
|
|
BfGetFilePointer (PbkHandle, &endPos);
|
|
endPos --;
|
|
} else {
|
|
beginPos = 0;
|
|
endPos = 0;
|
|
}
|
|
}
|
|
}
|
|
if (input == '\n') {
|
|
if (beginPos && endPos && (endPos > beginPos)) {
|
|
BfGetFilePointer (PbkHandle, &lastPos);
|
|
BfSetFilePointer (PbkHandle, beginPos);
|
|
resultTmp = PmGetMemory (g_RasPool, ((UINT) (endPos - beginPos) + 1) * sizeof (CHAR));
|
|
if (!BfReadFile (PbkHandle, (PBYTE) resultTmp, (UINT) (endPos - beginPos) + 1)) {
|
|
PmReleaseMemory (g_RasPool, resultTmp);
|
|
resultTmp = NULL;
|
|
} else {
|
|
resultTmp [(UINT) (endPos - beginPos)] = 0;
|
|
}
|
|
BfSetFilePointer (PbkHandle, lastPos);
|
|
break;
|
|
}
|
|
beginPos = 0;
|
|
endPos = 0;
|
|
}
|
|
}
|
|
#ifdef UNICODE
|
|
if (resultTmp) {
|
|
if (!g_SrcOSNT4) {
|
|
// make sure that the conversion is using UTF8
|
|
oldCodePage = SetConversionCodePage (CP_UTF8);
|
|
}
|
|
sizeW = SizeOfStringA(resultTmp);
|
|
resultW = PmGetMemory (g_RasPool, sizeW * sizeof (WCHAR));
|
|
if (resultW) {
|
|
KnownSizeAtoW (resultW, resultTmp);
|
|
}
|
|
if (!g_SrcOSNT4) {
|
|
SetConversionCodePage (oldCodePage);
|
|
}
|
|
if (resultW) {
|
|
result = PmDuplicateStringW (g_RasPool, resultW);
|
|
PmReleaseMemory (g_RasPool, resultW);
|
|
resultW = NULL;
|
|
}
|
|
}
|
|
#else
|
|
result = resultTmp;
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
BOOL
|
|
pGetNextRasPair (
|
|
IN HANDLE PbkHandle,
|
|
OUT PCTSTR *ValueName,
|
|
OUT PCTSTR *Value
|
|
)
|
|
{
|
|
BOOL error = FALSE;
|
|
CHAR input = 0;
|
|
ULONGLONG beginPos = 0;
|
|
ULONGLONG endPos = 0;
|
|
ULONGLONG lastPos = 0;
|
|
BOOL begin = TRUE;
|
|
BOOL inValue = FALSE;
|
|
PSTR valueName = NULL;
|
|
PSTR value = NULL;
|
|
#ifdef UNICODE
|
|
WORD oldCodePage;
|
|
DWORD sizeW = 0;
|
|
PWSTR valueNameW = NULL;
|
|
PWSTR valueW = NULL;
|
|
#endif
|
|
|
|
BfGetFilePointer (PbkHandle, &beginPos);
|
|
while (TRUE) {
|
|
if (!BfReadFile (PbkHandle, (PBYTE)(&input), sizeof (CHAR))) {
|
|
error = TRUE;
|
|
break;
|
|
}
|
|
if ((input == '[') && begin) {
|
|
BfSetFilePointer (PbkHandle, beginPos);
|
|
error = TRUE;
|
|
break;
|
|
}
|
|
if ((input == ' ') && begin) {
|
|
continue;
|
|
}
|
|
begin = FALSE;
|
|
if (input == '=') {
|
|
if (!inValue) {
|
|
BfGetFilePointer (PbkHandle, &endPos);
|
|
endPos --;
|
|
if (endPos > beginPos) {
|
|
BfGetFilePointer (PbkHandle, &lastPos);
|
|
BfSetFilePointer (PbkHandle, beginPos);
|
|
valueName = PmGetMemory (g_RasPool, ((UINT) (endPos - beginPos) + 1) * sizeof (CHAR));
|
|
if (!BfReadFile (PbkHandle, (PBYTE) valueName, (UINT) (endPos - beginPos) + 1)) {
|
|
error = TRUE;
|
|
break;
|
|
} else {
|
|
valueName [(UINT) (endPos - beginPos)] = 0;
|
|
}
|
|
BfSetFilePointer (PbkHandle, lastPos);
|
|
}
|
|
BfGetFilePointer (PbkHandle, &beginPos);
|
|
inValue = TRUE;
|
|
}
|
|
continue;
|
|
}
|
|
if (input == '\r') {
|
|
BfGetFilePointer (PbkHandle, &endPos);
|
|
endPos --;
|
|
continue;
|
|
}
|
|
if (input == '\n') {
|
|
if (endPos > beginPos) {
|
|
BfGetFilePointer (PbkHandle, &lastPos);
|
|
BfSetFilePointer (PbkHandle, beginPos);
|
|
if (inValue) {
|
|
value = PmGetMemory (g_RasPool, ((UINT) (endPos - beginPos) + 1) * sizeof (CHAR));
|
|
if (!BfReadFile (PbkHandle, (PBYTE) value, (UINT) (endPos - beginPos) + 1)) {
|
|
error = TRUE;
|
|
break;
|
|
} else {
|
|
value [(UINT) (endPos - beginPos)] = 0;
|
|
}
|
|
} else {
|
|
valueName = PmGetMemory (g_RasPool, ((UINT) (endPos - beginPos) + 1) * sizeof (CHAR));
|
|
if (!BfReadFile (PbkHandle, (PBYTE) valueName, (UINT) (endPos - beginPos) + 1)) {
|
|
error = TRUE;
|
|
break;
|
|
} else {
|
|
valueName [(UINT) (endPos - beginPos)] = 0;
|
|
}
|
|
}
|
|
BfSetFilePointer (PbkHandle, lastPos);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (error) {
|
|
if (valueName) {
|
|
PmReleaseMemory (g_RasPool, valueName);
|
|
valueName = NULL;
|
|
}
|
|
if (value) {
|
|
PmReleaseMemory (g_RasPool, value);
|
|
value = NULL;
|
|
}
|
|
}
|
|
|
|
// if this is NT4 and this is the first time we are called,
|
|
// we look to see if the first pair is the "Encoding=1" one.
|
|
// If not, we are going to return it anyway and leave the
|
|
// current read pair for the next time.
|
|
if (g_SrcOSNT4 &&
|
|
valueName &&
|
|
g_FirstRasPair &&
|
|
!StringIMatchA (valueName, "Encoding")
|
|
) {
|
|
g_FirstRasPair = FALSE;
|
|
// set the pointer to where we initially found it
|
|
BfSetFilePointer (PbkHandle, beginPos);
|
|
// free the valueName and value if needed
|
|
PmReleaseMemory (g_RasPool, valueName);
|
|
if (value) {
|
|
PmReleaseMemory (g_RasPool, value);
|
|
}
|
|
valueName = PmDuplicateStringA (g_RasPool, "Encoding");
|
|
value = PmDuplicateStringA (g_RasPool, "1");
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
if (ValueName) {
|
|
if (valueName) {
|
|
if (!g_SrcOSNT4) {
|
|
// make sure that the conversion is using UTF8
|
|
oldCodePage = SetConversionCodePage (CP_UTF8);
|
|
}
|
|
sizeW = SizeOfStringA (valueName);
|
|
valueNameW = PmGetMemory (g_RasPool, sizeW * sizeof (WCHAR));
|
|
if (valueNameW) {
|
|
KnownSizeAtoW (valueNameW, valueName);
|
|
}
|
|
if (!g_SrcOSNT4) {
|
|
SetConversionCodePage (oldCodePage);
|
|
}
|
|
if (valueNameW) {
|
|
*ValueName = PmDuplicateStringW (g_RasPool, valueNameW);
|
|
PmReleaseMemory (g_RasPool, valueNameW);
|
|
}
|
|
} else {
|
|
*ValueName = NULL;
|
|
}
|
|
}
|
|
if (Value) {
|
|
if (value) {
|
|
if (!g_SrcOSNT4) {
|
|
// make sure that the conversion is using UTF8
|
|
oldCodePage = SetConversionCodePage (CP_UTF8);
|
|
}
|
|
sizeW = SizeOfStringA(value);
|
|
valueW = PmGetMemory (g_RasPool, sizeW * sizeof (WCHAR));
|
|
if (valueW) {
|
|
KnownSizeAtoW (valueW, value);
|
|
}
|
|
if (!g_SrcOSNT4) {
|
|
SetConversionCodePage (oldCodePage);
|
|
}
|
|
if (valueW) {
|
|
*Value = PmDuplicateStringW (g_RasPool, valueW);
|
|
PmReleaseMemory (g_RasPool, valueW);
|
|
}
|
|
} else {
|
|
*Value = NULL;
|
|
}
|
|
}
|
|
#else
|
|
if (ValueName) {
|
|
*ValueName = valueName;
|
|
}
|
|
if (Value) {
|
|
*Value = value;
|
|
}
|
|
#endif
|
|
return !error;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetRasLineValue (
|
|
IN PCTSTR RasLines,
|
|
IN PCTSTR ValueName
|
|
)
|
|
{
|
|
MULTISZ_ENUM multiSzEnum;
|
|
BOOL first = TRUE;
|
|
BOOL found = FALSE;
|
|
|
|
if (EnumFirstMultiSz (&multiSzEnum, RasLines)) {
|
|
do {
|
|
if (found) {
|
|
return multiSzEnum.CurrentString;
|
|
}
|
|
if (first && StringIMatch (multiSzEnum.CurrentString, ValueName)) {
|
|
found = TRUE;
|
|
}
|
|
first = !first;
|
|
} while (EnumNextMultiSz (&multiSzEnum));
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
BOOL
|
|
pLoadRasConnections (
|
|
IN PCTSTR PbkFileName,
|
|
IN HASHTABLE RasTable
|
|
)
|
|
{
|
|
HANDLE pbkFileHandle;
|
|
PCTSTR entryName;
|
|
PCTSTR valueName;
|
|
PCTSTR value;
|
|
GROWBUFFER rasLines = INIT_GROWBUFFER;
|
|
PTSTR rasLinesStr;
|
|
MIG_OBJECTSTRINGHANDLE rasConnectionName;
|
|
RASCREDENTIALSA rasCredentials;
|
|
TCHAR valueStr [sizeof (DWORD) * 2 + 3];
|
|
DWORD err;
|
|
MIG_OSVERSIONINFO versionInfo;
|
|
BOOL versionOk = FALSE;
|
|
BOOL inMedia = FALSE;
|
|
BOOL result = FALSE;
|
|
#ifdef UNICODE
|
|
PCSTR tempStr1 = NULL;
|
|
PCSTR tempStr2 = NULL;
|
|
PCWSTR tempStr3 = NULL;
|
|
#endif
|
|
|
|
if (!RasTable) {
|
|
return FALSE;
|
|
}
|
|
|
|
pbkFileHandle = BfOpenReadFile (PbkFileName);
|
|
if (pbkFileHandle) {
|
|
while (TRUE) {
|
|
// get the next RAS connection
|
|
entryName = pGetNextRasConnection (pbkFileHandle);
|
|
if (!entryName) {
|
|
break;
|
|
}
|
|
rasLines.End = 0;
|
|
GbMultiSzAppend (&rasLines, TEXT("ConnectionName"));
|
|
GbMultiSzAppend (&rasLines, entryName);
|
|
versionOk = IsmGetOsVersionInfo (PLATFORM_SOURCE, &versionInfo);
|
|
// we use credentials API only on NT, on win9x the conversion code will automatically insert the fields
|
|
if (!versionOk || (versionInfo.OsType != OSTYPE_WINDOWS9X)) {
|
|
err = ERROR_INVALID_DATA;
|
|
if (g_RasGetCredentialsA) {
|
|
ZeroMemory (&rasCredentials, sizeof (RASCREDENTIALSA));
|
|
rasCredentials.dwSize = sizeof (RASCREDENTIALSA);
|
|
rasCredentials.dwMask = RASCM_UserName | RASCM_Domain | RASCM_Password;
|
|
#ifdef UNICODE
|
|
tempStr1 = ConvertWtoA (PbkFileName);
|
|
tempStr2 = ConvertWtoA (entryName);
|
|
err = g_RasGetCredentialsA (tempStr1, tempStr2, &rasCredentials);
|
|
FreeConvertedStr (tempStr1);
|
|
FreeConvertedStr (tempStr2);
|
|
#else
|
|
err = g_RasGetCredentialsA (PbkFileName, entryName, &rasCredentials);
|
|
#endif
|
|
if (!err) {
|
|
wsprintf (valueStr, TEXT("0x%08X"), rasCredentials.dwMask);
|
|
GbMultiSzAppend (&rasLines, TEXT("CredMask"));
|
|
GbMultiSzAppend (&rasLines, valueStr);
|
|
GbMultiSzAppend (&rasLines, TEXT("CredName"));
|
|
#ifndef UNICODE
|
|
GbMultiSzAppend (&rasLines, (*rasCredentials.szUserName)?rasCredentials.szUserName:TEXT("<empty>"));
|
|
#else
|
|
tempStr3 = ConvertAtoW (rasCredentials.szUserName);
|
|
GbMultiSzAppend (&rasLines, (*tempStr3)?tempStr3:TEXT("<empty>"));
|
|
FreeConvertedStr (tempStr3);
|
|
#endif
|
|
GbMultiSzAppend (&rasLines, TEXT("CredDomain"));
|
|
#ifndef UNICODE
|
|
GbMultiSzAppend (&rasLines, (*rasCredentials.szDomain)?rasCredentials.szDomain:TEXT("<empty>"));
|
|
#else
|
|
tempStr3 = ConvertAtoW (rasCredentials.szDomain);
|
|
GbMultiSzAppend (&rasLines, (*tempStr3)?tempStr3:TEXT("<empty>"));
|
|
FreeConvertedStr (tempStr3);
|
|
#endif
|
|
GbMultiSzAppend (&rasLines, TEXT("CredPassword"));
|
|
#ifndef UNICODE
|
|
GbMultiSzAppend (&rasLines, (*rasCredentials.szPassword)?rasCredentials.szPassword:TEXT("<empty>"));
|
|
#else
|
|
tempStr3 = ConvertAtoW (rasCredentials.szPassword);
|
|
GbMultiSzAppend (&rasLines, (*tempStr3)?tempStr3:TEXT("<empty>"));
|
|
FreeConvertedStr (tempStr3);
|
|
#endif
|
|
}
|
|
}
|
|
if (err) {
|
|
GbMultiSzAppend (&rasLines, TEXT("CredMask"));
|
|
GbMultiSzAppend (&rasLines, TEXT("<empty>"));
|
|
GbMultiSzAppend (&rasLines, TEXT("CredName"));
|
|
GbMultiSzAppend (&rasLines, TEXT("<empty>"));
|
|
GbMultiSzAppend (&rasLines, TEXT("CredDomain"));
|
|
GbMultiSzAppend (&rasLines, TEXT("<empty>"));
|
|
GbMultiSzAppend (&rasLines, TEXT("CredPassword"));
|
|
GbMultiSzAppend (&rasLines, TEXT("<empty>"));
|
|
}
|
|
}
|
|
inMedia = FALSE;
|
|
g_FirstRasPair = TRUE;
|
|
while (TRUE) {
|
|
// get the next RAS connection line
|
|
if (!pGetNextRasPair (pbkFileHandle, &valueName, &value)) {
|
|
break;
|
|
}
|
|
if (valueName &&
|
|
StringMatch (valueName, TEXT("MEDIA")) &&
|
|
value &&
|
|
StringIMatch (value, TEXT("serial"))
|
|
) {
|
|
inMedia = TRUE;
|
|
}
|
|
if (inMedia &&
|
|
valueName &&
|
|
StringMatch (valueName, TEXT("DEVICE"))
|
|
) {
|
|
inMedia = FALSE;
|
|
}
|
|
if (inMedia &&
|
|
valueName &&
|
|
StringIMatch (valueName, TEXT("Port"))
|
|
) {
|
|
if (value) {
|
|
PmReleaseMemory (g_RasPool, value);
|
|
value = NULL;
|
|
}
|
|
}
|
|
if (inMedia &&
|
|
valueName &&
|
|
StringMatch (valueName, TEXT("Device"))
|
|
) {
|
|
if (value) {
|
|
PmReleaseMemory (g_RasPool, value);
|
|
value = NULL;
|
|
}
|
|
}
|
|
GbMultiSzAppend (&rasLines, valueName?valueName:TEXT("<empty>"));
|
|
GbMultiSzAppend (&rasLines, value?value:TEXT("<empty>"));
|
|
if (valueName) {
|
|
PmReleaseMemory (g_RasPool, valueName);
|
|
valueName = NULL;
|
|
}
|
|
if (value) {
|
|
PmReleaseMemory (g_RasPool, value);
|
|
value = NULL;
|
|
}
|
|
}
|
|
GbMultiSzAppend (&rasLines, TEXT(""));
|
|
if (rasLines.End) {
|
|
// now add the RAS connection
|
|
rasLinesStr = PmGetMemory (g_RasPool, rasLines.End);
|
|
CopyMemory (rasLinesStr, rasLines.Buf, rasLines.End);
|
|
rasConnectionName = IsmCreateObjectHandle (PbkFileName, entryName);
|
|
MYASSERT (rasConnectionName);
|
|
if (rasConnectionName) {
|
|
result = TRUE;
|
|
HtAddStringEx (RasTable, rasConnectionName, &rasLinesStr, FALSE);
|
|
}
|
|
IsmDestroyObjectHandle (rasConnectionName);
|
|
}
|
|
PmReleaseMemory (g_RasPool, entryName);
|
|
}
|
|
|
|
CloseHandle (pbkFileHandle);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
UINT
|
|
PbkFilesCallback (
|
|
IN PCMIG_OBJECTENUMDATA Data,
|
|
IN ULONG_PTR CallerArg
|
|
)
|
|
{
|
|
if (Data->IsLeaf) {
|
|
// do this only if somebody actually persisted the object
|
|
if (IsmIsPersistentObject (Data->ObjectTypeId, Data->ObjectName) ||
|
|
IsmIsApplyObject (Data->ObjectTypeId, Data->ObjectName)
|
|
) {
|
|
// record all connections from this PBK file
|
|
if (pLoadRasConnections (Data->NativeObjectName, g_RasTable)) {
|
|
// this is really a PBK file and at least one valid
|
|
// connection was found
|
|
// set the PbkFile attribute so we won't restore this one as a file (if it survives)
|
|
IsmSetAttributeOnObject (Data->ObjectTypeId, Data->ObjectName, g_PbkFileAttribute);
|
|
}
|
|
}
|
|
}
|
|
return CALLBACK_ENUM_CONTINUE;
|
|
}
|
|
|
|
VOID
|
|
WINAPI
|
|
RasMigEtmNewUserCreated (
|
|
IN PCTSTR UserName,
|
|
IN PCTSTR DomainName,
|
|
IN PCTSTR UserProfileRoot,
|
|
IN PSID UserSid
|
|
)
|
|
{
|
|
// a new user was created, the RAS operations on object that
|
|
// belong exclusively to that user need to be delayed
|
|
g_DelayRasOp = TRUE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
RasMigSgmInitialize (
|
|
IN PMIG_LOGCALLBACK LogCallback,
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
RasMigSgmParse (
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
UINT
|
|
SgmRasConnectionsCallback (
|
|
IN PCMIG_OBJECTENUMDATA Data,
|
|
IN ULONG_PTR CallerArg
|
|
)
|
|
{
|
|
PCTSTR node, nodePtr, leaf;
|
|
PTSTR leafPtr;
|
|
PCTSTR rasLines;
|
|
PCTSTR rasValue;
|
|
MIG_OBJECTSTRINGHANDLE objectName;
|
|
MIG_CONTENT objectContent;
|
|
PCTSTR nativeName;
|
|
MIG_OSVERSIONINFO versionInfo;
|
|
BOOL versionOk = FALSE;
|
|
|
|
if (IsmGetRealPlatform () == PLATFORM_DESTINATION) {
|
|
// let's reset the PbkFileAttribute on the source of this connection
|
|
// because the attribute was lost during the transport
|
|
if (IsmCreateObjectStringsFromHandle (Data->ObjectName, &node, &leaf)) {
|
|
if (node) {
|
|
leafPtr = _tcsrchr (node, TEXT('\\'));
|
|
if (leafPtr) {
|
|
*leafPtr = 0;
|
|
leafPtr ++;
|
|
objectName = IsmCreateObjectHandle (node, leafPtr);
|
|
if (objectName) {
|
|
IsmSetAttributeOnObject (g_FileTypeId, objectName, g_PbkFileAttribute);
|
|
IsmDestroyObjectHandle (objectName);
|
|
}
|
|
}
|
|
}
|
|
IsmDestroyObjectString (node);
|
|
IsmDestroyObjectString (leaf);
|
|
}
|
|
}
|
|
// let's see if we can actually migrate this RAS connection
|
|
if (IsmAcquireObject (Data->ObjectTypeId, Data->ObjectName, &objectContent)) {
|
|
versionOk = IsmGetOsVersionInfo (PLATFORM_SOURCE, &versionInfo);
|
|
rasLines = (PCTSTR) objectContent.MemoryContent.ContentBytes;
|
|
rasValue = pGetRasLineValue (rasLines, TEXT("BaseProtocol"));
|
|
if (rasValue && (StringIMatch (rasValue, TEXT("1")) || StringIMatch (rasValue, TEXT("2")))) {
|
|
IsmAbandonObjectOnCollision (Data->ObjectTypeId, Data->ObjectName);
|
|
IsmMakeApplyObject (Data->ObjectTypeId, Data->ObjectName);
|
|
|
|
// now it's a good time to force the migration of the script file
|
|
// if this connection has one
|
|
rasValue = NULL;
|
|
if (versionOk) {
|
|
if (versionInfo.OsType == OSTYPE_WINDOWSNT) {
|
|
if (versionInfo.OsMajorVersion == OSMAJOR_WINNT4) {
|
|
rasValue = pGetRasLineValue (rasLines, TEXT("Type"));
|
|
}
|
|
if (versionInfo.OsMajorVersion == OSMAJOR_WINNT5) {
|
|
rasValue = pGetRasLineValue (rasLines, TEXT("Name"));
|
|
}
|
|
}
|
|
if (versionInfo.OsType == OSTYPE_WINDOWS9X) {
|
|
rasValue = pGetRasLineValue (rasLines, TEXT("Name"));
|
|
}
|
|
}
|
|
if (rasValue && *rasValue) {
|
|
node = DuplicatePathString (rasValue, 0);
|
|
if (_tcsnextc (node) == TEXT('[')) {
|
|
nodePtr = _tcsinc (node);
|
|
} else {
|
|
nodePtr = node;
|
|
}
|
|
leafPtr = _tcsrchr (nodePtr, TEXT('\\'));
|
|
if (leafPtr) {
|
|
*leafPtr = 0;
|
|
leafPtr ++;
|
|
objectName = IsmCreateObjectHandle (nodePtr, leafPtr);
|
|
if (objectName) {
|
|
IsmMakeApplyObject (g_FileTypeId, objectName);
|
|
IsmDestroyObjectHandle (objectName);
|
|
}
|
|
}
|
|
FreePathString (node);
|
|
}
|
|
} else {
|
|
// this is an unsupported framing protocol
|
|
// we will log a message and abandon this connection
|
|
nativeName = IsmGetNativeObjectName (Data->ObjectTypeId, Data->ObjectName);
|
|
LOG ((LOG_WARNING, (PCSTR) MSG_RASMIG_UNSUPPORTEDSETTINGS, nativeName));
|
|
IsmReleaseMemory (nativeName);
|
|
}
|
|
IsmReleaseObject (&objectContent);
|
|
}
|
|
return CALLBACK_ENUM_CONTINUE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
RasMigSgmQueueEnumeration (
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
ENCODEDSTRHANDLE pattern;
|
|
|
|
g_PbkFileAttribute = IsmRegisterAttribute (S_PBKFILE_ATTRIBUTE, FALSE);
|
|
MYASSERT (g_PbkFileAttribute);
|
|
|
|
if (IsmGetRealPlatform () == PLATFORM_SOURCE) {
|
|
|
|
// hook all PBK files enumeration, we will not migrate the files but the connections within
|
|
pattern = IsmCreateSimpleObjectPattern (NULL, FALSE, TEXT("*.PBK"), TRUE);
|
|
|
|
IsmHookEnumeration (
|
|
g_FileTypeId,
|
|
pattern,
|
|
PbkFilesCallback,
|
|
(ULONG_PTR) 0,
|
|
TEXT("PbkFiles")
|
|
);
|
|
|
|
IsmDestroyObjectHandle (pattern);
|
|
}
|
|
|
|
pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, TRUE);
|
|
IsmQueueEnumeration (
|
|
g_RasTypeId,
|
|
pattern,
|
|
SgmRasConnectionsCallback,
|
|
(ULONG_PTR) 0,
|
|
S_RAS_NAME
|
|
);
|
|
IsmDestroyObjectHandle (pattern);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
RasMigVcmInitialize (
|
|
IN PMIG_LOGCALLBACK LogCallback,
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
RasMigVcmParse (
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
return RasMigSgmParse (Reserved);
|
|
}
|
|
|
|
UINT
|
|
VcmRasConnectionsCallback (
|
|
IN PCMIG_OBJECTENUMDATA Data,
|
|
IN ULONG_PTR CallerArg
|
|
)
|
|
{
|
|
PCTSTR node, nodePtr;
|
|
PTSTR leafPtr;
|
|
PCTSTR rasLines;
|
|
PCTSTR rasValue;
|
|
MIG_OBJECTSTRINGHANDLE objectName;
|
|
MIG_CONTENT objectContent;
|
|
PCTSTR nativeName;
|
|
MIG_OSVERSIONINFO versionInfo;
|
|
BOOL versionOk = FALSE;
|
|
|
|
// let's see if we can actually migrate this RAS connection
|
|
if (IsmAcquireObject (Data->ObjectTypeId, Data->ObjectName, &objectContent)) {
|
|
versionOk = IsmGetOsVersionInfo (PLATFORM_SOURCE, &versionInfo);
|
|
rasLines = (PCTSTR) objectContent.MemoryContent.ContentBytes;
|
|
rasValue = pGetRasLineValue (rasLines, TEXT("BaseProtocol"));
|
|
if (rasValue && (StringIMatch (rasValue, TEXT("1")) || StringIMatch (rasValue, TEXT("2")))) {
|
|
IsmMakePersistentObject (Data->ObjectTypeId, Data->ObjectName);
|
|
|
|
// now it's a good time to force the migration of the script file
|
|
// if this connection has one
|
|
rasValue = NULL;
|
|
if (versionOk) {
|
|
if (versionInfo.OsType == OSTYPE_WINDOWSNT) {
|
|
if (versionInfo.OsMajorVersion == OSMAJOR_WINNT4) {
|
|
rasValue = pGetRasLineValue (rasLines, TEXT("Type"));
|
|
}
|
|
if (versionInfo.OsMajorVersion == OSMAJOR_WINNT5) {
|
|
rasValue = pGetRasLineValue (rasLines, TEXT("Name"));
|
|
}
|
|
}
|
|
if (versionInfo.OsType == OSTYPE_WINDOWS9X) {
|
|
rasValue = pGetRasLineValue (rasLines, TEXT("Name"));
|
|
}
|
|
}
|
|
if (rasValue && *rasValue) {
|
|
node = DuplicatePathString (rasValue, 0);
|
|
if (_tcsnextc (node) == TEXT('[')) {
|
|
nodePtr = _tcsinc (node);
|
|
} else {
|
|
nodePtr = node;
|
|
}
|
|
leafPtr = _tcsrchr (nodePtr, TEXT('\\'));
|
|
if (leafPtr) {
|
|
*leafPtr = 0;
|
|
leafPtr ++;
|
|
objectName = IsmCreateObjectHandle (nodePtr, leafPtr);
|
|
if (objectName) {
|
|
IsmMakePersistentObject (g_FileTypeId, objectName);
|
|
IsmDestroyObjectHandle (objectName);
|
|
}
|
|
}
|
|
FreePathString (node);
|
|
}
|
|
} else {
|
|
// this is an unsupported framing protocol
|
|
// we will log a message and abandon this connection
|
|
nativeName = IsmGetNativeObjectName (Data->ObjectTypeId, Data->ObjectName);
|
|
LOG ((LOG_WARNING, (PCSTR) MSG_RASMIG_UNSUPPORTEDSETTINGS, nativeName));
|
|
IsmReleaseMemory (nativeName);
|
|
}
|
|
IsmReleaseObject (&objectContent);
|
|
}
|
|
return CALLBACK_ENUM_CONTINUE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
RasMigVcmQueueEnumeration (
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
ENCODEDSTRHANDLE pattern;
|
|
|
|
g_PbkFileAttribute = IsmRegisterAttribute (S_PBKFILE_ATTRIBUTE, FALSE);
|
|
MYASSERT (g_PbkFileAttribute);
|
|
|
|
// hook all PBK files enumeration, we will not migrate the files but the connections within
|
|
pattern = IsmCreateSimpleObjectPattern (NULL, FALSE, TEXT("*.PBK"), TRUE);
|
|
|
|
IsmHookEnumeration (
|
|
g_FileTypeId,
|
|
pattern,
|
|
PbkFilesCallback,
|
|
(ULONG_PTR) 0,
|
|
TEXT("PbkFiles")
|
|
);
|
|
|
|
IsmDestroyObjectHandle (pattern);
|
|
|
|
pattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, TRUE);
|
|
IsmQueueEnumeration (
|
|
g_RasTypeId,
|
|
pattern,
|
|
VcmRasConnectionsCallback,
|
|
(ULONG_PTR) 0,
|
|
S_RAS_NAME
|
|
);
|
|
IsmDestroyObjectHandle (pattern);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
PbkRestoreCallback (
|
|
IN MIG_OBJECTTYPEID ObjectTypeId,
|
|
IN MIG_OBJECTID ObjectId,
|
|
IN MIG_OBJECTSTRINGHANDLE ObjectName
|
|
)
|
|
{
|
|
// if this is a PBK file we won't allow it to be restored like a file,
|
|
// we will add the proper connections ourselves.
|
|
return ((!IsmIsAttributeSetOnObjectId (ObjectId, g_PbkFileAttribute)) || g_AllowPbkRestore);
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
FilterRasAutoFilter (
|
|
IN PCMIG_FILTERINPUT InputData,
|
|
OUT PMIG_FILTEROUTPUT OutputData,
|
|
IN BOOL NoRestoreObject,
|
|
IN PCMIG_BLOB SourceOperationData, OPTIONAL
|
|
IN PCMIG_BLOB DestinationOperationData OPTIONAL
|
|
)
|
|
{
|
|
// This function will split the RAS connection, filter the PBK file
|
|
// so we know where it ends up, and rebuild the object name.
|
|
|
|
PCTSTR srcFile = NULL;
|
|
PTSTR srcFilePtr = NULL;
|
|
PCTSTR srcConn = NULL;
|
|
MIG_OBJECTSTRINGHANDLE pbkFile = NULL;
|
|
MIG_OBJECTSTRINGHANDLE newPbkFile = NULL;
|
|
BOOL orgDeleted = FALSE;
|
|
BOOL orgReplaced = FALSE;
|
|
PCTSTR newPbkNative = NULL;
|
|
|
|
//
|
|
// Filter the object name
|
|
//
|
|
|
|
IsmCreateObjectStringsFromHandle (
|
|
InputData->CurrentObject.ObjectName,
|
|
&srcFile,
|
|
&srcConn
|
|
);
|
|
|
|
if (srcFile && srcConn) {
|
|
srcFilePtr = _tcsrchr (srcFile, TEXT('\\'));
|
|
if (srcFilePtr) {
|
|
// we know that \ is not a dbcs character so this is safe
|
|
*srcFilePtr = 0;
|
|
srcFilePtr ++;
|
|
pbkFile = IsmCreateObjectHandle (srcFile, srcFilePtr);
|
|
if (pbkFile) {
|
|
g_AllowPbkRestore = TRUE;
|
|
newPbkFile = IsmFilterObject (
|
|
g_FileTypeId | PLATFORM_SOURCE,
|
|
pbkFile,
|
|
NULL,
|
|
&orgDeleted,
|
|
&orgReplaced
|
|
);
|
|
g_AllowPbkRestore = FALSE;
|
|
if (newPbkFile) {
|
|
newPbkNative = IsmGetNativeObjectName (g_FileTypeId | PLATFORM_SOURCE, newPbkFile);
|
|
if (newPbkNative) {
|
|
OutputData->NewObject.ObjectName = IsmCreateObjectHandle (newPbkNative, srcConn);
|
|
IsmReleaseMemory (newPbkNative);
|
|
newPbkNative = NULL;
|
|
}
|
|
IsmDestroyObjectHandle (newPbkFile);
|
|
newPbkFile = NULL;
|
|
}
|
|
IsmDestroyObjectHandle (pbkFile);
|
|
pbkFile = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
IsmDestroyObjectString (srcFile);
|
|
IsmDestroyObjectString (srcConn);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
RasMigOpmInitialize (
|
|
IN PMIG_LOGCALLBACK LogCallback,
|
|
IN PVOID Reserved
|
|
)
|
|
{
|
|
g_PbkFileAttribute = IsmRegisterAttribute (S_PBKFILE_ATTRIBUTE, FALSE);
|
|
MYASSERT (g_PbkFileAttribute);
|
|
|
|
IsmRegisterRestoreCallback (PbkRestoreCallback);
|
|
|
|
IsmRegisterGlobalFilterCallback (g_RasTypeId | PLATFORM_SOURCE, TEXT("AutoFilter"), FilterRasAutoFilter, TRUE, TRUE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
pEnumRasConnectionWorker (
|
|
OUT PMIG_TYPEOBJECTENUM EnumPtr,
|
|
IN PRAS_ENUM RasEnum
|
|
)
|
|
{
|
|
PCTSTR rasLines;
|
|
PCTSTR connName;
|
|
PCTSTR node, leaf;
|
|
|
|
if (EnumPtr->ObjectName) {
|
|
IsmDestroyObjectHandle (EnumPtr->ObjectName);
|
|
EnumPtr->ObjectName = NULL;
|
|
}
|
|
if (EnumPtr->NativeObjectName) {
|
|
IsmDestroyObjectHandle (EnumPtr->NativeObjectName);
|
|
EnumPtr->NativeObjectName = NULL;
|
|
}
|
|
if (EnumPtr->ObjectNode) {
|
|
IsmDestroyObjectString (EnumPtr->ObjectNode);
|
|
EnumPtr->ObjectNode = NULL;
|
|
}
|
|
if (EnumPtr->ObjectLeaf) {
|
|
IsmDestroyObjectString (EnumPtr->ObjectLeaf);
|
|
EnumPtr->ObjectLeaf = NULL;
|
|
}
|
|
do {
|
|
IsmCreateObjectStringsFromHandle (RasEnum->HashData.String, &node, &leaf);
|
|
if (RasEnum->HashData.ExtraData) {
|
|
rasLines = *((PCTSTR *) RasEnum->HashData.ExtraData);
|
|
connName = pGetRasLineValue (rasLines, TEXT("ConnectionName"));
|
|
EnumPtr->ObjectName = IsmCreateObjectHandle (node, connName?connName:leaf);
|
|
EnumPtr->NativeObjectName = IsmCreateObjectHandle (node, connName?connName:leaf);
|
|
} else {
|
|
EnumPtr->ObjectName = IsmCreateObjectHandle (node, leaf);
|
|
EnumPtr->NativeObjectName = IsmCreateObjectHandle (node, leaf);
|
|
}
|
|
if (!ObsPatternMatch (RasEnum->Pattern, EnumPtr->ObjectName)) {
|
|
if (!EnumNextHashTableString (&RasEnum->HashData)) {
|
|
AbortEnumRasConnection (EnumPtr);
|
|
return FALSE;
|
|
}
|
|
continue;
|
|
}
|
|
IsmCreateObjectStringsFromHandle (EnumPtr->ObjectName, &EnumPtr->ObjectNode, &EnumPtr->ObjectLeaf);
|
|
EnumPtr->Level = 1;
|
|
EnumPtr->SubLevel = 0;
|
|
EnumPtr->IsLeaf = TRUE;
|
|
EnumPtr->IsNode = FALSE;
|
|
EnumPtr->Details.DetailsSize = 0;
|
|
EnumPtr->Details.DetailsData = NULL;
|
|
return TRUE;
|
|
} while (TRUE);
|
|
}
|
|
|
|
BOOL
|
|
EnumFirstRasConnection (
|
|
IN OUT PMIG_TYPEOBJECTENUM EnumPtr, CALLER_INITIALIZED
|
|
IN MIG_OBJECTSTRINGHANDLE Pattern,
|
|
IN UINT MaxLevel
|
|
)
|
|
{
|
|
PRAS_ENUM rasEnum = NULL;
|
|
|
|
if (!g_RasTable) {
|
|
return FALSE;
|
|
}
|
|
rasEnum = (PRAS_ENUM) PmGetMemory (g_RasPool, sizeof (RAS_ENUM));
|
|
rasEnum->Pattern = PmDuplicateString (g_RasPool, Pattern);
|
|
EnumPtr->EtmHandle = (LONG_PTR) rasEnum;
|
|
|
|
if (EnumFirstHashTableString (&rasEnum->HashData, g_RasTable)) {
|
|
return pEnumRasConnectionWorker (EnumPtr, rasEnum);
|
|
} else {
|
|
AbortEnumRasConnection (EnumPtr);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
EnumNextRasConnection (
|
|
IN OUT PMIG_TYPEOBJECTENUM EnumPtr
|
|
)
|
|
{
|
|
PRAS_ENUM rasEnum = NULL;
|
|
|
|
rasEnum = (PRAS_ENUM)(EnumPtr->EtmHandle);
|
|
if (!rasEnum) {
|
|
return FALSE;
|
|
}
|
|
if (EnumNextHashTableString (&rasEnum->HashData)) {
|
|
return pEnumRasConnectionWorker (EnumPtr, rasEnum);
|
|
} else {
|
|
AbortEnumRasConnection (EnumPtr);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
AbortEnumRasConnection (
|
|
IN OUT PMIG_TYPEOBJECTENUM EnumPtr
|
|
)
|
|
{
|
|
PRAS_ENUM rasEnum = NULL;
|
|
|
|
if (EnumPtr->ObjectName) {
|
|
IsmDestroyObjectHandle (EnumPtr->ObjectName);
|
|
EnumPtr->ObjectName = NULL;
|
|
}
|
|
if (EnumPtr->NativeObjectName) {
|
|
IsmDestroyObjectHandle (EnumPtr->NativeObjectName);
|
|
EnumPtr->NativeObjectName = NULL;
|
|
}
|
|
if (EnumPtr->ObjectNode) {
|
|
IsmDestroyObjectString (EnumPtr->ObjectNode);
|
|
EnumPtr->ObjectNode = NULL;
|
|
}
|
|
if (EnumPtr->ObjectLeaf) {
|
|
IsmDestroyObjectString (EnumPtr->ObjectLeaf);
|
|
EnumPtr->ObjectLeaf = NULL;
|
|
}
|
|
rasEnum = (PRAS_ENUM)(EnumPtr->EtmHandle);
|
|
if (!rasEnum) {
|
|
return;
|
|
}
|
|
PmReleaseMemory (g_RasPool, rasEnum->Pattern);
|
|
PmReleaseMemory (g_RasPool, rasEnum);
|
|
ZeroMemory (EnumPtr, sizeof (MIG_TYPEOBJECTENUM));
|
|
}
|
|
|
|
BOOL
|
|
AcquireRasConnection (
|
|
IN MIG_OBJECTSTRINGHANDLE ObjectName,
|
|
OUT PMIG_CONTENT ObjectContent, CALLER_INITIALIZED
|
|
IN MIG_CONTENTTYPE ContentType,
|
|
IN UINT MemoryContentLimit
|
|
)
|
|
{
|
|
PTSTR rasLines;
|
|
BOOL result = FALSE;
|
|
|
|
if (!ObjectContent) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (ContentType == CONTENTTYPE_FILE) {
|
|
// nobody should request this as a file
|
|
MYASSERT (FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
if (HtFindStringEx (g_RasTable, ObjectName, &rasLines, FALSE)) {
|
|
|
|
ObjectContent->MemoryContent.ContentBytes = (PCBYTE) rasLines;
|
|
ObjectContent->MemoryContent.ContentSize = SizeOfMultiSz (rasLines);
|
|
|
|
result = TRUE;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
BOOL
|
|
ReleaseRasConnection (
|
|
IN OUT PMIG_CONTENT ObjectContent
|
|
)
|
|
{
|
|
ZeroMemory (ObjectContent, sizeof (MIG_CONTENT));
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
DoesRasConnectionExist (
|
|
IN MIG_OBJECTSTRINGHANDLE ObjectName
|
|
)
|
|
{
|
|
PCTSTR node = NULL;
|
|
PCTSTR leaf = NULL;
|
|
HASHTABLE rasTable;
|
|
BOOL result = FALSE;
|
|
|
|
if (ObjectName) {
|
|
|
|
if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
|
|
|
|
rasTable = HtAllocWithData (sizeof (PCTSTR));
|
|
|
|
if (rasTable) {
|
|
|
|
if (pLoadRasConnections (node, rasTable)) {
|
|
|
|
result = (HtFindStringEx (rasTable, ObjectName, NULL, FALSE) != NULL);
|
|
}
|
|
|
|
HtFree (rasTable);
|
|
}
|
|
|
|
IsmDestroyObjectString (node);
|
|
IsmDestroyObjectString (leaf);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
BOOL
|
|
RemoveRasConnection (
|
|
IN MIG_OBJECTSTRINGHANDLE ObjectName
|
|
)
|
|
{
|
|
PCTSTR node, leaf;
|
|
DWORD err = 0;
|
|
BOOL result = FALSE;
|
|
|
|
if (g_RasDeleteEntry) {
|
|
if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
|
|
MYASSERT (node);
|
|
MYASSERT (leaf);
|
|
if (node && leaf) {
|
|
err = g_RasDeleteEntry (node, leaf);
|
|
if (err == ERROR_SUCCESS) {
|
|
result = TRUE;
|
|
}
|
|
}
|
|
IsmDestroyObjectString (node);
|
|
IsmDestroyObjectString (leaf);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetNewFileLocation (
|
|
IN PCTSTR SrcFile
|
|
)
|
|
{
|
|
PTSTR node, nodePtr, leaf;
|
|
MIG_OBJECTSTRINGHANDLE objectName;
|
|
MIG_OBJECTSTRINGHANDLE newObjectName;
|
|
BOOL deleted;
|
|
BOOL replaced;
|
|
PCTSTR result = NULL;
|
|
|
|
node = PmDuplicateString (g_RasPool, SrcFile);
|
|
if (*node) {
|
|
if (_tcsnextc (node) == TEXT('[')) {
|
|
nodePtr = _tcsinc (node);
|
|
} else {
|
|
nodePtr = node;
|
|
}
|
|
leaf = _tcsrchr (nodePtr, TEXT('\\'));
|
|
if (leaf) {
|
|
*leaf = 0;
|
|
leaf++;
|
|
objectName = IsmCreateObjectHandle (nodePtr, leaf);
|
|
PmReleaseMemory (g_RasPool, node);
|
|
newObjectName = IsmFilterObject (
|
|
g_FileTypeId | PLATFORM_SOURCE,
|
|
objectName,
|
|
NULL,
|
|
&deleted,
|
|
&replaced
|
|
);
|
|
if (!deleted || replaced) {
|
|
if (!newObjectName) {
|
|
newObjectName = objectName;
|
|
}
|
|
if (IsmCreateObjectStringsFromHandle (newObjectName, &node, &leaf)) {
|
|
result = JoinPaths (node, leaf);
|
|
}
|
|
}
|
|
if (newObjectName && (newObjectName != objectName)) {
|
|
IsmDestroyObjectHandle (newObjectName);
|
|
}
|
|
IsmDestroyObjectHandle (objectName);
|
|
} else {
|
|
PmReleaseMemory (g_RasPool, node);
|
|
}
|
|
} else {
|
|
PmReleaseMemory (g_RasPool, node);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
BOOL
|
|
pTrackedCreateDirectory (
|
|
IN PCTSTR DirName
|
|
)
|
|
{
|
|
MIG_OBJECTSTRINGHANDLE objectName;
|
|
PTSTR pathCopy;
|
|
PTSTR p;
|
|
BOOL result = TRUE;
|
|
|
|
pathCopy = DuplicatePathString (DirName, 0);
|
|
|
|
//
|
|
// Advance past first directory
|
|
//
|
|
|
|
if (pathCopy[1] == TEXT(':') && pathCopy[2] == TEXT('\\')) {
|
|
//
|
|
// <drive>:\ case
|
|
//
|
|
|
|
p = _tcschr (&pathCopy[3], TEXT('\\'));
|
|
|
|
} else if (pathCopy[0] == TEXT('\\') && pathCopy[1] == TEXT('\\')) {
|
|
|
|
//
|
|
// UNC case
|
|
//
|
|
|
|
p = _tcschr (pathCopy + 2, TEXT('\\'));
|
|
if (p) {
|
|
p = _tcschr (p + 1, TEXT('\\'));
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// Relative dir case
|
|
//
|
|
|
|
p = _tcschr (pathCopy, TEXT('\\'));
|
|
}
|
|
|
|
//
|
|
// Make all directories along the path
|
|
//
|
|
|
|
while (p) {
|
|
|
|
*p = 0;
|
|
|
|
if (!DoesFileExist (pathCopy)) {
|
|
|
|
// record directory creation
|
|
objectName = IsmCreateObjectHandle (pathCopy, NULL);
|
|
IsmRecordOperation (
|
|
JRNOP_CREATE,
|
|
g_FileTypeId,
|
|
objectName
|
|
);
|
|
IsmDestroyObjectHandle (objectName);
|
|
|
|
result = CreateDirectory (pathCopy, NULL);
|
|
if (!result) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
*p = TEXT('\\');
|
|
p = _tcschr (p + 1, TEXT('\\'));
|
|
}
|
|
|
|
FreePathString (pathCopy);
|
|
|
|
return result;
|
|
}
|
|
|
|
BOOL
|
|
CreateRasConnection (
|
|
IN MIG_OBJECTSTRINGHANDLE ObjectName,
|
|
IN PMIG_CONTENT ObjectContent
|
|
)
|
|
{
|
|
PCTSTR rasLines;
|
|
MULTISZ_ENUM multiSzEnum;
|
|
PCTSTR pbkFileName = NULL;
|
|
PCTSTR connName = NULL;
|
|
HANDLE pbkFileHandle = NULL;
|
|
BOOL first = TRUE;
|
|
MIG_OSVERSIONINFO versionInfo;
|
|
BOOL versionOk = FALSE;
|
|
BOOL fileField = FALSE;
|
|
PCTSTR destFileName;
|
|
RASCREDENTIALS rasCredentials;
|
|
BOOL lastVNEmpty = FALSE;
|
|
BOOL result = FALSE;
|
|
WORD oldCodePage;
|
|
PCTSTR newUserProfile = NULL;
|
|
DWORD credResult;
|
|
|
|
__try {
|
|
|
|
if (ObjectContent->ContentInFile) {
|
|
__leave;
|
|
}
|
|
|
|
if (!ObjectContent->MemoryContent.ContentBytes) {
|
|
__leave;
|
|
}
|
|
|
|
if (!IsmCreateObjectStringsFromHandle (ObjectName, &pbkFileName, &connName)) {
|
|
__leave;
|
|
}
|
|
|
|
MYASSERT (pbkFileName);
|
|
if (!pbkFileName) {
|
|
__leave;
|
|
}
|
|
|
|
MYASSERT (connName);
|
|
if (!connName) {
|
|
__leave;
|
|
}
|
|
|
|
if (g_DelayRasOp) {
|
|
|
|
// we know that we created a new user (we are in cmd line mode).
|
|
// Let's try to see if this connection belongs to that user.
|
|
// If it does, we are going to delay the creation because
|
|
// we set credentials for the connection, and they need to be
|
|
// set in that user's context.
|
|
// If not, it means that this is a common connection so we are
|
|
// just going to go ahead and add it.
|
|
|
|
newUserProfile = IsmExpandEnvironmentString (PLATFORM_DESTINATION, S_SYSENVVAR_GROUP, TEXT ("%userprofile%"), NULL);
|
|
if (newUserProfile) {
|
|
if (StringIPrefix (pbkFileName, newUserProfile)) {
|
|
// we need to delay this operation
|
|
// record delayed printer replace operation
|
|
IsmRecordDelayedOperation (
|
|
JRNOP_CREATE,
|
|
g_RasTypeId,
|
|
ObjectName,
|
|
ObjectContent
|
|
);
|
|
result = TRUE;
|
|
__leave;
|
|
}
|
|
IsmReleaseMemory (newUserProfile);
|
|
newUserProfile = NULL;
|
|
}
|
|
}
|
|
|
|
ZeroMemory (&rasCredentials, sizeof (RASCREDENTIALS));
|
|
rasCredentials.dwSize = sizeof (RASCREDENTIALS);
|
|
|
|
rasLines = (PCTSTR) ObjectContent->MemoryContent.ContentBytes;
|
|
|
|
// record RAS entry creation
|
|
IsmRecordOperation (
|
|
JRNOP_CREATE,
|
|
g_RasTypeId,
|
|
ObjectName
|
|
);
|
|
|
|
if (EnumFirstMultiSz (&multiSzEnum, rasLines)) {
|
|
// get the first 8 fields as being part of rasCredentials structure
|
|
|
|
MYASSERT (StringIMatch (multiSzEnum.CurrentString, TEXT("ConnectionName")));
|
|
|
|
if (!EnumNextMultiSz (&multiSzEnum)) {
|
|
__leave;
|
|
}
|
|
// we are just skipping the connection name
|
|
|
|
if (!EnumNextMultiSz (&multiSzEnum)) {
|
|
__leave;
|
|
}
|
|
MYASSERT (StringIMatch (multiSzEnum.CurrentString, TEXT("CredMask")));
|
|
|
|
if (!EnumNextMultiSz (&multiSzEnum)) {
|
|
__leave;
|
|
}
|
|
if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
|
|
_stscanf (multiSzEnum.CurrentString, TEXT("%lx"), &(rasCredentials.dwMask));
|
|
}
|
|
|
|
if (!EnumNextMultiSz (&multiSzEnum)) {
|
|
__leave;
|
|
}
|
|
MYASSERT (StringIMatch (multiSzEnum.CurrentString, TEXT("CredName")));
|
|
|
|
if (!EnumNextMultiSz (&multiSzEnum)) {
|
|
__leave;
|
|
}
|
|
if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
|
|
StringCopyTcharCount (rasCredentials.szUserName, multiSzEnum.CurrentString, UNLEN + 1);
|
|
}
|
|
|
|
if (!EnumNextMultiSz (&multiSzEnum)) {
|
|
__leave;
|
|
}
|
|
MYASSERT (StringIMatch (multiSzEnum.CurrentString, TEXT("CredDomain")));
|
|
|
|
if (!EnumNextMultiSz (&multiSzEnum)) {
|
|
__leave;
|
|
}
|
|
if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
|
|
StringCopyTcharCount (rasCredentials.szDomain, multiSzEnum.CurrentString, DNLEN + 1);
|
|
}
|
|
|
|
if (!EnumNextMultiSz (&multiSzEnum)) {
|
|
__leave;
|
|
}
|
|
MYASSERT (StringIMatch (multiSzEnum.CurrentString, TEXT("CredPassword")));
|
|
|
|
if (!EnumNextMultiSz (&multiSzEnum)) {
|
|
__leave;
|
|
}
|
|
if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
|
|
StringCopyTcharCount (rasCredentials.szPassword, multiSzEnum.CurrentString, PWLEN + 1);
|
|
}
|
|
|
|
if (!EnumNextMultiSz (&multiSzEnum)) {
|
|
__leave;
|
|
}
|
|
|
|
pbkFileHandle = BfOpenFile (pbkFileName);
|
|
if (!pbkFileHandle) {
|
|
pTrackedCreateDirectory (pbkFileName);
|
|
pbkFileHandle = BfCreateFile (pbkFileName);
|
|
}
|
|
if (!pbkFileHandle) {
|
|
__leave;
|
|
}
|
|
BfGoToEndOfFile (pbkFileHandle, NULL);
|
|
WriteFileString (pbkFileHandle, TEXT("\r\n["));
|
|
// make sure that the conversion is using UTF8
|
|
oldCodePage = SetConversionCodePage (CP_UTF8);
|
|
WriteFileString (pbkFileHandle, connName);
|
|
SetConversionCodePage (oldCodePage);
|
|
WriteFileString (pbkFileHandle, TEXT("]\r\n"));
|
|
first = TRUE;
|
|
versionOk = IsmGetOsVersionInfo (PLATFORM_SOURCE, &versionInfo);
|
|
do {
|
|
if (first) {
|
|
if (StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
|
|
lastVNEmpty = TRUE;
|
|
} else {
|
|
lastVNEmpty = FALSE;
|
|
if (versionOk) {
|
|
if (versionInfo.OsType == OSTYPE_WINDOWSNT) {
|
|
if (versionInfo.OsMajorVersion == OSMAJOR_WINNT4) {
|
|
fileField = StringIMatch (multiSzEnum.CurrentString, TEXT("Type"));
|
|
}
|
|
if (versionInfo.OsMajorVersion == OSMAJOR_WINNT5) {
|
|
fileField = StringIMatch (multiSzEnum.CurrentString, TEXT("Name"));
|
|
}
|
|
}
|
|
if (versionInfo.OsType == OSTYPE_WINDOWS9X) {
|
|
fileField = StringIMatch (multiSzEnum.CurrentString, TEXT("Name"));
|
|
}
|
|
}
|
|
fileField = fileField || StringIMatch (multiSzEnum.CurrentString, TEXT("CustomDialDll"));
|
|
fileField = fileField || StringIMatch (multiSzEnum.CurrentString, TEXT("CustomRasDialDll"));
|
|
fileField = fileField || StringIMatch (multiSzEnum.CurrentString, TEXT("PrerequisitePbk"));
|
|
WriteFileString (pbkFileHandle, multiSzEnum.CurrentString);
|
|
}
|
|
} else {
|
|
if (StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
|
|
if (!lastVNEmpty) {
|
|
WriteFileString (pbkFileHandle, TEXT("="));
|
|
}
|
|
WriteFileString (pbkFileHandle, TEXT("\r\n"));
|
|
} else {
|
|
WriteFileString (pbkFileHandle, TEXT("="));
|
|
if (fileField) {
|
|
destFileName = pGetNewFileLocation (multiSzEnum.CurrentString);
|
|
} else {
|
|
destFileName = NULL;
|
|
}
|
|
if (destFileName) {
|
|
// make sure that the conversion is using UTF8
|
|
oldCodePage = SetConversionCodePage (CP_UTF8);
|
|
WriteFileString (pbkFileHandle, destFileName);
|
|
SetConversionCodePage (oldCodePage);
|
|
FreePathString (destFileName);
|
|
destFileName = NULL;
|
|
} else {
|
|
// make sure that the conversion is using UTF8
|
|
oldCodePage = SetConversionCodePage (CP_UTF8);
|
|
WriteFileString (pbkFileHandle, multiSzEnum.CurrentString);
|
|
oldCodePage = SetConversionCodePage (oldCodePage);
|
|
}
|
|
WriteFileString (pbkFileHandle, TEXT("\r\n"));
|
|
}
|
|
fileField = FALSE;
|
|
}
|
|
first = !first;
|
|
} while (EnumNextMultiSz (&multiSzEnum));
|
|
WriteFileString (pbkFileHandle, TEXT("\r\n"));
|
|
|
|
result = TRUE;
|
|
}
|
|
if (pbkFileHandle) {
|
|
CloseHandle (pbkFileHandle);
|
|
pbkFileHandle = NULL;
|
|
}
|
|
if (result) {
|
|
if (g_RasSetCredentials && rasCredentials.dwMask) {
|
|
credResult = g_RasSetCredentials (pbkFileName, connName, &rasCredentials, FALSE);
|
|
}
|
|
}
|
|
}
|
|
__finally {
|
|
|
|
IsmDestroyObjectString (pbkFileName);
|
|
IsmDestroyObjectString (connName);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
PCTSTR
|
|
ConvertRasConnectionToMultiSz (
|
|
IN MIG_OBJECTSTRINGHANDLE ObjectName,
|
|
IN PMIG_CONTENT ObjectContent
|
|
)
|
|
{
|
|
PCTSTR node, leaf;
|
|
PTSTR result = NULL;
|
|
BOOL bresult = TRUE;
|
|
PCTSTR rasLines;
|
|
MULTISZ_ENUM multiSzEnum;
|
|
|
|
if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
|
|
|
|
MYASSERT (leaf);
|
|
|
|
g_RasConversionBuff.End = 0;
|
|
|
|
if (node) {
|
|
GbCopyQuotedString (&g_RasConversionBuff, node);
|
|
} else {
|
|
GbCopyQuotedString (&g_RasConversionBuff, TEXT(""));
|
|
}
|
|
|
|
GbCopyQuotedString (&g_RasConversionBuff, leaf);
|
|
|
|
MYASSERT (ObjectContent->Details.DetailsSize == 0);
|
|
MYASSERT (!ObjectContent->ContentInFile);
|
|
|
|
if ((!ObjectContent->ContentInFile) &&
|
|
(ObjectContent->MemoryContent.ContentSize) &&
|
|
(ObjectContent->MemoryContent.ContentBytes)
|
|
) {
|
|
rasLines = (PCTSTR)ObjectContent->MemoryContent.ContentBytes;
|
|
if (EnumFirstMultiSz (&multiSzEnum, rasLines)) {
|
|
do {
|
|
if (StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
|
|
GbCopyQuotedString (&g_RasConversionBuff, TEXT(""));
|
|
} else {
|
|
GbCopyQuotedString (&g_RasConversionBuff, multiSzEnum.CurrentString);
|
|
}
|
|
} while (EnumNextMultiSz (&multiSzEnum));
|
|
}
|
|
} else {
|
|
bresult = FALSE;
|
|
}
|
|
|
|
if (bresult) {
|
|
GbCopyString (&g_RasConversionBuff, TEXT(""));
|
|
result = IsmGetMemory (g_RasConversionBuff.End);
|
|
CopyMemory (result, g_RasConversionBuff.Buf, g_RasConversionBuff.End);
|
|
}
|
|
|
|
g_RasConversionBuff.End = 0;
|
|
|
|
IsmDestroyObjectString (node);
|
|
IsmDestroyObjectString (leaf);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
BOOL
|
|
ConvertMultiSzToRasConnection (
|
|
IN PCTSTR ObjectMultiSz,
|
|
OUT MIG_OBJECTSTRINGHANDLE *ObjectName,
|
|
OUT PMIG_CONTENT ObjectContent OPTIONAL
|
|
)
|
|
{
|
|
MULTISZ_ENUM multiSzEnum;
|
|
PCTSTR node = NULL;
|
|
PCTSTR leaf = NULL;
|
|
UINT index;
|
|
|
|
g_RasConversionBuff.End = 0;
|
|
|
|
if (ObjectContent) {
|
|
ZeroMemory (ObjectContent, sizeof (MIG_CONTENT));
|
|
}
|
|
|
|
if (EnumFirstMultiSz (&multiSzEnum, ObjectMultiSz)) {
|
|
index = 0;
|
|
do {
|
|
if (index == 0) {
|
|
if (!StringIMatch (multiSzEnum.CurrentString, TEXT("<empty>"))) {
|
|
node = multiSzEnum.CurrentString;
|
|
}
|
|
}
|
|
if (index == 1) {
|
|
leaf = multiSzEnum.CurrentString;
|
|
}
|
|
if (index > 1) {
|
|
if (*multiSzEnum.CurrentString) {
|
|
GbMultiSzAppend (&g_RasConversionBuff, multiSzEnum.CurrentString);
|
|
} else {
|
|
GbMultiSzAppend (&g_RasConversionBuff, TEXT("<empty>"));
|
|
}
|
|
}
|
|
index ++;
|
|
} while (EnumNextMultiSz (&multiSzEnum));
|
|
}
|
|
GbMultiSzAppend (&g_RasConversionBuff, TEXT(""));
|
|
|
|
if (!leaf) {
|
|
GbFree (&g_RasConversionBuff);
|
|
return FALSE;
|
|
}
|
|
|
|
if (ObjectContent) {
|
|
|
|
if (g_RasConversionBuff.End) {
|
|
ObjectContent->MemoryContent.ContentSize = g_RasConversionBuff.End;
|
|
ObjectContent->MemoryContent.ContentBytes = IsmGetMemory (ObjectContent->MemoryContent.ContentSize);
|
|
CopyMemory (
|
|
(PBYTE)ObjectContent->MemoryContent.ContentBytes,
|
|
g_RasConversionBuff.Buf,
|
|
ObjectContent->MemoryContent.ContentSize
|
|
);
|
|
} else {
|
|
ObjectContent->MemoryContent.ContentSize = 0;
|
|
ObjectContent->MemoryContent.ContentBytes = NULL;
|
|
}
|
|
ObjectContent->Details.DetailsSize = 0;
|
|
ObjectContent->Details.DetailsData = NULL;
|
|
}
|
|
*ObjectName = IsmCreateObjectHandle (node, leaf);
|
|
|
|
GbFree (&g_RasConversionBuff);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
PCTSTR
|
|
GetNativeRasConnectionName (
|
|
IN MIG_OBJECTSTRINGHANDLE ObjectName
|
|
)
|
|
{
|
|
PCTSTR node = NULL, leaf = NULL;
|
|
UINT size;
|
|
PTSTR result = NULL;
|
|
|
|
if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
|
|
if (leaf) {
|
|
size = SizeOfString (leaf);
|
|
if (size) {
|
|
result = IsmGetMemory (size);
|
|
CopyMemory (result, leaf, size);
|
|
}
|
|
}
|
|
IsmDestroyObjectString (node);
|
|
IsmDestroyObjectString (leaf);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
PMIG_CONTENT
|
|
ConvertRasConnectionContentToUnicode (
|
|
IN MIG_OBJECTSTRINGHANDLE ObjectName,
|
|
IN PMIG_CONTENT ObjectContent
|
|
)
|
|
{
|
|
PMIG_CONTENT result = NULL;
|
|
|
|
if (!ObjectContent) {
|
|
return result;
|
|
}
|
|
|
|
if (ObjectContent->ContentInFile) {
|
|
return result;
|
|
}
|
|
|
|
result = IsmGetMemory (sizeof (MIG_CONTENT));
|
|
|
|
if (result) {
|
|
|
|
CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
|
|
|
|
if ((ObjectContent->MemoryContent.ContentSize != 0) &&
|
|
(ObjectContent->MemoryContent.ContentBytes != NULL)
|
|
) {
|
|
// convert Ras Connection content
|
|
result->MemoryContent.ContentBytes = IsmGetMemory (ObjectContent->MemoryContent.ContentSize * 2);
|
|
if (result->MemoryContent.ContentBytes) {
|
|
DirectDbcsToUnicodeN (
|
|
(PWSTR)result->MemoryContent.ContentBytes,
|
|
(PSTR)ObjectContent->MemoryContent.ContentBytes,
|
|
ObjectContent->MemoryContent.ContentSize
|
|
);
|
|
result->MemoryContent.ContentSize = SizeOfMultiSzW ((PWSTR)result->MemoryContent.ContentBytes);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
PMIG_CONTENT
|
|
ConvertRasConnectionContentToAnsi (
|
|
IN MIG_OBJECTSTRINGHANDLE ObjectName,
|
|
IN PMIG_CONTENT ObjectContent
|
|
)
|
|
{
|
|
PMIG_CONTENT result = NULL;
|
|
|
|
if (!ObjectContent) {
|
|
return result;
|
|
}
|
|
|
|
if (ObjectContent->ContentInFile) {
|
|
return result;
|
|
}
|
|
|
|
result = IsmGetMemory (sizeof (MIG_CONTENT));
|
|
|
|
if (result) {
|
|
|
|
CopyMemory (result, ObjectContent, sizeof (MIG_CONTENT));
|
|
|
|
if ((ObjectContent->MemoryContent.ContentSize != 0) &&
|
|
(ObjectContent->MemoryContent.ContentBytes != NULL)
|
|
) {
|
|
// convert Ras Connection content
|
|
result->MemoryContent.ContentBytes = IsmGetMemory (ObjectContent->MemoryContent.ContentSize);
|
|
if (result->MemoryContent.ContentBytes) {
|
|
DirectUnicodeToDbcsN (
|
|
(PSTR)result->MemoryContent.ContentBytes,
|
|
(PWSTR)ObjectContent->MemoryContent.ContentBytes,
|
|
ObjectContent->MemoryContent.ContentSize
|
|
);
|
|
result->MemoryContent.ContentSize = SizeOfMultiSzA ((PSTR)result->MemoryContent.ContentBytes);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
BOOL
|
|
FreeConvertedRasConnectionContent (
|
|
IN PMIG_CONTENT ObjectContent
|
|
)
|
|
{
|
|
if (!ObjectContent) {
|
|
return TRUE;
|
|
}
|
|
|
|
if (ObjectContent->MemoryContent.ContentBytes) {
|
|
IsmReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
|
|
}
|
|
|
|
IsmReleaseMemory (ObjectContent);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// Win9x specific code. Converts registry format into a PBK file
|
|
//
|
|
|
|
//
|
|
// AddrEntry serves as a header for the entire block of data in the <entry>
|
|
// blob. entries in it are offsets to the strings which follow it..in many cases
|
|
// (i.e. all of the *Off* members...)
|
|
//
|
|
typedef struct _AddrEntry {
|
|
DWORD dwVersion;
|
|
DWORD dwCountryCode;
|
|
UINT uOffArea;
|
|
UINT uOffPhone;
|
|
DWORD dwCountryID;
|
|
UINT uOffSMMCfg;
|
|
UINT uOffSMM;
|
|
UINT uOffDI;
|
|
} ADDRENTRY, *PADDRENTRY;
|
|
|
|
typedef struct {
|
|
DWORD Size;
|
|
DWORD Unknown1;
|
|
DWORD ModemUiOptions; // num seconds in high byte.
|
|
DWORD Unknown2;
|
|
DWORD Unknown3;
|
|
DWORD Unknown4;
|
|
DWORD ConnectionSpeed;
|
|
DWORD UnknownFlowControlData; //Somehow related to flow control.
|
|
DWORD Unknown5;
|
|
DWORD Unknown6;
|
|
DWORD Unknown7;
|
|
DWORD Unknown8;
|
|
DWORD Unknown9;
|
|
DWORD Unknown10;
|
|
DWORD Unknown11;
|
|
DWORD Unknown12;
|
|
DWORD Unknown13;
|
|
DWORD Unknown14;
|
|
DWORD Unknown15;
|
|
DWORD CancelSeconds; //Num seconds to wait before cancel if not connected. (0xFF equals off.)
|
|
DWORD IdleDisconnectSeconds; // 0 = Not Set.
|
|
DWORD Unknown16;
|
|
DWORD SpeakerVolume; // 0|1
|
|
DWORD ConfigOptions;
|
|
DWORD Unknown17;
|
|
DWORD Unknown18;
|
|
DWORD Unknown19;
|
|
} MODEMDEVINFO, *PMODEMDEVINFO;
|
|
|
|
typedef struct _SubConnEntry {
|
|
DWORD dwSize;
|
|
DWORD dwFlags;
|
|
CHAR szDeviceType[RAS_MaxDeviceType+1];
|
|
CHAR szDeviceName[RAS_MaxDeviceName+1];
|
|
CHAR szLocal[RAS_MaxPhoneNumber+1];
|
|
} SUBCONNENTRY, *PSUBCONNENTRY;
|
|
|
|
typedef struct _SMMCFG {
|
|
DWORD dwSize;
|
|
DWORD fdwOptions;
|
|
DWORD fdwProtocols;
|
|
} SMMCFG, *PSMMCFG;
|
|
|
|
typedef struct _DEVICEINFO {
|
|
DWORD dwVersion;
|
|
UINT uSize;
|
|
CHAR szDeviceName[RAS_MaxDeviceName+1];
|
|
CHAR szDeviceType[RAS_MaxDeviceType+1];
|
|
} DEVICEINFO, *PDEVICEINFO;
|
|
|
|
typedef struct _IPData {
|
|
DWORD dwSize;
|
|
DWORD fdwTCPIP;
|
|
DWORD dwIPAddr;
|
|
DWORD dwDNSAddr;
|
|
DWORD dwDNSAddrAlt;
|
|
DWORD dwWINSAddr;
|
|
DWORD dwWINSAddrAlt;
|
|
} IPDATA, *PIPDATA;
|
|
|
|
typedef struct {
|
|
PCTSTR String;
|
|
UINT Value;
|
|
WORD DataType;
|
|
} MEMDB_RAS_DATA, *PMEMDB_RAS_DATA;
|
|
|
|
#define PAESMMCFG(pAE) ((PSMMCFG)(((PBYTE)pAE)+(pAE->uOffSMMCfg)))
|
|
#define PAESMM(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffSMM)))
|
|
#define PAEDI(pAE) ((PDEVICEINFO)(((PBYTE)pAE)+(pAE->uOffDI )))
|
|
#define PAEAREA(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffArea)))
|
|
#define PAEPHONE(pAE) ((PSTR)(((PBYTE)pAE)+(pAE->uOffPhone)))
|
|
#define DECRYPTENTRY(x, y, z) EnDecryptEntry(x, (LPBYTE)y, z)
|
|
|
|
#define S_REMOTE_ACCESS_KEY TEXT("HKCU\\RemoteAccess")
|
|
#define S_DIALUI TEXT("DialUI")
|
|
#define S_ENABLE_REDIAL TEXT("EnableRedial")
|
|
#define S_REDIAL_TRY TEXT("RedialTry")
|
|
#define S_REDIAL_WAIT TEXT("RedialWait")
|
|
#define S_ENABLE_IMPLICIT TEXT("EnableImplicit")
|
|
#define S_PHONE_NUMBER TEXT("Phone Number")
|
|
#define S_AREA_CODE TEXT("Area Code")
|
|
#define S_SMM TEXT("SMM")
|
|
#define S_COUNTRY_CODE TEXT("Country Code")
|
|
#define S_COUNTRY_ID TEXT("Country Id")
|
|
#define S_DEVICE_NAME TEXT("Device Name")
|
|
#define S_DEVICE_TYPE TEXT("Device Type")
|
|
#define S_PROTOCOLS TEXT("Protocols")
|
|
#define S_SMM_OPTIONS TEXT("SMM Options")
|
|
#define S_IPINFO TEXT("IP")
|
|
#define S_IP_FTCPIP TEXT("_IP_FTCPIP")
|
|
#define S_IP_IPADDR TEXT("IpAddress")
|
|
#define S_IP_DNSADDR TEXT("IpDnsAddress")
|
|
#define S_IP_DNSADDR2 TEXT("IpDns2Address")
|
|
#define S_IP_WINSADDR TEXT("IpWinsAddress")
|
|
#define S_IP_WINSADDR2 TEXT("IpWins2Address")
|
|
#define S_DOMAIN TEXT("Domain")
|
|
#define S_USER TEXT("User")
|
|
|
|
#define S_MODEMS TEXT("HKLM\\System\\CurrentControlSet\\Services\\Class\\Modem")
|
|
#define S_ATTACHEDTO TEXT("AttachedTo")
|
|
#define S_DRIVERDESC TEXT("DriverDesc")
|
|
#define S_TERMINAL TEXT("Terminal")
|
|
#define S_MODE TEXT("Mode")
|
|
#define S_MULTILINK TEXT("MultiLink")
|
|
|
|
#define S_MODEM TEXT("Modem")
|
|
#define S_MODEMA "Modem"
|
|
#define S_MODEM_UI_OPTIONS TEXT("__UiOptions")
|
|
#define S_MODEM_SPEED TEXT("__Speed")
|
|
#define S_MODEM_SPEAKER_VOLUME TEXT("__SpeakerVolume")
|
|
#define S_MODEM_IDLE_DISCONNECT_SECONDS TEXT("__IdleDisconnect")
|
|
#define S_MODEM_CANCEL_SECONDS TEXT("__CancelSeconds")
|
|
#define S_MODEM_CFG_OPTIONS TEXT("__CfgOptions")
|
|
#define S_MODEM_COM_PORT TEXT("ComPort")
|
|
#define S_DEVICECOUNT TEXT("__DeviceCount")
|
|
|
|
#define S_PPP TEXT("PPP")
|
|
#define S_PPPA "PPP"
|
|
#define S_SLIP TEXT("Slip")
|
|
#define S_SLIPA "Slip"
|
|
#define S_CSLIP TEXT("CSlip")
|
|
#define S_CSLIPA "CSlip"
|
|
|
|
#define S_SERVICEREMOTEACCESS TEXT("HKLM\\System\\CurrentControlSet\\Services\\RemoteAccess")
|
|
#define S_REMOTE_ACCESS_KEY TEXT("HKCU\\RemoteAccess")
|
|
#define S_PROFILE_KEY TEXT("HKCU\\RemoteAccess\\Profile")
|
|
#define S_ADDRESSES_KEY TEXT("HKCU\\RemoteAccess\\Addresses")
|
|
#define S_SUBENTRIES TEXT("SubEntries")
|
|
|
|
#define S_EMPTY TEXT("")
|
|
|
|
#define S_PPPSCRIPT TEXT("PPPSCRIPT")
|
|
|
|
#define MEMDB_CATEGORY_RAS_INFO TEXT("RAS Info")
|
|
#define MEMDB_CATEGORY_RAS_USER TEXT("RAS User")
|
|
#define MEMDB_CATEGORY_RAS_DATA TEXT("Ras Data")
|
|
#define MEMDB_FIELD_USER_SETTINGS TEXT("User Settings")
|
|
|
|
#define RASTYPE_PHONE 1
|
|
#define RASTYPE_VPN 2
|
|
|
|
#define S_VPN TEXT("VPN")
|
|
#define S_ZERO TEXT("0")
|
|
#define S_ONE TEXT("1")
|
|
|
|
#define SMMCFG_SW_COMPRESSION 0x00000001 // Software compression is on
|
|
#define SMMCFG_PW_ENCRYPTED 0x00000002 // Encrypted password only
|
|
#define SMMCFG_NW_LOGON 0x00000004 // Logon to the network
|
|
|
|
// Negotiated protocols
|
|
//
|
|
#define SMMPROT_NB 0x00000001 // NetBEUI
|
|
#define SMMPROT_IPX 0x00000002 // IPX
|
|
#define SMMPROT_IP 0x00000004 // TCP/IP
|
|
|
|
#define IPF_IP_SPECIFIED 0x00000001
|
|
#define IPF_NAME_SPECIFIED 0x00000002
|
|
#define IPF_NO_COMPRESS 0x00000004
|
|
#define IPF_NO_WAN_PRI 0x00000008
|
|
|
|
#define RAS_UI_FLAG_TERMBEFOREDIAL 0x1
|
|
#define RAS_UI_FLAG_TERMAFTERDIAL 0x2
|
|
#define RAS_UI_FLAG_OPERATORASSISTED 0x4
|
|
#define RAS_UI_FLAG_MODEMSTATUS 0x8
|
|
|
|
#define RAS_CFG_FLAG_HARDWARE_FLOW_CONTROL 0x00000010
|
|
#define RAS_CFG_FLAG_SOFTWARE_FLOW_CONTROL 0x00000020
|
|
#define RAS_CFG_FLAG_STANDARD_EMULATION 0x00000040
|
|
#define RAS_CFG_FLAG_COMPRESS_DATA 0x00000001
|
|
#define RAS_CFG_FLAG_USE_ERROR_CONTROL 0x00000002
|
|
#define RAS_CFG_FLAG_ERROR_CONTROL_REQUIRED 0x00000004
|
|
#define RAS_CFG_FLAG_USE_CELLULAR_PROTOCOL 0x00000008
|
|
#define RAS_CFG_FLAG_NO_WAIT_FOR_DIALTONE 0x00000200
|
|
|
|
#define DIALUI_DONT_PROMPT_FOR_INFO 0x01
|
|
#define DIALUI_DONT_SHOW_ICON 0x04
|
|
|
|
|
|
//
|
|
// For each entry, the following basic information is stored.
|
|
//
|
|
#define ENTRY_SETTINGS \
|
|
FUNSETTING(CredMask) \
|
|
FUNSETTING(CredName) \
|
|
FUNSETTING(CredDomain) \
|
|
FUNSETTING(CredPassword) \
|
|
STRSETTING(Encoding,S_ONE) \
|
|
FUNSETTING(Type) \
|
|
STRSETTING(Autologon,S_ZERO) \
|
|
STRSETTING(DialParamsUID,S_EMPTY) \
|
|
STRSETTING(Guid,S_EMPTY) \
|
|
STRSETTING(UsePwForNetwork,S_EMPTY) \
|
|
STRSETTING(ServerType,S_EMPTY) \
|
|
FUNSETTING(BaseProtocol) \
|
|
FUNSETTING(VpnStrategy) \
|
|
STRSETTING(Authentication,S_EMPTY) \
|
|
FUNSETTING(ExcludedProtocols) \
|
|
STRSETTING(LcpExtensions,S_ONE) \
|
|
FUNSETTING(DataEncryption) \
|
|
STRSETTING(SkipNwcWarning,S_EMPTY) \
|
|
STRSETTING(SkipDownLevelDialog,S_EMPTY) \
|
|
FUNSETTING(SwCompression) \
|
|
FUNSETTING(ShowMonitorIconInTaskBar) \
|
|
STRSETTING(CustomAuthKey,S_EMPTY) \
|
|
STRSETTING(CustomAuthData,S_EMPTY) \
|
|
FUNSETTING(AuthRestrictions) \
|
|
STRSETTING(OverridePref,TEXT("15")) \
|
|
STRSETTING(DialMode,S_EMPTY) \
|
|
STRSETTING(DialPercent,S_EMPTY) \
|
|
STRSETTING(DialSeconds,S_EMPTY) \
|
|
STRSETTING(HangUpPercent,S_EMPTY) \
|
|
STRSETTING(HangUpSeconds,S_EMPTY) \
|
|
FUNSETTING(RedialAttempts) \
|
|
FUNSETTING(RedialSeconds) \
|
|
FUNSETTING(IdleDisconnectSeconds) \
|
|
STRSETTING(RedialOnLinkFailure,S_EMPTY) \
|
|
STRSETTING(CallBackMode,S_EMPTY) \
|
|
STRSETTING(CustomDialDll,S_EMPTY) \
|
|
STRSETTING(CustomDialFunc,S_EMPTY) \
|
|
STRSETTING(AuthenticateServer,S_EMPTY) \
|
|
STRSETTING(SecureLocalFiels,S_EMPTY) \
|
|
STRSETTING(ShareMsFilePrint,S_EMPTY) \
|
|
STRSETTING(BindMsNetClient,S_EMPTY) \
|
|
STRSETTING(SharedPhoneNumbers,S_EMPTY) \
|
|
STRSETTING(PrerequisiteEntry,S_EMPTY) \
|
|
FUNSETTING(PreviewUserPw) \
|
|
FUNSETTING(PreviewDomain) \
|
|
FUNSETTING(PreviewPhoneNumber) \
|
|
STRSETTING(ShowDialingProgress,S_ONE) \
|
|
FUNSETTING(IpPrioritizeRemote) \
|
|
FUNSETTING(IpHeaderCompression) \
|
|
FUNSETTING(IpAddress) \
|
|
FUNSETTING(IpAssign) \
|
|
FUNSETTING(IpDnsAddress) \
|
|
FUNSETTING(IpDns2Address) \
|
|
FUNSETTING(IpWINSAddress) \
|
|
FUNSETTING(IpWINS2Address) \
|
|
FUNSETTING(IpNameAssign) \
|
|
STRSETTING(IpFrameSize,S_EMPTY) \
|
|
|
|
//
|
|
// There can be multiple media sections for each entry.
|
|
//
|
|
#define MEDIA_SETTINGS \
|
|
FUNSETTING(MEDIA) \
|
|
FUNSETTING(Port) \
|
|
FUNSETTING(Device) \
|
|
FUNSETTING(ConnectBps) \
|
|
|
|
//
|
|
// There can be multiple device sections for each entry.
|
|
//
|
|
#define SWITCH_DEVICE_SETTINGS \
|
|
FUNSETTING(DEVICE) \
|
|
FUNSETTING(Name) \
|
|
FUNSETTING(Terminal) \
|
|
FUNSETTING(Script) \
|
|
|
|
#define MODEM_DEVICE_SETTINGS \
|
|
FUNSETTING(DEVICE) \
|
|
FUNSETTING(PhoneNumber) \
|
|
FUNSETTING(AreaCode) \
|
|
FUNSETTING(CountryCode) \
|
|
FUNSETTING(CountryID) \
|
|
FUNSETTING(UseDialingRules) \
|
|
STRSETTING(Comment,S_EMPTY) \
|
|
STRSETTING(LastSelectedPhone,S_EMPTY) \
|
|
STRSETTING(PromoteAlternates,S_EMPTY) \
|
|
STRSETTING(TryNextAlternateOnFail,S_EMPTY) \
|
|
FUNSETTING(HwFlowControl) \
|
|
FUNSETTING(Protocol) \
|
|
FUNSETTING(Compression) \
|
|
FUNSETTING(Speaker) \
|
|
|
|
#define PAD_DEVICE_SETTINGS \
|
|
STRSETTING(X25Pad,S_EMPTY) \
|
|
STRSETTING(X25Address,S_EMPTY) \
|
|
STRSETTING(UserData,S_EMPTY) \
|
|
STRSETTING(Facilities,S_EMPTY) \
|
|
|
|
#define ISDN_DEVICE_SETTINGS \
|
|
FUNSETTING(PhoneNumber) \
|
|
FUNSETTING(AreaCode) \
|
|
FUNSETTING(CountryCode) \
|
|
FUNSETTING(CountryID) \
|
|
FUNSETTING(UseDialingRules) \
|
|
STRSETTING(Comment,S_EMPTY) \
|
|
STRSETTING(LastSelectedPhone,S_EMPTY) \
|
|
STRSETTING(PromoteAlternates,S_EMPTY) \
|
|
STRSETTING(TryNextAlternateOnFail,S_EMPTY) \
|
|
STRSETTING(LineType,S_EMPTY) \
|
|
STRSETTING(FallBack,S_EMPTY) \
|
|
STRSETTING(EnableCompressiong,S_EMPTY) \
|
|
STRSETTING(ChannelAggregation,S_EMPTY) \
|
|
|
|
#define X25_DEVICE_SETTINGS \
|
|
STRSETTING(X25Address,S_EMPTY) \
|
|
STRSETTING(UserData,S_EMPTY) \
|
|
STRSETTING(Facilities,S_EMPTY) \
|
|
|
|
//
|
|
// Function prototypes.
|
|
//
|
|
typedef PCTSTR (DATA_FUNCTION_PROTOTYPE)(VOID);
|
|
typedef DATA_FUNCTION_PROTOTYPE * DATA_FUNCTION;
|
|
|
|
#define FUNSETTING(Data) DATA_FUNCTION_PROTOTYPE pGet##Data;
|
|
#define STRSETTING(x,y)
|
|
|
|
ENTRY_SETTINGS
|
|
MEDIA_SETTINGS
|
|
SWITCH_DEVICE_SETTINGS
|
|
MODEM_DEVICE_SETTINGS
|
|
PAD_DEVICE_SETTINGS
|
|
ISDN_DEVICE_SETTINGS
|
|
X25_DEVICE_SETTINGS
|
|
|
|
#undef FUNSETTING
|
|
#undef STRSETTING
|
|
|
|
#define FUNSETTING(x) {TEXT(#x), pGet##x, NULL},
|
|
#define STRSETTING(x,y) {TEXT(#x), NULL, y},
|
|
#define LASTSETTING {NULL,NULL,NULL}
|
|
|
|
typedef struct {
|
|
PCTSTR SettingName;
|
|
DATA_FUNCTION SettingFunction;
|
|
PCTSTR SettingValue;
|
|
} RAS_SETTING, * PRAS_SETTING;
|
|
|
|
|
|
RAS_SETTING g_EntrySettings[] = {ENTRY_SETTINGS LASTSETTING};
|
|
RAS_SETTING g_MediaSettings[] = {MEDIA_SETTINGS LASTSETTING};
|
|
RAS_SETTING g_SwitchDeviceSettings[] = {SWITCH_DEVICE_SETTINGS LASTSETTING};
|
|
RAS_SETTING g_ModemDeviceSettings[] = {MODEM_DEVICE_SETTINGS LASTSETTING};
|
|
RAS_SETTING g_PadDeviceSettings[] = {PAD_DEVICE_SETTINGS LASTSETTING};
|
|
RAS_SETTING g_IsdnDeviceSettings[] = {ISDN_DEVICE_SETTINGS LASTSETTING};
|
|
RAS_SETTING g_X25DeviceSettings[] = {X25_DEVICE_SETTINGS LASTSETTING};
|
|
|
|
BOOL g_InSwitchSection = FALSE;
|
|
PCTSTR g_CurrentConnection = NULL;
|
|
UINT g_CurrentDevice = 0;
|
|
UINT g_CurrentDeviceType = 0;
|
|
#define RAS_BUFFER_SIZE MEMDB_MAX
|
|
TCHAR g_TempBuffer [RAS_BUFFER_SIZE];
|
|
HASHTABLE g_DeviceTable = NULL;
|
|
|
|
|
|
BOOL
|
|
pIs9xRasInstalled (
|
|
void
|
|
)
|
|
{
|
|
HKEY testKey = NULL;
|
|
BOOL rf = FALSE;
|
|
|
|
testKey = OpenRegKeyStr (S_SERVICEREMOTEACCESS);
|
|
|
|
if (testKey) {
|
|
//
|
|
// Open key succeeded. Assume RAS is installed.
|
|
//
|
|
rf = TRUE;
|
|
CloseRegKey(testKey);
|
|
}
|
|
|
|
return rf;
|
|
}
|
|
|
|
static BYTE NEAR PASCAL GenerateEncryptKey (LPCSTR szKey)
|
|
{
|
|
BYTE bKey;
|
|
LPBYTE lpKey;
|
|
|
|
for (bKey = 0, lpKey = (LPBYTE)szKey; *lpKey != 0; lpKey++)
|
|
{
|
|
bKey += *lpKey;
|
|
};
|
|
|
|
return bKey;
|
|
}
|
|
|
|
DWORD NEAR PASCAL EnDecryptEntry (LPCSTR szEntry, LPBYTE lpEnt,
|
|
DWORD cb)
|
|
{
|
|
BYTE bKey;
|
|
|
|
// Generate the encryption key from the entry name
|
|
bKey = GenerateEncryptKey(szEntry);
|
|
|
|
// Encrypt the address entry one byte at a time
|
|
for (;cb > 0; cb--, lpEnt++)
|
|
{
|
|
*lpEnt ^= bKey;
|
|
};
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
PTSTR
|
|
pGetComPort (
|
|
IN PCTSTR DriverDesc
|
|
)
|
|
{
|
|
PTSTR rPort = NULL;
|
|
|
|
if (!HtFindStringEx (g_DeviceTable, DriverDesc, &rPort, FALSE)) {
|
|
DEBUGMSG ((DBG_WARNING, "Could not find com port for device %s."));
|
|
}
|
|
|
|
if (!rPort) {
|
|
rPort = S_EMPTY;
|
|
}
|
|
|
|
return rPort;
|
|
}
|
|
|
|
VOID
|
|
pInitializeDeviceTable (
|
|
VOID
|
|
)
|
|
{
|
|
MIG_OBJECTSTRINGHANDLE encodedRegPattern;
|
|
REGTREE_ENUM e;
|
|
PTSTR com;
|
|
PTSTR desc;
|
|
PTSTR p;
|
|
|
|
encodedRegPattern = IsmCreateSimpleObjectPattern (S_MODEMS, TRUE, TEXT("*"), TRUE);
|
|
|
|
if (EnumFirstRegObjectInTreeEx (
|
|
&e,
|
|
encodedRegPattern,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE,
|
|
1,
|
|
FALSE,
|
|
TRUE,
|
|
RegEnumDefaultCallback
|
|
)) {
|
|
do {
|
|
// we don't care about value names, we only want subkeys
|
|
if (!e.CurrentValueData) {
|
|
com = desc = NULL;
|
|
com = GetRegValueString (e.CurrentKeyHandle, S_ATTACHEDTO);
|
|
desc = GetRegValueString (e.CurrentKeyHandle, S_DRIVERDESC);
|
|
|
|
if (com && desc) {
|
|
p = PmDuplicateString (g_RasPool, com);
|
|
|
|
HtAddStringEx (g_DeviceTable, desc, (PBYTE) &p, FALSE);
|
|
|
|
DEBUGMSG ((DBG_RASMIG, "%s on %s added to driver table.", desc, com));
|
|
}
|
|
|
|
if (com) {
|
|
MemFree (g_hHeap, 0, com);
|
|
}
|
|
if (desc) {
|
|
MemFree (g_hHeap, 0, desc);
|
|
}
|
|
}
|
|
} while (EnumNextRegObjectInTree (&e));
|
|
}
|
|
|
|
//
|
|
// Clean up resources.
|
|
//
|
|
IsmDestroyObjectHandle (encodedRegPattern);
|
|
}
|
|
|
|
BOOL
|
|
pGetPerUserSettings (
|
|
VOID
|
|
)
|
|
{
|
|
HKEY settingsKey;
|
|
PDWORD data;
|
|
PCTSTR entryStr;
|
|
BOOL rSuccess = TRUE;
|
|
|
|
settingsKey = OpenRegKeyStr (S_REMOTE_ACCESS_KEY);
|
|
|
|
if (settingsKey) {
|
|
|
|
//
|
|
// Get UI settings.
|
|
//
|
|
data = (PDWORD) GetRegValueBinary (settingsKey, S_DIALUI);
|
|
|
|
//
|
|
// Save Dial User Interface info into memdb for this user.
|
|
//
|
|
if (data) {
|
|
|
|
entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, S_DIALUI, NULL));
|
|
|
|
rSuccess &= (MemDbSetValue (entryStr, *data) != 0);
|
|
|
|
MemFree (g_hHeap, 0, data);
|
|
}
|
|
ELSE_DEBUGMSG ((DBG_RASMIG, "No user UI settings found for current user."));
|
|
|
|
//
|
|
// Get Redial information.
|
|
//
|
|
data = (PDWORD) GetRegValueBinary (settingsKey, S_ENABLE_REDIAL);
|
|
|
|
if (data) {
|
|
|
|
entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, S_ENABLE_REDIAL, NULL));
|
|
|
|
rSuccess &= (MemDbSetValue (entryStr, *data) != 0);
|
|
|
|
MemFree (g_hHeap, 0, data);
|
|
}
|
|
ELSE_DEBUGMSG ((DBG_RASMIG, "No user redial information found for current user."));
|
|
|
|
data = (PDWORD) GetRegValueBinary (settingsKey, S_REDIAL_TRY);
|
|
|
|
if (data) {
|
|
|
|
entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, S_REDIAL_TRY, NULL));
|
|
|
|
rSuccess &= (MemDbSetValue (entryStr, *data) != 0);
|
|
|
|
MemFree (g_hHeap, 0, data);
|
|
}
|
|
ELSE_DEBUGMSG ((DBG_RASMIG, "No user redial information found for current user."));
|
|
|
|
data = (PDWORD) GetRegValueBinary (settingsKey, S_REDIAL_WAIT);
|
|
|
|
if (data) {
|
|
|
|
entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, S_REDIAL_WAIT, NULL));
|
|
|
|
rSuccess &= (MemDbSetValue (entryStr, HIWORD(*data) * 60 + LOWORD(*data)) != 0);
|
|
|
|
MemFree (g_hHeap, 0, data);
|
|
}
|
|
ELSE_DEBUGMSG ((DBG_RASMIG, "No user redial information found for current user."));
|
|
|
|
//
|
|
// Get implicit connection information. (Controls wether connection ui should be displayed or not)
|
|
//
|
|
data = (PDWORD) GetRegValueBinary (settingsKey, S_ENABLE_IMPLICIT);
|
|
|
|
if (data) {
|
|
|
|
entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, S_ENABLE_IMPLICIT, NULL));
|
|
|
|
rSuccess &= (MemDbSetValue (entryStr, *data) != 0);
|
|
|
|
MemFree(g_hHeap,0,data);
|
|
}
|
|
ELSE_DEBUGMSG ((DBG_RASMIG, "No user implicit connection information found for current user."));
|
|
|
|
CloseRegKey(settingsKey);
|
|
}
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
VOID
|
|
pSaveConnectionDataToMemDb (
|
|
IN PCTSTR Entry,
|
|
IN PCTSTR ValueName,
|
|
IN DWORD ValueType,
|
|
IN PBYTE Value
|
|
)
|
|
{
|
|
KEYHANDLE keyHandle;
|
|
PCTSTR entryStr;
|
|
PCTSTR entryTmp;
|
|
|
|
entryStr = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_INFO, Entry, ValueName, NULL));
|
|
|
|
switch (ValueType) {
|
|
case REG_SZ:
|
|
case REG_MULTI_SZ:
|
|
case REG_EXPAND_SZ:
|
|
DEBUGMSG ((DBG_RASMIG, "String Data - %s = %s", ValueName, (PCTSTR) Value));
|
|
|
|
entryTmp = JoinPaths (MEMDB_CATEGORY_RAS_DATA, (PCTSTR) Value);
|
|
|
|
keyHandle = MemDbSetKey (entryTmp);
|
|
|
|
if (!keyHandle) {
|
|
DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
|
|
}
|
|
|
|
FreePathString (entryTmp);
|
|
|
|
if (!MemDbSetValueAndFlagsEx (entryStr, TRUE, keyHandle, TRUE, REG_SZ, 0)) {
|
|
DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
|
|
}
|
|
|
|
break;
|
|
|
|
case REG_DWORD:
|
|
|
|
DEBUGMSG ((DBG_RASMIG, "DWORD Data - %s = %u", ValueName, (DWORD)(ULONG_PTR) Value));
|
|
|
|
if (!MemDbSetValueAndFlagsEx (entryStr, TRUE, (DWORD)(ULONG_PTR) Value, TRUE, ValueType, 0)) {
|
|
DEBUGMSG ((DBG_ERROR, "Error saving ras data into memdb."));
|
|
}
|
|
|
|
break;
|
|
|
|
case REG_BINARY:
|
|
|
|
DEBUGMSG ((DBG_RASMIG, "Binary data for %s.", ValueName));
|
|
|
|
if (StringIMatch (S_IPINFO, ValueName)) {
|
|
|
|
//
|
|
// Save IP address information.
|
|
//
|
|
pSaveConnectionDataToMemDb (Entry, S_IP_FTCPIP, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> fdwTCPIP);
|
|
pSaveConnectionDataToMemDb (Entry, S_IP_IPADDR, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> dwIPAddr);
|
|
pSaveConnectionDataToMemDb (Entry, S_IP_DNSADDR, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> dwDNSAddr);
|
|
pSaveConnectionDataToMemDb (Entry, S_IP_DNSADDR2, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> dwDNSAddrAlt);
|
|
pSaveConnectionDataToMemDb (Entry, S_IP_WINSADDR, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> dwWINSAddr);
|
|
pSaveConnectionDataToMemDb (Entry, S_IP_WINSADDR2, REG_DWORD, (PBYTE)(ULONG_PTR)((PIPDATA) Value) -> dwWINSAddrAlt);
|
|
|
|
} else if (StringIMatch (S_TERMINAL, ValueName)) {
|
|
|
|
//
|
|
// save information on the showcmd state. This will tell us how to set the ui display.
|
|
//
|
|
pSaveConnectionDataToMemDb (Entry, ValueName, REG_DWORD, (PBYTE)(ULONG_PTR)((PWINDOWPLACEMENT) Value) -> showCmd);
|
|
|
|
} else if (StringIMatch (S_MODE, ValueName)) {
|
|
|
|
//
|
|
// This value tells what to do with scripting.
|
|
//
|
|
pSaveConnectionDataToMemDb (Entry, ValueName, REG_DWORD, (PBYTE)(ULONG_PTR) *((PDWORD) Value));
|
|
|
|
} else if (StringIMatch (S_MULTILINK, ValueName)) {
|
|
|
|
//
|
|
// Save wether or not multilink is enabled.
|
|
//
|
|
pSaveConnectionDataToMemDb (Entry, ValueName, REG_DWORD,(PBYTE)(ULONG_PTR) *((PDWORD) Value));
|
|
|
|
} ELSE_DEBUGMSG ((DBG_WARNING, "Don't know how to handle binary data %s. It will be ignored.", ValueName));
|
|
|
|
break;
|
|
|
|
default:
|
|
DEBUGMSG ((DBG_WHOOPS, "Unknown type of registry data found in RAS settings. %s", ValueName));
|
|
break;
|
|
}
|
|
|
|
FreePathString (entryStr);
|
|
}
|
|
|
|
BOOL
|
|
pGetRasEntryAddressInfo (
|
|
IN PCTSTR KeyName,
|
|
IN PCTSTR EntryName
|
|
)
|
|
{
|
|
BOOL rSuccess = TRUE;
|
|
|
|
MIG_OBJECTSTRINGHANDLE encodedRegPattern;
|
|
MIG_OBJECTSTRINGHANDLE encodedSubPattern;
|
|
PBYTE data = NULL;
|
|
UINT count = 0;
|
|
UINT type = 0;
|
|
PADDRENTRY entry;
|
|
PSUBCONNENTRY subEntry;
|
|
PSMMCFG smmCfg;
|
|
PDEVICEINFO devInfo;
|
|
REGTREE_ENUM e;
|
|
PTSTR subEntriesKeyStr;
|
|
UINT sequencer = 0;
|
|
REGTREE_ENUM eSubEntries;
|
|
TCHAR buffer[MAX_TCHAR_PATH];
|
|
PMODEMDEVINFO modemInfo;
|
|
#ifdef UNICODE
|
|
PCSTR tempStr = NULL;
|
|
PCWSTR tempStrW = NULL;
|
|
#endif
|
|
|
|
//
|
|
// First we have to get the real entry name. It must match exactly even case. Unfortunately, it isn't neccessarily a given
|
|
// that the case between HKCU\RemoteAccess\Profiles\<Foo> and HKCU\RemoteAccess\Addresses\[Foo] is the same. The registry
|
|
// apis will of course work fine because they work case insensitively. However, I will be unable to decrypt the value
|
|
// if I use the wrong name.
|
|
//
|
|
|
|
|
|
encodedRegPattern = IsmCreateSimpleObjectPattern (KeyName, FALSE, TEXT("*"), TRUE);
|
|
|
|
if (EnumFirstRegObjectInTreeEx (
|
|
&e,
|
|
encodedRegPattern,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE,
|
|
REGENUM_ALL_SUBLEVELS,
|
|
FALSE,
|
|
TRUE,
|
|
RegEnumDefaultCallback
|
|
)) {
|
|
do {
|
|
if (StringIMatch (e.Name, EntryName)) {
|
|
|
|
//
|
|
// Found the correct entry. Use it.
|
|
//
|
|
data = e.CurrentValueData;
|
|
|
|
if (data) {
|
|
|
|
entry = (PADDRENTRY) data;
|
|
|
|
#ifdef UNICODE
|
|
tempStr = ConvertWtoA (e.Name);
|
|
DECRYPTENTRY(tempStr, entry, e.CurrentValueDataSize);
|
|
FreeConvertedStr (tempStr);
|
|
#else
|
|
DECRYPTENTRY(e.Name, entry, e.CurrentValueDataSize);
|
|
#endif
|
|
|
|
smmCfg = PAESMMCFG(entry);
|
|
devInfo = PAEDI(entry);
|
|
|
|
pSaveConnectionDataToMemDb (EntryName, S_PHONE_NUMBER, REG_SZ, (PBYTE) PAEPHONE(entry));
|
|
pSaveConnectionDataToMemDb (EntryName, S_AREA_CODE, REG_SZ, (PBYTE) PAEAREA(entry));
|
|
pSaveConnectionDataToMemDb (EntryName, S_SMM, REG_SZ, (PBYTE) PAESMM(entry));
|
|
pSaveConnectionDataToMemDb (EntryName, S_COUNTRY_CODE, REG_DWORD, (PBYTE)(ULONG_PTR) entry -> dwCountryCode);
|
|
pSaveConnectionDataToMemDb (EntryName, S_COUNTRY_ID, REG_DWORD, (PBYTE)(ULONG_PTR) entry -> dwCountryID);
|
|
pSaveConnectionDataToMemDb (EntryName, S_DEVICE_NAME, REG_SZ, (PBYTE) devInfo -> szDeviceName);
|
|
pSaveConnectionDataToMemDb (EntryName, S_DEVICE_TYPE, REG_SZ, (PBYTE) devInfo -> szDeviceType);
|
|
pSaveConnectionDataToMemDb (EntryName, S_PROTOCOLS, REG_DWORD, (PBYTE)(ULONG_PTR) smmCfg -> fdwProtocols);
|
|
pSaveConnectionDataToMemDb (EntryName, S_SMM_OPTIONS, REG_DWORD, (PBYTE)(ULONG_PTR) smmCfg -> fdwOptions);
|
|
|
|
//
|
|
// Save device information away.
|
|
//
|
|
if (StringIMatchA (devInfo -> szDeviceType, S_MODEMA)) {
|
|
|
|
modemInfo = (PMODEMDEVINFO) (devInfo->szDeviceType + RAS_MaxDeviceType + 3);
|
|
|
|
if (modemInfo -> Size >= sizeof (MODEMDEVINFO)) {
|
|
DEBUGMSG_IF ((modemInfo -> Size > sizeof (MODEMDEVINFO), DBG_RASMIG, "Structure size larger than our known size."));
|
|
|
|
pSaveConnectionDataToMemDb (EntryName, S_MODEM_UI_OPTIONS, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> ModemUiOptions);
|
|
pSaveConnectionDataToMemDb (EntryName, S_MODEM_SPEED, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> ConnectionSpeed);
|
|
pSaveConnectionDataToMemDb (EntryName, S_MODEM_SPEAKER_VOLUME, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> SpeakerVolume);
|
|
pSaveConnectionDataToMemDb (EntryName, S_MODEM_IDLE_DISCONNECT_SECONDS, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> IdleDisconnectSeconds);
|
|
pSaveConnectionDataToMemDb (EntryName, S_MODEM_CANCEL_SECONDS, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> CancelSeconds);
|
|
pSaveConnectionDataToMemDb (EntryName, S_MODEM_CFG_OPTIONS, REG_DWORD, (PBYTE)(ULONG_PTR) modemInfo -> ConfigOptions);
|
|
#ifdef UNICODE
|
|
tempStrW = ConvertAtoW (devInfo->szDeviceName);
|
|
pSaveConnectionDataToMemDb (EntryName, S_MODEM_COM_PORT, REG_SZ, (PBYTE) pGetComPort (tempStrW));
|
|
FreeConvertedStr (tempStrW);
|
|
#else
|
|
pSaveConnectionDataToMemDb (EntryName, S_MODEM_COM_PORT, REG_SZ, (PBYTE) pGetComPort (devInfo->szDeviceName));
|
|
#endif
|
|
|
|
}
|
|
ELSE_DEBUGMSG ((DBG_WHOOPS, "No modem configuration data saved. Size smaller than known structure. Investigate."));
|
|
}
|
|
|
|
//
|
|
// If SMM is not SLIP, CSLIP or PPP, we need to add a message to the upgrade report.
|
|
//
|
|
if (!StringIMatchA (PAESMM(entry), S_SLIPA) && !StringIMatchA (PAESMM(entry), S_PPPA) && !StringIMatchA (PAESMM(entry), S_CSLIPA)) {
|
|
LOG ((LOG_WARNING, (PCSTR) MSG_RASMIG_UNSUPPORTEDSETTINGS, EntryName));
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check to see if there are any sub-entries for this connection (MULTILINK settings..)
|
|
//
|
|
//
|
|
// Luckily, we don't have to do the same enumeration of these entries as we had to above to get around
|
|
// the case sensitivity bug. the 9x code uses the address key name above for encryption/decryption.
|
|
//
|
|
|
|
subEntriesKeyStr = JoinPathsInPoolEx ((NULL, KeyName, S_SUBENTRIES, e.Name, NULL));
|
|
sequencer = 1;
|
|
|
|
encodedSubPattern = IsmCreateSimpleObjectPattern (subEntriesKeyStr, FALSE, TEXT("*"), TRUE);
|
|
|
|
if (EnumFirstRegObjectInTreeEx (
|
|
&eSubEntries,
|
|
encodedSubPattern,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE,
|
|
REGENUM_ALL_SUBLEVELS,
|
|
FALSE,
|
|
TRUE,
|
|
RegEnumDefaultCallback
|
|
)) {
|
|
do {
|
|
|
|
DEBUGMSG ((DBG_RASMIG, "Multi-Link Subentries found for entry %s. Processing.", e.Name));
|
|
|
|
data = eSubEntries.CurrentValueData;
|
|
|
|
if (data) {
|
|
|
|
subEntry = (PSUBCONNENTRY) data;
|
|
#ifdef UNICODE
|
|
tempStr = ConvertWtoA (e.Name);
|
|
DECRYPTENTRY (tempStr, subEntry, eSubEntries.CurrentValueDataSize);
|
|
FreeConvertedStr (tempStr);
|
|
#else
|
|
DECRYPTENTRY (e.Name, subEntry, eSubEntries.CurrentValueDataSize);
|
|
#endif
|
|
wsprintf (buffer, TEXT("ml%d%s"), sequencer, S_DEVICE_TYPE);
|
|
pSaveConnectionDataToMemDb (EntryName, buffer, REG_SZ, (PBYTE) subEntry->szDeviceType);
|
|
|
|
wsprintf (buffer, TEXT("ml%d%s"), sequencer, S_DEVICE_NAME);
|
|
pSaveConnectionDataToMemDb (EntryName, buffer, REG_SZ, (PBYTE) subEntry->szDeviceName);
|
|
|
|
wsprintf (buffer, TEXT("ml%d%s"), sequencer, S_PHONE_NUMBER);
|
|
pSaveConnectionDataToMemDb (EntryName, buffer, REG_SZ, (PBYTE) subEntry->szLocal);
|
|
|
|
wsprintf (buffer, TEXT("ml%d%s"), sequencer, S_MODEM_COM_PORT);
|
|
#ifdef UNICODE
|
|
tempStrW = ConvertAtoW (subEntry->szDeviceName);
|
|
pSaveConnectionDataToMemDb (EntryName, buffer, REG_SZ, (PBYTE) pGetComPort (tempStrW));
|
|
FreeConvertedStr (tempStrW);
|
|
#else
|
|
pSaveConnectionDataToMemDb (EntryName, buffer, REG_SZ, (PBYTE) pGetComPort (subEntry->szDeviceName));
|
|
#endif
|
|
}
|
|
|
|
sequencer++;
|
|
|
|
} while (EnumNextRegObjectInTree (&eSubEntries));
|
|
}
|
|
|
|
IsmDestroyObjectHandle (encodedSubPattern);
|
|
FreePathString (subEntriesKeyStr);
|
|
|
|
//
|
|
// Save away the number of devices associated with this connection
|
|
//
|
|
pSaveConnectionDataToMemDb (EntryName, S_DEVICECOUNT, REG_DWORD, (PBYTE)(ULONG_PTR) sequencer);
|
|
|
|
//
|
|
// We're done. Break out of the enumeration.
|
|
//
|
|
AbortRegObjectInTreeEnum (&e);
|
|
break;
|
|
}
|
|
|
|
} while (EnumNextRegObjectInTree (&e));
|
|
}
|
|
|
|
IsmDestroyObjectHandle (encodedRegPattern);
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
BOOL
|
|
pGetRasEntrySettings (
|
|
IN PCTSTR KeyName,
|
|
IN PCTSTR EntryName
|
|
)
|
|
{
|
|
REGTREE_ENUM e;
|
|
MIG_OBJECTSTRINGHANDLE encodedRegPattern;
|
|
PBYTE curData = NULL;
|
|
BOOL rSuccess = TRUE;
|
|
|
|
encodedRegPattern = IsmCreateSimpleObjectPattern (KeyName, FALSE, TEXT("*"), TRUE);
|
|
|
|
if (EnumFirstRegObjectInTreeEx (
|
|
&e,
|
|
encodedRegPattern,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE,
|
|
REGENUM_ALL_SUBLEVELS,
|
|
FALSE,
|
|
TRUE,
|
|
RegEnumDefaultCallback
|
|
)) {
|
|
do {
|
|
if (e.CurrentValueData) {
|
|
pSaveConnectionDataToMemDb (
|
|
EntryName,
|
|
e.Name,
|
|
e.CurrentValueType,
|
|
e.CurrentValueType == REG_DWORD ? (PBYTE)(ULONG_PTR) (*((PDWORD)e.CurrentValueData)) : e.CurrentValueData
|
|
);
|
|
}
|
|
} while (EnumNextRegObjectInTree (&e));
|
|
}
|
|
|
|
IsmDestroyObjectHandle (encodedRegPattern);
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
BOOL
|
|
pGetPerConnectionSettings (
|
|
VOID
|
|
)
|
|
{
|
|
MIG_OBJECTSTRINGHANDLE encodedRegPattern;
|
|
REGTREE_ENUM e;
|
|
PCTSTR entryKey = NULL;
|
|
BOOL rSuccess = TRUE;
|
|
|
|
encodedRegPattern = IsmCreateSimpleObjectPattern (S_ADDRESSES_KEY, FALSE, TEXT("*"), TRUE);
|
|
|
|
//
|
|
// Enumerate each entry for this user.
|
|
//
|
|
if (EnumFirstRegObjectInTreeEx (
|
|
&e,
|
|
encodedRegPattern,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE,
|
|
TRUE,
|
|
REGENUM_ALL_SUBLEVELS,
|
|
FALSE,
|
|
TRUE,
|
|
RegEnumDefaultCallback
|
|
)) {
|
|
do {
|
|
//
|
|
// Get base connection info -- stored as binary blob under address key.
|
|
// All connections will have this info -- It contains such things
|
|
// as the phone number, area code, dialing rules, etc.. It does
|
|
// not matter wether the connection has been used or not.
|
|
//
|
|
rSuccess &= pGetRasEntryAddressInfo (S_ADDRESSES_KEY, e.Name);
|
|
|
|
//
|
|
// Under the profile key are negotiated options for the connection.
|
|
// This key will only exist if the entry has actually been connected
|
|
// to by the user.
|
|
//
|
|
entryKey = JoinPaths (S_PROFILE_KEY, e.Name);
|
|
|
|
if (entryKey) {
|
|
rSuccess &= pGetRasEntrySettings (entryKey, e.Name);
|
|
FreePathString (entryKey);
|
|
}
|
|
|
|
} while (EnumNextRegObjectInTree (&e));
|
|
}
|
|
|
|
//
|
|
// Clean up resources.
|
|
//
|
|
IsmDestroyObjectHandle (encodedRegPattern);
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
BOOL
|
|
pGetRasDataFromMemDb (
|
|
IN PCTSTR DataName,
|
|
OUT PMEMDB_RAS_DATA Data
|
|
)
|
|
{
|
|
BOOL rSuccess = FALSE;
|
|
PCTSTR key;
|
|
DWORD value;
|
|
DWORD flags;
|
|
PCTSTR tempBuffer;
|
|
|
|
MYASSERT(DataName && Data && g_CurrentConnection);
|
|
|
|
key = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_INFO, g_CurrentConnection, DataName, NULL));
|
|
rSuccess = MemDbGetValueAndFlags (key, &value, &flags);
|
|
FreePathString (key);
|
|
|
|
//
|
|
// If that wasn't successful, we need to look in the per-user settings.
|
|
//
|
|
if (!rSuccess) {
|
|
key = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_USER, MEMDB_FIELD_USER_SETTINGS, DataName, NULL));
|
|
rSuccess = MemDbGetValueAndFlags (key, &value, &flags);
|
|
flags = REG_DWORD;
|
|
}
|
|
|
|
if (rSuccess) {
|
|
//
|
|
// There is information stored here. Fill it in and send it back to the user.
|
|
//
|
|
if (flags == REG_SZ) {
|
|
|
|
//
|
|
// String data, the value points to the offset for the string.
|
|
//
|
|
tempBuffer = MemDbGetKeyFromHandle (value, 1);
|
|
if (!tempBuffer) {
|
|
DEBUGMSG ((
|
|
DBG_ERROR,
|
|
"Could not retrieve RAS string information stored in Memdb. Entry=%s,Setting=%s",
|
|
g_CurrentConnection,
|
|
DataName
|
|
));
|
|
return FALSE;
|
|
}
|
|
|
|
Data -> String = PmDuplicateString (g_RasPool, tempBuffer);
|
|
MemDbReleaseMemory (tempBuffer);
|
|
}
|
|
else {
|
|
|
|
//
|
|
// Not string data. The data is stored as the value.
|
|
//
|
|
Data -> Value = value;
|
|
|
|
}
|
|
|
|
Data -> DataType = (WORD) flags;
|
|
|
|
}
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
BOOL
|
|
pWritePhoneBookLine (
|
|
IN HANDLE FileHandle,
|
|
IN PCTSTR SettingName,
|
|
IN PCTSTR SettingValue
|
|
)
|
|
{
|
|
BOOL rSuccess = TRUE;
|
|
|
|
rSuccess &= WriteFileString (FileHandle, SettingName);
|
|
rSuccess &= WriteFileString (FileHandle, TEXT("="));
|
|
rSuccess &= WriteFileString (FileHandle, SettingValue ? SettingValue : S_EMPTY);
|
|
rSuccess &= WriteFileString (FileHandle, TEXT("\r\n"));
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
BOOL
|
|
pWriteSettings (
|
|
IN HANDLE FileHandle,
|
|
IN PRAS_SETTING SettingList
|
|
)
|
|
{
|
|
|
|
BOOL rSuccess = TRUE;
|
|
|
|
while (SettingList->SettingName) {
|
|
rSuccess &= pWritePhoneBookLine (
|
|
FileHandle,
|
|
SettingList->SettingName,
|
|
SettingList->SettingValue ?
|
|
SettingList->SettingValue :
|
|
SettingList->SettingFunction ());
|
|
|
|
SettingList++;
|
|
}
|
|
|
|
return rSuccess;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetSpeaker (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (g_CurrentDevice) {
|
|
return S_ONE;
|
|
}
|
|
|
|
if (!pGetRasDataFromMemDb (S_MODEM_SPEAKER_VOLUME, &d)) {
|
|
return S_ONE;
|
|
}
|
|
|
|
if (d.Value) {
|
|
return S_ONE;
|
|
}
|
|
|
|
return S_ZERO;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetCompression (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (g_CurrentDevice) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
if (!pGetRasDataFromMemDb (S_MODEM_CFG_OPTIONS, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
if (d.Value & RAS_CFG_FLAG_COMPRESS_DATA) {
|
|
return S_ONE;
|
|
}
|
|
|
|
return S_ZERO;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetProtocol (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (g_CurrentDevice) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
if (!pGetRasDataFromMemDb (S_MODEM_CFG_OPTIONS, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
if (d.Value & RAS_CFG_FLAG_USE_ERROR_CONTROL) {
|
|
return S_ONE;
|
|
}
|
|
|
|
return S_ZERO;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetHwFlowControl (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (g_CurrentDevice) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
if (!pGetRasDataFromMemDb (S_MODEM_CFG_OPTIONS, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
if (d.Value & RAS_CFG_FLAG_HARDWARE_FLOW_CONTROL) {
|
|
return S_ONE;
|
|
}
|
|
|
|
return S_ZERO;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetUseDialingRules (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
//
|
|
// Win9x sets the areacode, countrycode, countryid to zero if
|
|
// use dialing rules is disabled. For ease, we test off of country
|
|
// code. If we can't get it, or, it is set to zero, we assume
|
|
// that we should _not_ use dialing rules.
|
|
//
|
|
if (!pGetRasDataFromMemDb(S_COUNTRY_CODE, &d) || !d.Value) {
|
|
return S_ZERO;
|
|
}
|
|
|
|
return S_ONE;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetCountryID (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_COUNTRY_ID, &d) || !d.Value) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
wsprintf (g_TempBuffer, TEXT("%d"), d.Value);
|
|
|
|
return g_TempBuffer;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetCountryCode (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb(S_COUNTRY_CODE, &d) || !d.Value) {
|
|
return S_EMPTY;
|
|
}
|
|
wsprintf(g_TempBuffer,TEXT("%d"),d.Value);
|
|
|
|
return g_TempBuffer;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetAreaCode (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb(S_AREA_CODE, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
|
|
|
|
return d.String;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetPhoneNumber (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
TCHAR buffer[MAX_TCHAR_PATH];
|
|
|
|
if (g_CurrentDevice == 0) {
|
|
if (!pGetRasDataFromMemDb(S_PHONE_NUMBER, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
}
|
|
else {
|
|
|
|
wsprintf(buffer,TEXT("ml%d%s"),g_CurrentDevice,S_PHONE_NUMBER);
|
|
if (!pGetRasDataFromMemDb(buffer, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
}
|
|
|
|
return d.String;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetScript (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_PPPSCRIPT, &d)) {
|
|
|
|
return S_ZERO;
|
|
}
|
|
|
|
return S_ONE;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetTerminal (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_MODEM_UI_OPTIONS, &d)) {
|
|
|
|
return S_EMPTY;
|
|
}
|
|
|
|
if (d.Value & (RAS_UI_FLAG_TERMBEFOREDIAL | RAS_UI_FLAG_TERMAFTERDIAL)) {
|
|
return S_ONE;
|
|
}
|
|
|
|
return S_ZERO;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetName (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_PPPSCRIPT, &d)) {
|
|
|
|
return S_EMPTY;
|
|
}
|
|
else {
|
|
|
|
return d.String;
|
|
}
|
|
|
|
}
|
|
|
|
PCTSTR
|
|
pGetDEVICE (
|
|
VOID
|
|
)
|
|
{
|
|
if (g_InSwitchSection) {
|
|
return TEXT("Switch");
|
|
}
|
|
|
|
if (g_CurrentDeviceType == RASTYPE_VPN) {
|
|
return TEXT("rastapi");
|
|
}
|
|
|
|
return TEXT("modem");
|
|
|
|
}
|
|
|
|
PCTSTR
|
|
pGetConnectBps (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!g_CurrentDevice) {
|
|
|
|
if (!pGetRasDataFromMemDb (S_MODEM_SPEED, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
wsprintf (g_TempBuffer, TEXT("%d"), d.Value);
|
|
|
|
return g_TempBuffer;
|
|
}
|
|
|
|
return S_EMPTY;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetDevice (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
PTSTR p = S_MODEM_COM_PORT;
|
|
PTSTR value = NULL;
|
|
MEMDB_RAS_DATA d;
|
|
|
|
|
|
//
|
|
// Very easy if this is a vpn connection.
|
|
//
|
|
if (g_CurrentDeviceType == RASTYPE_VPN) {
|
|
return TEXT("rastapi");
|
|
}
|
|
|
|
|
|
|
|
if (g_CurrentDevice) {
|
|
wsprintf (g_TempBuffer, TEXT("ml%d%s"), g_CurrentDevice, S_MODEM_COM_PORT);
|
|
p = g_TempBuffer;
|
|
}
|
|
|
|
if (!pGetRasDataFromMemDb (p, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
if (!HtFindStringEx (g_DeviceTable, d.String, &value, FALSE)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetPort (
|
|
VOID
|
|
)
|
|
{
|
|
PTSTR value = NULL;
|
|
MEMDB_RAS_DATA d;
|
|
PTSTR p = S_MODEM_COM_PORT;
|
|
|
|
if (g_CurrentDeviceType == RASTYPE_VPN) {
|
|
return TEXT("VPN2-0");
|
|
}
|
|
|
|
|
|
if (g_CurrentDevice) {
|
|
wsprintf (g_TempBuffer, TEXT("ml%d%s"), g_CurrentDevice, S_MODEM_COM_PORT);
|
|
p = g_TempBuffer;
|
|
}
|
|
|
|
if (!pGetRasDataFromMemDb (p, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
if (!HtFindStringEx (g_DeviceTable, d.String, &value, FALSE)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
return d.String;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetMEDIA (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
if (g_CurrentDeviceType == RASTYPE_VPN) {
|
|
|
|
return TEXT("rastapi");
|
|
}
|
|
else {
|
|
|
|
return TEXT("Serial");
|
|
}
|
|
|
|
}
|
|
|
|
PCTSTR
|
|
pGetIpNameAssign (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_IP_FTCPIP, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
else if (d.Value & IPF_NAME_SPECIFIED) {
|
|
return TEXT("2");
|
|
}
|
|
else {
|
|
return S_ONE;
|
|
}
|
|
}
|
|
|
|
PCTSTR
|
|
pGetNetAddress (
|
|
IN PCTSTR Setting
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
BYTE address[4];
|
|
|
|
if (!pGetRasDataFromMemDb (Setting, &d) || !d.Value) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
//
|
|
// Data is stored as a REG_DWORD.
|
|
// We need to write it in dotted decimal form.
|
|
//
|
|
|
|
*((LPDWORD)address) = d.Value;
|
|
wsprintf (
|
|
g_TempBuffer,
|
|
TEXT("%d.%d.%d.%d"),
|
|
address[3],
|
|
address[2],
|
|
address[1],
|
|
address[0]
|
|
);
|
|
|
|
return g_TempBuffer;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetIpWINS2Address (
|
|
VOID
|
|
)
|
|
{
|
|
return pGetNetAddress (S_IP_WINSADDR2);
|
|
}
|
|
|
|
PCTSTR
|
|
pGetIpWINSAddress (
|
|
VOID
|
|
)
|
|
{
|
|
return pGetNetAddress (S_IP_WINSADDR);
|
|
}
|
|
|
|
PCTSTR
|
|
pGetIpDns2Address (
|
|
VOID
|
|
)
|
|
{
|
|
return pGetNetAddress (S_IP_DNSADDR2);
|
|
}
|
|
|
|
PCTSTR
|
|
pGetIpDnsAddress (
|
|
VOID
|
|
)
|
|
{
|
|
return pGetNetAddress (S_IP_DNSADDR);
|
|
}
|
|
|
|
PCTSTR
|
|
pGetIpAssign (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_IP_FTCPIP, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
else if (d.Value & IPF_IP_SPECIFIED) {
|
|
return TEXT("2");
|
|
}
|
|
else {
|
|
return S_ONE;
|
|
}
|
|
}
|
|
|
|
PCTSTR
|
|
pGetIpAddress (
|
|
VOID
|
|
)
|
|
{
|
|
return pGetNetAddress (S_IP_IPADDR);
|
|
}
|
|
|
|
PCTSTR
|
|
pGetIpHeaderCompression (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_IP_FTCPIP, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
else if (d.Value & IPF_NO_COMPRESS) {
|
|
return S_ZERO;
|
|
}
|
|
else {
|
|
return S_ONE;
|
|
}
|
|
}
|
|
|
|
PCTSTR
|
|
pGetIpPrioritizeRemote (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_IP_FTCPIP, &d)) {
|
|
return S_ONE;
|
|
}
|
|
else if (d.Value & IPF_NO_WAN_PRI) {
|
|
return S_ZERO;
|
|
}
|
|
else {
|
|
return S_ONE;
|
|
}
|
|
|
|
}
|
|
|
|
PCTSTR
|
|
pGetPreviewUserPw (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_DIALUI, &d)) {
|
|
return S_ONE;
|
|
}
|
|
|
|
if (d.Value & DIALUI_DONT_PROMPT_FOR_INFO) {
|
|
return S_ZERO;
|
|
}
|
|
|
|
|
|
return S_ONE;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetPreviewPhoneNumber (
|
|
VOID
|
|
)
|
|
{
|
|
if (g_CurrentDeviceType == RASTYPE_VPN) {
|
|
return S_ZERO;
|
|
}
|
|
|
|
return pGetPreviewUserPw ();
|
|
}
|
|
|
|
PCTSTR
|
|
pGetPreviewDomain (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_SMM_OPTIONS, &d)) {
|
|
return S_ONE;
|
|
}
|
|
|
|
//
|
|
// if 0x04 is set, then preview domain, otherwise don't.
|
|
//
|
|
|
|
if (d.Value & SMMCFG_NW_LOGON) {
|
|
return S_ONE;
|
|
}
|
|
|
|
return S_ZERO;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetIdleDisconnectSeconds (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_MODEM_IDLE_DISCONNECT_SECONDS, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
wsprintf (g_TempBuffer, TEXT("%d"), d.Value);
|
|
|
|
return g_TempBuffer;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetRedialSeconds (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
//
|
|
// NT wants this as a total number of seconds. The data we have from 9x has
|
|
// the number of minutes in the hiword and the number of seconds in the loword.
|
|
//
|
|
|
|
if (!pGetRasDataFromMemDb (S_REDIAL_WAIT, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
wsprintf (g_TempBuffer, TEXT("%d"), d.Value);
|
|
|
|
return g_TempBuffer;
|
|
|
|
}
|
|
|
|
PCTSTR
|
|
pGetRedialAttempts (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
MEMDB_RAS_DATA d;
|
|
|
|
//
|
|
// Before getting the number of redial attempts on windows 9x,
|
|
// we need to ensure that redialing is enabled. If it is not
|
|
// enabled, we set this field to zero, regardless.
|
|
//
|
|
|
|
|
|
if (pGetRasDataFromMemDb (S_ENABLE_REDIAL, &d)) {
|
|
if (!d.Value) {
|
|
return S_ZERO;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we have gotten this far, then redialing is enabled.
|
|
//
|
|
if (!pGetRasDataFromMemDb (S_REDIAL_TRY, &d)) {
|
|
DEBUGMSG((DBG_WARNING, "Redialing enabled, but no redial attempts info found."));
|
|
return S_ZERO;
|
|
|
|
}
|
|
|
|
wsprintf (g_TempBuffer, TEXT("%d"), d.Value);
|
|
|
|
return g_TempBuffer;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetAuthRestrictions (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_SMM_OPTIONS, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
//
|
|
// password should be encrypted if 0x02 is set.
|
|
//
|
|
if (d.Value & SMMCFG_PW_ENCRYPTED) {
|
|
return TEXT("2");
|
|
}
|
|
|
|
return S_EMPTY;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetShowMonitorIconInTaskBar (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
//
|
|
// This information is stored packed with other Dialing UI on
|
|
// windows 9x. All we need to do is look for the specific
|
|
// bit which is set when this is turned off.
|
|
//
|
|
|
|
if (pGetRasDataFromMemDb (S_DIALUI, &d) && (d.Value & DIALUI_DONT_SHOW_ICON)) {
|
|
return S_ZERO;
|
|
}
|
|
return S_ONE;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetSwCompression (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_SMM_OPTIONS, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
//
|
|
// the 1 bit in SMM_OPTIONS controls software based compression.
|
|
// if it is set, the connection is able to handled compression,
|
|
// otherwise, it cannot.
|
|
//
|
|
if (d.Value & SMMCFG_SW_COMPRESSION) {
|
|
return S_ONE;
|
|
}
|
|
|
|
return S_ZERO;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetDataEncryption (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
BOOL reqDataEncrypt;
|
|
|
|
if (!pGetRasDataFromMemDb (S_SMM_OPTIONS, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
//
|
|
// data should be encrypted if 0x1000 is set.
|
|
//
|
|
reqDataEncrypt = (d.Value & 0x1000);
|
|
if (!reqDataEncrypt) {
|
|
reqDataEncrypt = (d.Value & 0x200);
|
|
}
|
|
|
|
return reqDataEncrypt ? TEXT("256") : TEXT("8");
|
|
}
|
|
|
|
PCTSTR
|
|
pGetExcludedProtocols (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
//
|
|
// Excluded protocols lists what protocols
|
|
// are _not_ available for a particular ras connection.
|
|
// This is a bit field where bits are set for each protocol
|
|
// that is excluded.
|
|
// NP_Nbf (0x1), NP_Ipx (0x2), NP_Ip (0x4)
|
|
// Luckily, these are the same definitions as for win9x, except
|
|
// each bit represents a protocol that is _enabled_ not
|
|
// _disabled_. Therefore, all we need to do is reverse the bottom
|
|
// three bits of the number.
|
|
//
|
|
|
|
if (!pGetRasDataFromMemDb (S_PROTOCOLS, &d)) {
|
|
//
|
|
// No data found, so we default to all protocols enabled.
|
|
//
|
|
return S_ZERO;
|
|
}
|
|
|
|
wsprintf (g_TempBuffer, TEXT("%d"), ~d.Value & 0x7);
|
|
|
|
return g_TempBuffer;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetVpnStrategy (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
if (g_CurrentDeviceType == RASTYPE_VPN) {
|
|
return TEXT("2");
|
|
}
|
|
|
|
return S_EMPTY;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetBaseProtocol (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
//
|
|
// Only supported protocol types for NT 5 are
|
|
// BP_PPP (0x1), BP_SLIP (0x2), and BP_RAS (0x3)
|
|
//
|
|
// If we can't find one, we default to BP_PPP.
|
|
//
|
|
if (!pGetRasDataFromMemDb (S_SMM, &d) || StringIMatch (d.String, S_PPP)) {
|
|
return S_ONE;
|
|
}
|
|
|
|
//
|
|
// MaP CSLIP to SLIP -- Header Compression will be on.
|
|
//
|
|
if (StringIMatch (d.String, S_SLIP) || StringIMatch (d.String, S_CSLIP)) {
|
|
return TEXT("2");
|
|
}
|
|
|
|
DEBUGMSG ((
|
|
DBG_WARNING,
|
|
"RAS Migration: Unusable base protocol type (%s) for entry %s. Forcing PPP.",
|
|
d.String,
|
|
g_CurrentConnection
|
|
));
|
|
|
|
// we are going to return an invalid protocol so the connection
|
|
// does not get migrated.
|
|
return TEXT("3");
|
|
}
|
|
|
|
PCTSTR
|
|
pGetCredPassword (
|
|
VOID
|
|
)
|
|
{
|
|
return S_EMPTY;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetCredDomain (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_DOMAIN, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
|
|
return d.String;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetCredName (
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_RAS_DATA d;
|
|
|
|
if (!pGetRasDataFromMemDb (S_USER, &d)) {
|
|
return S_EMPTY;
|
|
}
|
|
|
|
return d.String;
|
|
}
|
|
|
|
PCTSTR
|
|
pGetCredMask (
|
|
VOID
|
|
)
|
|
{
|
|
return TEXT("0x00000005");
|
|
}
|
|
|
|
PCTSTR
|
|
pGetType (
|
|
VOID
|
|
)
|
|
{
|
|
|
|
if (g_CurrentDeviceType == RASTYPE_VPN) {
|
|
|
|
return TEXT("2");
|
|
}
|
|
else {
|
|
return S_ONE;
|
|
}
|
|
|
|
}
|
|
|
|
BOOL
|
|
pCreateUserPhonebook (
|
|
IN PCTSTR PbkFile
|
|
)
|
|
{
|
|
PCTSTR tempKey;
|
|
BOOL noError = FALSE;
|
|
MEMDB_RAS_DATA d;
|
|
MEMDB_ENUM e;
|
|
HANDLE file;
|
|
UINT i;
|
|
UINT count;
|
|
|
|
tempKey = JoinPathsInPoolEx ((NULL, MEMDB_CATEGORY_RAS_INFO, TEXT("\\*"), NULL));
|
|
|
|
if (MemDbEnumFirst (&e, tempKey, ENUMFLAG_ALL, 1, 1)) {
|
|
|
|
//
|
|
// Open the phonebook file and set the file pointer to the EOF.
|
|
//
|
|
|
|
file = CreateFile (
|
|
PbkFile,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
0, // No sharing.
|
|
NULL, // No inheritance
|
|
OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL // No template file.
|
|
);
|
|
|
|
if (file == INVALID_HANDLE_VALUE) {
|
|
DEBUGMSG ((DBG_ERROR, "Unable to open the phonebook file (%s)", PbkFile));
|
|
FreePathString (tempKey);
|
|
return FALSE;
|
|
}
|
|
|
|
SetFilePointer (file, 0, NULL, FILE_END);
|
|
|
|
//
|
|
// Now, enumerate all of the entries and write a phonebook entry to this
|
|
// file for each.
|
|
//
|
|
|
|
do {
|
|
|
|
g_CurrentConnection = e.KeyName;
|
|
g_CurrentDevice = 0;
|
|
if (!pGetRasDataFromMemDb (S_DEVICE_TYPE, &d)) {
|
|
g_CurrentDeviceType = RASTYPE_PHONE;
|
|
}
|
|
else {
|
|
if (StringIMatch (d.String, S_MODEM)) {
|
|
g_CurrentDeviceType = RASTYPE_PHONE;
|
|
}
|
|
else if (StringIMatch (d.String, S_VPN)) {
|
|
g_CurrentDeviceType = RASTYPE_VPN;
|
|
}
|
|
else {
|
|
g_CurrentDeviceType = RASTYPE_PHONE;
|
|
}
|
|
}
|
|
|
|
|
|
noError = TRUE;
|
|
|
|
//
|
|
// Add this entry to the phonebook.
|
|
//
|
|
|
|
//
|
|
// Write title.
|
|
//
|
|
noError &= WriteFileString (file, TEXT("["));
|
|
noError &= WriteFileString (file, g_CurrentConnection);
|
|
noError &= WriteFileString (file, TEXT("]\r\n"));
|
|
|
|
|
|
//
|
|
// Write base entry settings.
|
|
//
|
|
noError &= pWriteSettings (file, g_EntrySettings);
|
|
|
|
|
|
|
|
|
|
if (!pGetRasDataFromMemDb (S_DEVICECOUNT, &d)) {
|
|
count = 1;
|
|
DEBUGMSG ((DBG_WHOOPS, "No devices listed in memdb for connections %s.", g_CurrentConnection));
|
|
}
|
|
else {
|
|
count = d.Value;
|
|
}
|
|
for (i = 0; i < count; i++) {
|
|
|
|
g_CurrentDevice = i;
|
|
|
|
//
|
|
// Write media settings.
|
|
//
|
|
noError &= WriteFileString (file, TEXT("\r\n"));
|
|
noError &= pWriteSettings (file, g_MediaSettings);
|
|
|
|
//
|
|
// Write modem Device settings.
|
|
//
|
|
noError &= WriteFileString (file, TEXT("\r\n"));
|
|
noError &= pWriteSettings (file, g_ModemDeviceSettings);
|
|
noError &= WriteFileString (file, TEXT("\r\n\r\n"));
|
|
|
|
|
|
}
|
|
|
|
g_InSwitchSection = TRUE;
|
|
|
|
noError &= WriteFileString (file, TEXT("\r\n"));
|
|
noError &= pWriteSettings (file, g_SwitchDeviceSettings);
|
|
noError &= WriteFileString (file, TEXT("\r\n\r\n"));
|
|
|
|
g_InSwitchSection = FALSE;
|
|
|
|
|
|
if (!noError) {
|
|
LOG ((
|
|
LOG_ERROR,
|
|
"Error while writing phonebook for %s.",
|
|
g_CurrentConnection
|
|
));
|
|
}
|
|
|
|
} while (MemDbEnumNext (&e));
|
|
|
|
//
|
|
// Close the handle to the phone book file.
|
|
//
|
|
CloseHandle (file);
|
|
}
|
|
ELSE_DEBUGMSG ((DBG_RASMIG, "No dial-up entries for current user."));
|
|
|
|
FreePathString (tempKey);
|
|
|
|
return noError;
|
|
}
|
|
|
|
MIG_OBJECTSTRINGHANDLE
|
|
pCreate9xPbkFile (
|
|
VOID
|
|
)
|
|
{
|
|
MIG_OBJECTSTRINGHANDLE result = NULL;
|
|
PCTSTR nativeName = NULL;
|
|
TCHAR windir [MAX_PATH];
|
|
BOOL b = FALSE;
|
|
|
|
GetWindowsDirectory (windir, MAX_PATH);
|
|
result = IsmCreateObjectHandle (windir, TEXT("usmt.pbk"));
|
|
if (!result) {
|
|
return NULL;
|
|
}
|
|
nativeName = IsmGetNativeObjectName (g_FileTypeId, result);
|
|
if (!nativeName) {
|
|
IsmDestroyObjectHandle (result);
|
|
return NULL;
|
|
}
|
|
|
|
if (pIs9xRasInstalled ()) {
|
|
|
|
g_DeviceTable = HtAllocWithData (sizeof (PTSTR));
|
|
MYASSERT (g_DeviceTable);
|
|
|
|
pInitializeDeviceTable ();
|
|
|
|
__try {
|
|
b = pGetPerUserSettings ();
|
|
b = b && pGetPerConnectionSettings ();
|
|
b = b && pCreateUserPhonebook (nativeName);
|
|
}
|
|
__except (TRUE) {
|
|
DEBUGMSG ((DBG_WHOOPS, "Caught an exception while processing ras settings."));
|
|
}
|
|
HtFree (g_DeviceTable);
|
|
}
|
|
|
|
IsmReleaseMemory (nativeName);
|
|
|
|
if (!b) {
|
|
IsmDestroyObjectHandle (result);
|
|
result = NULL;
|
|
}
|
|
|
|
return result;
|
|
}
|