Hey,
As you've probably noticed, I've been working on implementing advpack for a couple months now; a lot of progress has been made, and I'm glad to say that the end is in sight. The rest of this email details the game plan for finishing advpack.
advpack has five main install functions: DoInfInstall, ExecuteCab, LaunchINFSection, LaunchINFSectionEx, and RunSetupCommand. They all basically do the same thing with minor differences in functionality. ExecuteCab extracts the files to install from a cab archive, LaunchINFSectionEx provides backup and rollback capability, and RunSetupCommand can also launch executables. When installing an INF section, advpack calls setupapi to install the base INF commands, such as CopyFiles and AddReg. After this, advpack parses the Advanced INF for advanced commands that are only installable when using advpack. These commands include:
Values: RequiredEngine - Use either setupapi or setupx, we will ignore it. CustomDestination - assigns ldids to extra directories. SmartReboot - same reboot options as LaunchINFSection. Cleanup - deletes the INF when the install/uninstall is finished if this is 1. CheckAdminRights - check if the user is admin if this is 1.
Actions: RegisterOCXs UnregisterOCXs BeginPrompt EndPrompt RunPreSetupCommands RunPostSetupCommands DelDirs PerUserInstall
Backup/Rollback: ComponentName ComponentVersion BackupReg PreRollBack BackupPath
Internally, there will be three main install functions: install_init, which will open the INF, make sure it's legit, and other initializations, spapi_install, which will call setupapi to install the base INF commands, and adv_install, which will parse the install section and run the provided commands. Each advanced command will be implemented by a function of similar name, e.g., RegisterOCXs would be implemented by the function register_ocxs, etc. All the command functions will be in a hash map, the key being the command name, the value being a pointer to the function that implements the command. adv_install will use setupapi to parse the entries of the install section, calling the function returned by a query to the hash map. According to INF Web [1], some commands are run before others, so there will probably be three or four maps, the functions in the maps grouped according to the order in which the commands should be run. For example, RunPreSetupCommands is to be executed after the BeginPrompt command, so begin_prompt would be in the phase 1 map, and run_pre_setup_commands would be in the phase 2 map. We would call the parser like so:
run_adv_commands("InstallSection", phase1_map); run_adv_commands("InstallSection", phase2_map); run_adv_commands("InstallSection", phase3_map);
If a command in the install section is not in the map, we just ignore it.
This is The Plan so far, so if anyone has any ideas or suggestions, I'd love to hear from you.
Thanks, James Hawkins