1409 lines
36 KiB
C++
1409 lines
36 KiB
C++
|
/*-----------------------------------------------------------------------------
|
||
|
misc.cpp
|
||
|
|
||
|
service functions
|
||
|
|
||
|
History:
|
||
|
1/7/98 DONALDM Moved to new ICW project and string
|
||
|
and nuked 16 bit stuff
|
||
|
-----------------------------------------------------------------------------*/
|
||
|
|
||
|
//#include <stdio.h>
|
||
|
#include "obcomglb.h"
|
||
|
#include <shlobj.h>
|
||
|
#include <winsock2.h>
|
||
|
#include <assert.h>
|
||
|
#include <ras.h>
|
||
|
#include <util.h>
|
||
|
#include <inetreg.h>
|
||
|
#include <userenv.h>
|
||
|
#include <userenvp.h>
|
||
|
#include <shlwapi.h>
|
||
|
#include <sddl.h>
|
||
|
extern "C"
|
||
|
{
|
||
|
#include <sputils.h>
|
||
|
}
|
||
|
|
||
|
#define DIR_SIGNUP L"signup"
|
||
|
#define DIR_WINDOWS L"windows"
|
||
|
#define DIR_SYSTEM L"system"
|
||
|
#define DIR_TEMP L"temp"
|
||
|
#define INF_DEFAULT L"SPAM SPAM SPAM SPAM SPAM SPAM EGGS AND SPAM"
|
||
|
const WCHAR cszFALSE[] = L"FALSE";
|
||
|
const WCHAR cszTRUE[] = L"TRUE";
|
||
|
|
||
|
BOOL g_bGotProxy=FALSE;
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
// NAME: GetSz
|
||
|
//
|
||
|
// Load strings from resources
|
||
|
//
|
||
|
// Created 1/28/96, Chris Kauffman
|
||
|
//+----------------------------------------------------------------------------
|
||
|
|
||
|
LPWSTR GetSz(DWORD dwszID)
|
||
|
{
|
||
|
/*
|
||
|
LPWSTR psz = szStrTable[iSzTable];
|
||
|
|
||
|
iSzTable++;
|
||
|
if (iSzTable >= MAX_STRINGS)
|
||
|
iSzTable = 0;
|
||
|
|
||
|
if (!LoadString(_Module.GetModuleInstance(), dwszID, psz, 512))
|
||
|
{
|
||
|
*psz = 0;
|
||
|
}
|
||
|
|
||
|
return (psz);
|
||
|
*/
|
||
|
return (NULL);
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ProcessDBCS
|
||
|
//
|
||
|
// Synopsis: Converts control to use DBCS compatible font
|
||
|
// Use this at the beginning of the dialog procedure
|
||
|
//
|
||
|
// Note that this is required due to a bug in Win95-J that prevents
|
||
|
// it from properly mapping MS Shell Dlg. This hack is not needed
|
||
|
// under winNT.
|
||
|
//
|
||
|
// Arguments: hwnd - Window handle of the dialog
|
||
|
// cltID - ID of the control you want changed.
|
||
|
//
|
||
|
// Returns: ERROR_SUCCESS
|
||
|
//
|
||
|
// History: 4/31/97 a-frankh Created
|
||
|
// 5/13/97 jmazner Stole from CM to use here
|
||
|
//----------------------------------------------------------------------------
|
||
|
void ProcessDBCS(HWND hDlg, int ctlID)
|
||
|
{
|
||
|
HFONT hFont = NULL;
|
||
|
|
||
|
/*if( IsNT() )
|
||
|
{
|
||
|
return;
|
||
|
}*/
|
||
|
|
||
|
hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
|
||
|
if (hFont == NULL)
|
||
|
hFont = (HFONT) GetStockObject(SYSTEM_FONT);
|
||
|
if (hFont != NULL)
|
||
|
SendMessage(GetDlgItem(hDlg, ctlID), WM_SETFONT, (WPARAM) hFont, MAKELPARAM(TRUE, 0));
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
// StoreInSignUpReg
|
||
|
//
|
||
|
// Created 3/18/96, Chris Kauffman
|
||
|
// ############################################################################
|
||
|
HRESULT StoreInSignUpReg(LPBYTE lpbData, DWORD dwSize, DWORD dwType, LPCWSTR pszKey)
|
||
|
{
|
||
|
HRESULT hr = ERROR_ACCESS_DENIED;
|
||
|
HKEY hKey;
|
||
|
|
||
|
hr = RegCreateKey(HKEY_LOCAL_MACHINE, SIGNUPKEY, &hKey);
|
||
|
if (hr != ERROR_SUCCESS) goto StoreInSignUpRegExit;
|
||
|
hr = RegSetValueEx(hKey, pszKey, 0,dwType,lpbData,dwSize);
|
||
|
|
||
|
|
||
|
RegCloseKey(hKey);
|
||
|
|
||
|
StoreInSignUpRegExit:
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT ReadSignUpReg(LPBYTE lpbData, DWORD *pdwSize, DWORD dwType, LPCWSTR pszKey)
|
||
|
{
|
||
|
HRESULT hr = ERROR_ACCESS_DENIED;
|
||
|
HKEY hKey = 0;
|
||
|
|
||
|
hr = RegOpenKey(HKEY_LOCAL_MACHINE, SIGNUPKEY, &hKey);
|
||
|
if (hr != ERROR_SUCCESS) goto ReadSignUpRegExit;
|
||
|
hr = RegQueryValueEx(hKey, pszKey, 0,&dwType,lpbData,pdwSize);
|
||
|
|
||
|
ReadSignUpRegExit:
|
||
|
if (hKey) RegCloseKey (hKey);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT DeleteSignUpReg(LPCWSTR pszKey)
|
||
|
{
|
||
|
HRESULT hr = ERROR_ACCESS_DENIED;
|
||
|
HKEY hKey = 0;
|
||
|
|
||
|
hr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SIGNUPKEY, 0, KEY_ALL_ACCESS, &hKey);
|
||
|
if (hr != ERROR_SUCCESS) goto ReadSignUpRegExit;
|
||
|
hr = RegDeleteValue(hKey, pszKey);
|
||
|
|
||
|
ReadSignUpRegExit:
|
||
|
if (hKey) RegCloseKey (hKey);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
// GetDataFromISPFile
|
||
|
//
|
||
|
// This function will read a specific piece of information from an ISP file.
|
||
|
//
|
||
|
// Created 3/16/96, Chris Kauffman
|
||
|
// ############################################################################
|
||
|
HRESULT GetDataFromISPFile
|
||
|
(
|
||
|
LPWSTR pszISPCode,
|
||
|
LPWSTR pszSection,
|
||
|
LPWSTR pszDataName,
|
||
|
LPWSTR pszOutput,
|
||
|
DWORD cchOutput)
|
||
|
{
|
||
|
LPWSTR pszTemp;
|
||
|
HRESULT hr = ERROR_SUCCESS;
|
||
|
WCHAR szTempPath[MAX_PATH];
|
||
|
//WCHAR szBuff256[256];
|
||
|
|
||
|
*pszOutput = L'\0'; // since lstrlen(pszOutput) is used later when
|
||
|
// pszOutput may be otherwise still uninitialized
|
||
|
|
||
|
// Locate ISP file
|
||
|
if (!SearchPath(NULL, pszISPCode, INF_SUFFIX,MAX_PATH,szTempPath,&pszTemp))
|
||
|
{
|
||
|
//wsprintf(szBuff256, L"Can not find:%s%s (%d) (connect.exe)", pszISPCode,INF_SUFFIX,GetLastError());
|
||
|
////AssertMsg(0, szBuff256);
|
||
|
//lstrcpyn(szTempPath, pszISPCode, MAX_PATH);
|
||
|
//lstrcpyn(&szTempPath[lstrlen(szTempPath)], INF_SUFFIX, MAX_PATH-lstrlen(szTempPath));
|
||
|
//wsprintf(szBuff256, GetSz(IDS_CANTLOADINETCFG), szTempPath);
|
||
|
////MessageBox(NULL, szBuff256, GetSz(IDS_TITLE),MB_MYERROR);
|
||
|
hr = ERROR_FILE_NOT_FOUND;
|
||
|
} else if (!GetPrivateProfileString(pszSection, pszDataName, INF_DEFAULT,
|
||
|
pszOutput, (int)cchOutput, szTempPath))
|
||
|
{
|
||
|
//TraceMsg(TF_GENERAL, L"ICWHELP: %s not specified in ISP file.\n", pszDataName);
|
||
|
hr = ERROR_FILE_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
// 10/23/96 jmazner Normandy #9921
|
||
|
// CompareString does _not_ have same return values as lsrtcmp!
|
||
|
// Return value of 2 indicates strings are equal.
|
||
|
//if (!CompareString(LOCALE_SYSTEM_DEFAULT, 0, INF_DEFAULT,lstrlen(INF_DEFAULT),pszOutput,lstrlen(pszOutput)))
|
||
|
if (2 == CompareString(LOCALE_SYSTEM_DEFAULT, 0, INF_DEFAULT,lstrlen(INF_DEFAULT),pszOutput,lstrlen(pszOutput)))
|
||
|
{
|
||
|
hr = ERROR_FILE_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
if (hr != ERROR_SUCCESS && cchOutput)
|
||
|
*pszOutput = L'\0'; // I suppose if CompareString fails, this is not
|
||
|
// redundant with the first *pszOutput = L'\0';.
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
// GetINTFromISPFile
|
||
|
//
|
||
|
// This function will read a specific integer from an ISP file.
|
||
|
//
|
||
|
//
|
||
|
// ############################################################################
|
||
|
HRESULT GetINTFromISPFile
|
||
|
(
|
||
|
LPWSTR pszISPCode,
|
||
|
LPWSTR pszSection,
|
||
|
LPWSTR pszDataName,
|
||
|
int far *lpData,
|
||
|
int iDefaultValue
|
||
|
)
|
||
|
{
|
||
|
LPWSTR pszTemp;
|
||
|
HRESULT hr = ERROR_SUCCESS;
|
||
|
WCHAR szTempPath[MAX_PATH];
|
||
|
//WCHAR szBuff256[256];
|
||
|
|
||
|
// Locate ISP file
|
||
|
if (!SearchPath(NULL, pszISPCode, INF_SUFFIX,MAX_PATH,szTempPath,&pszTemp))
|
||
|
{
|
||
|
//wsprintf(szBuff256, L"Can not find:%s%s (%d) (connect.exe)", pszISPCode,INF_SUFFIX,GetLastError());
|
||
|
////AssertMsg(0, szBuff256);
|
||
|
//lstrcpyn(szTempPath, pszISPCode, MAX_PATH);
|
||
|
//lstrcpyn(&szTempPath[lstrlen(szTempPath)], INF_SUFFIX, MAX_PATH-lstrlen(szTempPath));
|
||
|
//wsprintf(szBuff256, GetSz(IDS_CANTLOADINETCFG), szTempPath);
|
||
|
//MessageBox(NULL, szBuff256, GetSz(IDS_TITLE),MB_MYERROR);
|
||
|
hr = ERROR_FILE_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
*lpData = GetPrivateProfileInt(pszSection,
|
||
|
pszDataName,
|
||
|
iDefaultValue,
|
||
|
szTempPath);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: IsNT
|
||
|
//
|
||
|
// Synopsis: findout If we are running on NT
|
||
|
//
|
||
|
// Arguements: none
|
||
|
//
|
||
|
// Return: TRUE - Yes
|
||
|
// FALSE - No
|
||
|
//
|
||
|
//--------------------------------------------------------------------
|
||
|
BOOL IsNT ()
|
||
|
{
|
||
|
OSVERSIONINFO OsVersionInfo;
|
||
|
|
||
|
ZeroMemory(&OsVersionInfo, sizeof(OSVERSIONINFO));
|
||
|
OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||
|
GetVersionEx(&OsVersionInfo);
|
||
|
return (VER_PLATFORM_WIN32_NT == OsVersionInfo.dwPlatformId);
|
||
|
|
||
|
} //end of IsNT function call
|
||
|
|
||
|
//+-------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: IsNT4SP3Lower
|
||
|
//
|
||
|
// Synopsis: findout If we are running on NTSP3 or lower
|
||
|
//
|
||
|
// Arguements: none
|
||
|
//
|
||
|
// Return: TRUE - Yes
|
||
|
// FALSE - No
|
||
|
//
|
||
|
//--------------------------------------------------------------------
|
||
|
|
||
|
BOOL IsNT4SP3Lower()
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// ############################################################################
|
||
|
HRESULT ClearProxySettings()
|
||
|
{
|
||
|
/*
|
||
|
HINSTANCE hinst = NULL;
|
||
|
FARPROC fp;
|
||
|
HRESULT hr = ERROR_SUCCESS;
|
||
|
|
||
|
hinst = LoadLibrary(L"INETCFG.DLL");
|
||
|
if (hinst)
|
||
|
{
|
||
|
fp = GetProcAddress(hinst, "InetGetProxy");
|
||
|
if (!fp)
|
||
|
{
|
||
|
hr = GetLastError();
|
||
|
goto ClearProxySettingsExit;
|
||
|
}
|
||
|
//hr = ((PFNINETGETPROXY)fp)(&g_bProxy, NULL, 0,NULL,0);
|
||
|
if (hr == ERROR_SUCCESS)
|
||
|
g_bGotProxy = TRUE;
|
||
|
else
|
||
|
goto ClearProxySettingsExit;
|
||
|
|
||
|
if (g_bProxy)
|
||
|
{
|
||
|
fp = GetProcAddress(hinst, "InetSetProxy");
|
||
|
if (!fp)
|
||
|
{
|
||
|
hr = GetLastError();
|
||
|
goto ClearProxySettingsExit;
|
||
|
}
|
||
|
((PFNINETSETPROXY)fp)(FALSE, (LPCSTR)NULL, (LPCSTR)NULL);
|
||
|
}
|
||
|
} else {
|
||
|
hr = GetLastError();
|
||
|
}
|
||
|
|
||
|
ClearProxySettingsExit:
|
||
|
if (hinst)
|
||
|
FreeLibrary(hinst);
|
||
|
return hr;
|
||
|
*/
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
HRESULT RestoreProxySettings()
|
||
|
{
|
||
|
/*
|
||
|
HINSTANCE hinst = NULL;
|
||
|
FARPROC fp;
|
||
|
HRESULT hr = ERROR_SUCCESS;
|
||
|
|
||
|
hinst = LoadLibrary(L"INETCFG.DLL");
|
||
|
if (hinst && g_bGotProxy)
|
||
|
{
|
||
|
fp = GetProcAddress(hinst, "InetSetProxy");
|
||
|
if (!fp)
|
||
|
{
|
||
|
hr = GetLastError();
|
||
|
goto RestoreProxySettingsExit;
|
||
|
}
|
||
|
((PFNINETSETPROXY)fp)(g_bProxy, (LPCSTR)NULL, (LPCSTR)NULL);
|
||
|
} else {
|
||
|
hr = GetLastError();
|
||
|
}
|
||
|
|
||
|
RestoreProxySettingsExit:
|
||
|
if (hinst)
|
||
|
FreeLibrary(hinst);
|
||
|
return hr;
|
||
|
*/
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
BOOL FSz2Dw(LPCWSTR pSz, LPDWORD dw)
|
||
|
{
|
||
|
DWORD val = 0;
|
||
|
while (*pSz && *pSz != L'.')
|
||
|
{
|
||
|
if (*pSz >= L'0' && *pSz <= L'9')
|
||
|
{
|
||
|
val *= 10;
|
||
|
val += *pSz++ - L'0';
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return FALSE; //bad number
|
||
|
}
|
||
|
}
|
||
|
*dw = val;
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
LPWSTR GetNextNumericChunk(LPWSTR psz, LPWSTR pszLim, LPWSTR* ppszNext)
|
||
|
{
|
||
|
LPWSTR pszEnd;
|
||
|
|
||
|
// init for error case
|
||
|
*ppszNext = NULL;
|
||
|
// skip non numerics if any to start of next numeric chunk
|
||
|
while(*psz<L'0' || *psz>L'9')
|
||
|
{
|
||
|
if(psz >= pszLim) return NULL;
|
||
|
psz++;
|
||
|
}
|
||
|
// skip all numerics to end of country code
|
||
|
for(pszEnd=psz; *pszEnd>=L'0' && *pszEnd<=L'9' && pszEnd<pszLim; pszEnd++)
|
||
|
;
|
||
|
// zap whatever delimiter there was to terminate this chunk
|
||
|
*pszEnd++ = L'\0';
|
||
|
// return ptr to next chunk (pszEnd now points to it)
|
||
|
if(pszEnd<pszLim)
|
||
|
*ppszNext = pszEnd;
|
||
|
|
||
|
return psz; // return ptr to start of chunk
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
// BOOL FSz2DwEx(PCSTR pSz, DWORD *dw)
|
||
|
// Accepts -1 as a valid number. currently this is used for LCID, since all langs has a LDID == -1
|
||
|
BOOL FSz2DwEx(LPCWSTR pSz, DWORD far *dw)
|
||
|
{
|
||
|
DWORD val = 0;
|
||
|
BOOL bNeg = FALSE;
|
||
|
while (*pSz)
|
||
|
{
|
||
|
if( *pSz == L'-' )
|
||
|
{
|
||
|
bNeg = TRUE;
|
||
|
pSz++;
|
||
|
}
|
||
|
else if ((*pSz >= L'0' && *pSz <= L'9'))
|
||
|
{
|
||
|
val *= 10;
|
||
|
val += *pSz++ - L'0';
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return FALSE; //bad number
|
||
|
}
|
||
|
}
|
||
|
if(bNeg)
|
||
|
val = 0 - val;
|
||
|
|
||
|
*dw = val;
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
// BOOL FSz2WEx(PCSTR pSz, WORD *w)
|
||
|
//Accepts -1 as a valid number. currently this is used for LCID, since all langs has a LDID == -1
|
||
|
BOOL FSz2WEx(LPCWSTR pSz, WORD far *w)
|
||
|
{
|
||
|
DWORD dw;
|
||
|
if (FSz2DwEx(pSz, &dw))
|
||
|
{
|
||
|
*w = (WORD)dw;
|
||
|
return TRUE;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
// BOOL FSz2W(PCSTR pSz, WORD *w)
|
||
|
BOOL FSz2W(LPCWSTR pSz, WORD far *w)
|
||
|
{
|
||
|
DWORD dw;
|
||
|
if (FSz2Dw(pSz, &dw))
|
||
|
{
|
||
|
*w = (WORD)dw;
|
||
|
return TRUE;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
WORD Sz2W (LPCWSTR szBuf)
|
||
|
{
|
||
|
DWORD dw;
|
||
|
if (FSz2Dw(szBuf, &dw))
|
||
|
{
|
||
|
return (WORD)dw;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
// BOOL FSz2B(PCSTR pSz, BYTE *pb)
|
||
|
BOOL FSz2BOOL(LPCWSTR pSz, BOOL far *pbool)
|
||
|
{
|
||
|
if (lstrcmpi(cszFALSE, pSz) == 0)
|
||
|
{
|
||
|
*pbool = (BOOL)FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*pbool = (BOOL)TRUE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
// BOOL FSz2B(PCSTR pSz, BYTE *pb)
|
||
|
BOOL FSz2B(LPCWSTR pSz, BYTE far *pb)
|
||
|
{
|
||
|
DWORD dw;
|
||
|
if (FSz2Dw(pSz, &dw))
|
||
|
{
|
||
|
*pb = (BYTE)dw;
|
||
|
return TRUE;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL FSz2SPECIAL(LPCWSTR pSz, BOOL far *pbool, BOOL far *pbIsSpecial, int far *pInt)
|
||
|
{
|
||
|
// See if the value is a BOOL (TRUE or FALSE)
|
||
|
if (lstrcmpi(cszFALSE, pSz) == 0)
|
||
|
{
|
||
|
*pbool = FALSE;
|
||
|
*pbIsSpecial = FALSE;
|
||
|
}
|
||
|
else if (lstrcmpi(cszTRUE, pSz) == 0)
|
||
|
{
|
||
|
*pbool = (BOOL)TRUE;
|
||
|
*pbIsSpecial = FALSE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Not a BOOL, so it must be special
|
||
|
*pbool = (BOOL)FALSE;
|
||
|
*pbIsSpecial = TRUE;
|
||
|
*pInt = _wtoi(pSz);
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
int FIsDigit( int c )
|
||
|
{
|
||
|
WCHAR szIn[2];
|
||
|
WORD rwOut[2];
|
||
|
szIn[0] = (WCHAR)c;
|
||
|
szIn[1] = L'\0';
|
||
|
GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, szIn,-1,rwOut);
|
||
|
return rwOut[0] & C1_DIGIT;
|
||
|
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
LPBYTE MyMemSet(LPBYTE dest, int c, size_t count)
|
||
|
{
|
||
|
LPVOID pv = dest;
|
||
|
LPVOID pvEnd = (LPVOID)(dest + (WORD)count);
|
||
|
while (pv < pvEnd)
|
||
|
{
|
||
|
*(LPINT)pv = c;
|
||
|
//((WORD)pv)++;
|
||
|
pv=((LPINT)pv)+1;
|
||
|
}
|
||
|
return dest;
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
LPBYTE MyMemCpy(LPBYTE dest, const LPBYTE src, size_t count)
|
||
|
{
|
||
|
LPBYTE pbDest = (LPBYTE)dest;
|
||
|
LPBYTE pbSrc = (LPBYTE)src;
|
||
|
LPBYTE pbEnd = (LPBYTE)((DWORD_PTR)src + (DWORD_PTR)count);
|
||
|
while (pbSrc < pbEnd)
|
||
|
{
|
||
|
*pbDest = *pbSrc;
|
||
|
pbSrc++;
|
||
|
pbDest++;
|
||
|
}
|
||
|
return dest;
|
||
|
}
|
||
|
|
||
|
// ############################################################################
|
||
|
BOOL ShowControl(HWND hDlg, int idControl, BOOL fShow)
|
||
|
{
|
||
|
HWND hWnd;
|
||
|
|
||
|
if (NULL == hDlg)
|
||
|
{
|
||
|
////AssertMsg(0, L"Null Param");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
hWnd = GetDlgItem(hDlg, idControl);
|
||
|
if (hWnd)
|
||
|
{
|
||
|
ShowWindow(hWnd, fShow ? SW_SHOW : SW_HIDE);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL isAlnum(WCHAR c)
|
||
|
{
|
||
|
if ((c >= L'0' && c <= L'9') ||
|
||
|
(c >= L'a' && c <= L'z') ||
|
||
|
(c >= L'A' && c <= L'Z') )
|
||
|
return TRUE;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
// ############################################################################
|
||
|
BOOL FShouldRetry2(HRESULT hrErr)
|
||
|
{
|
||
|
BOOL bRC;
|
||
|
|
||
|
if (hrErr == ERROR_LINE_BUSY ||
|
||
|
hrErr == ERROR_VOICE_ANSWER ||
|
||
|
hrErr == ERROR_NO_ANSWER ||
|
||
|
hrErr == ERROR_NO_CARRIER ||
|
||
|
hrErr == ERROR_AUTHENTICATION_FAILURE ||
|
||
|
hrErr == ERROR_PPP_TIMEOUT ||
|
||
|
hrErr == ERROR_REMOTE_DISCONNECTION ||
|
||
|
hrErr == ERROR_AUTH_INTERNAL ||
|
||
|
hrErr == ERROR_PROTOCOL_NOT_CONFIGURED ||
|
||
|
hrErr == ERROR_PPP_NO_PROTOCOLS_CONFIGURED)
|
||
|
{
|
||
|
bRC = TRUE;
|
||
|
} else {
|
||
|
bRC = FALSE;
|
||
|
}
|
||
|
|
||
|
return bRC;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: FCampusNetOverride
|
||
|
//
|
||
|
// Synopsis: Detect if the dial should be skipped for the campus network
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: TRUE - overide enabled
|
||
|
//
|
||
|
// History: 8/15/96 ChrisK Created
|
||
|
//
|
||
|
//-----------------------------------------------------------------------------
|
||
|
#if defined(PRERELEASE)
|
||
|
BOOL FCampusNetOverride()
|
||
|
{
|
||
|
HKEY hkey = NULL;
|
||
|
BOOL bRC = FALSE;
|
||
|
DWORD dwType = 0;
|
||
|
DWORD dwSize = 0;
|
||
|
DWORD dwData = 0;
|
||
|
|
||
|
if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE,
|
||
|
L"Software\\Microsoft\\ISignup\\Debug", &hkey))
|
||
|
goto FCampusNetOverrideExit;
|
||
|
|
||
|
dwSize = sizeof(dwData);
|
||
|
if (ERROR_SUCCESS != RegQueryValueEx(hkey, L"CampusNet", 0,&dwType,
|
||
|
(LPBYTE)&dwData, &dwSize))
|
||
|
goto FCampusNetOverrideExit;
|
||
|
|
||
|
////AssertMsg(REG_DWORD == dwType, L"Wrong value type for CampusNet. Must be DWORD.\r\n");
|
||
|
bRC = (0 != dwData);
|
||
|
|
||
|
if (bRC)
|
||
|
{
|
||
|
if (IDOK != MessageBox(NULL, L"DEBUG ONLY: CampusNet will be used.", L"Testing Override",MB_OKCANCEL))
|
||
|
bRC = FALSE;
|
||
|
}
|
||
|
FCampusNetOverrideExit:
|
||
|
if (hkey)
|
||
|
RegCloseKey(hkey);
|
||
|
|
||
|
return bRC;
|
||
|
}
|
||
|
#endif //PRERELEASE
|
||
|
|
||
|
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
// Function CopyUntil
|
||
|
//
|
||
|
// Synopsis Copy from source until destination until running out of source
|
||
|
// or until the next character of the source is the chend character
|
||
|
//
|
||
|
// Arguments dest - buffer to recieve characters
|
||
|
// src - source buffer
|
||
|
// lpdwLen - length of dest buffer
|
||
|
// chend - the terminating character
|
||
|
//
|
||
|
// Returns FALSE - ran out of room in dest buffer
|
||
|
//
|
||
|
// Histroy 10/25/96 ChrisK Created
|
||
|
//-----------------------------------------------------------------------------
|
||
|
static BOOL CopyUntil(LPWSTR *dest, LPWSTR *src, LPDWORD lpdwLen, WCHAR chend)
|
||
|
{
|
||
|
while ((L'\0' != **src) && (chend != **src) && (0 != *lpdwLen))
|
||
|
{
|
||
|
**dest = **src;
|
||
|
(*lpdwLen)--;
|
||
|
(*dest)++;
|
||
|
(*src)++;
|
||
|
}
|
||
|
return (0 != *lpdwLen);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: GenericMsg
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
void GenericMsg
|
||
|
(
|
||
|
HWND hwnd,
|
||
|
UINT uId,
|
||
|
LPCWSTR lpszArg,
|
||
|
UINT uType
|
||
|
)
|
||
|
{
|
||
|
WCHAR szTemp[MAX_STRING + 1];
|
||
|
WCHAR szMsg[MAX_STRING + MAX_PATH + 1];
|
||
|
LPWSTR psz;
|
||
|
|
||
|
//Assert( lstrlen( GetSz(uId) ) <= MAX_STRING );
|
||
|
|
||
|
psz = GetSz( (DWORD)uId );
|
||
|
if (psz) {
|
||
|
lstrcpy( szTemp, psz );
|
||
|
}
|
||
|
else {
|
||
|
szTemp[0] = '\0';
|
||
|
}
|
||
|
|
||
|
if (lpszArg)
|
||
|
{
|
||
|
//Assert( lstrlen( lpszArg ) <= MAX_PATH );
|
||
|
wsprintf(szMsg, szTemp, lpszArg);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lstrcpy(szMsg, szTemp);
|
||
|
}
|
||
|
//MessageBox(hwnd,
|
||
|
// szMsg,
|
||
|
// GetSz(IDS_TITLE),
|
||
|
// uType);
|
||
|
}
|
||
|
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// MakeWideFromAnsi
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// given a string, make a BSTR out of it.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// LPWSTR - [in]
|
||
|
// BYTE - [in]
|
||
|
//
|
||
|
// Output:
|
||
|
// LPWSTR - needs to be cast to final desired result
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
LPWSTR MakeWideStrFromAnsi
|
||
|
(
|
||
|
LPSTR psz,
|
||
|
BYTE bType
|
||
|
)
|
||
|
{
|
||
|
LPWSTR pwsz = NULL;
|
||
|
int i;
|
||
|
|
||
|
// arg checking.
|
||
|
//
|
||
|
if (!psz)
|
||
|
return NULL;
|
||
|
|
||
|
// compute the length of the required BSTR
|
||
|
//
|
||
|
i = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
|
||
|
if (i <= 0) return NULL;
|
||
|
|
||
|
// allocate the widestr
|
||
|
//
|
||
|
switch (bType) {
|
||
|
case STR_BSTR:
|
||
|
// -1 since it'll add it's own space for a NULL terminator
|
||
|
//
|
||
|
pwsz = (LPWSTR) SysAllocStringLen(NULL, i - 1);
|
||
|
break;
|
||
|
case STR_OLESTR:
|
||
|
pwsz = (LPWSTR) CoTaskMemAlloc(BYTES_REQUIRED_BY_CCH(i));
|
||
|
break;
|
||
|
//default:
|
||
|
////AssertMsg(0, L"Bogus String Type.");
|
||
|
}
|
||
|
|
||
|
if (!pwsz) return NULL;
|
||
|
MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, i);
|
||
|
pwsz[i - 1] = 0;
|
||
|
return pwsz;
|
||
|
}
|
||
|
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// MakeWideStrFromResId
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// given a resource ID, load it, and allocate a wide string for it.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// WORD - [in] resource id.
|
||
|
// BYTE - [in] type of string desired.
|
||
|
//
|
||
|
// Output:
|
||
|
// LPWSTR - needs to be cast to desired string type.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
LPWSTR MakeWideStrFromResourceId
|
||
|
(
|
||
|
WORD wId,
|
||
|
BYTE bType
|
||
|
)
|
||
|
{
|
||
|
//int i;
|
||
|
|
||
|
CHAR szTmp[512] = "0";
|
||
|
|
||
|
// load the string from the resources.
|
||
|
//
|
||
|
//i = LoadString(_Module.GetModuleInstance(), wId, szTmp, 512);
|
||
|
//if (!i) return NULL;
|
||
|
|
||
|
return MakeWideStrFromAnsi(szTmp, bType);
|
||
|
}
|
||
|
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// MakeWideStrFromWide
|
||
|
//=--------------------------------------------------------------------------=
|
||
|
// given a wide string, make a new wide string with it of the given type.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// LPWSTR - [in] current wide str.
|
||
|
// BYTE - [in] desired type of string.
|
||
|
//
|
||
|
// Output:
|
||
|
// LPWSTR
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
LPWSTR MakeWideStrFromWide
|
||
|
(
|
||
|
LPWSTR pwsz,
|
||
|
BYTE bType
|
||
|
)
|
||
|
{
|
||
|
LPWSTR pwszTmp = NULL;
|
||
|
int i;
|
||
|
|
||
|
if (!pwsz) return NULL;
|
||
|
|
||
|
// just copy the string, depending on what type they want.
|
||
|
//
|
||
|
switch (bType) {
|
||
|
case STR_OLESTR:
|
||
|
i = lstrlenW(pwsz);
|
||
|
pwszTmp = (LPWSTR)CoTaskMemAlloc(BYTES_REQUIRED_BY_CCH(i+1));
|
||
|
if (!pwszTmp) return NULL;
|
||
|
memcpy(pwszTmp, pwsz, (BYTES_REQUIRED_BY_CCH(i+1)));
|
||
|
break;
|
||
|
|
||
|
case STR_BSTR:
|
||
|
pwszTmp = (LPWSTR)SysAllocString(pwsz);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return pwszTmp;
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
GetCommonAppDataDirectory(
|
||
|
LPWSTR szDirectory,
|
||
|
DWORD cchDirectory
|
||
|
)
|
||
|
{
|
||
|
assert(MAX_PATH <= cchDirectory);
|
||
|
if (MAX_PATH > cchDirectory)
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||
|
}
|
||
|
|
||
|
return SHGetFolderPath(NULL, // hwndOwner
|
||
|
CSIDL_COMMON_APPDATA,
|
||
|
NULL, // hAccessToken
|
||
|
SHGFP_TYPE_CURRENT,
|
||
|
szDirectory
|
||
|
);
|
||
|
}
|
||
|
|
||
|
const LPWSTR cszPhoneBookPath =
|
||
|
L"Microsoft\\Network\\Connections\\Pbk";
|
||
|
const LPWSTR cszDefPhoneBook = L"rasphone.pbk";
|
||
|
HRESULT
|
||
|
GetDefaultPhoneBook(
|
||
|
LPWSTR szPhoneBook,
|
||
|
DWORD cchPhoneBook
|
||
|
)
|
||
|
{
|
||
|
WCHAR rgchDirectory[MAX_PATH];
|
||
|
int cch;
|
||
|
HRESULT hr = GetCommonAppDataDirectory(rgchDirectory, MAX_PATH);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
if (cchPhoneBook < (DWORD)(lstrlen(rgchDirectory) + lstrlen(cszPhoneBookPath) + lstrlen(cszDefPhoneBook) + 3)
|
||
|
)
|
||
|
{
|
||
|
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||
|
}
|
||
|
|
||
|
cch = wsprintf(szPhoneBook, L"%s\\%s\\%s",
|
||
|
rgchDirectory, cszPhoneBookPath, cszDefPhoneBook
|
||
|
);
|
||
|
assert(cch == lstrlen(rgchDirectory) + lstrlen(cszPhoneBookPath) +
|
||
|
lstrlen(cszDefPhoneBook) + 2
|
||
|
);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
INetNToW(
|
||
|
struct in_addr inaddr,
|
||
|
LPWSTR szAddr
|
||
|
)
|
||
|
{
|
||
|
USES_CONVERSION;
|
||
|
|
||
|
LPSTR sz = inet_ntoa(inaddr);
|
||
|
|
||
|
if (NULL != sz)
|
||
|
{
|
||
|
lstrcpy(szAddr, A2W(sz));
|
||
|
}
|
||
|
|
||
|
return (NULL != sz);
|
||
|
|
||
|
} // INetNToW
|
||
|
|
||
|
|
||
|
#ifndef REGSTR_VAL_NONETAUTODIAL
|
||
|
#define REGSTR_VAL_NONETAUTODIAL L"NoNetAutodial"
|
||
|
#endif
|
||
|
|
||
|
LONG
|
||
|
SetAutodial(
|
||
|
IN HKEY hUserRoot, // HKEY_CURRENT_USER or other user hive root
|
||
|
IN AUTODIAL_TYPE eType, // Type of autodial for the connectoid
|
||
|
IN LPCWSTR szConnectoidName, // NULL terminated string of connectoid name
|
||
|
IN BOOL bSetICWCompleted // set ICW completed flag or not
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Set a particular per-user registry settings to default an autodial
|
||
|
connectoid to the name specified and always dial the autodial connection, and/or
|
||
|
set the ICW completed flag
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
WIN32 Error code, i.e. ERROR_SUCCESS on success, -1 or other non-zero value
|
||
|
on failure.
|
||
|
|
||
|
Note:
|
||
|
|
||
|
Despite the name, this function sets ICW Completed flag if bSetICWCompleted
|
||
|
is true and do not set autodial if szConnectoidName is NULL.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
LONG ret = -1;
|
||
|
HKEY hKey = NULL;
|
||
|
DWORD dwRet = -1;
|
||
|
|
||
|
if (bSetICWCompleted)
|
||
|
{
|
||
|
if (ERROR_SUCCESS == RegCreateKey( hUserRoot,
|
||
|
ICWSETTINGSPATH,
|
||
|
&hKey) )
|
||
|
{
|
||
|
DWORD dwCompleted = 1;
|
||
|
|
||
|
ret = RegSetValueEx( hKey,
|
||
|
ICWCOMPLETEDKEY,
|
||
|
0,
|
||
|
REG_DWORD,
|
||
|
(CONST BYTE*)&dwCompleted,
|
||
|
sizeof(dwCompleted) );
|
||
|
TRACE1(L"Setting ICW Completed key 0x%08lx", ret);
|
||
|
|
||
|
RegCloseKey(hKey);
|
||
|
}
|
||
|
}
|
||
|
// Set the name if given, else do not change the entry.
|
||
|
if (szConnectoidName)
|
||
|
{
|
||
|
// Set the name of the connectoid for autodial.
|
||
|
// HKCU\RemoteAccess\InternetProfile
|
||
|
if (ERROR_SUCCESS == RegCreateKey( hUserRoot,
|
||
|
REGSTR_PATH_REMOTEACCESS,
|
||
|
&hKey) )
|
||
|
{
|
||
|
ret = RegSetValueEx( hKey,
|
||
|
REGSTR_VAL_INTERNETPROFILE,
|
||
|
0,
|
||
|
REG_SZ,
|
||
|
(BYTE*)szConnectoidName,
|
||
|
BYTES_REQUIRED_BY_SZ(szConnectoidName) );
|
||
|
TRACE2(L"Setting IE autodial connectoid to %s 0x%08lx", szConnectoidName, ret);
|
||
|
|
||
|
RegCloseKey(hKey);
|
||
|
}
|
||
|
|
||
|
hKey = NULL;
|
||
|
if (ERROR_SUCCESS == ret)
|
||
|
{
|
||
|
// Set setting in the registry that indicates whether autodialing is enabled.
|
||
|
// HKCU\Software\Microsoft\Windows\CurrentVersion\InternetSettings\EnableAutodial
|
||
|
if (ERROR_SUCCESS == RegCreateKey( hUserRoot,
|
||
|
REGSTR_PATH_INTERNET_SETTINGS,
|
||
|
&hKey) )
|
||
|
{
|
||
|
DWORD dwValue;
|
||
|
|
||
|
dwValue = (eType == AutodialTypeAlways || eType == AutodialTypeNoNet) ? 1 : 0;
|
||
|
ret = RegSetValueEx( hKey,
|
||
|
REGSTR_VAL_ENABLEAUTODIAL,
|
||
|
0,
|
||
|
REG_DWORD,
|
||
|
(BYTE*)&dwValue,
|
||
|
sizeof(DWORD) );
|
||
|
TRACE1(L"Enable/Disable IE Autodial 0x%08lx", ret);
|
||
|
|
||
|
|
||
|
dwValue = (eType == AutodialTypeNoNet) ? 1 : 0;
|
||
|
ret = RegSetValueEx( hKey,
|
||
|
REGSTR_VAL_NONETAUTODIAL,
|
||
|
0,
|
||
|
REG_DWORD,
|
||
|
(BYTE*)&dwValue,
|
||
|
sizeof(DWORD) );
|
||
|
TRACE1(L"Setting Autodial mode 0x%08lx", ret);
|
||
|
|
||
|
RegCloseKey(hKey);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
LONG
|
||
|
SetUserAutodial(
|
||
|
IN LPWSTR szProfileDir, // Directory containing a user's ntuser.dat file
|
||
|
IN AUTODIAL_TYPE eType, // type of autodial for the connectoid
|
||
|
IN LPCWSTR szConnectoidName,// NULL terminated string of connectoid name
|
||
|
IN BOOL bSetICWCompleted // set the ICW completed key or not
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Modified a user profile, specified by the profile directory, to enable
|
||
|
autodial. SE_BACKUP_NAME and SE_RESTORE_NAME privileges are required to
|
||
|
load and unload a user hive.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
WIN32 Error code, i.e. ERROR_SUCCESS on success, -1 or other non-zero value
|
||
|
on failure.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
const WCHAR OOBE_USER_HIVE[] = L"OOBEUSERHIVE";
|
||
|
|
||
|
HKEY hUserHive = NULL;
|
||
|
WCHAR szProfilePath[MAX_PATH+1] = L"";
|
||
|
LONG ret = -1;
|
||
|
|
||
|
lstrcpyn(szProfilePath, szProfileDir, MAX_CHARS_IN_BUFFER(szProfilePath));
|
||
|
pSetupConcatenatePaths(szProfilePath,
|
||
|
L"\\NTUSER.DAT",
|
||
|
MAX_CHARS_IN_BUFFER(szProfilePath),
|
||
|
NULL);
|
||
|
ret = RegLoadKey(HKEY_USERS, OOBE_USER_HIVE, szProfilePath);
|
||
|
if (ret == ERROR_SUCCESS)
|
||
|
{
|
||
|
ret = RegOpenKeyEx( HKEY_USERS,
|
||
|
OOBE_USER_HIVE,
|
||
|
0,
|
||
|
KEY_WRITE,
|
||
|
&hUserHive );
|
||
|
if (ERROR_SUCCESS == ret)
|
||
|
{
|
||
|
ret = SetAutodial(hUserHive, eType, szConnectoidName, bSetICWCompleted);
|
||
|
RegCloseKey(hUserHive);
|
||
|
TRACE1(L"Autodial set %s", szProfilePath);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TRACE2(L"RegOpenKey %s failed %d", szProfilePath, ret);
|
||
|
}
|
||
|
RegUnLoadKey(HKEY_USERS, OOBE_USER_HIVE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TRACE2(L"RegLoadKey %s failed %d", szProfilePath, ret);
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
MyGetUserProfileDirectory(
|
||
|
IN LPWSTR szUser, // a user account name
|
||
|
OUT LPWSTR szUserProfileDir, // buffer to receive null terminate string
|
||
|
IN OUT LPDWORD pcchSize // input the buffer size in TCHAR, including terminating NULL
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function does what the SDK function GetUserProfileDirectory does,
|
||
|
except that it accepts a user account name instead of handle to a user
|
||
|
token.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE - Success
|
||
|
|
||
|
FALSE - Failure
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
PSID pSid = NULL;
|
||
|
DWORD cbSid = 0;
|
||
|
LPWSTR szDomainName = NULL;
|
||
|
DWORD cbDomainName = 0;
|
||
|
SID_NAME_USE eUse = SidTypeUser;
|
||
|
BOOL bRet;
|
||
|
|
||
|
bRet = LookupAccountName(NULL,
|
||
|
szUser,
|
||
|
NULL,
|
||
|
&cbSid,
|
||
|
NULL,
|
||
|
&cbDomainName,
|
||
|
&eUse);
|
||
|
|
||
|
if (!bRet && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||
|
{
|
||
|
pSid = (PSID) LocalAlloc(LPTR, cbSid);
|
||
|
szDomainName = (LPWSTR) LocalAlloc(LPTR, cbDomainName * sizeof(TCHAR));
|
||
|
|
||
|
if (pSid && szDomainName)
|
||
|
{
|
||
|
bRet = LookupAccountName(NULL,
|
||
|
szUser,
|
||
|
pSid,
|
||
|
&cbSid,
|
||
|
szDomainName,
|
||
|
&cbDomainName,
|
||
|
&eUse);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if (bRet && SidTypeUser == eUse)
|
||
|
{
|
||
|
bRet = GetUserProfileDirFromSid(pSid, szUserProfileDir, pcchSize);
|
||
|
if (!bRet)
|
||
|
{
|
||
|
TRACE1(L"GetUserProfileDirFromSid (%d)", GetLastError());
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (SidTypeUser == eUse)
|
||
|
{
|
||
|
TRACE2(L"LookupAccountName %s (%d)", szUser, GetLastError());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pSid)
|
||
|
{
|
||
|
LocalFree(pSid);
|
||
|
pSid = NULL;
|
||
|
}
|
||
|
|
||
|
if (szDomainName)
|
||
|
{
|
||
|
LocalFree(szDomainName);
|
||
|
szDomainName = NULL;
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
BOOL EnumBuildInAdministrators(
|
||
|
OUT LPWSTR* pszAlias // list of name delimited by null, double null-terminated
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
List all the build-in administrator accounts created by Windows Setup.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE - Success
|
||
|
|
||
|
FALSE - Failure
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
WCHAR szReservedAdmins[MAX_PATH * 2] = L"";
|
||
|
PWCHAR p = NULL;
|
||
|
DWORD len;
|
||
|
BOOL ret = FALSE;
|
||
|
HINSTANCE hInstance = NULL;
|
||
|
|
||
|
if (pszAlias != NULL)
|
||
|
{
|
||
|
*pszAlias = NULL;
|
||
|
|
||
|
hInstance = LoadLibraryEx(OOBE_MAIN_DLL, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||
|
|
||
|
if (hInstance != NULL)
|
||
|
{
|
||
|
|
||
|
len = LoadString(hInstance,
|
||
|
566, // IDS_ACCTLIST_RESERVEDADMINS in OOBE_MAIN_DLL
|
||
|
szReservedAdmins,
|
||
|
MAX_CHARS_IN_BUFFER(szReservedAdmins));
|
||
|
if (len)
|
||
|
{
|
||
|
DWORD cbSize;
|
||
|
|
||
|
p = StrChr(szReservedAdmins, L'|');
|
||
|
while ( p )
|
||
|
{
|
||
|
PWCHAR t = CharNext(p);
|
||
|
*p = L'\0';
|
||
|
p = StrChr(t, L'|');
|
||
|
}
|
||
|
|
||
|
cbSize = sizeof(WCHAR) * (len + 1);
|
||
|
// Make sure we have enough space for
|
||
|
// double NULL terminate the return value
|
||
|
*pszAlias = (LPWSTR) GlobalAlloc(GPTR, cbSize + sizeof(WCHAR));
|
||
|
if (*pszAlias)
|
||
|
{
|
||
|
CopyMemory(*pszAlias, szReservedAdmins, cbSize);
|
||
|
// double NULL terminate the string
|
||
|
(*pszAlias)[cbSize / sizeof(WCHAR)] = L'\0';
|
||
|
ret = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FreeLibrary(hInstance);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
SetMultiUserAutodial(
|
||
|
IN AUTODIAL_TYPE eType, // type of autodial for the connectoid
|
||
|
IN LPCWSTR szConnectoidName,// NULL terminated string of connectoid name
|
||
|
IN BOOL bSetICWCompleted // set the ICW completed key or not
|
||
|
)
|
||
|
{
|
||
|
BOOL bSucceed = TRUE;
|
||
|
LONG lRet = ERROR_SUCCESS;
|
||
|
WCHAR szProfileDir[MAX_PATH+1] = L"";
|
||
|
DWORD dwSize;
|
||
|
LPWSTR szAdmins = NULL;
|
||
|
|
||
|
// SYSTEM
|
||
|
lRet = SetAutodial(HKEY_CURRENT_USER, eType, szConnectoidName, bSetICWCompleted);
|
||
|
if (lRet != ERROR_SUCCESS)
|
||
|
{
|
||
|
bSucceed = FALSE;
|
||
|
}
|
||
|
|
||
|
pSetupEnablePrivilege(SE_BACKUP_NAME, TRUE);
|
||
|
pSetupEnablePrivilege(SE_RESTORE_NAME, TRUE);
|
||
|
|
||
|
// Default User, which will apply to any new user profiles created
|
||
|
// afterward.
|
||
|
dwSize = MAX_CHARS_IN_BUFFER(szProfileDir);
|
||
|
if (GetDefaultUserProfileDirectory(szProfileDir, &dwSize))
|
||
|
{
|
||
|
lRet = SetUserAutodial(szProfileDir, eType, szConnectoidName, bSetICWCompleted);
|
||
|
if (lRet != ERROR_SUCCESS)
|
||
|
{
|
||
|
bSucceed = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Built-in Administrators, e.g. Administrator.
|
||
|
if (EnumBuildInAdministrators(&szAdmins))
|
||
|
{
|
||
|
LPWSTR szAdmin = szAdmins;
|
||
|
while (*szAdmin)
|
||
|
{
|
||
|
// MAX_CHARS_IN_BUFFER excludes the terminating NULL
|
||
|
dwSize = MAX_CHARS_IN_BUFFER(szProfileDir) + 1;
|
||
|
if (MyGetUserProfileDirectory(szAdmin, szProfileDir, &dwSize))
|
||
|
{
|
||
|
lRet = SetUserAutodial(szProfileDir, eType, szConnectoidName, bSetICWCompleted);
|
||
|
if (lRet != ERROR_SUCCESS)
|
||
|
{
|
||
|
bSucceed = FALSE;
|
||
|
}
|
||
|
}
|
||
|
szAdmin += (lstrlen(szAdmin) + 1);
|
||
|
}
|
||
|
GlobalFree(szAdmins);
|
||
|
}
|
||
|
|
||
|
return bSucceed;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
SetDefaultConnectoid(
|
||
|
IN AUTODIAL_TYPE eType, // type of autodial for the connectoid
|
||
|
IN LPCWSTR szConnectoidName // null terminated autodial connectoid name
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Set the default autodial connectoid for SYSTEM, Default User and
|
||
|
build-in administrators. Assume that this function is run in System
|
||
|
context, i.e. it is SYSTEM who runs OOBE.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE - Success to set all user accounts
|
||
|
|
||
|
FALSE - Failure to set any one of the user accounts
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
BOOL bSucceed = TRUE;
|
||
|
LONG lRet = ERROR_SUCCESS;
|
||
|
RASAUTODIALENTRY adEntry;
|
||
|
|
||
|
|
||
|
//
|
||
|
// IE on WinXP use Ras autodial address, instead of its own registry
|
||
|
// key for autodial connection name, but it keeps using its own registry
|
||
|
// key for autodial mode.
|
||
|
//
|
||
|
ZeroMemory(&adEntry, sizeof(RASAUTODIALENTRY));
|
||
|
adEntry.dwSize = sizeof(RASAUTODIALENTRY);
|
||
|
lstrcpyn(adEntry.szEntry, szConnectoidName,
|
||
|
sizeof(adEntry.szEntry)/sizeof(WCHAR)
|
||
|
);
|
||
|
lRet = RasSetAutodialAddress(NULL,
|
||
|
NULL,
|
||
|
&adEntry,
|
||
|
sizeof(RASAUTODIALENTRY),
|
||
|
1
|
||
|
);
|
||
|
TRACE2(L"Setting default autodial connectoid to %s %d\n",
|
||
|
szConnectoidName, lRet);
|
||
|
|
||
|
if (lRet != ERROR_SUCCESS)
|
||
|
{
|
||
|
bSucceed = FALSE;
|
||
|
return bSucceed;
|
||
|
}
|
||
|
|
||
|
bSucceed = SetMultiUserAutodial(eType, szConnectoidName, FALSE);
|
||
|
|
||
|
return bSucceed;
|
||
|
}
|
||
|
|