util.vbs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. Set stdout = WScript.StdOut
  2. Set stderr = WScript.StdErr
  3. Set stdin = WScript.StdIn
  4. Set args = WScript.Arguments
  5. Set fs = CreateObject("scripting.filesystemobject")
  6. Dim OSArchitecture
  7. Sub WriteErr(message)
  8. stderr.Write message
  9. End Sub
  10. Sub WriteLineErr(message)
  11. stderr.WriteLine message
  12. End Sub
  13. Sub Write(message)
  14. stdout.Write message
  15. End Sub
  16. Sub WriteLine(message)
  17. stdout.WriteLine message
  18. End Sub
  19. Function IndexOf(varNeedle, arrHaystack)
  20. IndexOf = -1
  21. If Not IsArray(arrHaystack) Then
  22. Exit Function
  23. End If
  24. For xyz = 0 To UBound(arrHaystack)
  25. If arrHaystack(xyz) = varNeedle Then
  26. IndexOf = xyz
  27. Exit Function
  28. End If
  29. Next
  30. End Function
  31. Sub CheckZeroArgs(message)
  32. ' bail if args are missing
  33. If args.Count = 0 Then
  34. WriteLineErr message
  35. WScript.Quit 25121
  36. End If
  37. End Sub
  38. Dim ALLOWED_OS_ARCHITECTURE_VALUES: ALLOWED_OS_ARCHITECTURE_VALUES = Array("S", "A", "32", "64")
  39. '
  40. ' determine the architecture of the operating system, that will be used. there are 4 possibilities:
  41. ' A - means agnostic
  42. ' S - means that we want to use a specific architecture, but auto detect Item
  43. ' 32 - explicitly use 32 bit architecture
  44. ' 64 - explicitly use 64 bit architecture
  45. '
  46. Sub DetermineOSArchitecture()
  47. strArchitecture = args(0)
  48. If IsNull(strArchitecture) Then
  49. WriteLineErr "missing architecture argument"
  50. WScript.Quit 25124
  51. End If
  52. strArchitecture = UCase(strArchitecture)
  53. If IndexOf(strArchitecture, ALLOWED_OS_ARCHITECTURE_VALUES) = -1 Then
  54. WriteLineErr "invalid architecture argument"
  55. WScript.Quit 25124
  56. End If
  57. If (strArchitecture = "S") Then
  58. OSArchitecture = GetOSArchitecture()
  59. If OSArchitecture = -1 Then
  60. WriteLineErr "invalid os architecture detected " & OSArchitecture
  61. WScript.Quit 25126
  62. End If
  63. Else
  64. OSArchitecture = strArchitecture
  65. End If
  66. End Sub
  67. Sub Include(sPath)
  68. ' TODO this is fragile, but should work for "modules" nested relatively to script root
  69. include_ScriptPath = Left(WScript.ScriptFullName, InStr(WScript.ScriptFullName, WScript.ScriptName) - 2)
  70. sPath = include_ScriptPath & "\" & sPath
  71. include_code = fs.OpenTextFile(sPath).ReadAll
  72. ExecuteGlobal include_code
  73. End Sub
  74. Function GetOSArchitecture()
  75. Dim ObjWMI, ColSettings, ObjProcessor
  76. Dim StrComputer, ObjNetwork
  77. Set ObjWMI = GetObject("winmgmts:\Root\CIMV2")
  78. Set ColSettings = ObjWMI.ExecQuery ("SELECT DataWidth, AddressWidth, Architecture FROM Win32_Processor")
  79. ' I make two assumptions here:
  80. ' 1. Eveyone will have CPU0 device
  81. ' 2. There is only one cpu defined in the wmi database (and if not, then they are all of the same architecture)
  82. '
  83. ' from: https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor
  84. ' Architecture values:
  85. ' x86 (0)
  86. ' MIPS (1)
  87. ' Alpha (2)
  88. ' PowerPC (3)
  89. ' ARM (5)
  90. ' ia64 (6)
  91. ' x64 (9)
  92. ' ARM64 (12)
  93. Set ObjProcessor = ColSettings.Item("Win32_Processor.DeviceID=""CPU0""")
  94. If ObjProcessor.Architecture = 0 AND ObjProcessor.AddressWidth = 32 Then
  95. GetOSArchitecture = 32
  96. ElseIf (ObjProcessor.Architecture = 6 OR ObjProcessor.Architecture = 9) AND ObjProcessor.DataWidth = 64 AND ObjProcessor.AddressWidth = 32 Then
  97. GetOSArchitecture = 32
  98. ElseIf (ObjProcessor.Architecture = 6 OR ObjProcessor.Architecture = 9) AND ObjProcessor.DataWidth = 64 AND ObjProcessor.AddressWidth = 64 Then
  99. GetOSArchitecture = 64
  100. ' special case (could be included in the statements above) for Windows VM on Apple Silicon, tested only on parallels
  101. ElseIf ObjProcessor.Architecture = 12 AND ObjProcessor.DataWidth = 64 AND ObjProcessor.AddressWidth = 64 Then
  102. GetOSArchitecture = 64
  103. Else
  104. GetOSArchitecture = -1
  105. End If
  106. End Function
  107. Function JsonSafe(inStrText)
  108. If inStrText = "" Then
  109. JsonSafe = ""
  110. Exit Function
  111. End If
  112. Dim outStrText: outStrText = inStrText
  113. outStrText = Replace(outStrText, "\", "\\")
  114. outStrText = Replace(outStrText, vbcrlf, "\\r\\n")
  115. outStrText = Replace(outStrText, vblf, "\\n")
  116. outStrText = Replace(outStrText, vbcr, "\\r")
  117. outStrText = Replace(outStrText, """", "\""")
  118. outStrText = JsonU(outStrText)
  119. JsonSafe = outStrText
  120. End Function
  121. 'TODO: need to change this function's name to something more appropriate
  122. Function JsonU(astr)
  123. If isNull(astr) Then
  124. JsonU = ""
  125. Exit Function
  126. End If
  127. Dim c
  128. Dim utftext: utftext = ""
  129. For n = 1 To Len(astr)
  130. c = CLng(AscW(Mid(astr, n, 1)))
  131. If c < 0 Then
  132. c = &H10000 + c
  133. End If
  134. If c < &H80 Then
  135. utftext = utftext & Mid(astr, n, 1)
  136. ElseIf c < &H100 Then
  137. utftext = utftext & "\u00" & Hex(c)
  138. ElseIf c < &H1000 Then
  139. utftext = utftext & "\u0" & Hex(c)
  140. Else
  141. utftext = utftext & "\u" & Hex(c)
  142. End If
  143. Next
  144. JsonU = utftext
  145. End Function