INTRODUCTION ------------------- This document details how to add an external module, such as a tutorial, to OOBE. The information here is based on the mouse tutorial in ME OOBE. Goals for adding external modules: * Look and feel remains the same * OOBE navigation system is used * External module can be developed and tested with little help from OOBE development TEMPLATES ----------------- To address all three of these issues a set of template HTML and script files have been developed. These can be found in %SDXROOT%\ADMIN\NTSETUP\OOBE\HTML\TEMPLATE: * external.htm is the template for HTML files * external.js for script modules * testshel.htm is the OOBE shell to use for testing %SDXROOT%\ADMIN\NTSETUP\OOBE\HTML | |-- mymodule.js | |-- TEMPLATES | |-- testshel.htm |-- external.htm |-- external.js There can be as many HTML pages as are required. There should be exactly on script module and one test shell. When working with these templates, replace _MODULE_ with the name of your module and _MODULEDIR_ with the name of the directory containing your modules HTML files. ADDING FILES TO THE NT SOURCE TREE ------------------------------------ HTML pages should be added to a subdirectory of %SDXROOT%\ADMIN\NTSETUP\OOBE\HTML\HTML. Images should be in an IMAGES subdirectory below this directory. Script modules should be added to %SDXROOT%\ADMIN\NTSETUP\OOBE\HTML. %SDXROOT%\ADMIN\NTSETUP\OOBE\HTML | |-- mymod.js | |-- HTML | |-- MYMODULE | |-- mymod_a.htm |-- mymod_b.htm |-- ... |-- mymod_n.htm | |-- IMAGES | |-- mymod.jpg FILE NAMING ----------------- The name of your module subdirectory, the first page of your module, and your script file should be the same as the name of your module. For example, if your module is named MyMod, then your module subdirectory would be named MyMod, the first page of the module should be named MyMod.htm and your scripts should be in MyMod.js. This will allow the shell scripts to find your first page and scripts files. Other files may be named as you wish. All files should have 8.3 names. VARIABLE AND FUNCTION NAMING -------------------------------- Since your module will be dropped into a public name space it is a good idea to prepend all global variable and function names with the name of your module. TEST INSTALLATION ----------------- For testing purposes: * copy the test shell to %windir%\system32\oobe\msobshel.htm. This replaces the real OOBE shell with one that references your module. * copy your script file to %windir%\system32\oobe. * copy your HTML files to %windir%\system32\oobe\html\MyMod * copy your image files to %windir%\system32\oobe\html\MyMod\images %WINDIR%\SYSTEM32\OOBE | |-- msobshel.htm (renamed from testshel.htm) |-- mymod.js | |-- HTML | |-- MYMOD | |-- mymod_a.htm |-- mymod_b.htm |-- ... |-- mymod_n.htm | |-- IMAGES | |-- mymod.jpg WHISTLER INSTALLATION ----------------------- For installation by Whistler setup OOBE development will need the following information: * name of the directory your module is enlisted in * name of all HTML files * name of all image files * name of the script file SCRIPT MODULES --------------------- Scripts should be written in JScript. The script module will be included in the appropriate shell modules (msobshel.htm, dskshell.htm, ispshell.htm, regshell.htm) via a script tag. . If you named your script file per the naming convention suggestions this will be done automatically. Scripting docs can be found at http://msdn.microsoft.com/scripting. OOBE NAVIGATION ---------------- Navigation within your module is accomplished by creating a mapping between each file and the one that is to follow it. These mappings are stored in a Scripting.Dictionary object. The initialization should occur in the MyMod_InitSimpleNavMap function. For each page except the last add a line like the following: g_SimpleNavMap.Add("MyMod.htm", MyModDir+"MyMod_a.htm" ); The function called in response to the ONLOAD event will call InitButtons("DoMyModButtons"). This will set the ONCLICK handlers for the Back and Next buttons to window.parent.SimpleNavBack and window.parent.SimpleNavNext respectively. SimpleNavNext looks up the current page in g_SimpleNavMap, retrieves the path to the next page, and navigates to it. SimpleNavBack simply calls window.parent.history.back. The last page must call window.parent.GoNext(); This will cause OOBE to navigate to the page that should follow the external module. DEBUGGING -------------- * Install the Script Debugger from Control Panel\Add/Remove Programs\Add/Remove Windows Components. * ALWAYS set HKLM\Software\Microsoft\Windows\CurrentVersion\Setup\OOBE * OemDebug = 1 to turn on error popups and allow switching between OOBE and other tasks (such as ntsd and regedit) * MsDebug = 1 to allow tracing to the debugger from script. * To send trace output to the debugger use the window.parent.trace(str) function in testshel.htm. See the GoNavigate function in testshel.htm for examples. * Occasionally an error popup will be activated but not displayed. This will appear to you as if OOBE has hung. Try pressing the Enter or Esc keys to dismiss the popup and continue. If this happens continually, try putting a try...catch block around the suspect code and write the exception info to the debugger using trace( ). For example, try { // suspect code } catch (err) { window.parent.trace("ERROR: " + err.number + ":" + err.description); } * While OOBE is running you can press Shift+F10 to bring up a console window. This is especially helpful when something breaks in system context. RUNNING OOBE IN SYSTEM CONTEXT --------------------------------- OOBE runs in the system context (prior to any user logon). This can present problems if subsystems that we rely on assume a user is logged in. To run OOBE in this context do the following: * Set HKLM\System\Setup\ * CmdLine = %windir%\system32\oobe\msoobe.exe /f * SetupType = 2 (no reboot) * MiniSetupInProgress = 1 * Reboot the system The system will initialize, verify that the disks are okay, then run OOBE. EXTERNAL DEV TASKS -------------------------- Developers of external modules will need to perform the following tasks: * Develop pages and scripts based on template files. * Test pages and scripts using testshel.htm. Ideally this should be done in system context (ie. prior to logon). See the RUNNING OOBE IN SYSTEM CONTEXT section for more details. * Supply OOBE development with the following information: * Module name * Name of first HTML file (for checkpoint) * Name of script file (so it can be included in shell scripts) * Where module fits in OOBE flow EXTERNAL DEV INFO ----------------------- * window.external methods These are methods provided by OOBE via the window.external object in the Browser object. * InfoObj.get_FirstName Retrieves the user's first name. * InfoObj.get_LastName Retrieves the user's last name. * ApiObj.get_SystemDirectory Retrieves the path to the system directory. * DebugObj.Trace Output trace statements to the debugger from script. * DebugObj.get_MsDebugMode Is MsDebugMode on? If it is not, Trace does not work. * DebugObj.get_OemDebugMode Is OemDebugMode on? If it is not, you won't see error popups or be able to switch from OOBE to other apps. * Registry entries * Main OOBE reg key * HKLM\Software\Microsoft\Windows\CurrentVersion\Setup\OOBE * CKPT (Key) This is the checkpoint stack that tracks where the user has been. Whack this to restart OOBE. * Temp (Key) Temporary data store. We keep information here until OOBE has been successfully completed. * OemDebug (REG_DWORD) Set this to 1 turns on error notification and allow focus to shift away from OOBE. shift focus away from OOBE. * MsDebug (REG_DWORD) Set this to 1 to turn on tracing to the debugger from script (DebugObj.Trace). * System setup key * HKLM\System\Setup This key controls the way the way that setup apps are run. * CmdLine (REG_SZ) Command line to be run by winlogon at startup. For OOBE set this to %windir%\system32\oobe\msoobe.exe /f * SetupType (REG_DWORD) Set this to 0x00000002 to run the CmdLine. * MiniSetupInProgress (REG_DWORD) Set this to 0x00000001. OOBE mimics the state of mini-setup. * Template HTML and script files OOBE DEV TASKS ------------------- OOBE development will need to perform the following tasks to hook an external module into OOBE: * Add checkpoint for external module * Add case for external module to GoNext, GoBack, GoCancel, GoNavigate as appropriate * Add entry for checkpoint to status menus * Call MyMod_InitSimpleNavMap( ) in InitCKPT() * Call g_MyModLastPage = MyModGetLastPage() from InitCKPT() * Create a temporary msobshel.htm with above items for testing purposes.