InstallShield

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

InstallShield (last edited 2008-05-03 03:07:39 by nathan.n)