////////////////////////////////////////////////////////////////////////////////////// // // // By using this sofware or source code you agree to the following License terms: // // // // Grant of License. // // // // Mindcraft, Inc., the author of this software, grants you a personal, // // nontransferrable, nonexclusive, license to use this software on any computer // // system to which you personally have access. // // // // Copyright. // // // // This software is copyright (C)1998 Mindcraft, Inc. All rights are reserved. // // // // // // LIMITATION OF LIABILITY. // // // // UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING // // NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL MINDCRAFT BE LIABLE TO YOU OR ANY // // OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF // // ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK // // STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL // // DAMAGES OR LOSSES, EVEN IF MINDCRAFT SHALL HAVE BEEN INFORMED OF THE POSSIBILITY // // OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR // // DEATH OR PERSONAL INJURY RESULTING FROM MINDCRAFT'S NEGLIGENCE TO THE EXTENT // // APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE // // EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT // // EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. // // // // DISCLAIMER OF WARRANTY. // // // // THIS CODE IS PROVIDED UNDER LICENSE ON AN ``AS IS'' BASIS, WITHOUT WARRANTY OF // // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES // // THAT THE CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR // // NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE CODE IS // // WITH YOU. SHOULD THE CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT MINDCRAFT) // // ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS // // DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF // // ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. // // // // U.S. GOVERNMENT END USERS. // // // // The Covered Code is a ``commercial item,'' as that term is defined in 48 C.F.R. // // 2.101 (Oct. 1995), consisting of ``commercial computer software'' and // // ``commercial computer software documentation,'' as such terms are used in 48 // // C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. // // 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire // // Covered Code with only those rights set forth herein. // // // // MISCELLANEOUS. // // // // This License represents the complete agreement concerning subject matter hereof. // // If any provision of this License is held to be unenforceable, such provision // // shall be reformed only to the extent necessary to make it enforceable. This // // License shall be governed by California law provisions (except to the extent // // applicable law, if any, provides otherwise), excluding its conflict-of-law // // provisions. With respect to disputes in which at least one party is a citizen // // of, or an entity chartered or registered to do business in, the United States of // // America: (a) unless otherwise agreed in writing, all disputes relating to this // // License (excepting any dispute relating to intellectual property rights) shall // // be subject to final and binding arbitration, with the losing party paying all // // costs of arbitration; (b) any arbitration relating to this Agreement shall be // // held in Santa Clara County, California, under the auspices of JAMS/EndDispute; // // and (c) any litigation relating to this Agreement shall be subject to the // // jurisdiction of the Federal Courts of the Northern District of California, with // // venue lying in Santa Clara County, California, with the losing party responsible // // for costs, including without limitation, court costs and reasonable attorneys // // fees and expenses. The application of the United Nations Convention on Contracts // // for the International Sale of Goods is expressly excluded. Any law or regulation // // which provides that the language of a contract shall be construed against the // // drafter shall not apply to this License. // // // ////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// // // // InstallShield program to fix QuickTime plugin installation // // Written by: Greg Burrell // // Date: 10/30/98 // // // ////////////////////////////////////////////////////////////////////////////////////// // NOTE: If you are using InstallShield to build the demonstration then you // need the files setup.rul, README.txt, and license.txt which are // available at the Mindcraft web site (http://www.mindcraft.com/qtfix) #include "sdlang.h" #include "sddialog.h" #define UNINST_LOGFILE_NAME "Uninst.isu" #define MIME_DB_CONTENTTYPE_REGKEY "MIME\\Database\\Content Type\\" #define IE_REGKEY "SOFTWARE\\Microsoft\\Internet Explorer\\" #define IE_EXE_REGKEY "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE" #define IE_EXE_PROGNAME "iexplore.exe" #define IE_PLUGIN_FOLDER_NAME "Plugins" #define PLUGIN_DLL "npqtplugin.dll" #define PLUGIN_VERSION "2.0.1" #define PLUGIN_NAME "QuickTime Plug-In" #define TEST_PAGE "http://www.apple.com/quicktime/samples/showcase/index.html" #define LICENSE_FILENAME "license.txt" // generated prototype MoveFileData(); prototype HandleMoveDataError( NUMBER ); prototype ProcessBeforeDataMove(); prototype ProcessAfterDataMove(); prototype SetupRegistry(); prototype CleanUpInstall(); prototype SetupInstall(); prototype SetupScreen(); prototype CheckRequirements(); prototype DialogShowSdWelcome(); prototype DialogShowSdLicense(); prototype DialogShowSdFinishReboot(); prototype MC_VerifyIEAndQTPlugin(); prototype MC_GetIERegdata(); prototype MC_ShowLicense(); prototype MC_Tell_User_About_QT_Control_Panel(); prototype MC_Disable_ActiveX_Precedence(STRING, STRING); prototype MC_Tell_IE_Plugin_Supports_Extension(STRING, STRING); prototype MC_Add_RegKey_If_Absent(STRING); prototype MC_Set_RegValue_If_Different(STRING, STRING, STRING); // ----- global variables ------ BOOL bWinNT, bIsShellExplorer, bInstallAborted, bIs32BitSetup; STRING svDir; STRING svName, svCompany, svSerial; STRING svDefGroup; STRING szAppPath; STRING svSetupType; BOOL bHasIE; STRING svIEPluginExePath; STRING svIEExePath; /////////////////////////////////////////////////////////////////////////////// // // MAIN PROGRAM // // The setup begins here by hiding the visible setup // window. This is done to allow all the titles, images, etc. to // be established before showing the main window. The following // logic then performs the setup in a series of steps. // /////////////////////////////////////////////////////////////////////////////// program Disable( BACKGROUND ); CheckRequirements(); SetupInstall(); SetupScreen(); if (DialogShowSdWelcome() != NEXT) goto end_install; MC_VerifyIEAndQTPlugin(); if (DialogShowSdLicense() != NEXT) goto end_install; if (ProcessBeforeDataMove()<0) goto end_install; if (MoveFileData()<0) goto end_install; if (ProcessAfterDataMove()<0) goto end_install; if (SetupRegistry()<0) goto end_install; end_install: CleanUpInstall(); // If an unrecoverable error occurred, clean up the partial installation. // Otherwise, exit normally. if (bInstallAborted) then abort; endif; endprogram /////////////////////////////////////////////////////////////////////////////// // // // Function: DialogShowSdWelcome // // // // Purpose: This function handles the standard welcome dialog. // // // /////////////////////////////////////////////////////////////////////////////// function DialogShowSdWelcome() NUMBER nResult; STRING szTitle, szMsg; begin szTitle = "Welcome To the QuickTime for Internet Explorer Fix"; szMsg = ""; nResult = SdWelcome(szTitle, szMsg); return nResult; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: MC_VerifyIEAndQTPlugin // // // // Purpose: Explain to the user what this fix does and give the user a // // chance to bail out. // // // /////////////////////////////////////////////////////////////////////////////// function MC_VerifyIEAndQTPlugin() BOOL bvOpt1; BOOL bvOpt2; begin // Fine IE and QT plug-in data in registry. MC_GetIERegdata(); // Quit if couldn't find IE if (bHasIE != TRUE) then SdFinish("Unable to Find Internet Explorer", "Setup was unable to find Internet Explorer.", "No changes were made to this system.\n" + "Click Finish to exit setup.", "", "", bvOpt1, bvOpt2); exit; endif; // Quit if couldn't find IE's Plugins folder. if (svIEPluginExePath = "") then SdFinish("Unable to Find Internet Explorer's Plugins Folder", "Setup was unable to find Internet Explorer's Plugins folder." + "Please make sure that Internet Explorer was installed properly.", "No changes were made to this system.\n" + "Click Finish to exit setup.", "", "", bvOpt1, bvOpt2); exit; endif; // Quit if can't find QT plug-in in IE's Plugins folder if (Is(FILE_EXISTS, svIEPluginExePath) != TRUE) then SdFinish("QuickTime Plug-in Not Installed in Internet Explorer", "The QuickTime plug-in has not yet been installed in Internet Explorer." + "Please install QuickTime and then run this fix again.", "No changes were made to this system.\n" + "Click Finish to exit setup.", "", "", bvOpt1, bvOpt2); exit; endif; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: MC_GetIERegdata // // // // Purpose: Search the registry and see if Internet Explorer is installed // // on the system. If so then find the path to its QT plug-in. // // Finally, make sure the QT plug-in exists in IE's Plugins // // folder. // // // /////////////////////////////////////////////////////////////////////////////// function MC_GetIERegdata() NUMBER nRet; NUMBER nType; NUMBER nvSize; NUMBER nStrPos; STRING svAppMainPath; begin if (RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE) < 0) then MessageBox("Unable to access HKEY_LOCAL_MACHINE in registry", SEVERE); abort; endif; // To get IE Plugin directory: // 1. get exe path from registry. // 2. in exe path: find name of Internet Explorer executable. // 3. extract string up to "iexplore.exe" // 4. append "Plugins" since Plugins directory must // be a subdirectory of the main app directory. bHasIE = FALSE; svIEPluginExePath = ""; nRet = RegDBGetKeyValueEx(IE_EXE_REGKEY, "", nType, svIEExePath, nvSize); if ( (nRet = 0) && (nType = REGDB_STRING) && (svIEExePath != "") ) then nStrPos = StrFind(svIEExePath, IE_EXE_PROGNAME); if (nStrPos > 0) then StrSub(svAppMainPath, svIEExePath, 0, nStrPos); bHasIE = TRUE; svIEPluginExePath = svAppMainPath ^ IE_PLUGIN_FOLDER_NAME ^ PLUGIN_DLL; endif; endif; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: DialogShowSdLicense // // // // Purpose: This function displays the license agreement dialog. // // // // // /////////////////////////////////////////////////////////////////////////////// function DialogShowSdLicense() NUMBER nResult; STRING szTitle, szMsg, szQuestion, szLicenseFile; begin Disable(BACKBUTTON); szLicenseFile = SUPPORTDIR ^ LICENSE_FILENAME; szTitle = ""; szMsg = ""; szQuestion = ""; nResult = SdLicense( szTitle, szMsg, szQuestion, szLicenseFile ); return nResult; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: ProcessBeforeDataMove // // // // Purpose: This function performs any necessary operations prior to the // // actual data move operation. // // // /////////////////////////////////////////////////////////////////////////////// function ProcessBeforeDataMove() STRING svLogFile; NUMBER nResult; begin InstallationInfo( @COMPANY_NAME, @PRODUCT_NAME, @PRODUCT_VERSION, @PRODUCT_KEY ); svLogFile = UNINST_LOGFILE_NAME; nResult = DeinstallStart( svDir, svLogFile, @UNINST_KEY, 0 ); if (nResult < 0) then MessageBox( @ERROR_UNINSTSETUP, WARNING ); endif; szAppPath = TARGETDIR; if ((bIs32BitSetup) && (bIsShellExplorer)) then RegDBSetItem( REGDB_APPPATH, szAppPath ); RegDBSetItem( REGDB_APPPATH_DEFAULT, szAppPath ^ @PRODUCT_KEY ); RegDBSetItem( REGDB_UNINSTALL_NAME, @UNINST_DISPLAY_NAME ); endif; return 0; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: MoveFileData // // // // Purpose: This function handles the data movement for // // the setup. // // // /////////////////////////////////////////////////////////////////////////////// function MoveFileData() NUMBER nResult, nDisk; begin nDisk = 1; SetStatusWindow( 0, "" ); Disable( DIALOGCACHE ); Enable( STATUS ); StatusUpdate( ON, 100 ); nResult = ComponentMoveData( MEDIA, nDisk, 0 ); HandleMoveDataError( nResult ); Disable( STATUS ); return nResult; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: HandleMoveDataError // // // // Purpose: This function handles the error (if any) during the move data // // operation. // // // /////////////////////////////////////////////////////////////////////////////// function HandleMoveDataError( nResult ) begin switch (nResult) case 0: return 0; default: SprintfBox( SEVERE, @TITLE_CAPTIONBAR, @ERROR_MOVEDATA, nResult ); bInstallAborted = TRUE; return nResult; endswitch; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: ProcessAfterDataMove // // // // Purpose: This function performs any necessary operations needed after // // all data has been moved. // // // /////////////////////////////////////////////////////////////////////////////// function ProcessAfterDataMove() STRING szReferenceFile; begin // DeinstallSetReference specifies a file to be checked before // uninstallation. If the file is in use, uninstallation will not proceed. szReferenceFile = svDir ^ @PRODUCT_KEY; DeinstallSetReference( szReferenceFile ); return 0; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: CleanUpInstall // // // // Purpose: This cleans up the setup. Anything that should // // be released or deleted at the end of the setup should // // be done here. // // // /////////////////////////////////////////////////////////////////////////////// function CleanUpInstall() begin if (bInstallAborted) then return 0; endif; DialogShowSdFinishReboot(); if (BATCH_INSTALL) then // ensure locked files are properly written CommitSharedFiles(0); endif; return 0; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: SetupInstall // // // // Purpose: This will setup the installation. Any general initialization // // needed for the installation should be performed here. // // // /////////////////////////////////////////////////////////////////////////////// function SetupInstall() begin Enable( CORECOMPONENTHANDLING ); bInstallAborted = FALSE; if (bIs32BitSetup) then svDir = PROGRAMFILES ^ @COMPANY_NAME ^ @PRODUCT_NAME; else svDir = PROGRAMFILES ^ @COMPANY_NAME16 ^ @PRODUCT_NAME16; endif; TARGETDIR = svDir; SdProductName( @PRODUCT_NAME ); Enable( DIALOGCACHE ); return 0; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: SetupScreen // // // // Purpose: This function establishes the screen look. This includes // // colors, fonts, and text to be displayed. // // // /////////////////////////////////////////////////////////////////////////////// function SetupScreen() begin SetColor(BACKGROUND, BK_BLUE | BK_SMOOTH); Enable( FULLWINDOWMODE ); SetTitle( @TITLE_MAIN, 24, WHITE ); SetTitle( @TITLE_CAPTIONBAR, 0, BACKGROUNDCAPTION ); // Caption bar text. Enable( BACKGROUND ); Delay( 1 ); end; /////////////////////////////////////////////////////////////////////////////// // // // Function: CheckRequirements // // // // Purpose: This function checks all minimum requirements for the // // application being installed. If any fail, then the user // // is informed and the setup is terminated. // // // /////////////////////////////////////////////////////////////////////////////// function CheckRequirements() NUMBER nvDx, nvDy, nvResult; STRING svResult; begin bWinNT = FALSE; bIsShellExplorer = FALSE; // Check screen resolution. GetExtents( nvDx, nvDy ); if (nvDy < 480) then MessageBox( @ERROR_VGARESOLUTION, WARNING ); abort; endif; // set 'setup' operation mode bIs32BitSetup = TRUE; GetSystemInfo( ISTYPE, nvResult, svResult ); if (nvResult = 16) then bIs32BitSetup = FALSE; // running 16-bit setup return 0; // no additional information required endif; // --- 32-bit testing after this point --- // Determine the target system's operating system. GetSystemInfo( OS, nvResult, svResult ); if (nvResult = IS_WINDOWSNT) then // Running Windows NT. bWinNT = TRUE; // Check to see if the shell being used is EXPLORER shell. if (GetSystemInfo( OSMAJOR, nvResult, svResult ) = 0) then if (nvResult >= 4) then bIsShellExplorer = TRUE; endif; endif; elseif (nvResult = IS_WINDOWS95 ) then bIsShellExplorer = TRUE; endif; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: MC_Tell_User_About_QT_Control_Panel // // // // Purpose: Tell the user to set all three "File Type Associations" // // check boxes in the QuickTime control panel. // // // /////////////////////////////////////////////////////////////////////////////// function MC_Tell_User_About_QT_Control_Panel() begin MessageBox("In order for this fix to have full effect you must\n" + "go to the File Type Associations setting in the QuickTime\n" + " control panel and set all three checkboxes.", INFORMATION); end; /////////////////////////////////////////////////////////////////////////////// // // // Function: DialogShowSdFinishReboot // // // // Purpose: This function will show the last dialog of the product. // // It will allow the user to reboot and/or show some readme text. // // // /////////////////////////////////////////////////////////////////////////////// function DialogShowSdFinishReboot() NUMBER nResult, nDefOptions; STRING szTitle, szMsg1, szMsg2, szOption1, szOption2; NUMBER bOpt1, bOpt2; STRING svCmdLine; begin MC_Tell_User_About_QT_Control_Panel(); szTitle = "Fix Installation Complete"; szMsg1 = "The QuickTime Plugin fix for Internet Explorer has been installed."; szMsg2 = ""; if (!BATCH_INSTALL) then bOpt1 = FALSE; bOpt2 = FALSE; szOption1 = "Start Internet Explorer with QuickTime samples web page."; szOption2 = ""; nResult = SdFinish( szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2 ); // If the user chose then launch Internet Explorer with our test page. if (bOpt1 = TRUE) then svCmdLine = "-nohome " + TEST_PAGE; LaunchApp(svIEExePath, svCmdLine); endif; return 0; endif; nDefOptions = SYS_BOOTMACHINE; nResult = SdFinishReboot( szTitle, szMsg1, nDefOptions, szMsg2, 0 ); return nResult; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: SetupRegistry // // // // Purpose: This function makes the registry entries for this fix. // // // /////////////////////////////////////////////////////////////////////////////// function SetupRegistry() STRING szIEDisableRegistryInitRegkey; begin MC_Tell_IE_Plugin_Supports_Extension("video/quicktime", ".qt"); MC_Tell_IE_Plugin_Supports_Extension("audio/aiff", ".aifc"); MC_Tell_IE_Plugin_Supports_Extension("video/x-msvideo", ".vfw"); // Now set the Plugins\DisableRegistryInitOnStartup registry key to true. // Otherwise IE will remove the keys we added to Plugins\Extension. szIEDisableRegistryInitRegkey = IE_REGKEY + "Plugins\\DisableRegistryInitOnStartup"; MC_Add_RegKey_If_Absent(szIEDisableRegistryInitRegkey); MC_Set_RegValue_If_Different(szIEDisableRegistryInitRegkey, "", "true"); MC_Disable_ActiveX_Precedence("audio/aiff", ".aifc"); MC_Disable_ActiveX_Precedence("audio/aiff", ".aif"); /* for new MediaPlayer */ MC_Disable_ActiveX_Precedence("video/x-msvideo", ".vfw"); return 0; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: MC_Tell_IE_Plugin_Supports_Extension // // // // Add the extension to IE's Plugins registry key. // // // // A plugin DLL must contain a FileExtents line in its version // // information. FileExtents lists all the file extensions that // // the plugin supports. For each of these filename extensions // // the Internet Explorer web broswer creates a key under the // // HKLM\SOFTWARE\Microsoft\Internet Explorer\Plugins\Extension // // key. The values it contains are "default", "Content Type", // // "Version", and "Location". This is how the IE web browser // // knows what plugin to use for what filename extensions. If a // // plugin DLL omits a filename extension then we can still add // // the registry key so that the IE browser knows it should use // // the plugin for files with that filename extension. // // // /////////////////////////////////////////////////////////////////////////////// function MC_Tell_IE_Plugin_Supports_Extension(svMimetype, svExtension) STRING svIEPluginExtensionRegkey; begin if (RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE) < 0) then MessageBox("Unable to access HKEY_LOCAL_MACHINE in registry", SEVERE); abort; endif; svIEPluginExtensionRegkey = IE_REGKEY + "Plugins\\Extension\\" + svExtension; MC_Add_RegKey_If_Absent(svIEPluginExtensionRegkey); MC_Set_RegValue_If_Different(svIEPluginExtensionRegkey, "" , PLUGIN_NAME); MC_Set_RegValue_If_Different(svIEPluginExtensionRegkey, "Content Type", svMimetype); MC_Set_RegValue_If_Different(svIEPluginExtensionRegkey, "Version" , PLUGIN_VERSION); MC_Set_RegValue_If_Different(svIEPluginExtensionRegkey, "Location" , svIEPluginExePath); end; /////////////////////////////////////////////////////////////////////////////// // // // Function: MC_Disable_ActiveX_Precedence // // // // If the mimetype already exists in the registry and has a // // CLSID, then add the extension the EnablePlugin subsection // // of that CLSID. // // // // Each ActiveX control is identified in the registry by a CLSID // // (HKCR\CLSID\). A CLSID may have a sub-key named // // "EnablePlugin". Each key under EnablePlugin is named for a // // filename extension (for example, "EnablePlugin\.qt"). For // // those filename extensions, that particular ActiveX control // // will not have precedence over plugins installed in the // // Internet Explorer web browser. // // // /////////////////////////////////////////////////////////////////////////////// function MC_Disable_ActiveX_Precedence(svMimetype, svExtension) STRING svMimeRegkey; STRING svCLSIDValue; NUMBER nRet; NUMBER nType; NUMBER nvSize; begin if (RegDBSetDefaultRoot(HKEY_CLASSES_ROOT) < 0) then MessageBox("Unable to access HKEY_CLASSES_ROOT in registry", SEVERE); abort; endif; svMimeRegkey = MIME_DB_CONTENTTYPE_REGKEY + svMimetype; if (RegDBKeyExist(svMimeRegkey) = 1) then nRet = RegDBGetKeyValueEx(svMimeRegkey, "CLSID", nType, svCLSIDValue, nvSize); if ( (nRet = 0) && (nType = REGDB_STRING) && (svCLSIDValue != "") ) then MC_Add_RegKey_If_Absent("CLSID\\" + svCLSIDValue + "\\EnablePlugin\\" + svExtension); endif; endif; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: MC_Add_RegKey_If_Absent // // // // Purpose: If the given key isn't in the registry then add it. // // // /////////////////////////////////////////////////////////////////////////////// function MC_Add_RegKey_If_Absent(szRegKey) begin if (RegDBKeyExist(szRegKey) != 1) then if (RegDBCreateKeyEx(szRegKey, "") < 0) then MessageBox("Unable to create registry key: " + szRegKey, SEVERE); abort; endif; endif; end; /////////////////////////////////////////////////////////////////////////////// // // // Function: MC_Set_RegValue_If_Different // // // // Purpose: Set a value for a given reg key. Only set it if this new // // value differs from the current value in the registry. // // // /////////////////////////////////////////////////////////////////////////////// function MC_Set_RegValue_If_Different(szRegKey, szName, szValue) NUMBER nvType; STRING svOldValue; NUMBER nvSize; NUMBER nRet; begin nRet = RegDBGetKeyValueEx(szRegKey, szName, nvType, svOldValue, nvSize); if ( (nRet != 0) || (svOldValue != szValue) ) then // either the name wasn't present in the regkey or its old value // differs from this new value. So go ahead and set the new value. if (RegDBSetKeyValueEx(szRegKey, szName, REGDB_STRING, szValue, -1) < 0) then MessageBox("Unable to create registry value: " + szRegKey, SEVERE); abort; endif; endif; end; #include "sddialog.rul"