Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1146 lines
38 KiB

// PwdMsi.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include <winuser.h>
#include <stdio.h>
#include <lm.h>
#include <msi.h>
#include <msiquery.h>
#include <comdef.h>
#include <commdlg.h>
#include <Dsgetdc.h>
#include <eh.h>
#include "pwdfuncs.h"
#include "ADMTCrypt.h"
#include "PwdMsi.h"
bool b3DESNotInstalled = false;
bool bPESFileFound = false;
bool bPasswordNeeded = false;
HWND installWnd = 0;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is the constructor of a class that has been exported.
// see PwdMsi.h for the class definition
CPwdMsi::CPwdMsi()
{
return;
}
void LoadOLEAUT32OnNT4()
{
static BOOL bDone = FALSE;
static HMODULE hDllOleAut32 = NULL;
BOOL bIsNT4 = FALSE;
// only do this once
if (!bDone)
{
bDone = TRUE;
// test OS version
DWORD rc = NERR_Success;
SERVER_INFO_101 * servInfo = NULL;
// Check version info
rc = NetServerGetInfo(NULL, 101, (LPBYTE *)&servInfo);
if (rc == NERR_Success)
{
bIsNT4 = (servInfo->sv101_version_major < 5) ? TRUE : FALSE;
NetApiBufferFree(servInfo);
}
// if it is NT4, load oleaut32.dll
if (bIsNT4)
{
hDllOleAut32 = LoadLibrary(L"oleaut32.dll");
}
}
}
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 25 JAN 2001 *
* *
* This function is a callback function used by GetWndFromInstall*
* to compare titles and store the found HWND globally. *
* *
*********************************************************************/
//BEGIN CheckTitle
BOOL CALLBACK CheckTitle(HWND hwnd, LPARAM lParam)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local variables */
WCHAR sText[MAX_PATH];
WCHAR * pTitle;
BOOL bSuccess;
int len;
/* function body */
pTitle = (WCHAR*)lParam; //get the title to compare
//get the title of this window
len = GetWindowText(hwnd, sText, MAX_PATH);
if ((len) && (pTitle))
{
if (wcsstr(sText, pTitle))
{
installWnd = hwnd;
return FALSE;
}
}
return TRUE;
}
//END CheckTitle
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 25 JAN 2001 *
* *
* This function is responsible for getting the HWND of the *
* current installation to be used to display a MessageBox tied to *
* the install GUI. *
* *
*********************************************************************/
//BEGIN GetWndFromInstall
void GetWndFromInstall(MSIHANDLE hInstall)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local variables */
WCHAR szPropName[MAX_PATH];
UINT lret = ERROR_SUCCESS;
WCHAR sTitle[MAX_PATH];
DWORD nCount = MAX_PATH;
/* function body */
//get the installation's title
wcscpy(szPropName, L"ProductName");
lret = MsiGetProperty(hInstall, szPropName, sTitle, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sTitle, L"ADMT Password Migration DLL");
//get the window handle for the install GUI
EnumChildWindows(NULL, CheckTitle, (LPARAM)sTitle);
if (!installWnd)
installWnd = GetForegroundWindow();
}
//END GetWndFromInstall
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 11 DEC 2000 *
* *
* This function is responsible for retrieving a password *
* encryption key from the given path. *
* *
*********************************************************************/
//BEGIN RetrieveAndStorePwdKey
bool RetrieveAndStorePwdKey(WCHAR * sPwd, _bstr_t sPath)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local variables */
bool bRetrieved = false;
WCHAR * pDrive;
HANDLE hFile;
WIN32_FIND_DATA fDat;
_variant_t varData;
/* function body */
hFile = FindFirstFile((WCHAR*)sPath, &fDat);
//if found, retrieve and store the key
if (hFile != INVALID_HANDLE_VALUE)
{
FindClose(hFile);
try
{
bPESFileFound = true;
//get the data
varData = GetDataFromFloppy((WCHAR*)sPath);
if (varData.vt == (VT_UI1 | VT_ARRAY))
{
long uUBound;
LPBYTE pByte = NULL;
SafeArrayAccessData(varData.parray,(void**)&pByte);
BYTE byteKey = pByte[0];
SafeArrayUnaccessData(varData.parray);
//the first byte tells us if this key is password encrypted
//if password needed, return and have install display the UI
if (byteKey != 0)
{
if (sPwd)
{
//try saving the key with this password
try
{
CSourceCrypt aCryptObj; //create a crypt object
//try to store the key. If fails, it throws a com error caught below
aCryptObj.ImportEncryptionKey(varData, sPwd);
bRetrieved = true;
}
catch (_com_error& ce)
{
//if HES not installed, set flag
if (ce.Error() == NTE_KEYSET_NOT_DEF)
b3DESNotInstalled = true;
}
}
else
bPasswordNeeded = true;
}
else
{
bPasswordNeeded = false;
try
{
CSourceCrypt aCryptObj; //create a crypt object
//try to store the key. If fails, it throws a com error caught below
aCryptObj.ImportEncryptionKey(varData, NULL);
bRetrieved = true;
}
catch (_com_error& ce)
{
//if HES not installed, set flag
if (ce.Error() == NTE_KEYSET_NOT_DEF)
b3DESNotInstalled = true;
}
}
}
}
catch (...)
{
}
}
return bRetrieved;
}
//END RetrieveAndStorePwdKey
/**********************
* exported functions *
**********************/
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 12 SEPT 2000 *
* *
* This function is responsible for adding the PWMIG dll name to *
* the Multi-string value "Notification Packages" under the Lsa key. *
* *
*********************************************************************/
//BEGIN IsDC
PWDMSI_API UINT __stdcall IsDC(MSIHANDLE hInstall)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local constants */
const WCHAR sDCValue[2] = L"1";
/* local variables */
bool bDC = false;
DWORD dwLevel = 101;
LPSERVER_INFO_101 pBuf = NULL;
NET_API_STATUS nStatus;
WCHAR szPropName[MAX_PATH] = L"DC";
UINT lret = ERROR_SUCCESS;
/* function body */
nStatus = NetServerGetInfo(NULL,
dwLevel,
(LPBYTE *)&pBuf);
if (nStatus == NERR_Success)
{
//
// Check for the type of server.
//
if ((pBuf->sv101_type & SV_TYPE_DOMAIN_CTRL) ||
(pBuf->sv101_type & SV_TYPE_DOMAIN_BAKCTRL))
bDC = true;
NetApiBufferFree(pBuf);
}
if (bDC)
lret = MsiSetProperty(hInstall, szPropName, sDCValue);
return lret;
}
//END IsDC
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 12 SEPT 2000 *
* *
* This function is responsible for displaying a message box. *
* *
*********************************************************************/
//BEGIN DisplayExiting
PWDMSI_API UINT __stdcall DisplayExiting(MSIHANDLE hInstall)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local variables */
WCHAR sPropName[MAX_PATH];
UINT lret = ERROR_SUCCESS;
WCHAR sTitle[MAX_PATH];
WCHAR sMsg[MAX_PATH];
DWORD nCount = MAX_PATH;
bool bMsgGot = false;
/* function body */
//get the DC property
wcscpy(sPropName, L"DC");
//if this is not a DC, get its messages
if (MsiGetProperty(hInstall, sPropName, sMsg, &nCount) == ERROR_SUCCESS)
{
if (!wcscmp(sMsg, L"0"))
{
//get the leave messagebox msg string and title for not being a DC
wcscpy(sPropName, L"DCLeaveMsg");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, sPropName, sMsg, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sMsg, L"ADMT's Password Migration Filter DLL can only be installed on a DC, PDC, or BDC!");
wcscpy(sPropName, L"DCLeaveTitle");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, sPropName, sTitle, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sTitle, L"Invalid Machine!");
bMsgGot = true;
}
}
//if this is a DC then see if the High Encryption pack was not installed
if (!bMsgGot)
{
//get the HES flag property
wcscpy(sPropName, L"b3DESNotInstalled");
nCount = MAX_PATH;
//if HEP is not installed, get its messages
if (MsiGetProperty(hInstall, sPropName, sMsg, &nCount) == ERROR_SUCCESS)
{
if (!wcscmp(sMsg, L"1"))
{
//get the leave messagebox msg string and title for not getting a key
wcscpy(sPropName, L"HEPLeaveMsg");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, sPropName, sMsg, &nCount);
if (lret != ERROR_SUCCESS)
{
wcscpy(sMsg, L"The high encryption pack has not been installed on this machine. ADMT's ");
wcscat(sMsg, L"Password Migration Filter DLL will not install without the high encryption pack.");
}
wcscpy(sPropName, L"HEPLeaveTitle");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, sPropName, sTitle, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sTitle, L"High Encryption Pack Required!");
bMsgGot = true;
}
}
}
/* //see if an encryption key file was not found on a local drive
if (!bMsgGot)
{
//get the File flag property
wcscpy(sPropName, L"bPESFileNotFound");
nCount = MAX_PATH;
//if file not found, get its messages
if (MsiGetProperty(hInstall, sPropName, sMsg, &nCount) == ERROR_SUCCESS)
{
if (!wcscmp(sMsg, L"1"))
{
//get the leave messagebox msg string and title for not getting a key
wcscpy(sPropName, L"PESLeaveMsg");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, sPropName, sMsg, &nCount);
if (lret != ERROR_SUCCESS)
{
wcscpy(sMsg, L"An encryption key file (.pes) could not be found on any of the floppy drives.");
}
wcscpy(sPropName, L"PESLeaveTitle");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, sPropName, sTitle, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sTitle, L"File Not Found!");
bMsgGot = true;
}
}
}
*/
//else password was bad
if (!bMsgGot)
{
//get the leave messagebox msg string and title for not getting a key
wcscpy(sPropName, L"PwdLeaveMsg");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, sPropName, sMsg, &nCount);
if (lret != ERROR_SUCCESS)
{
wcscpy(sMsg, L"The supplied password does not match this encryption key's password. ADMT's ");
wcscat(sMsg, L"Password Migration Filter DLL will not install without a valid encryption key.");
}
wcscpy(sPropName, L"PwdLeaveTitle");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, sPropName, sTitle, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sTitle, L"Invalid Password!");
}
GetWndFromInstall(hInstall);
MessageBox(installWnd, sMsg, sTitle, MB_ICONSTOP | MB_OK);
return lret;
}
//END DisplayExiting
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 20 SEPT 2000 *
* *
* This function is responsible for trying to delete any files, *
* that will be installed, that may have been left around by previous*
* installations. *
* *
*********************************************************************/
//BEGIN DeleteOldFiles
PWDMSI_API UINT __stdcall DeleteOldFiles(MSIHANDLE hInstall)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local constants */
const int GETENVVAR_ERROR = 0; //this indicates an error from the "GetEnvironmentVariable" function
/* local variables */
WCHAR systemdir[MAX_PATH];
WCHAR filename[MAX_PATH];
int length;
UINT lret = ERROR_SUCCESS;
/* function body */
//try deleting previously installed files
length = GetEnvironmentVariable( L"windir", systemdir, MAX_PATH);
if (length != GETENVVAR_ERROR)
{
wcscat(systemdir, L"\\system32\\"); //go from windir to winsysdir
wcscpy(filename, systemdir);
wcscat(filename, L"PwMig.dll");
DeleteFile(filename);
wcscpy(filename, systemdir);
wcscat(filename, L"mschapp.dll");
DeleteFile(filename);
}
return lret;
}
//END DeleteOldFiles
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 6 DEC 2000 *
* *
* This function is responsible for displaying the necessary *
* dialogs to prompt for and retrieve a password encryption key off *
* of a floppy disk. This key is placed on a floppy disk via a *
* command line option on the ADMT machine. *
* *
*********************************************************************/
//BEGIN GetInstallEncryptionKey
PWDMSI_API UINT __stdcall GetInstallEncryptionKey(MSIHANDLE hInstall)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local constants */
const int ADRIVE_SIZE = 3; //length of a drive in the string (i.e "a:\")
/* local variables */
UINT lret = ERROR_SUCCESS;
WCHAR szPropName[MAX_PATH];
WCHAR sTitle[MAX_PATH];
WCHAR sMsg[MAX_PATH];
WCHAR sTemp[MAX_PATH];
DWORD nCount = MAX_PATH;
int nRet;
bool bRetrieved = false;
WCHAR sRetrieved[2] = L"0";
WCHAR sFlagSet[2] = L"1";
WCHAR sFlagClear[2] = L"0";
_bstr_t sDrives;
_bstr_t sPath;
WCHAR sADrive[ADRIVE_SIZE+1];
/* function body */
//if no path to file, return
wcscpy(szPropName, L"SENCRYPTIONFILEPATH");
lret = MsiGetProperty(hInstall, szPropName, sMsg, &nCount);
if (lret != ERROR_SUCCESS)
return lret;
sPath = sMsg; //save the given path
_wcslwr(sMsg); // convert the path to lower case for later comparison
//get the drive of the given path
wcsncpy(sADrive, sMsg, ADRIVE_SIZE);
sADrive[ADRIVE_SIZE] = L'\0';
//enumerate all local drives
sDrives = EnumLocalDrives();
_wcslwr(sDrives); // convert local drives to lower case for later comparison
//if the given file is not on a local drive, set a flag and return
WCHAR* pFound = wcsstr(sDrives, sADrive);
if ((!pFound) || (wcslen(sADrive) == 0) || (wcsstr(sMsg, L".pes") == NULL))
{
//set the bad path flag
wcscpy(szPropName, L"bBadKeyPath");
lret = MsiSetProperty(hInstall, szPropName, sFlagSet);
//if starts with "\\" then tell them it must be a local drive
if ((!pFound) && (wcsstr(sMsg, L"\\\\") == sMsg))
{
//get the bad path messagebox msg string and title
wcscpy(szPropName, L"BadDriveMsg");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, szPropName, sMsg, &nCount);
if (lret != ERROR_SUCCESS)
{
wcscpy(sMsg, L"The given path is not on a local drive and is therefore invalid.");
wcscat(sMsg, L" Please supply the path to a valid encryption key file on a local drive.");
}
wcscpy(szPropName, L"BadPathTitle");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, szPropName, sTitle, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sTitle, L"Invalid Local Drive!");
}
//else if the given file does end with ".pes", tell them it must
else if ((pFound) && (wcsstr(sMsg, L".pes") == NULL))
{
//get the bad file extension messagebox msg string
wcscpy(szPropName, L"BadFileExtMsg");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, szPropName, sMsg, &nCount);
if (lret != ERROR_SUCCESS)
{
wcscpy(sMsg, L"The given file must be a valid encryption key file ending with the \".pes\" extension.");
}
wcscpy(szPropName, L"BadFileExtTitle");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, szPropName, sTitle, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sTitle, L"Invalid File Extension!");
}
//else, tell them it is not a local drive
else
{
//get the bad path messagebox msg string and title
wcscpy(szPropName, L"BadPathMsg");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, szPropName, sTemp, &nCount);
if (lret != ERROR_SUCCESS)
{
wcscpy(sTemp, L"The given drive, %s, is not a local drive and is therefore invalid.");
wcscat(sTemp, L" Please supply the path to a valid encryption key file on a local drive.");
}
swprintf(sMsg, sTemp, sADrive);
wcscpy(szPropName, L"BadPathTitle");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, szPropName, sTitle, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sTitle, L"Invalid Local Drive!");
}
GetWndFromInstall(hInstall);
MessageBox(installWnd, sMsg, sTitle, MB_ICONSTOP | MB_OK);
return lret;
}
else
{
//else clear the bad path flag
wcscpy(szPropName, L"bBadKeyPath");
lret = MsiSetProperty(hInstall, szPropName, sFlagClear);
}
//try to retrieve the encryption key
if (RetrieveAndStorePwdKey(NULL, sPath))
wcscpy(sRetrieved, L"1");
else if (bPasswordNeeded)
{
wcscpy(szPropName, L"bPwdNeeded");
lret = MsiSetProperty(hInstall, szPropName, sFlagSet);
}
//set the key retrieved flag
wcscpy(szPropName, L"bKeyRetrieved");
lret = MsiSetProperty(hInstall, szPropName, sRetrieved);
//if file not found at the given path, prompt the user for a new one
if (!bPESFileFound)
{
//set the bad path flag
wcscpy(szPropName, L"bBadKeyPath");
lret = MsiSetProperty(hInstall, szPropName, sFlagSet);
//get the bad path messagebox msg string and title
wcscpy(szPropName, L"PESLeaveMsg");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, szPropName, sTemp, &nCount);
if (lret != ERROR_SUCCESS)
{
wcscpy(sTemp, L"The given encryption key file, %s, could not be found.");
wcscat(sTemp, L" Please enter the path to a valid encryption key file.");
}
swprintf(sMsg, sTemp, (WCHAR*)sPath);
wcscpy(szPropName, L"PESLeaveTitle");
nCount = MAX_PATH;
lret = MsiGetProperty(hInstall, szPropName, sTitle, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sTitle, L"File Not Found!");
GetWndFromInstall(hInstall);
MessageBox(installWnd, sMsg, sTitle, MB_ICONSTOP | MB_OK);
return lret;
}
//if HES is not installed, set that flag
if (b3DESNotInstalled)
{
wcscpy(szPropName, L"b3DESNotInstalled");
lret = MsiSetProperty(hInstall, szPropName, sFlagSet);
}
return lret;
}
//END GetInstallEncryptionKey
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 12 SEPT 2000 *
* *
* This function is used by the installation routine and is *
* responsible for adding the PWMIG dll name to the Multi-string *
* value "Notification Packages" under the Lsa key. *
* *
*********************************************************************/
//BEGIN AddToLsaNotificationPkgValue
PWDMSI_API UINT __stdcall AddToLsaNotificationPkgValue(MSIHANDLE hInstall)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local constants */
const WCHAR sLsaKey[40] = L"SYSTEM\\CurrentControlSet\\Control\\Lsa";
const WCHAR sLsaValue[25] = L"Notification Packages";
const WCHAR sNewAddition[10] = L"PWMIG";
/* local variables */
bool bSuccess = false;
bool bFound = false;
bool bAlreadyThere = false;
DWORD rc;
DWORD type;
HKEY hKey;
WCHAR sString[MAX_PATH];
DWORD len = sizeof(sString);
WCHAR sTemp[MAX_PATH];
int currentPos = 0;
UINT lret = ERROR_SUCCESS;
/* function body */
//open the Lsa registry key
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
sLsaKey,
0,
KEY_ALL_ACCESS,
&hKey);
if (rc == ERROR_SUCCESS)
{
//get the current value string
rc = RegQueryValueEx(hKey, sLsaValue, NULL, &type, (LPBYTE)sString, &len);
if ((rc == ERROR_SUCCESS) && (type == REG_MULTI_SZ))
{
sString[MAX_PATH - 1] = L'\0';
//copy each string in the multi-string until the end is reached
while (!bFound)
{
if (!wcscmp(sString+currentPos, sNewAddition))
bAlreadyThere = true;
wcscpy(sTemp+currentPos, sString+currentPos);
currentPos += wcslen(sTemp+currentPos) + 1;
if (sString[currentPos] == L'\0')
bFound = true;
}
if (!bAlreadyThere)
{
//now add our new text and terminate the string
wcscpy(sTemp+currentPos, sNewAddition);
currentPos += wcslen(sNewAddition) + 1;
sTemp[currentPos] = L'\0';
//save the new value in the registry
len = (currentPos + 1) * sizeof(WCHAR);
rc = RegSetValueEx(hKey, sLsaValue, 0, type, (LPBYTE)sTemp, len);
if (rc == ERROR_SUCCESS)
bSuccess = true;
}
}
RegCloseKey(hKey);
}
//tell installer we want to reboot
MsiSetMode(hInstall, MSIRUNMODE_REBOOTATEND, TRUE);
return lret;
}
//END AddToLsaNotificationPkgValue
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 12 SEPT 2000 *
* *
* This function is used by the installation routine and is *
* responsible for deleting the PWMIG dll name from the Multi-string *
* value "Notification Packages" under the Lsa key. *
* *
*********************************************************************/
//BEGIN DeleteFromLsaNotificationPkgValue
PWDMSI_API UINT __stdcall DeleteFromLsaNotificationPkgValue(MSIHANDLE hInstall)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local constants */
const WCHAR sLsaKey[40] = L"SYSTEM\\CurrentControlSet\\Control\\Lsa";
const WCHAR sLsaValue[25] = L"Notification Packages";
const WCHAR sNewAddition[10] = L"PWMIG";
/* local variables */
bool bSuccess = false;
DWORD rc;
DWORD type;
HKEY hKey;
WCHAR sString[MAX_PATH];
DWORD len = sizeof(sString);
WCHAR sTemp[MAX_PATH];
int currentPos = 0;
int tempPos = 0;
UINT lret = ERROR_SUCCESS;
/* function body */
//open the Lsa registry key
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
sLsaKey,
0,
KEY_ALL_ACCESS,
&hKey);
if (rc == ERROR_SUCCESS)
{
//get the current value string
rc = RegQueryValueEx(hKey, sLsaValue, NULL, &type, (LPBYTE)sString, &len);
if ((rc == ERROR_SUCCESS) && (type == REG_MULTI_SZ))
{
sString[MAX_PATH - 1] = L'\0';
//copy each string in the multi-string until the desired string
while (sString[currentPos] != L'\0')
{
//if not string wanted, copy to destination string
if (wcscmp(sString+currentPos, sNewAddition))
{
wcscpy(sTemp+tempPos, sString+currentPos);
tempPos += wcslen(sString+currentPos) + 1;
currentPos += wcslen(sString+currentPos) + 1;
}
else //else this is our string, skip it
{
currentPos += wcslen(sString+currentPos) + 1;
}
}
//add the ending NULL
sTemp[tempPos] = L'\0';
//save the new value in the registry
len = (tempPos + 1) * sizeof(WCHAR);
rc = RegSetValueEx(hKey, sLsaValue, 0, type, (LPBYTE)sTemp, len);
if (rc == ERROR_SUCCESS)
bSuccess = true;
}
RegCloseKey(hKey);
}
//tell installer we want to reboot
MsiSetMode(hInstall, MSIRUNMODE_REBOOTATEND, TRUE);
return lret;
}
//END DeleteFromLsaNotificationPkgValue
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 23 JAN 2001 *
* *
* This function is responsible for displaying the necessary *
* dialogs to prompt for and retrieve a password encryption key off *
* of a floppy disk. This key is placed on a floppy disk via a *
* command line option on the ADMT machine. *
* *
*********************************************************************/
//BEGIN FinishWithPassword
PWDMSI_API UINT __stdcall FinishWithPassword(MSIHANDLE hInstall)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local variables */
UINT lret = ERROR_SUCCESS;
WCHAR szPropName[MAX_PATH];
WCHAR sPwd[MAX_PATH];
WCHAR sMsg[MAX_PATH];
DWORD nCount = MAX_PATH;
_bstr_t sPath;
WCHAR sFlagSet[2] = L"1";
/* function body */
//get the password to try
wcscpy(szPropName, L"sKeyPassword");
lret = MsiGetProperty(hInstall, szPropName, sPwd, &nCount);
if (lret != ERROR_SUCCESS)
return lret;
//if no path to file, return
nCount = MAX_PATH;
wcscpy(szPropName, L"SENCRYPTIONFILEPATH");
lret = MsiGetProperty(hInstall, szPropName, sMsg, &nCount);
if (lret != ERROR_SUCCESS)
return lret;
sPath = sMsg; //save the given path
//try saving the key with this password
if (RetrieveAndStorePwdKey(sPwd, sPath))
{
wcscpy(szPropName, L"bKeyRetrieved");
lret = MsiSetProperty(hInstall, szPropName, sFlagSet);
}
//if HES is not installed, set that flag
if (b3DESNotInstalled)
{
wcscpy(szPropName, L"b3DESNotInstalled");
lret = MsiSetProperty(hInstall, szPropName, sFlagSet);
}
/* //if file not found on the floppy, set that flag
if (!bPESFileFound)
{
wcscpy(szPropName, L"bPESFileNotFound");
lret = MsiSetProperty(hInstall, szPropName, sFlagSet);
}
*/
return lret;
}
//END FinishWithPassword
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 24 JAN 2001 *
* *
* This function is responsible for displaying a MesasgeBox *
* the user that the passwords did not match. *
* *
*********************************************************************/
//BEGIN PwdsDontMatch
PWDMSI_API UINT __stdcall PwdsDontMatch(MSIHANDLE hInstall)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local variables */
UINT lret = ERROR_SUCCESS;
WCHAR szPropName[MAX_PATH];
WCHAR sMsg[MAX_PATH];
WCHAR sTitle[MAX_PATH];
DWORD nCount = MAX_PATH;
WCHAR sEmpty[2] = L"";
/* function body */
//get the message to display
wcscpy(szPropName, L"PwdMatchMsg");
lret = MsiGetProperty(hInstall, szPropName, sMsg, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sMsg, L"The passwords entered do not match each other. Please try again!");
//get the title string
nCount = MAX_PATH;
wcscpy(szPropName, L"PwdMatchTitle");
lret = MsiGetProperty(hInstall, szPropName, sTitle, &nCount);
if (lret != ERROR_SUCCESS)
wcscpy(sTitle, L"Password Mismatch");
GetWndFromInstall(hInstall);
MessageBox(installWnd, sMsg, sTitle, MB_ICONSTOP | MB_OKCANCEL);
return lret;
}
//END PwdsDontMatch
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 28 MAR 2001 *
* *
* This function is responsible for displaying a browse dialog to*
* aid the install user in finding a password encryption key file, *
* which has a .PES extension. *
* *
*********************************************************************/
//BEGIN BrowseForEncryptionKey
PWDMSI_API UINT __stdcall BrowseForEncryptionKey(MSIHANDLE hInstall)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local variables */
UINT lret = ERROR_SUCCESS;
WCHAR szPropName[MAX_PATH];
WCHAR sMsg[2*MAX_PATH];
WCHAR sFile[2*MAX_PATH];
DWORD nCount = 2*MAX_PATH;
_bstr_t sPath = L"";
int nRet;
OPENFILENAME ofn;
HANDLE hFile;
WCHAR sFilter[MAX_PATH];
bool bFile, bFolder = false;
/* function body */
//get the starting location
wcscpy(szPropName, L"SENCRYPTIONFILEPATH");
lret = MsiGetProperty(hInstall, szPropName, sMsg, &nCount);
if (lret != ERROR_SUCCESS)
{
wcscpy(sMsg, L"");
bFile = false;
}
else
{
WCHAR* pFound = wcsstr(sMsg, L".pes");
if (pFound)
bFile = true;
else
{
WCHAR* pFound = wcsrchr(sMsg, L'\\');
if (pFound)
{
// *pFound = L'\0';
bFolder = true;
}
bFile = false;
}
}
//get a handle to the install
GetWndFromInstall(hInstall);
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
ofn.hwndOwner = installWnd;
if (bFile)
ofn.lpstrFile = sMsg;
else
{
wcscpy(sFile, L"");
ofn.lpstrFile = sFile;
}
if (bFolder)
ofn.lpstrInitialDir = sMsg;
ofn.nMaxFile = 2*MAX_PATH;
ofn.lpstrFilter = L"Password Encryption Files (*.pes)\0*.pes\0";
ofn.nFilterIndex = 0;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_LONGNAMES |
OFN_NONETWORKBUTTON;
// Display the Open dialog box.
if (GetOpenFileName(&ofn))
{
//get the given file path
sPath = ofn.lpstrFile;
//set the filepath property
wcscpy(szPropName, L"sFilePath");
lret = MsiSetProperty(hInstall, szPropName, sPath);
}
return lret;
}
//END BrowseForEncryptionKey
/*********************************************************************
* *
* Written by: Paul Thompson *
* Date: 28 MAR 2001 *
* *
* This function is responsible for setting the *
* "sEncryptionFilePath" property to a default location. If the *
* property is not "None" then we will not set the property. *
* *
*********************************************************************/
//BEGIN GetDefaultPathToEncryptionKey
PWDMSI_API UINT __stdcall GetDefaultPathToEncryptionKey(MSIHANDLE hInstall)
{
// call LoadOLEAUT32OnNT4 to keep ref count of OLEAUT32
// greater than zero
LoadOLEAUT32OnNT4();
/* local constants */
const WCHAR TOKENS[3] = L",\0";
/* local variables */
_bstr_t sFloppies;
WCHAR * pDrive;
HANDLE hFile;
WIN32_FIND_DATA fDat;
_bstr_t sPath;
_bstr_t sPathSaved = L"";
_bstr_t sDrive = L"";
int ndx = 0;
int ndx2 = 0;
UINT lret = ERROR_SUCCESS;
WCHAR szPropName[MAX_PATH];
WCHAR sMsg[2*MAX_PATH];
DWORD nCount = 2*MAX_PATH;
/* function body */
//if already set don't get again
wcscpy(szPropName, L"SENCRYPTIONFILEPATH");
lret = MsiGetProperty(hInstall, szPropName, sMsg, &nCount);
if ((lret == ERROR_SUCCESS) && (wcscmp(sMsg, L"None")))
return lret;
//enumerate all local drives
sDrive = EnumLocalDrives();
//check each drive for the file
pDrive = wcstok((WCHAR*)sDrive, TOKENS);
while (pDrive != NULL)
{
if (ndx == 0)
sPathSaved = pDrive;
ndx++;
//see if a .pes file is on this drive
sPath = pDrive;
sPath += L"*.pes";
hFile = FindFirstFile((WCHAR*)sPath, &fDat);
//if found, store the file path
if (hFile != INVALID_HANDLE_VALUE)
{
FindClose(hFile);
//get the data
sPath = pDrive;
sPath += fDat.cFileName;
if (ndx2 == 0)
sPathSaved = sPath;
ndx2++;
}
//get the next drive
pDrive = wcstok(NULL, TOKENS);
}
//set the filepath property
wcscpy(szPropName, L"SENCRYPTIONFILEPATH");
lret = MsiSetProperty(hInstall, szPropName, sPathSaved);
return lret;
}
//END GetDefaultPathToEncryptionKey