1058 lines
34 KiB
C++
1058 lines
34 KiB
C++
|
// 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;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*********************************************************************
|
||
|
* *
|
||
|
* 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)
|
||
|
{
|
||
|
/* 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)
|
||
|
{
|
||
|
/* 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)
|
||
|
{
|
||
|
/* 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)
|
||
|
{
|
||
|
/* 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)
|
||
|
{
|
||
|
/* 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)
|
||
|
{
|
||
|
/* 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)
|
||
|
{
|
||
|
/* 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
|
||
|
|
||
|
//get the drive of the given path
|
||
|
wcsncpy(sADrive, sMsg, ADRIVE_SIZE);
|
||
|
sADrive[ADRIVE_SIZE] = L'\0';
|
||
|
|
||
|
//enumerate all local drives
|
||
|
sDrives = EnumLocalDrives();
|
||
|
|
||
|
//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)
|
||
|
{
|
||
|
/* 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;
|
||
|
DWORD len = MAX_PATH * sizeof(WCHAR*);
|
||
|
HKEY hKey;
|
||
|
WCHAR sString[MAX_PATH];
|
||
|
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))
|
||
|
{
|
||
|
//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)
|
||
|
{
|
||
|
/* 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;
|
||
|
DWORD len = MAX_PATH * sizeof(WCHAR*);
|
||
|
HKEY hKey;
|
||
|
WCHAR sString[MAX_PATH];
|
||
|
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))
|
||
|
{
|
||
|
//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)
|
||
|
{
|
||
|
/* 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)
|
||
|
{
|
||
|
/* 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)
|
||
|
{
|
||
|
/* 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)
|
||
|
{
|
||
|
/* 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
|