InstallShield status
Currently InstallShield is mostly working. RobShearman has added the last patches bringing InstallShield up to a working state. JeremyWhite and CodeWeavers are offering InstallerBounties on non-working installers.
Problems include:
Ref counting: IDriver doesn't shut down properly in some circumstances.
InstallShield notes
InstallShield is based around the concept of a small "stub" loader program which installs the IKernel/IDriver install engine, then activates it to start the actual install process itself. The stub is the thing that the user runs (FoobarAppSetup.exe), typically this is a simple self-extractor which writes a bunch of files to a temporary directory somewhere, then invokes the extracted setup.exe. The extracted setup.exe then installs the InstallShield engine, registering it as a COM object in the process, then uses DCOM to activate it as an out-of-process server. The install process then begins.
This rather bizarre system is because InstallShield dates from a time when software was mostly distributed on floppy disks and CD-ROMs, where it was OK for a setup program to consist of multiple files. With the advent of the net, single file installers became necessary so a simple wrapper was added that just extracts the real installer to this temporary directory and then runs it.
The kernel is copied across to C:\Program Files\Common Files\InstallShield then activated using CoCreateInstance. At this point there are two processes running: setup.exe and "iKernel.exe -Embedding". The -Embedding switch tells the iKernel process to create a couple of objects then register them with CoRegisterClassObject:
SetupKernel: {91814ec0-b5f0-11d2-80b9-00104b1f6cea}
SetupLogServices: {22d84ec7-e201-4432-b3ed-a9dca3604594}
The process of registering them unblocks CoCreateInstance which then demarshals them into the setup.exe process. Now the engine has to start itself up, and the loader program (setup.exe) has to tell the kernel what to do.
The SetupKernel classfactory is marshalled back to setup.exe, which then does a IClassFactory::CreateInstance RPC on it. This returns a marshalled ISetupMedia interface pointer. ISetupMedia and indeed all InstallShield interfaces are currently marshalled using the typelib marshaller. This means the interface vtables are constructed on the fly from small blocks of assembly that jump to xCall in tmarshal.c and then marshalled using the type information loaded from the databases inside the EXE and DLL files of the InstallShield kernel.
The first RPC that takes place is ISetupMedia::OpenCAB. This opens up the shipped data.cab file (remember this is sitting in the temporary directory).
The following RPCs take place during startup. As you can see the kernel does regular callbacks to the setup.exe loader informing it of the kernel's progress.
9232:setup.exe ->ISetupMedia::OpenCAB 10000:setup.exe ->ISetupCABFile::IncludedLanguages 10047:setup.exe ->ISetupCABFile::IncludedLanguages 10091:setup.exe ->ISetupCABFile::Components 10363:setup.exe ->ISetupComponents::Item 12191:setup.exe ->ISetupBasicFeature::State 12297:setup.exe ->ISetupComponent::ForceTransfer 12342:setup.exe ->ISetupComponent::Cost 12526:setup.exe ->ISetupFilesCost::TransferLow 12567:setup.exe ->ISetupFilesCost::TransferHigh 12678:setup.exe ->ISetupComponents::Item 12821:setup.exe ->ISetupComponent::Components 13092:setup.exe ->ISetupComponents::Item 14881:setup.exe ->ISetupComponent::Components 15152:setup.exe ->ISetupComponents::Item 17156:setup.exe ->ISetupComponent::EnterNewState 17426:iKernel.exe ->ISetupTransferEvents::Entering 18909:iKernel.exe ->ISetupTransferEvents::Entered 19111:setup.exe ->ISetupBasicFeature::State 19220:setup.exe ->ISetupCABFile::InitializeLog 19426:setup.exe ->ISetupBasicFeature::State 19563:setup.exe ->ISetupBasicFeature::State 19668:setup.exe ->ISetupComponent::EnterNewState 19784:iKernel.exe ->ISetupTransferEvents::Entering 21262:iKernel.exe ->ISetupTransferEvents::Entering 23304:iKernel.exe ->ISetupTransferEvents::InstallingFile 23356:iKernel.exe ->ISetupTransferEvents2::TransferRate 23396:iKernel.exe ->ISetupTransferEvents::Progress 23451:iKernel.exe ->ISetupTransferEvents::InstallingFile 23543:iKernel.exe ->ISetupTransferEvents::InstallingFile 23598:iKernel.exe ->ISetupTransferEvents::Progress 23645:iKernel.exe ->ISetupTransferEvents::Progress 23692:iKernel.exe ->ISetupTransferEvents::Progress 23739:iKernel.exe ->ISetupTransferEvents::Progress 23786:iKernel.exe ->ISetupTransferEvents::Progress 23841:iKernel.exe ->ISetupTransferEvents::InstallingFile 25547:iKernel.exe ->ISetupTransferEvents::InstallingFile 25603:iKernel.exe ->ISetupTransferEvents::Progress 25649:iKernel.exe ->ISetupTransferEvents::Progress 25704:iKernel.exe ->ISetupTransferEvents::InstallingFile 25789:iKernel.exe ->ISetupTransferEvents::InstallingFile 25844:iKernel.exe ->ISetupTransferEvents::Progress 25891:iKernel.exe ->ISetupTransferEvents::Progress 25939:iKernel.exe ->ISetupTransferEvents::Progress 25986:iKernel.exe ->ISetupTransferEvents::Progress 26033:iKernel.exe ->ISetupTransferEvents::Progress 26080:iKernel.exe ->ISetupTransferEvents::Progress 26127:iKernel.exe ->ISetupTransferEvents::Progress 26174:iKernel.exe ->ISetupTransferEvents::Progress 26220:iKernel.exe ->ISetupTransferEvents::Progress 26267:iKernel.exe ->ISetupTransferEvents::Progress 26314:iKernel.exe ->ISetupTransferEvents::Progress 26369:iKernel.exe ->ISetupTransferEvents::InstallingFile 28350:iKernel.exe ->ISetupTransferEvents::InstallingFile 28400:iKernel.exe ->ISetupTransferEvents2::TransferRate 28442:iKernel.exe ->ISetupTransferEvents::Progress 28488:iKernel.exe ->ISetupTransferEvents::Progress 28535:iKernel.exe ->ISetupTransferEvents::Progress 28582:iKernel.exe ->ISetupTransferEvents::Progress 28629:iKernel.exe ->ISetupTransferEvents::Progress 28676:iKernel.exe ->ISetupTransferEvents::Progress 28723:iKernel.exe ->ISetupTransferEvents::Progress 28770:iKernel.exe ->ISetupTransferEvents::Progress 28818:iKernel.exe ->ISetupTransferEvents::Progress 28864:iKernel.exe ->ISetupTransferEvents::Progress 28911:iKernel.exe ->ISetupTransferEvents::Progress 28958:iKernel.exe ->ISetupTransferEvents::Progress 29005:iKernel.exe ->ISetupTransferEvents::Progress 29060:iKernel.exe ->ISetupTransferEvents::InstallingFile 29391:iKernel.exe ->ISetupTransferEvents::Entering 33097:iKernel.exe ->ISetupTransferEvents::InstallingFile 33152:iKernel.exe ->ISetupTransferEvents::Progress 33207:iKernel.exe ->ISetupTransferEvents::InstallingFile 36936:iKernel.exe ->ISetupTransferEvents::Entered 37078:iKernel.exe ->ISetupTransferEvents::Entered 37220:iKernel.exe ->ISetupTransferEvents::Entering 38071:iKernel.exe ->ISetupTransferEvents::Entering 39585:iKernel.exe ->ISetupTransferEvents::InstallingFile 39636:iKernel.exe ->ISetupTransferEvents2::TransferRate 39677:iKernel.exe ->ISetupTransferEvents::Progress 39724:iKernel.exe ->ISetupTransferEvents::Progress 39771:iKernel.exe ->ISetupTransferEvents::Progress 39818:iKernel.exe ->ISetupTransferEvents::Progress 39865:iKernel.exe ->ISetupTransferEvents::Progress 39912:iKernel.exe ->ISetupTransferEvents::Progress 39959:iKernel.exe ->ISetupTransferEvents::Progress 40014:iKernel.exe ->ISetupTransferEvents::InstallingFile 40072:iKernel.exe ->ISetupTransferEvents::Entered 40214:iKernel.exe ->ISetupTransferEvents::Entering 41728:iKernel.exe ->ISetupTransferEvents::InstallingFile 41783:iKernel.exe ->ISetupTransferEvents::Progress 41830:iKernel.exe ->ISetupTransferEvents::Progress 41877:iKernel.exe ->ISetupTransferEvents::Progress 41924:iKernel.exe ->ISetupTransferEvents::Progress 41971:iKernel.exe ->ISetupTransferEvents::Progress 42018:iKernel.exe ->ISetupTransferEvents::Progress 42065:iKernel.exe ->ISetupTransferEvents::Progress 42112:iKernel.exe ->ISetupTransferEvents::Progress 42167:iKernel.exe ->ISetupTransferEvents::InstallingFile 42248:iKernel.exe ->ISetupTransferEvents::InstallingFile 42303:iKernel.exe ->ISetupTransferEvents::Progress 42358:iKernel.exe ->ISetupTransferEvents::InstallingFile 42450:iKernel.exe ->ISetupTransferEvents::InstallingFile 42505:iKernel.exe ->ISetupTransferEvents::Progress 42560:iKernel.exe ->ISetupTransferEvents::InstallingFile 42652:iKernel.exe ->ISetupTransferEvents::InstallingFile 42707:iKernel.exe ->ISetupTransferEvents::Progress 42762:iKernel.exe ->ISetupTransferEvents::InstallingFile 42843:iKernel.exe ->ISetupTransferEvents::InstallingFile 42898:iKernel.exe ->ISetupTransferEvents::Progress 42945:iKernel.exe ->ISetupTransferEvents::Progress 42992:iKernel.exe ->ISetupTransferEvents::Progress 43039:iKernel.exe ->ISetupTransferEvents::Progress 43086:iKernel.exe ->ISetupTransferEvents::Progress 43133:iKernel.exe ->ISetupTransferEvents::Progress 43180:iKernel.exe ->ISetupTransferEvents::Progress 43227:iKernel.exe ->ISetupTransferEvents::Progress 43274:iKernel.exe ->ISetupTransferEvents::Progress 43321:iKernel.exe ->ISetupTransferEvents::Progress 43369:iKernel.exe ->ISetupTransferEvents::Progress 43415:iKernel.exe ->ISetupTransferEvents::Progress 43470:iKernel.exe ->ISetupTransferEvents::InstallingFile 43562:iKernel.exe ->ISetupTransferEvents::InstallingFile 43617:iKernel.exe ->ISetupTransferEvents::Progress 43664:iKernel.exe ->ISetupTransferEvents::Progress 43711:iKernel.exe ->ISetupTransferEvents::Progress 43758:iKernel.exe ->ISetupTransferEvents::Progress 43801:iKernel.exe ->ISetupTransferEvents2::TransferRate 43842:iKernel.exe ->ISetupTransferEvents::Progress 43889:iKernel.exe ->ISetupTransferEvents::Progress 43936:iKernel.exe ->ISetupTransferEvents::Progress 43982:iKernel.exe ->ISetupTransferEvents::Progress 44029:iKernel.exe ->ISetupTransferEvents::Progress 44076:iKernel.exe ->ISetupTransferEvents::Progress 44123:iKernel.exe ->ISetupTransferEvents::Progress 44170:iKernel.exe ->ISetupTransferEvents::Progress 44217:iKernel.exe ->ISetupTransferEvents::Progress 44272:iKernel.exe ->ISetupTransferEvents::InstallingFile 44330:iKernel.exe ->ISetupTransferEvents::Entered 44472:iKernel.exe ->ISetupTransferEvents::Entering 45984:iKernel.exe ->ISetupTransferEvents::InstallingFile 46040:iKernel.exe ->ISetupTransferEvents::Progress 46095:iKernel.exe ->ISetupTransferEvents::InstallingFile 46153:iKernel.exe ->ISetupTransferEvents::Entered 46295:iKernel.exe ->ISetupTransferEvents::Entering 47808:iKernel.exe ->ISetupTransferEvents::InstallingFile 47864:iKernel.exe ->ISetupTransferEvents::Progress 47911:iKernel.exe ->ISetupTransferEvents::Progress 47958:iKernel.exe ->ISetupTransferEvents::Progress 48005:iKernel.exe ->ISetupTransferEvents::Progress 48052:iKernel.exe ->ISetupTransferEvents::Progress 48099:iKernel.exe ->ISetupTransferEvents::Progress 48146:iKernel.exe ->ISetupTransferEvents::Progress 48193:iKernel.exe ->ISetupTransferEvents::Progress 48240:iKernel.exe ->ISetupTransferEvents::Progress 48287:iKernel.exe ->ISetupTransferEvents::Progress 48334:iKernel.exe ->ISetupTransferEvents::Progress 48381:iKernel.exe ->ISetupTransferEvents::Progress 48428:iKernel.exe ->ISetupTransferEvents::Progress 48475:iKernel.exe ->ISetupTransferEvents::Progress 48522:iKernel.exe ->ISetupTransferEvents::Progress 48569:iKernel.exe ->ISetupTransferEvents::Progress 48616:iKernel.exe ->ISetupTransferEvents::Progress 48663:iKernel.exe ->ISetupTransferEvents::Progress 48710:iKernel.exe ->ISetupTransferEvents::Progress 48757:iKernel.exe ->ISetupTransferEvents::Progress 48804:iKernel.exe ->ISetupTransferEvents::Progress 48859:iKernel.exe ->ISetupTransferEvents::InstallingFile 48940:iKernel.exe ->ISetupTransferEvents::InstallingFile 48995:iKernel.exe ->ISetupTransferEvents::Progress 49050:iKernel.exe ->ISetupTransferEvents::InstallingFile 49105:iKernel.exe ->ISetupTransferEvents::Entered 49247:iKernel.exe ->ISetupTransferEvents::Entering 50760:iKernel.exe ->ISetupTransferEvents::InstallingFile 50816:iKernel.exe ->ISetupTransferEvents::Progress 50863:iKernel.exe ->ISetupTransferEvents::Progress 50906:iKernel.exe ->ISetupTransferEvents2::TransferRate 50947:iKernel.exe ->ISetupTransferEvents::Progress 50994:iKernel.exe ->ISetupTransferEvents::Progress 51041:iKernel.exe ->ISetupTransferEvents::Progress 51088:iKernel.exe ->ISetupTransferEvents::Progress 51135:iKernel.exe ->ISetupTransferEvents::Progress 51182:iKernel.exe ->ISetupTransferEvents::Progress 51229:iKernel.exe ->ISetupTransferEvents::Progress 51276:iKernel.exe ->ISetupTransferEvents::Progress 51321:iKernel.exe ->ISetupTransferEvents::Progress 51368:iKernel.exe ->ISetupTransferEvents::Progress 51415:iKernel.exe ->ISetupTransferEvents::Progress 51462:iKernel.exe ->ISetupTransferEvents::Progress 51509:iKernel.exe ->ISetupTransferEvents::Progress 51564:iKernel.exe ->ISetupTransferEvents::InstallingFile 51622:iKernel.exe ->ISetupTransferEvents::Entered 51765:iKernel.exe ->ISetupTransferEvents::Entered 51908:iKernel.exe ->ISetupTransferEvents::Entered 52076:setup.exe ->ISetupCABFile::IncludedLanguages 52123:setup.exe ->ISetupCABFile::IncludedPatforms 52373:setup.exe ->ISetupServiceProvider::QueryService 52916:setup.exe ->ISetupTextSubstitution::Value 52958:setup.exe ->ISetupTextSubstitution::Value 53066:setup.exe ->ISetupServiceProvider::QueryService 53478:setup.exe ->ISetupInfo::ProcessSetupIni 53520:setup.exe ->ISetupInfo::ProcessCommandLine 53561:setup.exe ->ISetupCABFile::MainObject 54232:iKernel.exe ->ISetupUserInterface::RegisterServices 54560:0044 ->ISetupServiceProvider::QueryService 54792:iKernel.exe ->ISetupUserInterface::MainWindow 58762:setup.exe ->ISetupDriver::Run 59192:iKernel.exe ->IDispatch::GetIDsOfNames 59406:iKernel.exe ->IDispatch::Invoke 59734:iKernel.exe ->ISetupMainWindow::Caption 59883:iKernel.exe ->ISetupUserInterface::MainWindow 60045:iKernel.exe ->ISetupUserInterface::MainWindow 60310:iKernel.exe ->ISetupMainWindow::Create 60612:iKernel.exe ->ISetupMainWindow::hWnd 60879:setup.exe ->ISetupServiceProvider::QueryService 61309:setup.exe ->ISetupReboot::NeedReboot 61354:setup.exe ->ISetupComponent::LeaveCurrentState 61467:iKernel.exe ->ISetupTransferEvents::Leaving 61604:iKernel.exe ->ISetupTransferEvents::Leaving 61745:iKernel.exe ->ISetupTransferEvents::Progress 61792:iKernel.exe ->ISetupTransferEvents::Progress 61839:iKernel.exe ->ISetupTransferEvents::Progress 61886:iKernel.exe ->ISetupTransferEvents::Progress 61940:iKernel.exe ->ISetupTransferEvents::UninstallingFile 61994:iKernel.exe ->ISetupTransferEvents::Progress 62048:iKernel.exe ->ISetupTransferEvents::UninstallingFile 62102:iKernel.exe ->ISetupTransferEvents::Progress 62146:iKernel.exe ->ISetupTransferEvents::Left 62284:iKernel.exe ->ISetupTransferEvents::Leaving 62425:iKernel.exe ->ISetupTransferEvents::Progress 62472:iKernel.exe ->ISetupTransferEvents::Progress 62517:iKernel.exe ->ISetupTransferEvents::Progress 62564:iKernel.exe ->ISetupTransferEvents::Progress 62618:iKernel.exe ->ISetupTransferEvents::UninstallingFile 62672:iKernel.exe ->ISetupTransferEvents::Progress 62726:iKernel.exe ->ISetupTransferEvents::UninstallingFile 62787:iKernel.exe ->ISetupTransferEvents::UninstallingFile 62841:iKernel.exe ->ISetupTransferEvents::Progress 62895:iKernel.exe ->ISetupTransferEvents::UninstallingFile 62949:iKernel.exe ->ISetupTransferEvents::Progress 62993:iKernel.exe ->ISetupTransferEvents::Left 63131:iKernel.exe ->ISetupTransferEvents::Leaving 63272:iKernel.exe ->ISetupTransferEvents::Progress 63319:iKernel.exe ->ISetupTransferEvents::Progress 63366:iKernel.exe ->ISetupTransferEvents::Progress 63413:iKernel.exe ->ISetupTransferEvents::Progress 63467:iKernel.exe ->ISetupTransferEvents::UninstallingFile 63521:iKernel.exe ->ISetupTransferEvents::Progress 63575:iKernel.exe ->ISetupTransferEvents::UninstallingFile 63629:iKernel.exe ->ISetupTransferEvents::Progress 63673:iKernel.exe ->ISetupTransferEvents::Left 63811:iKernel.exe ->ISetupTransferEvents::Leaving 63952:iKernel.exe ->ISetupTransferEvents::Progress 63999:iKernel.exe ->ISetupTransferEvents::Progress 64044:iKernel.exe ->ISetupTransferEvents::Progress 64091:iKernel.exe ->ISetupTransferEvents::Progress 64145:iKernel.exe ->ISetupTransferEvents::UninstallingFile 64199:iKernel.exe ->ISetupTransferEvents::Progress 64253:iKernel.exe ->ISetupTransferEvents::UninstallingFile 64312:iKernel.exe ->ISetupTransferEvents::UninstallingFile 64366:iKernel.exe ->ISetupTransferEvents::Progress 64420:iKernel.exe ->ISetupTransferEvents::UninstallingFile 64481:iKernel.exe ->ISetupTransferEvents::UninstallingFile 64535:iKernel.exe ->ISetupTransferEvents::Progress 64589:iKernel.exe ->ISetupTransferEvents::UninstallingFile 64650:iKernel.exe ->ISetupTransferEvents::UninstallingFile 64704:iKernel.exe ->ISetupTransferEvents::Progress 64758:iKernel.exe ->ISetupTransferEvents::UninstallingFile 64819:iKernel.exe ->ISetupTransferEvents::UninstallingFile 64873:iKernel.exe ->ISetupTransferEvents::Progress 64927:iKernel.exe ->ISetupTransferEvents::UninstallingFile 64987:iKernel.exe ->ISetupTransferEvents::UninstallingFile 65041:iKernel.exe ->ISetupTransferEvents::Progress 65095:iKernel.exe ->ISetupTransferEvents::UninstallingFile 65149:iKernel.exe ->ISetupTransferEvents::Progress 65193:iKernel.exe ->ISetupTransferEvents::Left 65331:iKernel.exe ->ISetupTransferEvents::Leaving 65472:iKernel.exe ->ISetupTransferEvents::Progress 65519:iKernel.exe ->ISetupTransferEvents::Progress 65565:iKernel.exe ->ISetupTransferEvents::Progress 65612:iKernel.exe ->ISetupTransferEvents::Progress 65666:iKernel.exe ->ISetupTransferEvents::UninstallingFile 65720:iKernel.exe ->ISetupTransferEvents::Progress 65774:iKernel.exe ->ISetupTransferEvents::UninstallingFile 65835:iKernel.exe ->ISetupTransferEvents::UninstallingFile 65889:iKernel.exe ->ISetupTransferEvents::Progress 65943:iKernel.exe ->ISetupTransferEvents::UninstallingFile 66004:iKernel.exe ->ISetupTransferEvents::UninstallingFile 66058:iKernel.exe ->ISetupTransferEvents::Progress 66111:iKernel.exe ->ISetupTransferEvents::UninstallingFile 66172:iKernel.exe ->ISetupTransferEvents::UninstallingFile 66226:iKernel.exe ->ISetupTransferEvents::Progress 66280:iKernel.exe ->ISetupTransferEvents::UninstallingFile 66334:iKernel.exe ->ISetupTransferEvents::Progress 66378:iKernel.exe ->ISetupTransferEvents::Left 66520:iKernel.exe ->ISetupTransferEvents::Progress 66567:iKernel.exe ->ISetupTransferEvents::Progress 66614:iKernel.exe ->ISetupTransferEvents::Progress 66661:iKernel.exe ->ISetupTransferEvents::Progress 66708:iKernel.exe ->ISetupTransferEvents::Progress 66752:iKernel.exe ->ISetupTransferEvents::Left
The exact purpose of these objects is currently unknown, but it doesn't matter. They're internal to the setup process and as long as the marshalling is correct they'll work.
A word about InstallShield's error handling. There isn't any. A common error is the notorious "Object reference not set" message. It was originally believed that this had some single cause but these days the most popular explanation is that the installer contains some iScript (InstallShield's own scripting language) like this:
foo = bar(); foo.baz();
If bar crashes, either in the function itself or in DCOM marshalling code, then an exception is thrown. This is swallowed by InstallShield which apparently ignores it. Instead, foo is set to null and at some arbitrary later point the script tries to invoke a method on a null object, creating this error message. In other words, the true cause of the error is likely to be earlier on in the installer. Attempting to work backwards from the message box call is usually an excercise in futility: instead look for the exception that causes it. The first exception is not an error, it is Wine working around InstallShield writing directly to the resources. Don't be fooled.
Re-entrancy is very important to InstallShield: simply initialising the kernel itself requires it as the setup.exe loader does an RPC to the kernel, which then does RPCs back to the loader to inform it of progress. The entire setup proceeds whilst inside an RPC. It also makes heavy use of inter-thread marshalling: the actual install takes place inside one or more threads which report progress back to the GUI thread via DCOM RPCs. It's therefore important that performance is good, as every single file copied causes an RPC back to the GUI thread.
Related bug
Here's a related bug on performance: http://bugs.winehq.org/show_bug.cgi?id=3817
