home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 May / W2KPRK.iso / ras.cab / listprinters.vbs < prev    next >
Text File  |  1999-11-04  |  23KB  |  650 lines

  1. '********************************************************************
  2. '*
  3. '* File:           ListPrinters.Vbs
  4. '* Created:        March 1999
  5. '* Version:        1.0
  6. '*
  7. '*  Main Function:  Lists properties of all printers installed on a computer.
  8. '*
  9. '*  ListPrinters.vbs      [/S <server>] [/U <username>] [/W <password>] 
  10. '*                        [/O <outputfile>]
  11. '*
  12. '* Copyright (C) 1999 Microsoft Corporation
  13. '*
  14. '********************************************************************
  15.  
  16. OPTION EXPLICIT
  17.  
  18.     'Define constants
  19.     CONST CONST_ERROR                   = 0
  20.     CONST CONST_WSCRIPT                 = 1
  21.     CONST CONST_CSCRIPT                 = 2
  22.     CONST CONST_SHOW_USAGE              = 3
  23.     CONST CONST_PROCEED                 = 4
  24.  
  25.     'Declare variables
  26.     Dim intOpMode, i
  27.     Dim strServer, strUserName, strPassword, strOutputFile
  28.  
  29.     'Make sure the host is csript, if not then abort
  30.     VerifyHostIsCscript()
  31.  
  32.     'Parse the command line
  33.     intOpMode = intParseCmdLine(strServer     ,  _
  34.                                 strUserName   ,  _
  35.                                 strPassword   ,  _
  36.                                 strOutputFile    )
  37.  
  38.  
  39.     Select Case intOpMode
  40.  
  41.         Case CONST_SHOW_USAGE
  42.             Call ShowUsage()
  43.  
  44.         Case CONST_PROCEED                 
  45.             Call ListPrinters(strServer     , _
  46.                              strOutputFile , _
  47.                              strUserName   , _
  48.                              strPassword     )
  49.  
  50.         Case CONST_ERROR
  51.             'Do Nothing
  52.  
  53.         Case Else                    'Default -- should never happen
  54.             Call Wscript.Echo("Error occurred in passing parameters.")
  55.  
  56.     End Select
  57.  
  58. '********************************************************************
  59. '* End of Script
  60. '********************************************************************
  61.  
  62. '********************************************************************
  63. '*
  64. '* Sub ListPrinters()
  65. '*
  66. '* Purpose: Lists properties of all printers installed on a computer.
  67. '*
  68. '* Input:   strServer           a machine name
  69. '*          strOutputFile       an output file name
  70. '*          strUserName         the current user's name
  71. '*          strPassword         the current user's password
  72. '*
  73. '* Output:  Results are either printed on screen or saved in strOutputFile.
  74. '*
  75. '********************************************************************
  76. Private Sub ListPrinters(strServer, strOutputFile, strUserName, strPassword)
  77.  
  78.  
  79.     ON ERROR RESUME NEXT
  80.  
  81.     Dim objFileSystem, objOutputFile, objService, objPrinterSet, objPrinter
  82.     Dim strWBEMClass, strPrinterAttributes
  83.     strPrinterAttributes = Array("Queued"             , _
  84.                                  "Direct"             , _
  85.                                  "Default"            , _
  86.                                  "Shared"             , _ 
  87.                                  "Network"            , _
  88.                                  "Hidden"             , _
  89.                                  "Local"              , _
  90.                                  "Enable DevQ"        , _
  91.                                  "Keep Printed Jobs"  , _
  92.                                  "Do Complete First"  , _
  93.                                  "Work Offline"       , _
  94.                                  "Enable BIDI"        , _
  95.                                  "Raw Only"             )
  96.  
  97.     strWBEMClass = "Win32_Printer"
  98.  
  99.     'Open a text file for output if the file is requested
  100.     If Not IsEmpty(strOutputFile) Then
  101.         If (NOT blnOpenFile(strOutputFile, objOutputFile)) Then
  102.             Call Wscript.Echo ("Could not open an output file.")
  103.             Exit Sub
  104.         End If
  105.     End If
  106.  
  107.     'Establish a connection with the server.
  108.     If blnConnect("root\cimv2" , _
  109.                    strUserName , _
  110.                    strPassword , _
  111.                    strServer   , _
  112.                    objService  ) Then
  113.         Call Wscript.Echo("")
  114.         Call Wscript.Echo("Please check the server name, " _
  115.                         & "credentials and WBEM Core.")
  116.         Exit Sub
  117.     End If
  118.  
  119.     'Get the set
  120.     Set objPrinterSet = objService.InstancesOf(strWBEMClass)
  121.     If blnErrorOccurred("Could not obtain " & strWBEMClass & " instance.") Then
  122.         Exit Sub
  123.     End If
  124.  
  125.     If objPrinterSet.Count = 0 Then
  126.         Call WriteLine("No printers information is available.", _
  127.                         objOutputFile)    
  128.         Exit Sub
  129.     End If
  130.  
  131.     Call WriteLine("Printers for machine " & _
  132.                     strServer, objOutputFile)
  133.     Call WriteLine("", objOutputFile)
  134.  
  135.     For Each objPrinter In objPrinterSet
  136.         Call WriteLine("Name        = " & objPrinter.Caption, objOutputFile)
  137.         Call WriteLine("Location    = " & objPrinter.Location, objOutputFile)
  138.         Call WriteLine("Description = " & objPrinter.Description, objOutputFile)
  139.         Call WriteLine("Driver      = " & objPrinter.DriverName, objOutputFile)
  140.         Call WriteLine("Error State = " & objPrinter.DetectedErrorState, _
  141.                         objOutputFile)
  142.         For I = 1 to len(objPrinter.Attributes)
  143.             If I = 1 then
  144.                 Call WriteLine("Attributes  = " & strPrinterAttributes _
  145.                                 (Mid(objPrinter.Attributes,I,1)), objOutputFile)
  146.             Else
  147.                 Call WriteLine("              " & strPrinterAttributes _
  148.                                 (Mid(objPrinter.Attributes,I,1)), objOutputFile)            
  149.             End If
  150.         Next
  151.     Next
  152.  
  153.     If IsObject(objOutputFile) Then
  154.         objOutputFile.Close
  155.         Call Wscript.Echo ("Results are saved in file " & strOutputFile & ".")
  156.     End If
  157. End Sub
  158.  
  159. '********************************************************************
  160. '*
  161. '* Function intParseCmdLine()
  162. '*
  163. '* Purpose: Parses the command line.
  164. '* Input:   
  165. '*
  166. '* Output:  strServer         a remote server ("" = local server")
  167. '*          strUserName       the current user's name
  168. '*          strPassword       the current user's password
  169. '*          strOutputFile     an output file name
  170. '*
  171. '********************************************************************
  172. Private Function intParseCmdLine( ByRef strServer,        _
  173.                                   ByRef strUserName,      _
  174.                                   ByRef strPassword,      _
  175.                                   ByRef strOutputFile     )
  176.  
  177.  
  178.     ON ERROR RESUME NEXT
  179.  
  180.     Dim strFlag
  181.     Dim intState, intArgIter
  182.     Dim objFileSystem
  183.  
  184.     If Wscript.Arguments.Count > 0 Then
  185.         strFlag = Wscript.arguments.Item(0)
  186.     End If
  187.  
  188.     If IsEmpty(strFlag) Then                'No arguments have been received
  189.         intParseCmdLine = CONST_PROCEED
  190.         Exit Function
  191.     End If
  192.  
  193.     'Check if the user is asking for help or is just confused
  194.     If (strFlag="help") OR (strFlag="/h") OR (strFlag="\h") OR (strFlag="-h") _
  195.         OR (strFlag = "\?") OR (strFlag = "/?") OR (strFlag = "?") _ 
  196.         OR (strFlag="h") Then
  197.         intParseCmdLine = CONST_SHOW_USAGE
  198.         Exit Function
  199.     End If
  200.  
  201.     'Retrieve the command line and set appropriate variables
  202.      intArgIter = 0
  203.     Do While intArgIter <= Wscript.arguments.Count - 1
  204.         Select Case Left(LCase(Wscript.arguments.Item(intArgIter)),2)
  205.   
  206.             Case "/s"
  207.                 If Not blnGetArg("Server", strServer, intArgIter) Then
  208.                     intParseCmdLine = CONST_ERROR
  209.                     Exit Function
  210.                 End If
  211.                 intArgIter = intArgIter + 1
  212.  
  213.             Case "/o"
  214.                 If Not blnGetArg("Output File", strOutputFile, intArgIter) Then
  215.                     intParseCmdLine = CONST_ERROR
  216.                     Exit Function
  217.                 End If
  218.                 intArgIter = intArgIter + 1
  219.  
  220.             Case "/u"
  221.                 If Not blnGetArg("User Name", strUserName, intArgIter) Then
  222.                     intParseCmdLine = CONST_ERROR
  223.                     Exit Function
  224.                 End If
  225.                 intArgIter = intArgIter + 1
  226.  
  227.             Case "/w"
  228.                 If Not blnGetArg("User Password", strPassword, intArgIter) Then
  229.                     intParseCmdLine = CONST_ERROR
  230.                     Exit Function
  231.                 End If
  232.                 intArgIter = intArgIter + 1
  233.  
  234.             Case Else 'We shouldn't get here
  235.                 Call Wscript.Echo("Invalid or misplaced parameter: " _
  236.                    & Wscript.arguments.Item(intArgIter) & vbCRLF _
  237.                    & "Please check the input and try again," & vbCRLF _
  238.                    & "or invoke with '/?' for help with the syntax.")
  239.                 Wscript.Quit
  240.  
  241.         End Select
  242.  
  243.     Loop '** intArgIter <= Wscript.arguments.Count - 1
  244.  
  245.     If IsEmpty(intParseCmdLine) Then _
  246.         intParseCmdLine = CONST_PROCEED
  247.  
  248. End Function
  249.  
  250. '********************************************************************
  251. '*
  252. '* Sub ShowUsage()
  253. '*
  254. '* Purpose: Shows the correct usage to the user.
  255. '*
  256. '* Input:   None
  257. '*
  258. '* Output:  Help messages are displayed on screen.
  259. '*
  260. '********************************************************************
  261. Private Sub ShowUsage()
  262.  
  263.     Wscript.Echo ""
  264.     Wscript.Echo "Lists properties of all printers installed on a computer."
  265.     Wscript.Echo ""
  266.     Wscript.Echo "SYNTAX:"
  267.     Wscript.Echo "  ListOs.vbs [/S <server>] [/U <username>] [/W <password>]"
  268.     Wscript.Echo "              [/O <outputfile>]"
  269.     Wscript.Echo ""
  270.     Wscript.Echo "PARAMETER SPECIFIERS:"
  271.     Wscript.Echo "   server        A machine name."
  272.     Wscript.Echo "   username      The current user's name."
  273.     Wscript.Echo "   password      Password of the current user."
  274.     Wscript.Echo "   outputfile    The output file name."
  275.     Wscript.Echo ""
  276.     Wscript.Echo "EXAMPLE:"
  277.     Wscript.Echo "1. cscript ListPrinters.vbs"
  278.     Wscript.Echo "   List printer information for the current machine."
  279.     Wscript.Echo "2. cscript ListPrinters.vbs /S MyMachine2"
  280.     Wscript.Echo "   List printer information for the machine MyMachine2."
  281.  
  282. End Sub
  283.  
  284. '********************************************************************
  285. '* General Routines
  286. '********************************************************************
  287.  
  288. '********************************************************************
  289. '*
  290. '* Function strPackString()
  291. '*
  292. '* Purpose: Attaches spaces to a string to increase the length to intWidth.
  293. '*
  294. '* Input:   strString   a string
  295. '*          intWidth    the intended length of the string
  296. '*          blnAfter    Should spaces be added after the string?
  297. '*          blnTruncate specifies whether to truncate the string or not if
  298. '*                      the string length is longer than intWidth
  299. '*
  300. '* Output:  strPackString is returned as the packed string.
  301. '*
  302. '********************************************************************
  303. Private Function strPackString( ByVal strString, _
  304.                                 ByVal intWidth,  _
  305.                                 ByVal blnAfter,  _
  306.                                 ByVal blnTruncate)
  307.  
  308.     ON ERROR RESUME NEXT
  309.  
  310.     intWidth      = CInt(intWidth)
  311.     blnAfter      = CBool(blnAfter)
  312.     blnTruncate   = CBool(blnTruncate)
  313.  
  314.     If Err.Number Then
  315.         Call Wscript.Echo ("Argument type is incorrect!")
  316.         Err.Clear
  317.         Wscript.Quit
  318.     End If
  319.  
  320.     If IsNull(strString) Then
  321.         strPackString = "null" & Space(intWidth-4)
  322.         Exit Function
  323.     End If
  324.  
  325.     strString = CStr(strString)
  326.     If Err.Number Then
  327.         Call Wscript.Echo ("Argument type is incorrect!")
  328.         Err.Clear
  329.         Wscript.Quit
  330.     End If
  331.  
  332.     If intWidth > Len(strString) Then
  333.         If blnAfter Then
  334.             strPackString = strString & Space(intWidth-Len(strString))
  335.         Else
  336.             strPackString = Space(intWidth-Len(strString)) & strString & " "
  337.         End If
  338.     Else
  339.         If blnTruncate Then
  340.             strPackString = Left(strString, intWidth-1) & " "
  341.         Else
  342.             strPackString = strString & " "
  343.         End If
  344.     End If
  345.  
  346. End Function
  347.  
  348. '********************************************************************
  349. '* 
  350. '*  Function blnGetArg()
  351. '*
  352. '*  Purpose: Helper to intParseCmdLine()
  353. '* 
  354. '*  Usage:
  355. '*
  356. '*     Case "/s" 
  357. '*       blnGetArg ("server name", strServer, intArgIter)
  358. '*
  359. '********************************************************************
  360. Private Function blnGetArg ( ByVal StrVarName,   _
  361.                              ByRef strVar,       _
  362.                              ByRef intArgIter) 
  363.  
  364.     blnGetArg = False 'failure, changed to True upon successful completion
  365.  
  366.     If Len(Wscript.Arguments(intArgIter)) > 2 then
  367.         If Mid(Wscript.Arguments(intArgIter),3,1) = ":" then
  368.             If Len(Wscript.Arguments(intArgIter)) > 3 then
  369.                 strVar = Right(Wscript.Arguments(intArgIter), _
  370.                          Len(Wscript.Arguments(intArgIter)) - 3)
  371.                 blnGetArg = True
  372.                 Exit Function
  373.             Else
  374.                 intArgIter = intArgIter + 1
  375.                 If intArgIter > (Wscript.Arguments.Count - 1) Then
  376.                     Call Wscript.Echo( "Invalid " & StrVarName & ".")
  377.                     Call Wscript.Echo( "Please check the input and try again.")
  378.                     Exit Function
  379.                 End If
  380.  
  381.                 strVar = Wscript.Arguments.Item(intArgIter)
  382.                 If Err.Number Then
  383.                     Call Wscript.Echo( "Invalid " & StrVarName & ".")
  384.                     Call Wscript.Echo( "Please check the input and try again.")
  385.                     Exit Function
  386.                 End If
  387.  
  388.                 If InStr(strVar, "/") Then
  389.                     Call Wscript.Echo( "Invalid " & StrVarName)
  390.                     Call Wscript.Echo( "Please check the input and try again.")
  391.                     Exit Function
  392.                 End If
  393.  
  394.                 blnGetArg = True 'success
  395.             End If
  396.         Else
  397.             strVar = Right(Wscript.Arguments(intArgIter), _
  398.                      Len(Wscript.Arguments(intArgIter)) - 2)
  399.             blnGetArg = True 'success
  400.             Exit Function
  401.         End If
  402.     Else
  403.         intArgIter = intArgIter + 1
  404.         If intArgIter > (Wscript.Arguments.Count - 1) Then
  405.             Call Wscript.Echo( "Invalid " & StrVarName & ".")
  406.             Call Wscript.Echo( "Please check the input and try again.")
  407.             Exit Function
  408.         End If
  409.  
  410.         strVar = Wscript.Arguments.Item(intArgIter)
  411.         If Err.Number Then
  412.             Call Wscript.Echo( "Invalid " & StrVarName & ".")
  413.             Call Wscript.Echo( "Please check the input and try again.")
  414.             Exit Function
  415.         End If
  416.  
  417.         If InStr(strVar, "/") Then
  418.             Call Wscript.Echo( "Invalid " & StrVarName)
  419.             Call Wscript.Echo( "Please check the input and try again.")
  420.             Exit Function
  421.         End If
  422.         blnGetArg = True 'success
  423.     End If
  424. End Function
  425.  
  426. '********************************************************************
  427. '*
  428. '* Function blnConnect()
  429. '*
  430. '* Purpose: Connects to machine strServer.
  431. '*
  432. '* Input:   strServer       a machine name
  433. '*          strNameSpace    a namespace
  434. '*          strUserName     name of the current user
  435. '*          strPassword     password of the current user
  436. '*
  437. '* Output:  objService is returned  as a service object.
  438. '*          strServer is set to local host if left unspecified
  439. '*
  440. '********************************************************************
  441. Private Function blnConnect(ByVal strNameSpace, _
  442.                             ByVal strUserName,  _
  443.                             ByVal strPassword,  _
  444.                             ByRef strServer,    _
  445.                             ByRef objService)
  446.  
  447.     ON ERROR RESUME NEXT
  448.  
  449.     Dim objLocator, objWshNet
  450.  
  451.     blnConnect = False     'There is no error.
  452.  
  453.     'Create Locator object to connect to remote CIM object manager
  454.     Set objLocator = CreateObject("WbemScripting.SWbemLocator")
  455.     If Err.Number then
  456.         Call Wscript.Echo( "Error 0x" & CStr(Hex(Err.Number)) & _
  457.                            " occurred in creating a locator object." )
  458.         If Err.Description <> "" Then
  459.             Call Wscript.Echo( "Error description: " & Err.Description & "." )
  460.         End If
  461.         Err.Clear
  462.         blnConnect = True     'An error occurred
  463.         Exit Function
  464.     End If
  465.  
  466.     'Connect to the namespace which is either local or remote
  467.     Set objService = objLocator.ConnectServer (strServer, strNameSpace, _
  468.        strUserName, strPassword)
  469.     ObjService.Security_.impersonationlevel = 3
  470.     If Err.Number then
  471.         Call Wscript.Echo( "Error 0x" & CStr(Hex(Err.Number)) & _
  472.                            " occurred in connecting to server " _
  473.            & strServer & ".")
  474.         If Err.Description <> "" Then
  475.             Call Wscript.Echo( "Error description: " & Err.Description & "." )
  476.         End If
  477.         Err.Clear
  478.         blnConnect = True     'An error occurred
  479.     End If
  480.  
  481.     'Get the current server's name if left unspecified
  482.     If IsEmpty(strServer) Then
  483.         Set objWshNet = CreateObject("Wscript.Network")
  484.     strServer     = objWshNet.ComputerName
  485.     End If
  486.  
  487. End Function
  488.  
  489. '********************************************************************
  490. '*
  491. '* Sub      VerifyHostIsCscript()
  492. '*
  493. '* Purpose: Determines which program is used to run this script.
  494. '*
  495. '* Input:   None
  496. '*
  497. '* Output:  If host is not cscript, then an error message is printed 
  498. '*          and the script is aborted.
  499. '*
  500. '********************************************************************
  501. Sub VerifyHostIsCscript()
  502.  
  503.     ON ERROR RESUME NEXT
  504.  
  505.     Dim strFullName, strCommand, i, j, intStatus
  506.  
  507.     strFullName = WScript.FullName
  508.  
  509.     If Err.Number then
  510.         Call Wscript.Echo( "Error 0x" & CStr(Hex(Err.Number)) & " occurred." )
  511.         If Err.Description <> "" Then
  512.             Call Wscript.Echo( "Error description: " & Err.Description & "." )
  513.         End If
  514.         intStatus =  CONST_ERROR
  515.     End If
  516.  
  517.     i = InStr(1, strFullName, ".exe", 1)
  518.     If i = 0 Then
  519.         intStatus =  CONST_ERROR
  520.     Else
  521.         j = InStrRev(strFullName, "\", i, 1)
  522.         If j = 0 Then
  523.             intStatus =  CONST_ERROR
  524.         Else
  525.             strCommand = Mid(strFullName, j+1, i-j-1)
  526.             Select Case LCase(strCommand)
  527.                 Case "cscript"
  528.                     intStatus = CONST_CSCRIPT
  529.                 Case "wscript"
  530.                     intStatus = CONST_WSCRIPT
  531.                 Case Else       'should never happen
  532.                     Call Wscript.Echo( "An unexpected program was used to " _
  533.                                        & "run this script." )
  534.                     Call Wscript.Echo( "Only CScript.Exe or WScript.Exe can " _
  535.                                        & "be used to run this script." )
  536.                     intStatus = CONST_ERROR
  537.                 End Select
  538.         End If
  539.     End If
  540.  
  541.     If intStatus <> CONST_CSCRIPT Then
  542.         Call WScript.Echo( "Please run this script using CScript." & vbCRLF & _
  543.              "This can be achieved by" & vbCRLF & _
  544.              "1. Using ""CScript ListPrinters.vbs arguments"" for Windows 95/98 or" _
  545.              & vbCRLF & "2. Changing the default Windows Scripting Host " _
  546.              & "setting to CScript" & vbCRLF & "    using ""CScript " _
  547.              & "//H:CScript //S"" and running the script using" & vbCRLF & _
  548.              "    ""ListPrinters.vbs arguments"" for Windows NT/2000." )
  549.         WScript.Quit
  550.     End If
  551.  
  552. End Sub
  553.  
  554. '********************************************************************
  555. '*
  556. '* Sub WriteLine()
  557. '* Purpose: Writes a text line either to a file or on screen.
  558. '* Input:   strMessage  the string to print
  559. '*          objFile     an output file object
  560. '* Output:  strMessage is either displayed on screen or written to a file.
  561. '*
  562. '********************************************************************
  563. Sub WriteLine(ByVal strMessage, ByVal objFile)
  564.  
  565.     On Error Resume Next
  566.     If IsObject(objFile) then        'objFile should be a file object
  567.         objFile.WriteLine strMessage
  568.     Else
  569.         Call Wscript.Echo( strMessage )
  570.     End If
  571.  
  572. End Sub
  573.  
  574. '********************************************************************
  575. '* 
  576. '* Function blnErrorOccurred()
  577. '*
  578. '* Purpose: Reports error with a string saying what the error occurred in.
  579. '*
  580. '* Input:   strIn        string saying what the error occurred in.
  581. '*
  582. '* Output:  displayed on screen 
  583. '* 
  584. '********************************************************************
  585. Private Function blnErrorOccurred (ByVal strIn)
  586.  
  587.     If Err.Number Then
  588.         Call Wscript.Echo( "Error 0x" & CStr(Hex(Err.Number)) & ": " & strIn)
  589.         If Err.Description <> "" Then
  590.             Call Wscript.Echo( "Error description: " & Err.Description)
  591.         End If
  592.         Err.Clear
  593.         blnErrorOccurred = True
  594.     Else
  595.         blnErrorOccurred = False
  596.     End If
  597.  
  598. End Function
  599.  
  600. '********************************************************************
  601. '* 
  602. '* Function blnOpenFile
  603. '*
  604. '* Purpose: Opens a file.
  605. '*
  606. '* Input:   strFileName        A string with the name of the file.
  607. '*
  608. '* Output:  Sets objOpenFile to a FileSystemObject and setis it to 
  609. '*            Nothing upon Failure.
  610. '* 
  611. '********************************************************************
  612. Private Function blnOpenFile(ByVal strFileName, ByRef objOpenFile)
  613.  
  614.     ON ERROR RESUME NEXT
  615.  
  616.     Dim objFileSystem
  617.  
  618.     Set objFileSystem = Nothing
  619.  
  620.     If IsEmpty(strFileName) OR strFileName = "" Then
  621.         blnOpenFile = False
  622.         Set objOpenFile = Nothing
  623.         Exit Function
  624.     End If
  625.  
  626.     'Create a file object
  627.     Set objFileSystem = CreateObject("Scripting.FileSystemObject")
  628.     If blnErrorOccurred("Could not create filesystem object.") Then
  629.         blnOpenFile = False
  630.         Set objOpenFile = Nothing
  631.         Exit Function
  632.     End If
  633.  
  634.     'Open the file for output
  635.     Set objOpenFile = objFileSystem.OpenTextFile(strFileName, 8, True)
  636.     If blnErrorOccurred("Could not open") Then
  637.         blnOpenFile = False
  638.         Set objOpenFile = Nothing
  639.         Exit Function
  640.     End If
  641.     blnOpenFile = True
  642.  
  643. End Function
  644.  
  645. '********************************************************************
  646. '*                                                                  *
  647. '*                           End of File                            *
  648. '*                                                                  *
  649. '********************************************************************
  650.