; ======================================================================
; File:			OEMSETUP.INF
;
; Contains:		Virtual PC Network Services for Windows NT 4.0 INF file
;
; Copyright:	(c) 2001-2003, Connectix Corporation
; ======================================================================

; ======================================================================
;	Install Options
; ======================================================================

[Identification]
    OptionType = NetTransport

[Options]
    VPCNetNT

[ProductType]
    STF_PRODUCT  = WinNT
    STF_PLATFORM = I386

; ======================================================================
; Constants
; ======================================================================

[FileConstants]
	UtilityInf      = "UTILITY.INF"
	ParamInf        = "NCPARAM.INF"
	subroutineinf   = "SUBROUTN.INF"
	Exit_Code       = 0

	NetEventDLL     = "%SystemRoot%\System32\netevent.dll"
	IoLogMsgDLL     = "%SystemRoot%\System32\IoLogMsg.dll"

	Manufacturer         = "Connectix"
	ProductMajorVersion  = "2"
	ProductMinorVersion  = "3"
	ProductVersion       = $(ProductMajorVersion)"."$(ProductMinorVersion)
	ProductName          = "VPCNetNT"
	MaxNumberOfLowerNICs = 1
	MaxCardsToCheck      = 100

	ServiceLogFiles          = "%SystemRoot%\System32\drivers\VPCNetNT.sys;%SystemRoot%\System32\IoLogMsg.dll;%SystemRoot%\System32\netevent.dll"

	NDISProtocolImagePath		 = "\SystemRoot\System32\drivers\VPCNetNT.sys"
	NDISProtocolName			 = $(ProductName)
	NDISProtocolServiceType		 = 4
	NDISProtocolServiceStart	 = 3
	NetRuleNDISProtocolType      = "VPCNetNT VPCNetNT"
	NetRuleNDISProtocolClass     = {"VPCNetNT basic"}
	NetRuleNDISProtocolUse       = "transport none none"
	NetRuleNDISProtocolBindForm  = """VPCNetNT"" yes yes simple"
	NetRuleNDISProtocolBindable  = {"VPCNetNT ndisDriver non non 100"}
	NDISProtocolReviewBindings   = 1
	NDISProtocolHide			 = 0
	NDISProtocolOperationsSupport= 133
	NDISProtocolProductKeyName	 = $(!NTN_SoftwareBase)"\"$(Manufacturer)"\"$(NDISProtocolName)"\CurrentVersion"
	NDISProtocolServiceKeyName	 = $(!NTN_ServiceBase)"\"$(NDISProtocolName)
	NDISProtocolParamKeyName	 = $(!NTN_ServiceBase)"\"$(NDISProtocolName)"\Parameters"
	NDISProtocolLinkageKeyName	 = $(!NTN_ServiceBase)"\"$(NDISProtocolName)"\Linkage"
	OEM_ABANDON_PROTOCOL		 = FALSE

	NDISMiniportImagePath		 = "\SystemRoot\System32\drivers\VPCNetNT.sys"
	NDISMiniportName			 = $(ProductName)"Miniport"
	NDISMiniportServiceType		 = 1
	NDISMiniportServiceStart	 = 2
	NetRuleNDISMiniportType		 = "VPCNetNTSys ndisDriver VPCNetNTDriver"
	NetRuleNDISMiniportClass	 = {"VPCNetNTDriver basic"}
	NetRuleNDISMiniportUse		 = "driver"
	NetRuleNDISMiniportBindForm	 = """VPCNetNTSys"" yes no simple"
	NetRuleNDISMiniportBindable	 = {"VPCNetNTDriver VPCNetNTAdapter non exclusive 100"}
	NDISMiniportReviewBindings	 = 0
	NDISMiniportHide			 = 0
	NDISMiniportOperationsSupport= 132
	NDISMiniportProductKeyName	 = $(!NTN_SoftwareBase)"\"$(Manufacturer)"\"$(NDISMiniportName)"\CurrentVersion"
	NDISMiniportServiceKeyName	 = $(!NTN_ServiceBase)"\"$(NDISMiniportName)
	NDISMiniportParamKeyName	 = $(!NTN_ServiceBase)"\"$(NDISMiniportName)"\Parameters"
	NDISMiniportLinkageKeyName	 = $(!NTN_ServiceBase)"\"$(NDISMiniportName)"\Linkage"
	NDISMiniportSignature		 = $(NDISMiniportName)
	OEM_ABANDON_MINIPORT		 = FALSE

	AdapterName					 = $(NDISMiniportName)
	NetRuleAdapterType			 = "VPCNetNTVirtualNIC VPCNetNTAdapter"
	NetRuleAdapterClass			 = {"VPCNetNTAdapter basic"}
	NetRuleAdapterBindForm		 = " yes yes simple"
	AdapterOperationsSupport	 = $(NDISMiniportOperationsSupport)
	AdapterProductKeyName		 = $(!NTN_SoftwareBase)"\"$(Manufacturer)"\"$(AdapterName)"\CurrentVersion"
	AdapterServiceKeyName		 = $(!NTN_ServiceBase)"\"$(AdapterName)
	AdapterParamKeyName			 = $(!NTN_ServiceBase)"\"$(AdapterName)"\Parameters"
	AdapterLinkageKeyName		 = $(!NTN_ServiceBase)"\"$(AdapterName)"\Linkage"

	DisableProtocolsList		 = {"AppleTalk", "DLC", "Nbf", "NwLnkIpx", "Tcpip", "NetBT"}

[GeneralConstants]
    from      = ""
    to        = ""

    ExitCodeOk     = 0
    ExitCodeCancel = 1
    ExitCodeFatal  = 2

    KeyNull            = ""
    MAXIMUM_ALLOWED    = 33554432
    RegistryErrorIndex = NO_ERROR
    KeyProduct         = ""
    KeyParameters      = ""

    TRUE               = 1
    FALSE              = 0
    NoTitle            = 0

    ExitState          = "Active"
    OldVersionExisted  = $(FALSE)

    DriverPath         = $(!STF_NTPATH)\drivers

	NetworkCardKeyName	 = $(!NTN_SoftwareBase)"\Microsoft\Windows NT\CurrentVersion\NetworkCards"

[date]
    Now = {} ? $(!LIBHANDLE) GetSystemDate

; ======================================================================
; Localization
; ======================================================================

[LanguagesSupported]
    ENG


[OptionsTextENG]
    VPCNetNT = "Virtual PC Emulated Ethernet Switch for Windows NT 4.0"


[FileConstantsENG]
    ProCaption                  = "Windows NT Setup"
    ProCancel                   = "Cancel"
    ProCancelMsg                = "Windows NT Networking is not correctly installed.  "+
                                  "Are you sure you want to cancel copying files?"
    ProCancelCap                = "Network Setup Message"
    ProText1                    = "Copying:"
    ProText2                    = "To:"
    ShellCodeErrorTitle         = "Error: "$(FunctionTitle)
    ShellCodeErrorText          = "Shell Code Error."

	ProductDesc				 = "Virtual PC Emulated Ethernet Switch"
    FunctionTitle			 = "Virtual PC Emulated Ethernet Switch Setup"

    NDISProtocolTitle        = "Virtual PC Emulated Ethernet Switch (Protocol)"
    NDISProtocolDescription	 = "Provides support for Virtual PC's Virtual Switch networking feature."

    NDISMiniportTitle        = "Virtual PC Emulated Ethernet Switch"
    NDISMiniportDescription	 = "Provides support for Virtual PC's Virtual Switch networking feature."

	AdapterTitle			 = "Virtual PC Emulated Ethernet Switch (Adapter)"
	AdapterDescription		 = "Provides support for Virtual PC's Virtual Switch networking feature."

[DialogConstantsENG]
    Help        = "&Help"
    Exit        = "Cancel"
    OK          = "OK"
    HelpContext = ""
    Continue    = "Continue"
    Cancel      = "Cancel"

[RemoveProtocolMessageDlgENG]
DlgType = "MessageBox"
    STF_MB_TITLE = "Important Deinstallation Information"
    STF_MB_TEXT  = "To uninstall this adapter, remove "$(NDISProtocolTitle)" from Protocols."
    STF_MB_TYPE  = 1    ; display OK button
    STF_MB_ICON  = 5    ; ! icon
    STF_MB_DEF   = 1    ; default button is OK

[ReenableBindingsMessageDlgENG]
DlgType = "MessageBox"
    STF_MB_TITLE = "Important Deinstallation Information"
    STF_MB_TEXT  = "In order to restore complete network connectivity, you must manually re-enable the protocol bindings to your real adapter(s)."
    STF_MB_TYPE  = 1    ; display OK button
    STF_MB_ICON  = 5    ; ! icon
    STF_MB_DEF   = 1    ; default button is OK

[ProtocolBindingsMessageDlgENG]
DlgType = "MessageBox"
    STF_MB_TITLE = "Important Configuration Information"
    STF_MB_TEXT  = "To complete the setup of "$(ProductDesc)", make sure that TCP/IP, the WINS Client and any protocols other than "$(NDISProtocolTitle)" are bound only to the "$(NDISMiniportTitle)" adapter(s). "$(NDISProtocolTitle)" must be bound to the real Ethernet adapter(s) installed in this computer."
    STF_MB_TYPE  = 1    ; display OK button
    STF_MB_ICON  = 5    ; ! icon
    STF_MB_DEF   = 1    ; default button is OK

[ConfigureMessageDlgENG]
DlgType = "MessageBox"
    STF_MB_TITLE = "Configuration Not Supported"
    STF_MB_TEXT  = "Configuration of this component is not necessary."
    STF_MB_TYPE  = 1    ; display OK button
    STF_MB_ICON  = 5    ; ! icon
    STF_MB_DEF   = 1    ; default button is OK

; ======================================================================
; Install Sections
; ======================================================================

[Install-Option]
    set STF_VITAL = "1"
    set STF_DECOMPRESS = "1"
    ifstr(i) $(AddCopy) == "YES"
        AddSectionFilesToCopyList Files-Driver $(SrcDir) $(!STF_WINDOWSSYSPATH)\drivers
    endif
    ifstr(i) $(DoCopy) == "YES"
       set !STF_NCPA_FLUSH_COPYLIST = TRUE
       CopyFilesInCopyList
    endif
    ifstr(i) $(DoConfig) == "YES"
    endif
    Exit


[Install-Update]
    set STF_VITAL      = "1"
    set STF_DECOMPRESS = "1"
    AddSectionFilesToCopyList Files-Driver $(SrcDir) $(!STF_WINDOWSSYSPATH)\drivers
    AddSectionFilesToCopyList Files-Inf $(SrcDir) $(!STF_WINDOWSSYSPATH)
    set !STF_NCPA_FLUSH_COPYLIST = TRUE
    CopyFilesInCopyList
    exit


[Source Media Descriptions]
    1  = "Virtual PC Emulated Ethernet Switch Setup Disk", TAGFILE = VPCNetNT.

; ======================================================================
; Files List
; ======================================================================

[Files-Inf]
    1,  oemsetup.inf, RENAME=$(!UG_Filename), SIZE=40, !DECOMPRESS


[Files-Driver]
    1,  VPCNetNT.sys, SIZE=100

; ======================================================================
; Required Sections
; ======================================================================

[Identify]
    set !G:DebugOutputControl = 1
    Debug-Output "VPCNetNT - Identify section"

    read-syms Identification

    set Status     = STATUS_SUCCESSFUL
    set Identifier = $(OptionType)
    set Media      = #("Source Media Descriptions", 1, 1)

    Return $(Status) $(Identifier) $(Media)


[ReturnOptions]
    set !G:DebugOutputControl = 1
    Debug-Output "VPCNetNT - ReturnOptions section"
	Debug-Output "VPCNetNT: --> Language : "$($0)

    set Status         = STATUS_FAILED
    set OptionList     = {}
    set OptionTextList = {}

    set LanguageList = ^(LanguagesSupported, 1)
    Ifcontains(i) $($0) in $(LanguageList)
        goto returnoptions
    else
        set Status = STATUS_NOLANGUAGE
        goto finish_ReturnOptions
    endif

returnoptions = +
    set OptionList     = ^(Options, 1)
    set OptionTextList = ^(OptionsText$($0), 1)
    set Status         = STATUS_SUCCESSFUL

finish_ReturnOptions = +
    Return $(Status) $(OptionList) $(OptionTextList)


[InstallOption]
    set !G:DebugOutputControl = 1
    Debug-Output "VPCNetNT - InstallOption section"

    set Status   = STATUS_FAILED

	set Language = $($0)
    set Option   = $($1)
    set SrcDir   = $($2)
    set AddCopy  = $($3)
    set DoCopy   = $($4)
    set DoConfig = $($5)

	Debug-Output "VPCNetNT: --> Language : "$(Language)
	Debug-Output "VPCNetNT: --> Option   : "$(Option)
	Debug-Output "VPCNetNT: --> SrcDir   : "$(SrcDir)
	Debug-Output "VPCNetNT: --> AddCopy  : "$(AddCopy)
	Debug-Output "VPCNetNT: --> DoCopy   : "$(DoCopy)
	Debug-Output "VPCNetNT: --> DoConfig : "$(DoConfig)

    set LanguageList = ^(LanguagesSupported, 1)
    Ifcontains(i) $(Language) NOT-IN $(LanguageList)
        Return STATUS_NOLANGUAGE
    endif

    set-subst LF = "\n"

    read-syms GeneralConstants
    read-syms FileConstants

    read-syms DialogConstants$(!STF_LANGUAGE)
    ifstr(i) $(!NTN_Origination) == "NCPA"
        set Continue = $(OK)
    endif
    read-syms FileConstants$(!STF_LANGUAGE)

    detect date

    set-title  $(FunctionTitle)

    set to   = Begin
    set from = Begin
    ;
    ;  Assume all is well.
    ;
    ; STATUS_SUCCESSFUL
    ; STATUS_USERCANCEL
    ; STATUS_NO_EFFECT
    ; STATUS_REBIND
    ; STATUS_REBOOT

    set CommonStatus = STATUS_SUCCESSFUL

    EndWait

Begin = +
    ;
    Debug-Output "VPCNetNT - Begin label "
	Debug-Output "VPCNetNT: --> NTN_InstallMode : "$(!NTN_InstallMode)

	ifstr(i) $(!NTN_InstallMode) == deinstall
		set StartLabel = ReviewBindings
		set RemoveBindings = TRUE
		set CheckBindings = FALSE
		set WhenDone = RemoveSoftware
		set FirstTime = FALSE
	else-ifstr(i) $(!NTN_InstallMode) == Update
		set StartLabel = UpgradeSoftware
		set RemoveBindings = FALSE
		set CheckBindings = TRUE
		set WhenDone = end
		set FirstTime = FALSE
	else-ifstr(i) $(!NTN_InstallMode) == bind
		set StartLabel = ReviewBindings
		set RemoveBindings = FALSE
		set CheckBindings = TRUE
		set WhenDone = end
		set FirstTime = FALSE
	else-ifstr(i) $(!NTN_InstallMode) == configure
		set StartLabel = ConfigureSoftware
		set RemoveBindings = FALSE
		set CheckBindings = TRUE
		set WhenDone = end
		set FirstTime = FALSE
	else
		set StartLabel = installadapter
		set OEM_ABANDON_OPTIONS = {}
		set OEM_ABANDON_PROTOCOL = FALSE
		set OEM_ABANDON_ON = TRUE
		set RemoveBindings = FALSE
		set CheckBindings = TRUE
		set WhenDone = end
		set FirstTime = TRUE
	endif

	Set from = $(fatal)
	Set to = $(fatal)
	Goto $(StartLabel)

; -----------------------------------------------
; UpgradeSoftware
; -----------------------------------------------

UpgradeSoftware = +

    Debug-Output "VPCNetNT - UpgradeSoftware label"
	Debug-Output "VPCNetNT: --> NTN_RegBase : "$(!NTN_RegBase)

    OpenRegKey $(!REG_H_LOCAL) "" $(NDISProtocolProductKeyName) $(MAXIMUM_ALLOWED) ProtocolKey
    ifstr(i) $(ProtocolKey) == $(KeyNull)
		Debug-Output "VPCNetNT: Failed to open key "$(NDISProtocolProductKeyName)
        goto fatalregistry
	else
		OpenRegKey $(!REG_H_LOCAL) "" $(NDISMiniportProductKeyName) $(MAXIMUM_ALLOWED) MiniportKey
		ifstr(i) $(MiniportKey) == $(KeyNull)
			CloseRegKey $(ProtocolKey)

			Debug-Output "VPCNetNT: Failed to open key "$(NDISMiniportProductKeyName)
			goto fatalregistry
		else
			Shell $(UtilityInf), GetInfFileNameFromRegistry, $(ProtocolKey)
			ifint $($ShellCode) != $(!SHELL_CODE_OK)
				Debug-Output "ShellCode error"
				goto ShellCodeError
			endif
			set !UG_Filename = $($R0)

			install "Install-Update"
			ifstr(i) $(STF_INSTALL_OUTCOME) != STF_SUCCESS
				goto fatal
			endif

			set NewValueList = { +
				{"InstallDate",			 $(NoTitle), $(!REG_VT_DWORD),	 *($(Now),1)}, +
				{"MajorVersion",		 $(NoTitle), $(!REG_VT_DWORD),	 $(ProductMajorVersion)},+
				{"MinorVersion",		 $(NoTitle), $(!REG_VT_DWORD),	 $(ProductMinorVersion)},+
				{"OperationsSupport",	 $(NoTitle), $(!REG_VT_DWORD),	 $(NDISProtocolOperationsSupport)}+
				}
			Shell  $(UtilityInf), AddValueList, $(ProtocolKey), $(NewValueList)
			ifint $($ShellCode) != $(!SHELL_CODE_OK)
				Debug-Output "VPCNetNT: ShellCode error - "$($ShellCode)
			endif

			set NewValueList = { +
				{"InstallDate",			 $(NoTitle), $(!REG_VT_DWORD),	 *($(Now),1)}, +
				{"MajorVersion",		 $(NoTitle), $(!REG_VT_DWORD),	 $(ProductMajorVersion)},+
				{"MinorVersion",		 $(NoTitle), $(!REG_VT_DWORD),	 $(ProductMinorVersion)},+
				{"OperationsSupport",	 $(NoTitle), $(!REG_VT_DWORD),	 $(NDISMiniportOperationsSupport)}+
				}
			Shell  $(UtilityInf), AddValueList, $(MiniportKey), $(NewValueList)
			ifint $($ShellCode) != $(!SHELL_CODE_OK)
				Debug-Output "VPCNetNT: ShellCode error - "$($ShellCode)
			endif

			CloseRegKey $(MiniportKey)
		endif
        CloseRegKey $(ProtocolKey)
    endif

    goto ReviewBindings


; -----------------------------------------------
; RemoveSoftware
; -----------------------------------------------

RemoveSoftware = +

    Debug-Output "VPCNetNT - RemoveSoftware label"
	Debug-Output "VPCNetNT: --> NTN_RegBase : "$(!NTN_RegBase)

	ifstr(i) $(!NTN_RegBase) != $(NDISProtocolProductKeyName)
		read-syms RemoveProtocolMessageDlg$(!STF_LANGUAGE)
		ui start "MessageBox"
		ifstr(i) $(DLGEVENT) == "OK" ; DLGEVENT indicates button pressed
			Debug-Output "VPCNetNT - user agreed"
		endif
	else
		;; Get the current bindings
		Debug-Output "VPCNetNT: Retreiving bindings in "$(NDISProtocolLinkageKeyName)

		OpenRegKey $(!REG_H_LOCAL) "" $(NDISProtocolLinkageKeyName) $(MAXIMUM_ALLOWED) NDISProtocolLinkageKey
		ifstr(i) $(NDISProtocolLinkageKey) == $(KeyNull)
			Debug-Output "VPCNetNT: Failed to open linkage key "$(NDISProtocolLinkageKeyName)
			goto fatalregistry
		endif

		GetRegValue $(NDISProtocolLinkageKey) "Bind" KeyValue
		ifint $(RegLastError) == 0
			set Bindings = *($(KeyValue), 4)
		else
			set Bindings = {}
		endif

		set DisabledBindings = {}
		OpenRegKey $(NDISProtocolLinkageKey) "" "Disabled" $(MAXIMUM_ALLOWED) DisabledLinkageKey
		ifstr(i) $(DisabledLinkageKey) == $(KeyNull)
			Debug-Output "VPCNetNT: Failed to open disabled linkage key "$(NDISProtocolLinkageKeyName)"\Disabled"
		else
			GetRegValue $(DisabledLinkageKey) "Bind" KeyValue
			ifint $(RegLastError) == 0
				set DisabledBindings = *($(KeyValue), 4)
			endif

			CloseRegKey $(DisabledLinkageKey)
		endif

		CloseRegKey $(NDISProtocolLinkageKey)

		Debug-Output "VPCNetNT: Bind             : "$(Bindings)
		Debug-Output "VPCNetNT: DisabledBindings : "$(DisabledBindings)

		;; Parse the bindings to create a list of adapter cards
		set CardList = {}
		set CreateCardList = {}
		ForListDo $(Bindings)
			Split-String $($) "\" ValueList
			QueryListSize ValueListSize $(ValueList)
			set CardServiceName = *($(ValueList), $(ValueListSize))
			Debug-Output "VPCNetNT: Found binding to card "$(CardServiceName)
			set CardList	 = >($(CardList), $(CardServiceName))
		EndForListDo ; $(Bindings)
		ForListDo $(DisabledBindings)
			Split-String $($) "\" ValueList
			QueryListSize ValueListSize $(ValueList)
			set CardServiceName = *($(ValueList), $(ValueListSize))
			ifcontains(i) $(CardServiceName) in $(CardList)
				Debug-Output "VPCNetNT: Found duplicate disabled binding to card "$(CardServiceName)
			else
				Debug-Output "VPCNetNT: Found disabled binding to card "$(CardServiceName)
				set CardList	 = >($(CardList), $(CardServiceName))
			endif
		EndForListDo ; ($DisabledBindings)

		Debug-Output "VPCNetNT: CardList == "$(CardList)

		set CreatedNewAdapter	 = FALSE
		ForListDo $(CardList)
			Debug-Output "VPCNetNT: Processing "$($)"..."

			set RegKeyName	 = $(!NTN_ServiceBase)"\"$($)"\Parameters\"$(NDISProtocolName)
			OpenRegKey $(!REG_H_LOCAL) "" $(RegKeyName) $(MAXIMUM_ALLOWED) RegKey
			ifstr(i) $(RegKey) == $(KeyNull)
				Debug-Output "VPCNetNT: Failed to open key "$(RegKeyName)
			else
				;; Get the adapter number and remove the virtual adapter
				GetRegValue $(RegKey) "AdapterNumber" KeyValue
				set AdapterNumber	 = *($(KeyValue), 4)
				CloseRegKey $(RegKey)

				Debug-Output "VPCNetNT: Removing adapter number "$(AdapterNumber)

				set AdapterRegKeyName	 = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\"$(AdapterNumber)
				Shell $(UtilityInf), RemoveHardwareComponent, $(Manufacturer), $(AdapterName), $(AdapterRegKeyName)
				ifint $($ShellCode) != $(!SHELL_CODE_OK)
					Debug-Output "VPCNetNT: Failed to remove "$(AdapterRegKeyName)
				else
					set RegKeyName = $(!NTN_ServiceBase)"\"$($)"\Parameters"
					OpenRegKey $(!REG_H_LOCAL) "" $(RegKeyName) $(MAXIMUM_ALLOWED) RegKey
					ifstr(i) $(RegKey) == $(KeyNull)
						Debug-Output "VPCNetNT: Failed to remove "$(RegKeyName)
					else
						DeleteRegTree $(RegKey) $(NDISProtocolName)
						CloseRegKey $(RegKey)
					endif
				endif
			endif
		EndForListDo ; $(CardList)

		;; Enable the protocol bindings to the real NIC

		;; FIX ME! We should really find some way of dynamically determining
		;; the protocols to disable rather than relying on a fixed list of
		;; protocols.

		ForListDo $(DisableProtocolsList)
			Shell "", AdjustBindings, $($), $(CardList), activate
			ifint $($ShellCode) != $(!SHELL_CODE_OK)
				Debug-Output "VPCNetNT: AdjustBindings failed! ShellCode "$($ShellCode)
			endif
		EndForListDo ; $(DisableProtocolsList)

		Debug-Output "VPCNetNT: Removing "$(NDISProtocolName)

		Shell $(UtilityInf), RemoveSoftwareComponent, $(Manufacturer), $(NDISProtocolName)
		ifint $($ShellCode) != $(!SHELL_CODE_OK)
			Debug-Output "VPCNetNT: Failed to remove "$(NDISProtocolName)" - ShellCode "$($ShellCode)
		endif

	;;	read-syms ReenableBindingsMessageDlg$(!STF_LANGUAGE)
	;;	ui start "MessageBox"
	;;	ifstr(i) $(DLGEVENT) == "OK" ; DLGEVENT indicates button pressed
	;;		Debug-Output "VPCNetNT - user agreed"
	;;	endif

	endif

    goto end

; -----------------------------------------------
; Install Adapter
; ----------------------------------------------

installadapter = +
    Debug-Output "VPCNetNT - installadapter label"

    OpenRegKey $(!REG_H_LOCAL) "" $(NDISProtocolProductKeyName) $(MAXIMUM_ALLOWED) KeyProduct

    ifstr $(KeyProduct) != $(KeyNull)
        CloseRegKey $(KeyProduct)

        Shell $(UtilityInf), VerExistedDlg, $(NDISProtocolTitle),+
              $(ProductVersion)
        ifint $($ShellCode) != $(!SHELL_CODE_OK)
            Debug-Output "ShellCode error: cannot get an error string."
            goto ShellCodeError
        endif
        set CommonStatus = STATUS_USERCANCEL
        goto end
    endif

    StartWait

    ifstr(i) $(DoCopy) == "YES"

       Shell $(UtilityInf), DoAskSource, $(!STF_CWDDIR), $(SrcDir) YES

       Ifint $($ShellCode) != $(!SHELL_CODE_OK)
           Goto ShellCodeError
       Else-ifstr(i) $($R0) == STATUS_FAILED
           Shell $(UtilityInf) RegistryErrorString "ASK_SOURCE_FAIL"
           ifint $($ShellCode) != $(!SHELL_CODE_OK)
               goto ShellCodeError
           endif
           set Error = $($R0)
           Goto fatal
       Else-ifstr(i) $($R0) == STATUS_USERCANCEL
           Goto end
       Endif

       Set SrcDir = $($R1)

    endif

	Debug-Output "VPCNetNT: Installing files..."

    install "Install-Option"
    ifstr(i) $(STF_INSTALL_OUTCOME) != STF_SUCCESS
       Shell $(UtilityInf) RegistryErrorString "UNABLE_COPY_FILE"
       ifint $($ShellCode) != $(!SHELL_CODE_OK)
           goto ShellCodeError
       endif
       set Error = $($R0)
       goto fatal
    endif

	;; Install the NDIS Protocol interface
	Debug-Output "VPCNetNT: Installing NDIS Protocol interface..."

    Shell $(UtilityInf), AddSoftwareComponent, $(Manufacturer), +
        $(NDISProtocolName), +
        $(NDISProtocolName), +
        $(NDISProtocolTitle), $(STF_CONTEXTINFNAME), +
        $(NDISProtocolImagePath), "kernel", "TDI", {}, "",+
        $(NetEventDLL)

    set OEM_ABANDON_PROTOCOL = TRUE

    ifint $($ShellCode) != $(!SHELL_CODE_OK)
        Debug-Output "ShellCode error"
        goto ShellCodeError
    endif

    set RegistryErrorIndex = $($R0)
    set KeyProduct         = $($R1)
    Set SoftNetRulesKey    = $($R2)
    CloseRegKey $($R3)
    CloseRegKey $($R4)
    CloseRegKey $($R5)

    ifstr(i) $(RegistryErrorIndex) != NO_ERROR
        EndWait
        Debug-Output "Registry error: add software components"
        CloseRegKey $(KeyProduct)
        CloseRegKey $(SoftNetRulesKey)
        goto fatalregistry
    endif

    set NewValueList = { +
		{"Description",			 $(NoTitle), $(!REG_VT_SZ),		 $(NDISProtocolDescription)},+
		{"Hidden",				 $(NoTitle), $(!REG_VT_DWORD),	 $(NDISProtocolHide)},+
		{"InstallDate",			 $(NoTitle), $(!REG_VT_DWORD),	 *($(Now),1)}, +
		{"MajorVersion",		 $(NoTitle), $(!REG_VT_DWORD),	 $(ProductMajorVersion)},+
		{"MinorVersion",		 $(NoTitle), $(!REG_VT_DWORD),	 $(ProductMinorVersion)},+
		{"OperationsSupport",	 $(NoTitle), $(!REG_VT_DWORD),	 $(NDISProtocolOperationsSupport)},+
		{"Review",				 $(NoTitle), $(!REG_VT_DWORD),	 $(NDISProtocolReviewBindings)},+
		{"ServiceName",			 $(NoTitle), $(!REG_VT_SZ),		 $(NDISProtocolName)},+
		{"SoftwareType",		 $(NoTitle), $(!REG_VT_SZ),		 "transport"},+
		{"Title",				 $(NoTitle), $(!REG_VT_SZ),		 $(NDISProtocolTitle)} +
		}
    Shell  $(UtilityInf), AddValueList, $(KeyProduct), $(NewValueList)
    ifint $($ShellCode) != $(!SHELL_CODE_OK)
        Debug-Output "ShellCode error."
        goto ShellCodeError
    endif

    set RegistryErrorIndex = $($R0)

    ifstr(i) $(RegistryErrorIndex) != NO_ERROR
        EndWait
        Debug-Output "Registry error: add value list."
        CloseRegKey $(KeyProduct)
        CloseRegKey $(SoftNetRulesKey)
        goto fatalregistry
    endif

    set NewValueList = { +
		{"type",	 $(NoTitle), $(!REG_VT_SZ),		 $(NetRuleNDISProtocolType)},+
		{"use",		 $(NoTitle), $(!REG_VT_SZ),		 $(NetRuleNDISProtocolUse)}, +
		{"bindform", $(NoTitle), $(!REG_VT_SZ),		 $(NetRuleNDISProtocolBindForm)}, +
		{"class",	 $(NoTitle), $(!REG_VT_MULTI_SZ),$(NetRuleNDISProtocolClass)}, +
		{"bindable", $(NoTitle), $(!REG_VT_MULTI_SZ),$(NetRuleNDISProtocolBindable)}, +
		{"InfOption",$(NoTitle), $(!REG_VT_SZ),		 $(Option)} +
		}
    Shell  $(UtilityInf), AddValueList, $(SoftNetRulesKey), $(NewValueList)
    ifint $($ShellCode) != $(!SHELL_CODE_OK)
        Debug-Output "ShellCode error."
        goto ShellCodeError
    endif

    set RegistryErrorIndex = $($R0)

    CloseRegKey $(KeyProduct)
    CloseRegKey $(SoftNetRulesKey)

    ifstr(i) $(RegistryErrorIndex) != NO_ERROR
        EndWait
        Debug-Output "Registry error: add value list."
        goto fatalregistry
    endif

	;; Install the NDIS Miniport interface
	Debug-Output "VPCNetNT: Installing NDIS Miniport interface..."

	Shell $(UtilityInf), AddSoftwareComponent, $(Manufacturer), +
		$(NDISMiniportName), +
		$(NDISMiniportName), +
		$(NDISMiniportTitle), $(STF_CONTEXTINFNAME), +
		$(NDISMiniportImagePath), "kernel", "NDIS", {}, "",+
		$(NetEventDLL)

	set OEM_ABANDON_MINIPORT = TRUE

	ifint $($ShellCode) != $(!SHELL_CODE_OK)
		Debug-Output "ShellCode error"
		goto ShellCodeError
	endif

	set RegistryErrorIndex = $($R0)
	set KeyProduct         = $($R1)
	Set HardNetRulesKey    = $($R2)
	CloseRegKey $($R3)
	CloseRegKey $($R4)
	CloseRegKey $($R5)

	ifstr(i) $(RegistryErrorIndex) != NO_ERROR
		EndWait
		Debug-Output "Registry error: add software components"
		CloseRegKey $(KeyProduct)
		CloseRegKey $(HardNetRulesKey)
		goto fatalregistry
	endif

	set NewValueList = { +
		{"SoftwareType", $(NoTitle), $(!REG_VT_SZ),		 "driver"},+
		{"MajorVersion", $(NoTitle), $(!REG_VT_DWORD),	 $(ProductMajorVersion)},+
		{"MinorVersion", $(NoTitle), $(!REG_VT_DWORD),	 $(ProductMinorVersion)},+
		{"Title",		 $(NoTitle), $(!REG_VT_SZ),		 $(NDISMiniportTitle)},+
		{"Description",	 $(NoTitle), $(!REG_VT_SZ),		 $(NDISMiniportDescription)},+
		{"ServiceName",	 $(NoTitle), $(!REG_VT_SZ),		 $(NDISMiniportName)},+
		{"Review",		 $(NoTitle), $(!REG_VT_DWORD),	 $(NDISMiniportReviewBindings)},+
		{"Hidden",		 $(NoTitle), $(!REG_VT_DWORD),	 $(NDISMiniportHide)},+
		{"InstallDate",	 $(NoTitle), $(!REG_VT_DWORD),	 *($(Now),1)} +
		}
	Shell  $(UtilityInf), AddValueList, $(KeyProduct), $(NewValueList)
	ifint $($ShellCode) != $(!SHELL_CODE_OK)
		Debug-Output "ShellCode error."
		goto ShellCodeError
	endif

	set RegistryErrorIndex = $($R0)

	ifstr(i) $(RegistryErrorIndex) != NO_ERROR
		EndWait
		Debug-Output "Registry error: add value list."
		CloseRegKey $(KeyProduct)
		CloseRegKey $(HardNetRulesKey)
		goto fatalregistry
	endif

	set NewValueList = { +
		{"type",	 $(NoTitle), $(!REG_VT_SZ),		 $(NetRuleNDISMiniportType)},+
		{"use",		 $(NoTitle), $(!REG_VT_SZ),		 $(NetRuleNDISMiniportUse)}, +
		{"bindform", $(NoTitle), $(!REG_VT_SZ),		 $(NetRuleNDISMiniportBindForm)}, +
		{"class",	 $(NoTitle), $(!REG_VT_MULTI_SZ),$(NetRuleNDISMiniportClass)}, +
		{"bindable", $(NoTitle), $(!REG_VT_MULTI_SZ),$(NetRuleNDISMiniportBindable)}, +
		{"InfOption",$(NoTitle), $(!REG_VT_SZ),		 $(Option)} +
		}
	Shell  $(UtilityInf), AddValueList, $(HardNetRulesKey), $(NewValueList)
	ifint $($ShellCode) != $(!SHELL_CODE_OK)
		Debug-Output "ShellCode error."
		goto ShellCodeError
	endif

	set RegistryErrorIndex = $($R0)

	CloseRegKey $(KeyProduct)
	CloseRegKey $(HardNetRulesKey)

	ifstr(i) $(RegistryErrorIndex) != NO_ERROR
		EndWait
		Debug-Output "Resgitry error: add value list."
		goto fatalregistry
	endif

	EndWait

	;; Intentional fall-through to ReviewBindings

; -----------------------------------------------
; ReviewBindings
; -----------------------------------------------

ReviewBindings =+
	Debug-Output "VPCNetNT: ReviewBindings label"
	Debug-Output "VPCNetNT: --> NTN_RegBase : "$(!NTN_RegBase)

	ifstr(i) $(FirstTime) == TRUE
		set CheckBindings	 = TRUE
	endif

	ifstr(i) $(CheckBindings) == TRUE

		;; Get the current bindings
		Debug-Output "VPCNetNT: Reviewing bindings in "$(NDISProtocolLinkageKeyName)

		OpenRegKey $(!REG_H_LOCAL) "" $(NDISProtocolLinkageKeyName) $(MAXIMUM_ALLOWED) NDISProtocolLinkageKey
		ifstr(i) $(NDISProtocolLinkageKey) == $(KeyNull)
			Debug-Output "VPCNetNT: Failed to open linkage key for "$(NDISProtocolLinkageKeyName)
			goto fatalregistry
		endif

		GetRegValue $(NDISProtocolLinkageKey) "Bind" KeyValue
		ifint $(RegLastError) == 0
			set Bindings	 = *($(KeyValue), 4)
		else
			set Bindings	 = {}
		endif
		Debug-Output "VPCNetNT: Bind : "$(Bindings)

		set DisabledBind	 = {}
		set DisabledExport	 = {}
		set DisabledRoute	 = {}

		;; Get the currently disabled bindings, exports and routes
		OpenRegKey $(NDISProtocolLinkageKey) "" "Disabled" $(MAXIMUM_ALLOWED) NDISProtocolLinkageDisabledKey
		ifstr(i) $(NDISProtocolLinkageDisabledKey) != $(KeyNull)
			GetRegValue $(NDISProtocolLinkageDisabledKey) "Bind" KeyValue
			ifint $(RegLastError) == 0
				set DisabledBind	 = *($(KeyValue), 4)

				GetRegValue $(NDISProtocolLinkageDisabledKey) "Export" KeyValue
				set DisabledExport	 = *($(KeyValue), 4)

				GetRegValue $(NDISProtocolLinkageDisabledKey) "Route" KeyValue
				set DisabledRoute	 = *($(KeyValue), 4)
			endif
		endif ; $(NDISProtocolLinkageDisabledKey) != $(KeyNull)

		Debug-Output "VPCNetNT: DisabledBind : "$(DisabledBind)

		QueryListSize BindingsCount $(Bindings)
		Debug-Output "VPCNetNT: BindingsCount : "$(BindingsCount)

		QueryListSize DisabledBindingsCount $(DisabledBind)
		Debug-Output "VPCNetNT: DisabledBindingsCount : "$(DisabledBindingsCount)

		set-add	BindingsCount	 = $(BindingsCount), $(DisabledBindingsCount)

		ifint $(BindingsCount) == 0
			;; This is probably the first time we've installed, so generate
			;; an artificial binding list from the list of network adapters
			OpenRegKey $(!REG_H_LOCAL) "" $(NetworkCardKeyName) $(MAXIMUM_ALLOWED) NetworkCardsKey
			ifstr(i) $(NetworkCardsKey) == $(KeyNull)
				Debug-Output "VPCNetNT: Failed to open network cards key"
				goto fatalregistry
			endif

			set Bindings	 = {}
			EnumRegKey $(NetworkCardsKey) KeyList
			ForListDo $(KeyList)
				set CardKeyName	 = *($($), 1)
				OpenRegKey $(NetworkCardsKey) "" $(CardKeyName) $(MAXIMUM_ALLOWED) CardKey
				ifstr(i) $(CardKey) != $(KeyNull)
					Shell "", CanBindToCard, $(NDISProtocolName), $(NetRuleNDISProtocolBindable), $(CardKey)
					ifint $($ShellCode) != $(!SHELL_CODE_OK)
						Debug-Output "VPCNetNT: Failed to call CanBindToCard, skipping card - ShellCode "$($ShellCode)
					else-ifstr(i) $($R0) == TRUE
						GetRegValue $(CardKey) "ServiceName" KeyValue
						ifint $(RegLastError) != 0
							Debug-Output "VPCNetNT: Failed to get ServiceName key value - error "$(RegLastError)
						else
							set ServiceName	 = *($(KeyValue), 4)
							set Bindings	 = >($(Bindings), "\Device\"$(ServiceName))
						endif
					endif

					CloseRegKey $(CardKey)
				endif ; $(CardKey) != $(KeyNull)

			EndForListDo ; $(KeyList)

			CloseRegKey $(NetworkCardsKey)
		endif ; $(BindingsCount) != 0

		;; Parse the bindings to create a list of adapter cards and a list
		;; of our virtual NICs. We will disable any bindings to our virtual
		;; NIC.
		set CardList		 = {}
		set CreateCardList	 = {}
		set NewBind			 = {}
		set NewExport		 = {}
		set NewRoute		 = {}
		ForListDo $(Bindings)
			Split-String $($) "\" ValueList
			QueryListSize ValueListSize $(ValueList)
			set CardServiceName = *($(ValueList), $(ValueListSize))

			;; Open the card entry at "SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\N"
			Shell "", OpenNetworkCardFromServiceName, $(CardServiceName)
			ifint $($ShellCode) != $(!SHELL_CODE_OK)
				Debug-Output "VPCNetNT: Failed to find card entry for "$(CardServiceName)" - ShellCode "$($ShellCode)
			else-ifstr(i) $($R0) == $(KeyNull)
				Debug-Output "VPCNetNT: Failed to find card entry for "$(CardServiceName)
			else
				set NetworkCardKey	 = $($R0)

				;; Check to see if this is a binding to ourselves - if so, disable it
				GetRegValue $(NetworkCardKey) "ProductName" KeyValue
				set CardProductName	 = *($(KeyValue), 4)
				ifstr(i) $(CardProductName) == $(NDISMiniportName)
					Debug-Output "VPCNetNT: Found binding to card "$(CardServiceName)" - disabling"

					set DisabledBind	 = >($(DisabledBind), $($))
					set DisabledExport	 = >($(DisabledExport), "\Device\"$(NDISProtocolName)"_"$(CardServiceName))
					set DisabledRoute	 = >($(DisabledRoute), """"$(CardProductName)""" """$(CardServiceName)"""")
				else
					Debug-Output "VPCNetNT: Found binding to card "$(CardServiceName)

					set NewBind		 = >($(NewBind), $($))
					set NewExport	 = >($(NewExport), "\Device\"$(NDISProtocolName)"_"$(CardServiceName))
					set NewRoute	 = >($(NewRoute), """"$(CardProductName)""" """$(CardServiceName)"""")

					set CardList	 = >($(CardList), $(CardServiceName))
				endif

				CloseRegKey $(NetworkCardKey)
			endif

		EndForListDo ; $(Bindings)

		Debug-Output "VPCNetNT: Updating protocol linkage..."
		Debug-Output "VPCNetNT: Bind   : "$(NewBind)
		Debug-Output "VPCNetNT: Export : "$(NewExport)
		Debug-Output "VPCNetNT: Route  : "$(NewRoute)

		set NewValueList	 = { +
			{"Bind",	 $(NoTitle), $(!REG_VT_MULTI_SZ), $(NewBind)}, +
			{"Export",	 $(NoTitle), $(!REG_VT_MULTI_SZ), $(NewExport)}, +
			{"Route",	 $(NoTitle), $(!REG_VT_MULTI_SZ), $(NewRoute)} +
			}
		Shell $(UtilityInf), AddValueList, $(NDISProtocolLinkageKey), $(NewValueList)
		ifint $($ShellCode) != $(!SHELL_CODE_OK)
			Debug-Output "VPCNetNT: Failed to add values list! ShellCode "$($ShellCode)

			CloseRegKey $(NDISProtocolLinkageDisabledKey)
			CloseRegKey $(NDISProtocolLinkageKey)
			goto fatal
		else-ifstr(i) $($R0) != NO_ERROR
			Debug-Output "VPCNetNT: Failed to add values list! RegistryError "$($R0)

			set RegistryErrorIndex	 = $($R0)

			CloseRegKey $(NDISProtocolLinkageDisabledKey)
			CloseRegKey $(NDISProtocolLinkageKey)
			goto fatalregistry
		endif

		ifstr(i) $(NDISProtocolLinkageDisabledKey) != $(KeyNull)
			Debug-Output "VPCNetNT: Disabled\Bind   : "$(DisabledBind)
			Debug-Output "VPCNetNT: Disabled\Export : "$(DisabledExport)
			Debug-Output "VPCNetNT: Disabled\Route  : "$(DisabledRoute)

			set NewValueList	 = { +
				{"Bind",	 $(NoTitle), $(!REG_VT_MULTI_SZ), $(DisabledBind)}, +
				{"Export",	 $(NoTitle), $(!REG_VT_MULTI_SZ), $(DisabledExport)}, +
				{"Route",	 $(NoTitle), $(!REG_VT_MULTI_SZ), $(DisabledRoute)} +
				}
			Shell $(UtilityInf), AddValueList, $(NDISProtocolLinkageDisabledKey), $(NewValueList)
			ifint $($ShellCode) != $(!SHELL_CODE_OK)
				Debug-Output "VPCNetNT: Failed to add values list! ShellCode "$($ShellCode)
			else-ifstr(i) $($R0) != NO_ERROR
				Debug-Output "VPCNetNT: Failed to add values list! RegistryError "$($R0)
			endif

			CloseRegKey $(NDISProtocolLinkageDisabledKey)
		endif ; $(NDISProtocolLinkageDisabledKey) != $(KeyNull)

		CloseRegKey $(NDISProtocolLinkageKey)

		Debug-Output "VPCNetNT: CardList : "$(CardList)

		set CreatedNewAdapter	 = FALSE
		ForListDo $(CardList)
			set CardServiceName	 = $($)

			Debug-Output "VPCNetNT: Processing "$(CardServiceName)"..."

			set CardKeyName	 = $(!NTN_ServiceBase)"\"$(CardServiceName)
			OpenRegKey $(!REG_H_LOCAL) "" $(CardKeyName) $(MAXIMUM_ALLOWED) CardKey
			ifstr(i) $(CardKey) == $(KeyNull)
				Debug-Output "VPCNetNT: Failed to open key "$(CardKeyName)
			else
				;; Open the card entry at "SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\N"
				Shell "", OpenNetworkCardFromServiceName, $($)
				ifint $($ShellCode) != $(!SHELL_CODE_OK)
					Debug-Output "VPCNetNT: Failed to find card entry for "$(CardServiceName)" - ShellCode "$($ShellCode)
				else-ifstr(i) $($R0) == $(KeyNull)
					Debug-Output "VPCNetNT: Failed to find card entry for "$(CardServiceName)
				else
					set NetworkCardKey	 = $($R0)

					;; Check to see if this is a binding to ourselves - if so, skip it
					GetRegValue $(NetworkCardKey) "ProductName" KeyValue
					set CardProductName	 = *($(KeyValue), 4)
					ifstr(i) $(CardProductName) == $(NDISMiniportName)
						Debug-Output "VPCNetNT: Skipping bind to ourselves"
					else
						;; Open or create the protocol specific key in the adapter's parameters
						OpenRegKey $(CardKey) "" "Parameters\"$(NDISProtocolName) $(MAXIMUM_ALLOWED) ProtocolParametersKey
						ifstr(i) $(ProtocolParametersKey) != $(KeyNull)
							;; skip this adapter as we have already processed it
							Debug-Output "VPCNetNT: "$(CardServiceName)" has already been processed - skipping."
							CloseRegKey $(ProtocolParametersKey)
						else
							;; Get the card title
							GetRegValue $(NetworkCardKey) "Title" KeyValue
							set CardTitle	 = *($(KeyValue), 4)

							;; Create a title for our virtual NIC
							set AdapterTitleBase	 = $(NDISMiniportTitle)" -> "$(CardTitle)

							;; Add a virtual NIC for this card
							Shell "", CreateVirtualNIC, $(Option), $(STF_CONTEXTINFNAME), $(AdapterTitleBase), *($(Now), 1)
							ifint $($ShellCode) != $(!SHELL_CODE_OK)
								Debug-Output "VPCNetNT: Failed to create virtual NIC for "$(CardServiceName)" - ShellCode "$($ShellCode)
							else-ifstr(i) $($R0) != NO_ERROR
								Debug-Output "VPCNetNT: Failed to create virtual NIC for "$(CardServiceName)" - RegistryError "$($R0)
							else
								set AdapterKey			 = $($R1)
								set AdapterRulesKey		 = $($R2)
								set AdapterParametersKey = $($R3)
								set AdapterNumber		 = $($R4)
								set AdapterServiceName	 = $($R5)

								set OEM_ABANDON_OPTIONS	 = >($(OEM_ABANDON_OPTIONS), $(!NTN_SoftwareBase)"\Microsoft\Windows NT\CurrentVersion\NetworkCards\"$(AdapterNumber))

								CloseRegKey $(AdapterKey)
								CloseRegKey $(AdapterRulesKey)

								OpenRegKey $(CardKey) "" "Parameters" $(MAXIMUM_ALLOWED) CardParametersKey
								ifstr(i) $(CardParametersKey) == $(KeyNull)
									Debug-Output "VPCNetNT: Failed to open card parameters key"
								else
									;; Copy the protocol parameters from the real NIC to our virtual NIC
									EnumRegKey $(CardParametersKey) KeyList
									ForListDo $(KeyList)
										set KeyName	 = *($($), 1)

										Debug-Output "VPCNetNT: Copying key """$(KeyName)""" from "$(CardServiceName)" to "$(AdapterServiceName)"..."

										OpenRegKey $(CardParametersKey) "" $(KeyName) $(MAXIMUM_ALLOWED) TempKey
										ifstr(i) $(TempKey) == $(KeyNull)
											Debug-Output "VPCNetNT: Failed to open card parameter key """$(KeyName)""""
										else
											Shell $(UtilityInf), CopyRegTreeAs, $(TempKey), $(AdapterParametersKey), $(KeyName)
											ifint $($ShellCode) != $(!SHELL_CODE_OK)
												Debug-Output "VPCNetNT: Failed to copy key """$(KeyName)""" to virtual NIC parameter key - ShellCode "$($ShellCode)
											else-ifstr(i) $($R0) != NO_ERROR
												Debug-Output "VPCNetNT: Failed to copy key """$(KeyName)""" to virtual NIC parameter key - RegistryErrorIndex "$($R0)
											endif

											CloseRegKey $(TempKey)
										endif
									EndForListDo ; $(KeyList)

									;; Add our protocol specific parameter key
									Debug-Output "VPCNetNT: Adding """$(NDISProtocolName)""" key to """$($)"\Parameters"""
									CreateRegKey $(CardParametersKey) {$(NDISProtocolName), $(NoTitle), GenericClass} "" $(MAXIMUM_ALLOWED) "" ProtocolParametersKey
									ifstr(i) $(ProtocolParametersKey) == $(KeyNull)
										Debug-Output "VPCNetNT: Failed to create key Parameters\"$(NDISProtocolName)
									else
										;; Add our protocol specific parameter values
										set NewValueList	 = { +
											{"AdapterNumber",		 $(NoTitle), $(!REG_VT_SZ),		 $(AdapterNumber)}, +
											{"LowerNICTitle",		 $(NoTitle), $(!REG_VT_SZ),		 $(CardTitle)}, +
											{"NextGuestID",			 $(NoTitle), $(!REG_VT_DWORD),	 1}, +
											{"NextVirtualAdapterID", $(NoTitle), $(!REG_VT_DWORD),	 1}, +
											{"UpperBindings",		 $(NoTitle), $(!REG_VT_SZ),		 $(AdapterServiceName)} +
											}
										Shell $(UtilityInf), AddValueList, $(ProtocolParametersKey), $(NewValueList)
										ifint $($ShellCode) != $(!SHELL_CODE_OK)
											Debug-Output "VPCNetNT: Failed to add values list! ShellCode "$($ShellCode)
										else-ifstr(i) $($R0) != NO_ERROR
											Debug-Output "VPCNetNT: Failed to add values list! RegistryError "$($R0)
										endif

										set CreatedNewAdapter	 = TRUE

										CloseRegKey $(ProtocolParametersKey)
									endif ; $(ProtocolParametersKey) == $(KeyNull)

									CloseRegKey $(CardParametersKey)
								endif ; $(CardParametersKey) == $(KeyNull)
							endif
						endif ; $(ProtocolParametersKey) != $(KeyNull)
					endif ; $(CardProductName) == $(NDISMiniportName)

					CloseRegKey $(NetworkCardKey)
				endif

				CloseRegKey $(CardKey)
			endif ; $(CardKey) == $(KeyNull)
		EndForListDo ; $(CardList)

		;; Disable the protocol bindings to the real NIC

		;; FIX ME! We should really find some way of dynamically determining
		;; the protocols to disable rather than relying on a fixed list of
		;; protocols.

		ForListDo $(DisableProtocolsList)
			Shell "", AdjustBindings, $($), $(CardList), disable
			ifint $($ShellCode) != $(!SHELL_CODE_OK)
				Debug-Output "VPCNetNT: AdjustBindings failed! ShellCode "$($ShellCode)
			endif
		EndForListDo ; $(DisableProtocolsList)

		ifstr(i) $(CreatedNewAdapter) == TRUE

			;; We added a new virtual adapter, so we need to tell NCPA to
			;; review the bindings.
			set NCPAKeyName	 = $(!NTN_SoftwareBase)"\Microsoft\NCPA\CurrentVersion"
			OpenRegKey $(!REG_H_LOCAL) "" $(NCPAKeyName) $(MAXIMUM_ALLOWED) NCPAKey
			ifstr(i) $(NCPAKey) == $(KeyNull)
				Debug-Output "Failed to open key "$(NCPAKeyName)
				goto fatalregistry
			endif

			SetRegValue $(NCPAKey) {"BindRestart", $(NoTitle), $(!REG_VT_DWORD), 1}
			CloseRegKey $(NCPAKey)

		endif ; $(CreatedNewAdapter) == TRUE

	endif ;  $(CheckBindings) == TRUE

;;	ifstr(i) $(FirstTime) == TRUE
;;		read-syms ProtocolBindingsMessageDlg$(!STF_LANGUAGE)
;;		ui start "MessageBox"
;;		ifstr(i) $(DLGEVENT) == "OK" ; DLGEVENT indicates button pressed
;;			Debug-Output "VPCNetNT - user agreed"
;;		endif
;;	endif

    Goto $(WhenDone)

; -----------------------------------------------
; Configure Adapter
; -----------------------------------------------

ConfigureSoftware = +
	Debug-Output "VPCNetNT: ConfigureSoftware label"
	Debug-Output "VPCNetNT: --> NTN_RegBase : "$(!NTN_RegBase)

	Debug-Output "VPCNetNT: Configuration is not yet supported!"

	read-syms ConfigureMessageDlg$(!STF_LANGUAGE)
	ui start "MessageBox"
	ifstr(i) $(DLGEVENT) == "OK" ; DLGEVENT indicates button pressed
		Debug-Output "VPCNetNT - user agreed"
	endif

;;	set CommonStatus	 = STATUS_REBIND

	goto $(WhenDone)

; -----------------------------------------------
; Error Handling
; -----------------------------------------------

abandon = +
    ;
    Debug-Output "VPCNetNT - abandon label"
    ;
    ForListDo $(OEM_ABANDON_OPTIONS)
        Shell $(UtilityInf), RemoveHardwareComponent, $(Manufacturer), +
            $(NDISMiniportName), $($)
        ifint $($ShellCode) != $(!SHELL_CODE_OK)
            Debug-Output "ShellCode error"
            goto ShellCodeError
        endif
        set RegistryErrorIndex = $($R0)
        ifstr(i) $(RegistryErrorIndex) != NO_ERROR
            goto fatalregistry
        endif
    EndForListDo
    ifstr(i) $(OEM_ABANDON_PROTOCOL) == TRUE
        Shell $(UtilityInf), RemoveSoftwareComponent, $(Manufacturer), +
            $(NDISProtocolName), FALSE
        ifint $($ShellCode) != $(!SHELL_CODE_OK)
            Debug-Output "ShellCode error"
            goto ShellCodeError
        endif
        set RegistryErrorIndex = $($R0)
        ifstr(i) $(RegistryErrorIndex) != NO_ERROR
            goto fatalregistry
        endif
    endif

	goto end

fatalregistry = +
    ;
    Debug-Output "VPCNetNT - fatalregistry label"
    ;
    Shell $(UtilityInf) RegistryErrorString $(RegistryErrorIndex)
    ifint $($ShellCode) != $(!SHELL_CODE_OK)
        goto ShellCodeError
    endif
    set Error = $($R0)
    goto fatal

fatal = +
    ;
    Debug-Output "VPCNetNT - fatal label"
    ;
    ifstr(i) $(Error) == ""
        Shell $(UtilityInf) RegistryErrorString "SETUP_FAIL"
        ifint $($ShellCode) != $(!SHELL_CODE_OK)
            goto ShellCodeError
        endif
        set Error = $($R0)
    endif
    Shell $(subroutineinf) SetupMessage, $(!STF_LANGUAGE), "FATAL", $(Error)
    ifint $($ShellCode) != $(!SHELL_CODE_OK)
        goto ShellCodeError
    endif
    goto setfailed

ShellCodeError = +
    ;
    Debug-Output "VPCNetNT - ShellCodeError label"
    ;
    set DlgType      = "MessageBox"
    set STF_MB_TITLE = $(ShellCodeErrorTitle)
    set STF_MB_TEXT  = $(ShellCodeErrorText)
    set STF_MB_TYPE  = 1
    set STF_MB_ICON  = 3
    set STF_MB_DEF   = 1
    ui start "Error Message"
    goto setfailed

SetFailed = +
    ;
    Debug-Output "VPCNetNT - setfailed label"
    ;
    set CommonStatus = STATUS_FAILED
    ifstr(i) $(OEM_ABANDON_ON) == TRUE
        set OEM_ABANDON_ON = FALSE
        goto abandon
    endif
    goto end

end = +
    ;
    Debug-Output "VPCNetNT - end label"
    ;
    Return $(CommonStatus)

; ======================================================================
;	Subroutines
; ======================================================================

; ----------------------------------------------------------------------
;	OpenNetworkCardFromServiceName
;
;	This subroutine return a handle to registry key "SOFTWARE\Microsoft\
;	Windows NT\CurrentVersion\NetworkCards\N" where "N" is the adapter
;	number of the card referenced by the specified service name.
;
;	Parameters:
;		In:		$($0)	- The card service name
;		Out:	$($R0)	- The network card key
; ----------------------------------------------------------------------

[OpenNetworkCardFromServiceName]
	read-syms	GeneralConstants
	read-syms	FileConstants
	read-syms	FileConstants$(!STF_LANGUAGE)

	set DesiredCardServiceName	 = $($0)

	Debug-Output "VPCNetNT: OpenNetworkCardFromServiceName called!"
	Debug-Output "VPCNetNT: --> DesiredCardServiceName : "$(DesiredCardServiceName)

	set ReturnedCardKey		 = $(KeyNull)

	OpenRegKey $(!REG_H_LOCAL) "" $(NetworkCardKeyName) $(MAXIMUM_ALLOWED) NetworkCardsKey
	ifstr(i) $(NetworkCardsKey) != $(KeyNull)
		EnumRegKey $(NetworkCardsKey) NetworkCardsList
		
		ForListDo $(NetworkCardsList)
			set CardNumber	 = *($($), 1)

			OpenRegKey $(NetworkCardsKey) "" $(CardNumber) $(MAXIMUM_ALLOWED) CardKey

			ifstr(i) $(CardKey) != $(KeyNull)
				GetRegValue $(CardKey) "ServiceName" KeyValue
				set CardServiceName = *($(KeyValue), 4)

				ifstr(i) $(CardServiceName) != $(DesiredCardServiceName)
					CloseRegKey $(CardKey)
				else
					Debug-Output "VPCNetNT: Found desired card key at "$(CardNumber)

					ifstr(i) $(ReturnedCardKey) != $(KeyNull)
						CloseRegKey $(ReturnedCardKey)
					endif
					set ReturnedCardKey	 = $(CardKey)
				endif ; $(CardServiceName) != $(DesiredCardServiceName)
			endif ; $(CardKey) != $(KeyNull)

		EndForListDo ; $(NetworkCardsList)

		CloseRegKey $(NetworkCardsKey)
	endif ; $(NetworkCardsKey) != $(KeyNull)

	Return $(ReturnedCardKey)

; ----------------------------------------------------------------------
;	CanBindToCard
;
;	This subroutine checks to see if the specified network component
;	can be bound to the specified network card
;
;	Parameters:
;		In:		$($0)	- The component name
;				$($1)	- The component's bindable rule
;				$($2)	- A handle to the network card key
;		Out:	$($R0)	- TRUE if the component can bind to the card
; ----------------------------------------------------------------------

[CanBindToCard]
	read-syms	GeneralConstants
	read-syms	FileConstants
	read-syms	FileConstants$(!STF_LANGUAGE)

	set ComponentName	 = $($0)
	set Bindable		 = $($1)
	set NetworkCardKey	 = $($2)

	Debug-Output "VPCNetNT: CanBindToCard called!"
	Debug-Output "VPCNetNT: --> ComponentName : "$(ComponentName)
	Debug-Output "VPCNetNT: --> Bindable      : "$(Bindable)

	set CanBind	 = FALSE

	;; Find the card's software product registry key
	GetRegValue $(NetworkCardKey) "Manufacturer" KeyValue
	ifint $(RegLastError) != 0
		Debug-Output "VPCNetNT: Failed to get Manufacturer key value - error "$(RegLastError)
	else
		set Manufacturer = *($(KeyValue), 4)
		GetRegValue $(NetworkCardKey) "ProductName" KeyValue
		ifint $(RegLastError) != 0
			Debug-Output "VPCNetNT: Failed to get ProductName key value - error "$(RegLastError)
		else
			set ProductName	 = *($(KeyValue), 4)

			set NetRuleKeyName	 = $(!NTN_SoftwareBase)"\"$(Manufacturer)"\"$(ProductName)"\CurrentVersion\NetRules"
			OpenRegKey $(!REG_H_LOCAL) "" $(NetRuleKeyName) $(MAXIMUM_ALLOWED) NetRuleKey
			ifstr(i) $(NetRuleKey) == $(KeyNull)
				Debug-Output "VPCNetNT: Failed to open key "$(NetRuleKeyName)
			else
				GetRegValue $(NetRuleKey) "type" KeyValue
				ifint $(RegLastError) != 0
					Debug-Output "VPCNetNT: Failed to get type net rule - error "$(RegLastError)
				else
					Split-String *($(KeyValue), 4) " " TypeRule
					set CardClass	 = *($(TypeRule), 3)

					Debug-Output "VPCNetNT: The card's class is """$(CardClass)""""

					ForListDo $(Bindable)
						Split-String $($) " " EntryValue

						ifstr(i) *($(EntryValue), 1) == $(ComponentName)
							set TargetClass	 = *($(EntryValue), 3)
							
							ifstr(i) $(TargetClass) == $(CardClass)
								set CanBind	 = TRUE
							endif
							
						endif ; *($(EntryValue), 1) == $(ComponentName)
					EndForListDo ; $(Bindable)
				endif ; $(RegLastError) != 0

				CloseRegKey $(NetRuleKey)
			endif ; $(NetRuleKey) == $(KeyNull)
		endif ; $(RegLastError) != 0
	endif ; $(RegLastError) != 0

	Return $(CanBind)

; ----------------------------------------------------------------------
;	CreateVirtualNIC
;
;	This subroutine returns a list of all real network adapters in the 
;	computer.
;
;	Parameters:
;		In:		$($0)	- The name of the option being installed
;				$($1)	- The Inf filename
;				$($2)	- The title name of the NIC to which this
;				$($3)	- The installation date
;		Out:	$($R0)	- A registry error index or NO_ERROR
;				$($R1)	- A handle to the key HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\N
;				$($R2)	- A handle to the key HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\N\NetRule
;				$($R3)	- A handle to the key HKLM\SYSTEM\CurrentControlSet\Services\<service-name>\Parameters
;				$($R4)	- Adapter number of newly created Virtual NIC
;				$($R5)	- The service name of the newly created Virtual NIC
; ----------------------------------------------------------------------

[CreateVirtualNIC]
	read-syms	GeneralConstants
	read-syms	FileConstants
	read-syms	FileConstants$(!STF_LANGUAGE)
	read-syms	DialogConstants$(!STF_LANGUAGE)

	set Option			 = $($0)
	set InfName			 = $($1)
	set AdapterTitleBase = $($2)
	set InstallDate		 = $($3)

	Debug-Output "VPCNetNT: CreateVirtualNIC called!"
	Debug-Output "VPCNetNT: --> Option           : "$(Option)
	Debug-Output "VPCNetNT: --> InfName          : "$(InfName)
	Debug-Output "VPCNetNT: --> AdapterTitleBase : "$(AdapterTitleBase)
	Debug-Output "VPCNetNT: --> InstallDate      : "$(InstallDate)

	Shell $(UtilityInf), AddHardwareComponent, $(AdapterName), $(InfName), $(NDISMiniportProductKeyName)
	ifint $($ShellCode) != $(!SHELL_CODE_OK)
		Debug-Output "VPCNetNT: AddHardwareComponent failed - ShellCode "$($ShellCode)
		set RegistryErrorIndex	 = SETUP_FAIL
		goto CreateVirtualNIC_AddHardwareComponentFailed
	else-ifstr(i) $($R0) != NO_ERROR
		set RegistryKeyIndex	 = $($R0)
		Debug-Output "VPCNetNT: AddHardwareComponent failed - registry error "$(RegistryKeyIndex)
		goto CreateVirtualNIC_AddHardwareComponentFailed
	endif

	set AdapterKey			 = $($R1)
	set AdapterRulesKey		 = $($R2)
	set AdapterParametersKey = $($R3)
	set AdapterNumber		 = $($R4)
	set AdapterServiceName	 = $($R5)

	;; Prepend the adapter number to the adapter title
	set AdapterTitle	 = "["$(AdapterNumber)"] "$(AdapterTitleBase)

	;; Add the required adapter information to the adapter registry key
	set NewValueList	 = { +
		{"Description",		 $(NoTitle), $(!REG_VT_SZ),		 $(AdapterDescription)}, +
		{"InstallDate",		 $(NoTitle), $(!REG_VT_SZ),		 $(InstallDate)}, +
		{"Manufacturer",	 $(NoTitle), $(!REG_VT_SZ),		 $(Manufacturer)}, +
		{"OperationsSupport",$(NoTitle), $(!REG_VT_DWORD),	 $(AdapterOperationsSupport)}, +
		{"ProductName",		 $(NoTitle), $(!REG_VT_SZ),		 $(AdapterName)}, +
		{"ServiceName",		 $(NoTitle), $(!REG_VT_SZ),		 $(AdapterServiceName)}, +
		{"Title",			 $(NoTitle), $(!REG_VT_SZ),		 $(AdapterTitle)} +
	}
	Shell $(UtilityInf), AddValueList, $(AdapterKey), $(NewValueList)
	ifint $($ShellCode) != $(!SHELL_CODE_OK)
		Debug-Output "VPCNetNT: AddValueList failed - ShellCode "$($ShellCode)
		set RegistryErrorIndex	 = SETUP_FAIL
		goto CreateVirtualNIC_Failure1
	else-ifstr(i) $($R0) != NO_ERROR
		set RegistryKeyIndex	 = $($R0)
		Debug-Output "VPCNetNT: AddValueList failed - registry error "$(RegistryKeyIndex)
		goto CreateVirtualNIC_Failure1
	endif

	;; Add the appropriate entries to the NetRule subkey
	set TempProductName	 = """"$(AdapterName)$(AdapterNumber)""""
	set TempBindForm	 = $(TempProductName)$(NetRuleAdapterBindForm)
	set NewValueList	 = { +
		{"bindform",	 $(NoTitle), $(!REG_VT_SZ),	 $(TempBindForm)}, +
		{"class",		 $(NoTitle), $(!REG_VT_SZ),	 $(NetRuleAdapterClass)}, +
		{"InfOption",	 $(NoTitle), $(!REG_VT_SZ),	 $(Option)}, +
		{"type",		 $(NoTitle), $(!REG_VT_SZ),	 $(NetRuleAdapterType)} +
		}
	Shell $(UtilityInf), AddValueList, $(AdapterRulesKey), $(NewValueList)
	ifint $($ShellCode) != $(!SHELL_CODE_OK)
		Debug-Output "VPCNetNT: AddValueList failed - ShellCode "$($ShellCode)
		set RegistryErrorIndex	 = SETUP_FAIL
		goto CreateVirtualNIC_Failure1
	else-ifstr(i) $($R0) != NO_ERROR
		set RegistryKeyIndex	 = $($R0)
		Debug-Output "VPCNetNT: AddValueList failed - registry error "$(RegistryKeyIndex)
		goto CreateVirtualNIC_Failure1
	endif

	Return NO_ERROR, $(AdapterKey), $(AdapterRulesKey), $(AdapterParametersKey), $(AdapterNumber), $(AdapterServiceName)

CreateVirtualNIC_Failure1 = +
	Shell $(UtilityInf), RemoveHardwareComponent, $(Manufacturer), $(AdapterName), +
		$(!NTN_SoftwareBase)"\Microsoft\Windows NT\CurrentVersion\NetworkCards\"$(AdapterNumber)

CreateVirtualNIC_AddHardwareComponentFailed = +
	CloseRegKey	$(AdapterKey)
	CloseRegKey $(AdapterRulesKey)
	CloseRegKey $(AdapterParametersKey)

	Return $(RegistryErrorIndex), $(KeyNull), $(KeyNull), $(KeyNull), -1, ""

; ----------------------------------------------------------------------
;	AdjustBindings
;
;	This subroutine enables or disables the specified binding of one 
;	network component (usually a protocol) to another network component 
;	(usually a driver).
;
;	Parameters:
;		In:		$($0)	- The service name of the component whose binding
;							is to be disabled
;				$($1)	- A list of service names of the bindings to disable
;				$($2)	- "activate" or "disable"
;		Out:	$($R0)	- If TRUE, any binding was disabled; if FALSE,
;							no binding could not be disabled
; ----------------------------------------------------------------------

[AdjustBindings]
	read-syms	GeneralConstants
	read-syms	FileConstants

	set FromService		 = $($0)
	set ToServiceList	 = $($1)
	set Action			 = $($2)

	set Disabled	 = FALSE

	Debug-Output "VPCNetNT: AdjustBindings called!"
	Debug-Output "--> FromService   : "$(FromService)
	Debug-Output "--> ToServiceList : "$(ToServiceList)
	Debug-Output "--> Action        : "$(Action)

	;; Get the "From" service bindings
	ifstr(i) $(Action) == activate
		set FromServiceLinkageKeyName	 = $(!NTN_ServiceBase)"\"$(FromService)"\Linkage\Disabled"
	else
		set FromServiceLinkageKeyName	 = $(!NTN_ServiceBase)"\"$(FromService)"\Linkage"
	endif

	OpenRegKey $(!REG_H_LOCAL) "" $(FromServiceLinkageKeyName) $(MAXIMUM_ALLOWED) FromServiceLinkageKey
	ifstr(i) $(FromServiceLinkageKey) == $(KeyNull)
		Debug-Output "VPCNetNT: Failed to open linkage key "$(FromServiceLinkageKeyName)
		goto AdjustBindings_FatalError
	endif

	GetRegValue $(FromServiceLinkageKey) "Bind" KeyValue
	ifint $(RegLastError) == 0
		set Bindings	 = *($(KeyValue), 4)
	else
		set Bindings	 = {}
	endif

	CloseRegKey $(FromServiceLinkageKey)

	Debug-Output "VPCNetNT: Bindings : "$(Bindings)

	set BindingIndex	 = 0
	ForListDo $(Bindings)
		set-add BindingIndex	 = $(BindingIndex), 1
		set		CurrentBinding	 = $($)

		;; FIX ME! This won't work correctly for service names that contain the
		;; "_" character.
		Split-String $(CurrentBinding) "\_" BindingPath

		ForListDo $(ToServiceList)
			ifcontains(i) $($) in $(BindingPath)
				Debug-Output "VPCNetNT: "$(Action)" binding "$(CurrentBinding)" from "$(FromService)
				Shell $(UtilityInf), ToggleBinding, $(FromService), $(BindingIndex), $(Action)
				ifint $($ShellCode) != $(!SHELL_CODE_OK)
					Debug-Output "VPCNetNT: Failed to "$(Action)" binding! ShellCode "$($ShellCode)
				else-ifstr(i) $($R0) != NO_ERROR
					Debug-Output "VPCNetNT: Failed to "$(Action)" binding! Status "$($R0)
				else
					set-sub BindingIndex = $(BindingIndex), 1
					set		Disabled	 = TRUE
				endif
			endif 
		EndForListDo ; $(ToServiceList)
	EndForListDo ; $(Bindings)

	Return $(Disabled)

AdjustBindings_FatalError = +
	Return FALSE