Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
10 KiB

  1. '<script language='VBScript'>
  2. ' wixload.inc - preprocessor for Windows Installer XML
  3. '
  4. ' 1999/12/31 - created - Rob Mensching (robmen@microsoft.com)
  5. '
  6. ' requires:
  7. ' wixerror.inc
  8. ' xmlconsts.inc
  9. '
  10. ' entrypoints:
  11. ' WixLoad
  12. ' WixApplyStyleSheet
  13. ' WixPreProcess
  14. '
  15. Public wixload_dictPreProcessVars ' As Scripting.Dictionary
  16. Public wixload_sPreProcessIncludePaths ' As String
  17. Public wixload_fso ' As Scripting.FileSystemObject
  18. Public wixload_sLoadDir ' As String
  19. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' robmen ''
  20. ' WixLoad
  21. Function WixLoad(ByVal sPath, ByVal sIncludePaths, ByRef dictVars, ByVal bProcess)
  22. Dim xmlDoc : Set xmlDoc = WScript.CreateObject("Microsoft.XMLDOM")
  23. 'WScript.Echo "Including: " & sPath
  24. ' set the global variables
  25. If Not IsEmpty(sIncludePaths) Then wixload_sPreProcessIncludePaths = sIncludePaths
  26. If Not IsEmpty(dictVars) Then Set wixload_dictPreProcessVars = dictVars
  27. If IsEmpty(wixload_dictPreProcessVars) Then Set wixload_dictPreProcessVars = WScript.CreateObject("Scripting.Dictionary")
  28. If IsEmpty(wixload_fso) Then Set wixload_fso = WScript.CreateObject("Scripting.FileSystemObject")
  29. If IsEmpty(wixload_sLoadDir) Then
  30. wixload_sLoadDir = wixload_fso.GetParentFolderName(wixload_fso.GetAbsolutePathName(sPath))
  31. Dim nFind : nFind = InStrRev(sPath, "\")
  32. If 0 < nFind Then sPath = Mid(sPath, nFind + 1)
  33. End If
  34. ' try to load the document
  35. xmlDoc.preserveWhiteSpace = False
  36. xmlDoc.async = False
  37. ' xmlDoc.validateOnParse = False
  38. ' xmlDoc.resolveExternals = False
  39. 'WScript.Echo "Xml validate: " & xmlDoc.validateOnParse
  40. 'WScript.Echo "Xml resolve: " & xmlDoc.resolveExternals
  41. ' Dim e : Set e = xmlDoc.createEntityReference("foo")
  42. ' Dim n : Set n = xmlDoc.createElement("wazz")
  43. ' n.nodeValue = "up"
  44. ' e.nodeValue = "bar"
  45. ' n.appendChild e
  46. 'WScript.Echo "xml: " & e.xml
  47. Dim bLoaded : bLoaded = xmlDoc.load(wixload_sLoadDir & "\" & sPath)
  48. If Not bLoaded Then
  49. Dim pe : Set pe = xmlDoc.parseError
  50. Dim sErr : sErr = "Failed to load XML file: " & pe.url & vbCrLf & " " & pe.errorCode & " - " & pe.reason & vbCrLf & " Line:" & pe.line & ", Character: " & pe.linepos
  51. Fail sErr
  52. End If
  53. ' if there is no root return with nothing
  54. Dim root : Set root = xmlDoc.firstChild
  55. If root Is Nothing Then
  56. Set WixLoad = Nothing
  57. Exit Function
  58. End If
  59. If bProcess Then WixPreProcess root, Empty, Empty
  60. ' return the preprocessed
  61. Set WixLoad = xmlDoc
  62. End Function ' WixLoad
  63. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' robmen ''
  64. ' WixApplyStyleSheet
  65. Function WixApplyStyleSheet(ByRef xmlDoc, ByVal sPath)
  66. Dim xmlStyle : Set xmlStyle = WixLoad(sPath, Empty, Empty, False)
  67. ' if there is no root return with nothing changed
  68. Dim root : Set root = xmlStyle.firstChild
  69. If root Is Nothing Then
  70. Set WixApplyStyleSheet = xmlDoc
  71. Exit Function
  72. End If
  73. Dim s : sApplied = xmlDoc.transformNode(xmlStyle)
  74. xmlDoc.loadXml sApplied
  75. If xmlDoc.parseError.errorCode <> 0 Then
  76. Dim pe : Set pe = xmlDoc.parseError
  77. Dim sErr : sErr = "Failed to properly apply stylesheet: " & sPath & " to XML file: " & pe.url & vbCrLf & " " & pe.errorCode & " - " & pe.reason & vbCrLf & " Line:" & pe.line & ", Character: " & pe.linepos
  78. Fail sErr
  79. End If
  80. Set WixApplyStyleSheet = xmlDoc
  81. End Function ' WixApplyStyleSheet
  82. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' robmen ''
  83. ' WixPreProcess
  84. Function WixPreProcess(ByRef root, ByVal sIncludePaths, ByRef dictVars)
  85. Dim child, nStartEntity, nEndEntity
  86. 'WScript.Echo "WixPreProcess"
  87. ' set the global variables
  88. If Not IsEmpty(sIncludePaths) Then wixload_sPreProcessIncludePaths = sIncludePaths
  89. If Not IsEmpty(dictVars) Then Set wixload_dictPreProcessVars = dictVars
  90. If IsEmpty(wixload_dictPreProcessVars) Then Set wixload_dictPreProcessVars = WScript.CreateObject("Scripting.Dictionary")
  91. ' if there is no root return with nothing
  92. ' Set root = xmlDoc.firstChild
  93. If root Is Nothing Then
  94. Set WixPreProcess = Nothing
  95. Exit Function
  96. End If
  97. 'WScript.Echo "Foo"
  98. ' loop through all of the nodes in the document
  99. ' !!! - should root just get children who are processing instructions?
  100. For Each child In root.childNodes
  101. 'WScript.Echo "child: " & child.nodeName
  102. ' look only at processing instructions
  103. If NODE_PROCESSING_INSTRUCTION = child.nodeType Then
  104. Select Case(child.target)
  105. Case "include" : wixload_WixProcessInclude child, child.parentNode : child.parentNode.removeChild child
  106. Case "if" : wixload_WixProcessIf child, child.parentNode
  107. Case "define"
  108. Dim var, name, value
  109. var = Split(child.data, "=")
  110. name = wixload_WixFixVarName(var(0))
  111. If UBound(var) > 0 Then value = var(1) Else value = True
  112. wixload_dictPreProcessVars.Add name, value
  113. Case "else"
  114. Case "endif"
  115. Case Else : Fail "Unexpected processor instruction: " & child.target
  116. End Select
  117. ElseIf NODE_CDATA_SECTION <> child.nodeType Then ' don't do entity replacments in CDATA Sections
  118. nStartEntity = InStr(child.nodeValue, "&")
  119. If 0 < nStartEntity Then
  120. nEndEntity = InStr(child.nodeValue, ";")
  121. If nEndEntity < nStartEntity Then
  122. Fail "Failed entity lookup for: " & child.nodeValue
  123. Else
  124. sVar = Mid(child.nodeValue, nStartEntity + 1, nEndEntity - nStartEntity - 1)
  125. If Not wixload_dictPreProcessVars.Exists(sVar) Then
  126. Fail "Unknown entity reference: " & sVar
  127. Else
  128. child.nodeValue = Left(child.nodeValue, 0, nStartEntity - 1) & wixload_dictPreProcessVars.Item(sVar) & Mid(child.nodeValue, nEndEntity + 1)
  129. End If
  130. End If
  131. End If
  132. End If
  133. If child.HasChildNodes Then
  134. 'WScript.Echo "Going down"
  135. WixPreProcess child, Empty, Empty
  136. End If
  137. Next
  138. Set WixPreProcess = root
  139. End Function
  140. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' robmen ''
  141. ' wixload_WixProcessIf
  142. Function wixload_WixProcessIf(node, nodeParent)
  143. Dim sEval : sEval = node.data
  144. Dim fInclude
  145. Dim fKeep : fKeep = wixload_WixEvaluate(sEval)
  146. Dim remove ' node to remove possibly
  147. Dim sibling : Set sibling = node.nextSibling
  148. Do Until sibling Is Nothing
  149. fInclude = False ' make sure the include flag is always started off
  150. If NODE_PROCESSING_INSTRUCTION = sibling.nodeType Then
  151. Select Case sibling.target
  152. Case "endif" : Exit Do
  153. Case "else" : fKeep = Not fKeep
  154. Case "include" : fInclude = True
  155. Case Else : Fail "Unexepected processor instruction: " & sibling.target
  156. End Select
  157. End If
  158. ' move the sibling along
  159. Set remove = sibling
  160. Set sibling = sibling.nextSibling
  161. ' if we're not keeping nodes toast this one
  162. If Not fKeep Then
  163. nodeParent.removeChild remove
  164. ElseIf fInclude Then ' if we're keeping nodes and this is an include node
  165. wixload_WixProcessInclude remove, remove.parentNode
  166. nodeParent.removeChild remove ' always remove the <?include ?> node
  167. End If
  168. Loop
  169. End Function ' wixload_WixProcessIf
  170. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' robmen ''
  171. ' wixload_WixProcessInclude
  172. Function wixload_WixProcessInclude(node, nodeParent)
  173. Dim sOldDir, sLoad, sProcess
  174. 'WScript.Echo "Processing include, load: " & sLoad
  175. sLoad = node.data
  176. If InStr(sLoad , "\") Or InStr(sLoad, "/") Then
  177. sProcess = wixload_fso.GetAbsolutePathName(sLoad)
  178. If wixload_sLoadDir <> wixload_fso.GetParentFolderName(sProcess) Then
  179. sOldDir = wixload_sLoadDir
  180. wixload_sLoadDir = wixload_fso.GetParentFolderName(sProcess)
  181. 'WScript.Echo "Changing load dir from: " & sOldDir & " to: " & wixload_sLoadDir
  182. sLoad = wixload_fso.GetFileName(sLoad)
  183. End If
  184. End If
  185. Dim xmlInclude : Set xmlInclude = WixLoad(sLoad, Empty, Empty, True)
  186. If xmlInclude Is Nothing Then Fail "Failed to include: " & sLoad
  187. ' reset the wixload directory
  188. If 0 < Len(sOldDir) Then wixload_sLoadDir = sOldDir
  189. ' load the fragment and make sure it hooked up correctly
  190. Dim sParent, nodeFragment : Set nodeFragment = xmlInclude.firstChild
  191. If "Fragment" <> nodeFragment.nodeName Then Fail "Can only <?include ?> <Fragments />."
  192. If Not nodeFragment.selectSingleNode("text()") Is Nothing Then
  193. sParent = nodeFragment.firstChild.nodeValue ' get the type of <Fragment>
  194. End If
  195. If Len(sParent) > 0 And nodeParent.nodeName <> sParent Then Fail "Fragment type: " & sParent & " does not match parent type: " & nodeParent.nodeName
  196. Dim child
  197. For Each child In nodeFragment.childNodes
  198. ' If NODE_ELEMENT = child.nodeType Then nodeParent.insertBefore child, node
  199. nodeParent.insertBefore child, node
  200. Next
  201. Set wixload_WixProcessInclude = node
  202. End Function ' wixload_WixProcessInclude
  203. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  204. ' helper functions
  205. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' robmen ''
  206. ' wixload_WixFixVarName
  207. Function wixload_WixFixVarName(ByVal s)
  208. If "[" = Left(s, 1) Then s = Mid(s, 2)
  209. If "]" = Right(s, 1) Then s = Mid(s, 1, Len(s) - 1)
  210. If Instr(1, s, "]") Or Instr(1, s, "[") Then Fail "Invalid variable name: " & s
  211. wixload_WixFixVarName = s
  212. End Function ' wixload_WixFixVarName
  213. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''' robmen ''
  214. ' wixload_WixEvaluate
  215. Function wixload_WixEvaluate(sExpression)
  216. sExpression = Replace(sExpression, "[", " wixload_dictPreProcessVars.Item(""")
  217. sExpression = Replace(sExpression, "]", """) ")
  218. wixload_WixEvaluate = CBool(Eval(sExpression))
  219. End Function ' wixload_WixEvaluate