SMTPReg.Vbs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. 'THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT
  2. 'WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
  3. 'INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
  4. 'OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  5. 'PURPOSE
  6. '------------------------------------------------------------------------------
  7. 'FILE DESCRIPTION: Script for registering for SMTP Protocol sinks.
  8. '
  9. 'File Name: smtpreg.vbs
  10. '
  11. '
  12. ' Copyright (c) Microsoft Corporation 1993-1999. All rights reserved.
  13. '------------------------------------------------------------------------------
  14. Option Explicit
  15. '
  16. '
  17. ' the OnArrival event GUID
  18. Const GUIDComCatOnArrival = "{ff3caa23-00b9-11d2-9dfb-00C04FA322BA}"
  19. ' the SMTP source type
  20. Const GUIDSourceType = "{FB65C4DC-E468-11D1-AA67-00C04FA345F6}"
  21. '
  22. Const GUIDCat = "{871736c0-fd85-11d0-869a-00c04fd65616}"
  23. Const GUIDSources = "{DBC71A31-1F4B-11d0-869D-80C04FD65616}"
  24. ' the SMTP service display name. This is used to key which service to
  25. ' edit
  26. Const szService = "smtpsvc"
  27. ' the event manager object. This is used to communicate with the
  28. ' event binding database.
  29. Dim EventManager
  30. Set EventManager = WScript.CreateObject("Event.Manager")
  31. '
  32. ' register a new sink with event manager
  33. '
  34. ' iInstance - the instance to work against
  35. ' szEvent - OnArrival
  36. ' szDisplayName - the display name for this new sink
  37. ' szProgID - the progid to call for this event
  38. ' szRule - the rule to set for this event
  39. '
  40. public sub RegisterSink(iInstance, szEvent, szDisplayName, szProgID, szRule)
  41. Dim SourceType
  42. Dim szSourceDisplayName
  43. Dim Source
  44. Dim Binding
  45. Dim GUIDComCat
  46. Dim PrioVal
  47. ' figure out which event they are trying to register with and set
  48. ' the comcat for this event in GUIDComCat
  49. select case LCase(szEvent)
  50. case "onarrival"
  51. GUIDComCat = GUIDComCatOnArrival
  52. case else
  53. WScript.echo "invalid event: " & szEvent
  54. exit sub
  55. end select
  56. ' enumerate through each of the registered instances for the SMTP source
  57. ' type and look for the display name that matches the instance display
  58. ' name
  59. set SourceType = EventManager.SourceTypes(GUIDSourceType)
  60. szSourceDisplayName = szService & " " & iInstance
  61. for each Source in SourceType.Sources
  62. if Source.DisplayName = szSourceDisplayName then
  63. ' we've found the desired instance. now add a new binding
  64. ' with the right event GUID. by not specifying a GUID to the
  65. ' Add method we get server events to create a new ID for this
  66. ' event
  67. set Binding = Source.GetBindingManager.Bindings(GUIDComCat).Add("")
  68. ' set the binding properties
  69. Binding.DisplayName = szDisplayName
  70. Binding.SinkClass = szProgID
  71. ' register a rule with the binding
  72. Binding.SourceProperties.Add "Rule", szRule
  73. ' register a priority with the binding
  74. PrioVal = GetNextPrio(Source, GUIDComCat)
  75. If PrioVal < 0 then
  76. WScript.Echo "assigning priority to default value (24575)"
  77. Binding.SourceProperties.Add "Priority", 24575
  78. else
  79. WScript.Echo "assigning priority (" & PrioVal & " of 32767)"
  80. Binding.SourceProperties.Add "Priority", PrioVal
  81. end if
  82. ' save the binding
  83. Binding.Save
  84. WScript.Echo "registered " & szDisplayName
  85. exit sub
  86. end if
  87. next
  88. end sub
  89. '
  90. ' iterate through the bindings in a source, find the binding
  91. ' with the lowest priority, and return the next priority value.
  92. ' If the next value exceeds the range, return -1.
  93. '
  94. public function GetNextPrio(oSource, GUIDComCat)
  95. ' it's possible that priority values will not be
  96. ' numbers, so we add error handling for this case
  97. on error resume next
  98. Dim Bindings
  99. Dim Binding
  100. Dim nLowestPrio
  101. Dim nPrioVal
  102. nLowestPrio = 0
  103. set Bindings = oSource.GetBindingManager.Bindings(GUIDComCat)
  104. ' if the bindings collection is empty, then this is the first
  105. ' sink. It gets the highest priority (0).
  106. if Bindings.Count = 0 then
  107. GetNextPrio = 0
  108. else
  109. ' get the lowest existing priority value
  110. for each Binding in Bindings
  111. nPrioVal = Binding.SourceProperties.Item("Priority")
  112. if CInt(nPrioVal) > nLowestPrio then
  113. if err.number = 13 then
  114. err.clear
  115. else
  116. nLowestPrio = CInt(nPrioVal)
  117. end if
  118. end if
  119. next
  120. ' assign priority values in increments of 10 so priorities
  121. ' can be shuffled later without the need to reorder all
  122. ' binding priorities. Valid priority values are 0 - 32767
  123. if nLowestPrio + 10 > 32767 then
  124. GetNextPrio = -1
  125. else
  126. GetNextPrio = nLowestPrio + 10
  127. end if
  128. end if
  129. end function
  130. '
  131. ' check for a previously registered sink with the passed in name
  132. '
  133. ' iInstance - the instance to work against
  134. ' szEvent - OnArrival
  135. ' szDisplayName - the display name of the event to check
  136. ' bCheckError - Any errors returned
  137. public sub CheckSink(iInstance, szEvent, szDisplayName, bCheckError)
  138. Dim SourceType
  139. Dim GUIDComCat
  140. Dim szSourceDisplayName
  141. Dim Source
  142. Dim Bindings
  143. Dim Binding
  144. bCheckError = FALSE
  145. select case LCase(szEvent)
  146. case "onarrival"
  147. GUIDComCat = GUIDComCatOnArrival
  148. case else
  149. WScript.echo "invalid event: " & szEvent
  150. exit sub
  151. end select
  152. ' find the source for this instance
  153. set SourceType = EventManager.SourceTypes(GUIDSourceType)
  154. szSourceDisplayName = szService & " " & iInstance
  155. for each Source in SourceType.Sources
  156. if Source.DisplayName = szSourceDisplayName then
  157. ' find the binding by display name. to do this we enumerate
  158. ' all of the bindings and try to match on the display name
  159. set Bindings = Source.GetBindingManager.Bindings(GUIDComCat)
  160. for each Binding in Bindings
  161. if Binding.DisplayName = szDisplayName then
  162. ' we've found the binding, now log an error
  163. WScript.Echo "Binding with the name " & szDisplayName & " already exists"
  164. exit sub
  165. end if
  166. next
  167. end if
  168. next
  169. bCheckError = TRUE
  170. end sub
  171. '
  172. ' unregister a previously registered sink
  173. '
  174. ' iInstance - the instance to work against
  175. ' szEvent - OnArrival
  176. ' szDisplayName - the display name of the event to remove
  177. '
  178. public sub UnregisterSink(iInstance, szEvent, szDisplayName)
  179. Dim SourceType
  180. Dim GUIDComCat
  181. Dim szSourceDisplayName
  182. Dim Source
  183. Dim Bindings
  184. Dim Binding
  185. select case LCase(szEvent)
  186. case "onarrival"
  187. GUIDComCat = GUIDComCatOnArrival
  188. case else
  189. WScript.echo "invalid event: " & szEvent
  190. exit sub
  191. end select
  192. ' find the source for this instance
  193. set SourceType = EventManager.SourceTypes(GUIDSourceType)
  194. szSourceDisplayName = szService & " " & iInstance
  195. for each Source in SourceType.Sources
  196. if Source.DisplayName = szSourceDisplayName then
  197. ' find the binding by display name. to do this we enumerate
  198. ' all of the bindings and try to match on the display name
  199. set Bindings = Source.GetBindingManager.Bindings(GUIDComCat)
  200. for each Binding in Bindings
  201. if Binding.DisplayName = szDisplayName then
  202. ' we've found the binding, now remove it
  203. Bindings.Remove(Binding.ID)
  204. WScript.Echo "removed " & szDisplayName & " " & Binding.ID
  205. end if
  206. next
  207. end if
  208. next
  209. end sub
  210. '
  211. ' add or remove a property from the source or sink propertybag for an event
  212. '
  213. ' iInstance - the SMTP instance to edit
  214. ' szEvent - the event type (OnArrival)
  215. ' szDisplayName - the display name of the event
  216. ' szPropertyBag - the property bag to edit ("source" or "sink")
  217. ' szOperation - "add" or "remove"
  218. ' szPropertyName - the name to edit in the property bag
  219. ' szPropertyValue - the value to assign to the name (ignored for remove)
  220. '
  221. public sub EditProperty(iInstance, szEvent, szDisplayName, szPropertyBag, szOperation, szPropertyName, szPropertyValue)
  222. Dim SourceType
  223. Dim GUIDComCat
  224. Dim szSourceDisplayName
  225. Dim Source
  226. Dim Bindings
  227. Dim Binding
  228. Dim PropertyBag
  229. select case LCase(szEvent)
  230. case "onarrival"
  231. GUIDComCat = GUIDComCatOnArrival
  232. case else
  233. WScript.echo "invalid event: " & szEvent
  234. exit sub
  235. end select
  236. ' find the source for this instance
  237. set SourceType = EventManager.SourceTypes(GUIDSourceType)
  238. szSourceDisplayName = szService & " " & iInstance
  239. for each Source in SourceType.Sources
  240. if Source.DisplayName = szSourceDisplayName then
  241. set Bindings = Source.GetBindingManager.Bindings(GUIDComCat)
  242. ' find the binding by display name. to do this we enumerate
  243. ' all of the bindings and try to match on the display name
  244. for each Binding in Bindings
  245. if Binding.DisplayName = szDisplayName then
  246. ' figure out which set of properties we want to modify
  247. ' based on the szPropertyBag parameter
  248. select case LCase(szPropertyBag)
  249. case "source"
  250. set PropertyBag = Binding.SourceProperties
  251. case "sink"
  252. set PropertyBag = Binding.SinkProperties
  253. case else
  254. WScript.echo "invalid propertybag: " & szPropertyBag
  255. exit sub
  256. end select
  257. ' figure out what operation we want to perform
  258. select case LCase(szOperation)
  259. case "remove"
  260. ' they want to remove szPropertyName from the
  261. ' property bag
  262. PropertyBag.Remove szPropertyName
  263. WScript.echo "removed property " & szPropertyName
  264. case "add"
  265. ' add szPropertyName to the property bag and
  266. ' set its value to szValue. if this value
  267. ' already exists then this will change the value
  268. ' it to szValue.
  269. PropertyBag.Add szPropertyName, szPropertyValue
  270. WScript.echo "set property " & szPropertyName & " to " & szPropertyValue
  271. case else
  272. WScript.echo "invalid operation: " & szOperation
  273. exit sub
  274. end select
  275. ' save the binding
  276. Binding.Save
  277. end if
  278. next
  279. end if
  280. next
  281. end sub
  282. '
  283. ' this helper function takes an IEventSource object and a event category
  284. ' and dumps all of the bindings for this category under the source
  285. '
  286. ' Source - the IEventSource object to display the bindings for
  287. ' GUIDComCat - the event category to display the bindings for
  288. '
  289. public sub DisplaySinksHelper(Source, GUIDComCat)
  290. Dim Binding
  291. Dim propval
  292. ' walk each of the registered bindings for this component category
  293. for each Binding in Source.GetBindingManager.Bindings(GUIDComCat)
  294. ' display the binding properties
  295. WScript.echo " Binding " & Binding.ID & " {"
  296. WScript.echo " DisplayName = " & Binding.DisplayName
  297. WScript.echo " SinkClass = " & Binding.SinkClass
  298. if Binding.Enabled = True then
  299. WScript.echo " Status = Enabled"
  300. else
  301. WScript.echo " Status = Disabled"
  302. end if
  303. ' walk each of the source properties and display them
  304. WScript.echo " SourceProperties {"
  305. for each propval in Binding.SourceProperties
  306. WScript.echo " " & propval & " = " & Binding.SourceProperties.Item(propval)
  307. next
  308. WScript.echo " }"
  309. ' walk each of the sink properties and display them
  310. WScript.echo " SinkProperties {"
  311. for each Propval in Binding.SinkProperties
  312. WScript.echo " " & propval & " = " & Binding.SinkProperties.Item(Propval)
  313. next
  314. WScript.echo " }"
  315. WScript.echo " }"
  316. next
  317. end sub
  318. '
  319. ' dumps all of the information in the binding database related to SMTP
  320. '
  321. public sub DisplaySinks
  322. Dim SourceType
  323. Dim Source
  324. ' look for each of the sources registered for the SMTP source type
  325. set SourceType = EventManager.SourceTypes(GUIDSourceType)
  326. for each Source in SourceType.Sources
  327. ' display the source properties
  328. WScript.echo "Source " & Source.ID & " {"
  329. WScript.echo " DisplayName = " & Source.DisplayName
  330. ' display all of the sinks registered for the OnArrival event
  331. WScript.echo " OnArrival Sinks {"
  332. call DisplaySinksHelper(Source, GUIDComCatOnArrival)
  333. WScript.echo " }"
  334. next
  335. end sub
  336. '
  337. ' enable/disable a registered sink
  338. '
  339. ' iInstance - the instance to work against
  340. ' szEvent - OnArrival
  341. ' szDisplayName - the display name for this new sink
  342. '
  343. public sub SetSinkEnabled(iInstance, szEvent, szDisplayName, szEnable)
  344. Dim SourceType
  345. Dim GUIDComCat
  346. Dim szSourceDisplayName
  347. Dim Source
  348. Dim Bindings
  349. Dim Binding
  350. select case LCase(szEvent)
  351. case "onarrival"
  352. GUIDComCat = GUIDComCatOnArrival
  353. case else
  354. WScript.echo "invalid event: " + szEvent
  355. exit sub
  356. end select
  357. ' find the source for this instance
  358. set SourceType = EventManager.SourceTypes(GUIDSourceType)
  359. szSourceDisplayName = szService + " " + iInstance
  360. for each Source in SourceType.Sources
  361. if Source.DisplayName = szSourceDisplayName then
  362. ' find the binding by display name. to do this we enumerate
  363. ' all of the bindings and try to match on the display name
  364. set Bindings = Source.GetBindingManager.Bindings(GUIDComCat)
  365. for each Binding in Bindings
  366. if Binding.DisplayName = szDisplayName then
  367. ' we've found the binding, now enable/disable it
  368. ' we don't need "case else' because szEnable's value
  369. ' is set internally, not by users
  370. select case LCase(szEnable)
  371. case "true"
  372. Binding.Enabled = True
  373. Binding.Save
  374. WScript.Echo "enabled " + szDisplayName + " " + Binding.ID
  375. case "false"
  376. Binding.Enabled = False
  377. Binding.Save
  378. WScript.Echo "disabled " + szDisplayName + " " + Binding.ID
  379. end select
  380. end if
  381. next
  382. end if
  383. next
  384. end sub
  385. '
  386. ' display usage information for this script
  387. '
  388. public sub DisplayUsage
  389. WScript.echo "usage: cscript smtpreg.vbs <command> <arguments>"
  390. WScript.echo " commands:"
  391. WScript.echo " /add <Instance> <Event> <DisplayName> <SinkClass> <Rule>"
  392. WScript.echo " /remove <Instance> <Event> <DisplayName>"
  393. WScript.echo " /setprop <Instance> <Event> <DisplayName> <PropertyBag> <PropertyName> "
  394. WScript.echo " <PropertyValue>"
  395. WScript.echo " /delprop <Instance> <Event> <DisplayName> <PropertyBag> <PropertyName>"
  396. WScript.echo " /enable <Instance> <Event> <DisplayName>"
  397. WScript.echo " /disable <Instance> <Event> <DisplayName>"
  398. WScript.echo " /enum"
  399. WScript.echo " arguments:"
  400. WScript.echo " <Instance> is the SMTP instance to work against"
  401. WScript.echo " <Event> can be OnArrival"
  402. WScript.echo " <DisplayName> is the display name of the event to edit"
  403. WScript.echo " <SinkClass> is the sink class for the event"
  404. WScript.echo " <Rule> is the rule to use for the event"
  405. WScript.echo " <PropertyBag> can be Source or Sink"
  406. WScript.echo " <PropertyName> is the name of the property to edit"
  407. WScript.echo " <PropertyValue> is the value to assign to the property"
  408. end sub
  409. Dim iInstance
  410. Dim szEvent
  411. Dim szDisplayName
  412. Dim szSinkClass
  413. Dim szRule
  414. Dim szPropertyBag
  415. Dim szPropertyName
  416. Dim szPropertyValue
  417. dim bCheck
  418. '
  419. ' this is the main body of our script. it reads the command line parameters
  420. ' specified and then calls the appropriate function to perform the operation
  421. '
  422. if WScript.Arguments.Count = 0 then
  423. call DisplayUsage
  424. else
  425. Select Case LCase(WScript.Arguments(0))
  426. Case "/add"
  427. if not WScript.Arguments.Count = 6 then
  428. call DisplayUsage
  429. else
  430. iInstance = WScript.Arguments(1)
  431. szEvent = WScript.Arguments(2)
  432. szDisplayName = WScript.Arguments(3)
  433. szSinkClass = WScript.Arguments(4)
  434. szRule = WScript.Arguments(5)
  435. call CheckSink(iInstance, szEvent, szDisplayName, bCheck)
  436. if bCheck = TRUE then
  437. call RegisterSink(iInstance, szEvent, szDisplayName, szSinkClass, szRule)
  438. End if
  439. end if
  440. Case "/remove"
  441. if not WScript.Arguments.Count = 4 then
  442. call DisplayUsage
  443. else
  444. iInstance = WScript.Arguments(1)
  445. szEvent = WScript.Arguments(2)
  446. szDisplayName = WScript.Arguments(3)
  447. call UnregisterSink(iInstance, szEvent, szDisplayName)
  448. end if
  449. Case "/setprop"
  450. if not WScript.Arguments.Count = 7 then
  451. call DisplayUsage
  452. else
  453. iInstance = WScript.Arguments(1)
  454. szEvent = WScript.Arguments(2)
  455. szDisplayName = WScript.Arguments(3)
  456. szPropertyBag = WScript.Arguments(4)
  457. szPropertyName = WScript.Arguments(5)
  458. szPropertyValue = WScript.Arguments(6)
  459. call EditProperty(iInstance, szEvent, szDisplayName, szPropertyBag, "add", szPropertyName, szPropertyValue)
  460. end if
  461. Case "/delprop"
  462. if not WScript.Arguments.Count = 6 then
  463. call DisplayUsage
  464. else
  465. iInstance = WScript.Arguments(1)
  466. szEvent = WScript.Arguments(2)
  467. szDisplayName = WScript.Arguments(3)
  468. szPropertyBag = WScript.Arguments(4)
  469. szPropertyName = WScript.Arguments(5)
  470. call EditProperty(iInstance, szEvent, szDisplayName, szPropertyBag, "remove", szPropertyName, "")
  471. end if
  472. Case "/enable"
  473. if not WScript.Arguments.Count = 4 then
  474. call DisplayUsage
  475. else
  476. iInstance = WScript.Arguments(1)
  477. szEvent = WScript.Arguments(2)
  478. szDisplayName = WScript.Arguments(3)
  479. call SetSinkEnabled(iInstance, szEvent, szDisplayName, "True")
  480. end if
  481. Case "/disable"
  482. if not WScript.Arguments.Count = 4 then
  483. call DisplayUsage
  484. else
  485. iInstance = WScript.Arguments(1)
  486. szEvent = WScript.Arguments(2)
  487. szDisplayName = WScript.Arguments(3)
  488. call SetSinkEnabled(iInstance, szEvent, szDisplayName, "False")
  489. end if
  490. Case "/enum"
  491. if not WScript.Arguments.Count = 1 then
  492. call DisplayUsage
  493. else
  494. call DisplaySinks
  495. end if
  496. Case Else
  497. call DisplayUsage
  498. End Select
  499. end if