// PwdMsi.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include #include #include #include #include #include #include #include #include #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