VERSION 5.00
Object = "{6B7E6392-850A-101B-AFC0-4210102A8DA7}#1.3#0"; "COMCTL32.OCX"
Object = "{BDC217C8-ED16-11CD-956C-0000C04E4C0A}#1.1#0"; "TABCTL32.OCX"
Begin VB.Form frmMain 
   BorderStyle     =   1  'Fixed Single
   Caption         =   "Windows-Batch-Deployment Server Demonstration"
   ClientHeight    =   8535
   ClientLeft      =   45
   ClientTop       =   390
   ClientWidth     =   11895
   BeginProperty Font 
      Name            =   "Tahoma"
      Size            =   8.25
      Charset         =   0
      Weight          =   400
      Underline       =   0   'False
      Italic          =   0   'False
      Strikethrough   =   0   'False
   EndProperty
   LinkMode        =   1  'Source
   LinkTopic       =   "frmMain"
   MaxButton       =   0   'False
   ScaleHeight     =   8535
   ScaleWidth      =   11895
   StartUpPosition =   2  'CenterScreen
   Begin VB.Timer Timer2 
      Interval        =   100
      Left            =   0
      Top             =   0
   End
   Begin VB.Timer Timer1 
      Interval        =   1000
      Left            =   240
      Top             =   360
   End
   Begin VB.Frame Frame1 
      Caption         =   "Client"
      Height          =   2535
      Left            =   120
      TabIndex        =   9
      Top             =   120
      Width           =   11655
      Begin VB.CommandButton btnClient 
         Caption         =   "Uninstall"
         Height          =   255
         Index           =   5
         Left            =   10200
         TabIndex        =   5
         Top             =   2160
         Width           =   1335
      End
      Begin VB.CommandButton btnClient 
         Caption         =   "Update"
         Height          =   255
         Index           =   4
         Left            =   10200
         TabIndex        =   4
         Top             =   1920
         Width           =   1335
      End
      Begin VB.CommandButton btnClient 
         Caption         =   "Configure"
         Height          =   255
         Index           =   6
         Left            =   10200
         TabIndex        =   35
         Top             =   1680
         Width           =   1335
      End
      Begin VB.CommandButton btnClient 
         Caption         =   "Reboot"
         Height          =   255
         Index           =   3
         Left            =   10200
         TabIndex        =   3
         Top             =   1440
         Width           =   1335
      End
      Begin VB.CommandButton btnClient 
         Caption         =   "Shutdown"
         Height          =   255
         Index           =   2
         Left            =   10200
         TabIndex        =   2
         Top             =   1200
         Width           =   1335
      End
      Begin VB.CommandButton btnClient 
         Caption         =   "Disconnect"
         Height          =   255
         Index           =   1
         Left            =   10200
         TabIndex        =   1
         ToolTipText     =   "You cannot perform any operation after disconnecting the client."
         Top             =   960
         Width           =   1335
      End
      Begin VB.CommandButton btnClient 
         Caption         =   "Connect"
         Height          =   255
         Index           =   0
         Left            =   10200
         TabIndex        =   0
         ToolTipText     =   "You must connect to the client before performing any operation."
         Top             =   720
         Width           =   1335
      End
      Begin VB.CommandButton btnClient 
         Caption         =   "Refresh List"
         Height          =   255
         Index           =   7
         Left            =   10200
         TabIndex        =   37
         Top             =   240
         Width           =   1335
      End
      Begin VB.CheckBox Check1 
         Caption         =   "Automatically"
         Height          =   195
         Left            =   10200
         TabIndex        =   36
         Top             =   510
         Value           =   1  'Checked
         Width           =   1260
      End
      Begin ComctlLib.ListView lvClient 
         Height          =   2175
         Left            =   120
         TabIndex        =   10
         Top             =   240
         Width           =   9975
         _ExtentX        =   17595
         _ExtentY        =   3836
         View            =   3
         LabelEdit       =   1
         LabelWrap       =   -1  'True
         HideSelection   =   0   'False
         _Version        =   327682
         ForeColor       =   -2147483640
         BackColor       =   -2147483643
         BorderStyle     =   1
         Appearance      =   1
         BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
            Name            =   "Tahoma"
            Size            =   8.25
            Charset         =   0
            Weight          =   400
            Underline       =   0   'False
            Italic          =   0   'False
            Strikethrough   =   0   'False
         EndProperty
         NumItems        =   6
         BeginProperty ColumnHeader(1) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "ID"
            Object.Width           =   353
         EndProperty
         BeginProperty ColumnHeader(2) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   1
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "IP"
            Object.Width           =   3352
         EndProperty
         BeginProperty ColumnHeader(3) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   2
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "System"
            Object.Width           =   1764
         EndProperty
         BeginProperty ColumnHeader(4) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   3
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "Name"
            Object.Width           =   3706
         EndProperty
         BeginProperty ColumnHeader(5) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   4
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "Status"
            Object.Width           =   1764
         EndProperty
         BeginProperty ColumnHeader(6) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   5
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "Hash"
            Object.Width           =   2824
         EndProperty
      End
   End
   Begin TabDlg.SSTab SSTab1 
      Height          =   5655
      Left            =   120
      TabIndex        =   6
      Top             =   2760
      Width           =   11655
      _ExtentX        =   20558
      _ExtentY        =   9975
      _Version        =   393216
      Tabs            =   6
      TabsPerRow      =   6
      TabHeight       =   520
      BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
         Name            =   "Tahoma"
         Size            =   8.25
         Charset         =   0
         Weight          =   400
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      TabCaption(0)   =   "File"
      TabPicture(0)   =   "frmMain.frx":0000
      Tab(0).ControlEnabled=   -1  'True
      Tab(0).Control(0)=   "cmdFile(3)"
      Tab(0).Control(0).Enabled=   0   'False
      Tab(0).Control(1)=   "cmdFile(2)"
      Tab(0).Control(1).Enabled=   0   'False
      Tab(0).Control(2)=   "Frame2"
      Tab(0).Control(2).Enabled=   0   'False
      Tab(0).Control(3)=   "Frame3"
      Tab(0).Control(3).Enabled=   0   'False
      Tab(0).Control(4)=   "btnFile(1)"
      Tab(0).Control(4).Enabled=   0   'False
      Tab(0).Control(5)=   "btnFile(0)"
      Tab(0).Control(5).Enabled=   0   'False
      Tab(0).ControlCount=   6
      TabCaption(1)   =   "Registry"
      TabPicture(1)   =   "frmMain.frx":001C
      Tab(1).ControlEnabled=   0   'False
      Tab(1).Control(0)=   "txtTempRegData"
      Tab(1).Control(1)=   "btnOperate(19)"
      Tab(1).Control(2)=   "btnOperate(18)"
      Tab(1).Control(3)=   "txtRegPath"
      Tab(1).Control(4)=   "lvReg"
      Tab(1).ControlCount=   5
      TabCaption(2)   =   "Process"
      TabPicture(2)   =   "frmMain.frx":0038
      Tab(2).ControlEnabled=   0   'False
      Tab(2).Control(0)=   "lvProc"
      Tab(2).Control(1)=   "lvMod"
      Tab(2).ControlCount=   2
      TabCaption(3)   =   "Disk"
      TabPicture(3)   =   "frmMain.frx":0054
      Tab(3).ControlEnabled=   0   'False
      Tab(3).Control(0)=   "Frame10"
      Tab(3).Control(1)=   "Frame9"
      Tab(3).Control(2)=   "Frame8"
      Tab(3).Control(3)=   "Frame7"
      Tab(3).Control(4)=   "txtDiskInfo"
      Tab(3).ControlCount=   5
      TabCaption(4)   =   "Terminal"
      TabPicture(4)   =   "frmMain.frx":0070
      Tab(4).ControlEnabled=   0   'False
      Tab(4).Control(0)=   "txtCmdRet"
      Tab(4).Control(1)=   "txtCMD"
      Tab(4).Control(2)=   "btnOperate(2)"
      Tab(4).Control(3)=   "btnOperate(3)"
      Tab(4).ControlCount=   4
      TabCaption(5)   =   "Auto-Run"
      TabPicture(5)   =   "frmMain.frx":008C
      Tab(5).ControlEnabled=   0   'False
      Tab(5).Control(0)=   "Frame4"
      Tab(5).Control(1)=   "Frame5"
      Tab(5).Control(2)=   "Frame6"
      Tab(5).ControlCount=   3
      Begin VB.Frame Frame10 
         Caption         =   "Text Box"
         Height          =   1095
         Left            =   -65040
         TabIndex        =   79
         Top             =   420
         Width           =   1575
         Begin VB.CheckBox Check2 
            Caption         =   "Read Only"
            Height          =   255
            Left            =   120
            TabIndex        =   82
            Top             =   780
            Value           =   1  'Checked
            Width           =   1215
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Clear"
            Height          =   495
            Index           =   25
            Left            =   840
            TabIndex        =   81
            Top             =   240
            Width           =   615
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Copy"
            Height          =   495
            Index           =   24
            Left            =   120
            TabIndex        =   80
            Top             =   240
            Width           =   615
         End
      End
      Begin VB.Frame Frame9 
         Caption         =   "Partition Information"
         Height          =   1095
         Left            =   -74880
         TabIndex        =   77
         Top             =   420
         Width           =   1815
         Begin VB.CommandButton btnOperate 
            Caption         =   "Query"
            Height          =   795
            Index           =   4
            Left            =   120
            TabIndex        =   78
            Top             =   210
            Width           =   1575
         End
      End
      Begin VB.Frame Frame8 
         Caption         =   "Read Write Disk: Disk_Id | LB_Address | LB_Count | LB_Size"
         Height          =   1095
         Left            =   -69840
         TabIndex        =   66
         Top             =   420
         Width           =   4695
         Begin VB.CommandButton btnOperate 
            Caption         =   "-"
            Height          =   255
            Index           =   23
            Left            =   2040
            TabIndex        =   76
            ToolTipText     =   "LBA-1"
            Top             =   240
            Width           =   255
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "+"
            Height          =   255
            Index           =   22
            Left            =   1800
            TabIndex        =   75
            ToolTipText     =   "LBA+1"
            Top             =   240
            Width           =   255
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Write"
            Height          =   375
            Index           =   21
            Left            =   2400
            TabIndex        =   74
            ToolTipText     =   "Only allowed to write 1 logical block for testing, parameter ""LB_Count"" is ignored."
            Top             =   600
            Width           =   2175
         End
         Begin VB.TextBox txtLBS 
            Height          =   285
            Left            =   3600
            TabIndex        =   73
            Text            =   "512"
            Top             =   240
            Width           =   975
         End
         Begin VB.TextBox txtLBC 
            Height          =   285
            Left            =   2400
            TabIndex        =   72
            Text            =   "1"
            Top             =   240
            Width           =   1095
         End
         Begin VB.TextBox txtLBA 
            Height          =   285
            Left            =   600
            TabIndex        =   71
            Text            =   "0"
            Top             =   240
            Width           =   1215
         End
         Begin VB.TextBox txtDiskId 
            Height          =   285
            Left            =   120
            TabIndex        =   70
            Text            =   "0"
            Top             =   240
            Width           =   375
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Read"
            Height          =   375
            Index           =   20
            Left            =   120
            TabIndex        =   69
            Top             =   600
            Width           =   2175
         End
      End
      Begin VB.Frame Frame7 
         Caption         =   "File Layout Information"
         Height          =   1095
         Left            =   -72960
         TabIndex        =   65
         Top             =   420
         Width           =   3015
         Begin VB.CommandButton btnOperate 
            Caption         =   "Query"
            Height          =   375
            Index           =   5
            Left            =   120
            TabIndex        =   68
            Top             =   600
            Width           =   2775
         End
         Begin VB.TextBox txtFileForPos 
            Height          =   285
            Left            =   120
            TabIndex        =   67
            Text            =   "C:\WINDOWS\NOTEPAD.EXE"
            Top             =   240
            Width           =   2775
         End
      End
      Begin VB.TextBox txtDiskInfo 
         BeginProperty Font 
            Name            =   "Courier New"
            Size            =   9
            Charset         =   0
            Weight          =   400
            Underline       =   0   'False
            Italic          =   0   'False
            Strikethrough   =   0   'False
         EndProperty
         Height          =   3975
         Left            =   -74880
         Locked          =   -1  'True
         MultiLine       =   -1  'True
         ScrollBars      =   3  'Both
         TabIndex        =   64
         Top             =   1560
         Width           =   11415
      End
      Begin VB.CommandButton btnOperate 
         Caption         =   "Clear"
         Height          =   255
         Index           =   3
         Left            =   -64320
         TabIndex        =   61
         Top             =   420
         Width           =   855
      End
      Begin VB.CommandButton btnOperate 
         Caption         =   "Execute"
         Height          =   255
         Index           =   2
         Left            =   -65280
         TabIndex        =   60
         Top             =   420
         Width           =   855
      End
      Begin VB.TextBox txtCMD 
         Height          =   285
         Left            =   -74880
         TabIndex        =   59
         Text            =   "ipconfig"
         Top             =   420
         Width           =   9495
      End
      Begin VB.TextBox txtCmdRet 
         BeginProperty Font 
            Name            =   "Courier New"
            Size            =   9
            Charset         =   0
            Weight          =   400
            Underline       =   0   'False
            Italic          =   0   'False
            Strikethrough   =   0   'False
         EndProperty
         Height          =   4785
         Left            =   -74880
         Locked          =   -1  'True
         MultiLine       =   -1  'True
         ScrollBars      =   3  'Both
         TabIndex        =   58
         Top             =   750
         Width           =   11415
      End
      Begin VB.Frame Frame4 
         Caption         =   "Driver"
         Height          =   5055
         Left            =   -74880
         TabIndex        =   52
         Top             =   420
         Width           =   3735
         Begin VB.ListBox lstDrv 
            Height          =   4350
            Left            =   120
            TabIndex        =   57
            Top             =   240
            Width           =   3495
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Refresh"
            Height          =   255
            Index           =   6
            Left            =   120
            TabIndex        =   56
            Top             =   4680
            Width           =   855
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Add"
            Height          =   255
            Index           =   7
            Left            =   1080
            TabIndex        =   55
            Top             =   4680
            Width           =   735
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Delete"
            Height          =   255
            Index           =   8
            Left            =   1920
            TabIndex        =   54
            Top             =   4680
            Width           =   735
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Delete All"
            Height          =   255
            Index           =   9
            Left            =   2760
            TabIndex        =   53
            Top             =   4680
            Width           =   855
         End
      End
      Begin VB.Frame Frame5 
         Caption         =   "Program (EXE)"
         Height          =   5055
         Left            =   -71040
         TabIndex        =   46
         Top             =   420
         Width           =   3735
         Begin VB.ListBox lstExe 
            Height          =   4350
            Left            =   120
            TabIndex        =   51
            Top             =   240
            Width           =   3495
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Refresh"
            Height          =   255
            Index           =   10
            Left            =   120
            TabIndex        =   50
            Top             =   4680
            Width           =   855
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Add"
            Height          =   255
            Index           =   11
            Left            =   1080
            TabIndex        =   49
            Top             =   4680
            Width           =   735
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Delete"
            Height          =   255
            Index           =   12
            Left            =   1920
            TabIndex        =   48
            Top             =   4680
            Width           =   735
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Delete All"
            Height          =   255
            Index           =   13
            Left            =   2760
            TabIndex        =   47
            Top             =   4680
            Width           =   855
         End
      End
      Begin VB.Frame Frame6 
         Caption         =   "Program (DLL)"
         Height          =   5055
         Left            =   -67200
         TabIndex        =   40
         Top             =   420
         Width           =   3735
         Begin VB.CommandButton btnOperate 
            Caption         =   "Delete All"
            Height          =   255
            Index           =   17
            Left            =   2760
            TabIndex        =   45
            Top             =   4680
            Width           =   855
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Delete"
            Height          =   255
            Index           =   16
            Left            =   1920
            TabIndex        =   44
            Top             =   4680
            Width           =   735
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Add"
            Height          =   255
            Index           =   15
            Left            =   1080
            TabIndex        =   43
            Top             =   4680
            Width           =   735
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Refresh"
            Height          =   255
            Index           =   14
            Left            =   120
            TabIndex        =   42
            Top             =   4680
            Width           =   855
         End
         Begin VB.ListBox lstDLL 
            Height          =   4350
            Left            =   120
            TabIndex        =   41
            Top             =   240
            Width           =   3495
         End
      End
      Begin VB.CommandButton btnFile 
         Caption         =   "Upload"
         Height          =   495
         Index           =   0
         Left            =   120
         TabIndex        =   39
         Top             =   4980
         Width           =   1815
      End
      Begin VB.CommandButton btnFile 
         Caption         =   "Download"
         Height          =   495
         Index           =   1
         Left            =   2040
         TabIndex        =   38
         Top             =   4980
         Width           =   1815
      End
      Begin VB.TextBox txtTempRegData 
         Height          =   285
         Left            =   -65400
         TabIndex        =   34
         Top             =   960
         Visible         =   0   'False
         Width           =   1815
      End
      Begin VB.CommandButton btnOperate 
         Caption         =   "Go To P.D"
         Height          =   255
         Index           =   19
         Left            =   -64560
         TabIndex        =   23
         ToolTipText     =   "Return to the parent directory"
         Top             =   420
         Width           =   1095
      End
      Begin VB.CommandButton btnOperate 
         Caption         =   "Go To"
         Height          =   255
         Index           =   18
         Left            =   -65280
         TabIndex        =   22
         Top             =   420
         Width           =   615
      End
      Begin VB.TextBox txtRegPath 
         Height          =   285
         Left            =   -74880
         TabIndex        =   21
         Text            =   "\Registry"
         Top             =   420
         Width           =   9495
      End
      Begin VB.Frame Frame3 
         Caption         =   "Remote"
         Height          =   5055
         Left            =   3960
         TabIndex        =   15
         Top             =   420
         Width           =   7575
         Begin VB.CommandButton btnFile 
            Caption         =   "create new file"
            Height          =   255
            Index           =   11
            Left            =   6000
            TabIndex        =   33
            Tag             =   "http://libevent.org/sm-web-appnexus-logo.png"
            Top             =   4680
            Visible         =   0   'False
            Width           =   1455
         End
         Begin VB.CommandButton btnFile 
            Caption         =   "CRC32"
            Height          =   255
            Index           =   9
            Left            =   5280
            TabIndex        =   31
            Tag             =   "http://libevent.org/sm-web-appnexus-logo.png"
            Top             =   4680
            Visible         =   0   'False
            Width           =   735
         End
         Begin VB.CommandButton btnFile 
            Caption         =   "Get Attr"
            Height          =   255
            Index           =   7
            Left            =   4560
            TabIndex        =   25
            Top             =   4680
            Visible         =   0   'False
            Width           =   735
         End
         Begin VB.CommandButton btnFile 
            Caption         =   "delay move/del"
            Height          =   255
            Index           =   10
            Left            =   6000
            TabIndex        =   32
            Tag             =   "http://libevent.org/sm-web-appnexus-logo.png"
            Top             =   4440
            Visible         =   0   'False
            Width           =   1455
         End
         Begin VB.CommandButton btnFile 
            Caption         =   "Rename"
            Height          =   255
            Index           =   5
            Left            =   3840
            TabIndex        =   27
            Top             =   4680
            Visible         =   0   'False
            Width           =   735
         End
         Begin VB.CommandButton btnFile 
            Caption         =   "HTTP"
            Height          =   255
            Index           =   8
            Left            =   5280
            TabIndex        =   24
            Tag             =   "http://libevent.org/sm-web-appnexus-logo.png"
            Top             =   4440
            Visible         =   0   'False
            Width           =   735
         End
         Begin VB.CommandButton btnFile 
            Caption         =   "Set Attr"
            Height          =   255
            Index           =   6
            Left            =   4560
            TabIndex        =   26
            Top             =   4440
            Visible         =   0   'False
            Width           =   735
         End
         Begin VB.CommandButton btnFile 
            Caption         =   "Delete"
            Height          =   255
            Index           =   4
            Left            =   3840
            TabIndex        =   28
            Top             =   4440
            Visible         =   0   'False
            Width           =   735
         End
         Begin VB.CommandButton btnFile 
            Caption         =   "Copy"
            Height          =   255
            Index           =   3
            Left            =   3120
            TabIndex        =   29
            Top             =   4680
            Visible         =   0   'False
            Width           =   735
         End
         Begin VB.CommandButton btnFile 
            Caption         =   "new dir"
            Height          =   255
            Index           =   2
            Left            =   3120
            TabIndex        =   30
            Top             =   4440
            Visible         =   0   'False
            Width           =   735
         End
         Begin ComctlLib.ListView lvFile 
            Height          =   4350
            Left            =   120
            TabIndex        =   19
            ToolTipText     =   "Double click to open directory or execute program."
            Top             =   600
            Width           =   7335
            _ExtentX        =   12938
            _ExtentY        =   7673
            View            =   3
            LabelEdit       =   1
            LabelWrap       =   -1  'True
            HideSelection   =   0   'False
            _Version        =   327682
            ForeColor       =   -2147483640
            BackColor       =   -2147483643
            BorderStyle     =   1
            Appearance      =   1
            BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
               Name            =   "Tahoma"
               Size            =   8.25
               Charset         =   0
               Weight          =   400
               Underline       =   0   'False
               Italic          =   0   'False
               Strikethrough   =   0   'False
            EndProperty
            NumItems        =   3
            BeginProperty ColumnHeader(1) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
               Key             =   ""
               Object.Tag             =   ""
               Text            =   "Name"
               Object.Width           =   5645
            EndProperty
            BeginProperty ColumnHeader(2) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
               SubItemIndex    =   1
               Key             =   ""
               Object.Tag             =   ""
               Text            =   "Size"
               Object.Width           =   2469
            EndProperty
            BeginProperty ColumnHeader(3) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
               SubItemIndex    =   2
               Key             =   ""
               Object.Tag             =   ""
               Text            =   "Last Modify Time"
               Object.Width           =   2645
            EndProperty
         End
         Begin VB.TextBox txtFilePath 
            Height          =   285
            Left            =   120
            TabIndex        =   18
            Text            =   "\"
            Top             =   240
            Width           =   5415
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Go To"
            Height          =   255
            Index           =   0
            Left            =   5640
            TabIndex        =   17
            Top             =   240
            Width           =   615
         End
         Begin VB.CommandButton btnOperate 
            Caption         =   "Go To P.D"
            Height          =   255
            Index           =   1
            Left            =   6360
            TabIndex        =   16
            ToolTipText     =   "Return to the parent directory"
            Top             =   240
            Width           =   1095
         End
      End
      Begin VB.Frame Frame2 
         Caption         =   "Local"
         Height          =   4515
         Left            =   120
         TabIndex        =   11
         Top             =   420
         Width           =   3735
         Begin VB.DriveListBox Drive1 
            Appearance      =   0  'Flat
            Height          =   315
            Left            =   120
            TabIndex        =   14
            Top             =   240
            Width           =   3495
         End
         Begin VB.DirListBox Dir1 
            Height          =   1665
            Left            =   120
            TabIndex        =   13
            ToolTipText     =   "Right-click to refresh."
            Top             =   600
            Width           =   3495
         End
         Begin VB.FileListBox File1 
            Height          =   2040
            Left            =   120
            TabIndex        =   12
            ToolTipText     =   "Right-click to refresh."
            Top             =   2340
            Width           =   3495
         End
      End
      Begin VB.CommandButton cmdFile 
         Caption         =   "Download"
         Height          =   375
         Index           =   2
         Left            =   720
         TabIndex        =   8
         Top             =   7140
         Width           =   1215
      End
      Begin VB.CommandButton cmdFile 
         Caption         =   "Upload"
         Height          =   375
         Index           =   3
         Left            =   2040
         TabIndex        =   7
         Top             =   7140
         Width           =   1215
      End
      Begin ComctlLib.ListView lvReg 
         Height          =   4815
         Left            =   -74880
         TabIndex        =   20
         ToolTipText     =   "Double click to open key or edit value."
         Top             =   750
         Width           =   11415
         _ExtentX        =   20135
         _ExtentY        =   8493
         View            =   3
         LabelEdit       =   1
         LabelWrap       =   -1  'True
         HideSelection   =   0   'False
         _Version        =   327682
         ForeColor       =   -2147483640
         BackColor       =   -2147483643
         BorderStyle     =   1
         Appearance      =   1
         BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
            Name            =   "Tahoma"
            Size            =   8.25
            Charset         =   0
            Weight          =   400
            Underline       =   0   'False
            Italic          =   0   'False
            Strikethrough   =   0   'False
         EndProperty
         NumItems        =   4
         BeginProperty ColumnHeader(1) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "Type"
            Object.Width           =   2469
         EndProperty
         BeginProperty ColumnHeader(2) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   1
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "Name"
            Object.Width           =   4939
         EndProperty
         BeginProperty ColumnHeader(3) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   2
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "Data"
            Object.Width           =   9347
         EndProperty
         BeginProperty ColumnHeader(4) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   3
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "Length"
            Object.Width           =   706
         EndProperty
      End
      Begin ComctlLib.ListView lvProc 
         Height          =   2535
         Left            =   -74880
         TabIndex        =   62
         ToolTipText     =   "Double click to view process module"
         Top             =   420
         Width           =   11415
         _ExtentX        =   20135
         _ExtentY        =   4471
         View            =   3
         LabelEdit       =   1
         LabelWrap       =   -1  'True
         HideSelection   =   0   'False
         _Version        =   327682
         ForeColor       =   -2147483640
         BackColor       =   -2147483643
         BorderStyle     =   1
         Appearance      =   1
         BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
            Name            =   "Tahoma"
            Size            =   8.25
            Charset         =   0
            Weight          =   400
            Underline       =   0   'False
            Italic          =   0   'False
            Strikethrough   =   0   'False
         EndProperty
         NumItems        =   3
         BeginProperty ColumnHeader(1) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "EPROCESS"
            Object.Width           =   3175
         EndProperty
         BeginProperty ColumnHeader(2) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   1
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "PID"
            Object.Width           =   1587
         EndProperty
         BeginProperty ColumnHeader(3) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   2
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "PATH"
            Object.Width           =   13229
         EndProperty
      End
      Begin ComctlLib.ListView lvMod 
         Height          =   2535
         Left            =   -74880
         TabIndex        =   63
         Top             =   3000
         Width           =   11415
         _ExtentX        =   20135
         _ExtentY        =   4471
         View            =   3
         LabelEdit       =   1
         LabelWrap       =   -1  'True
         HideSelection   =   0   'False
         _Version        =   327682
         ForeColor       =   -2147483640
         BackColor       =   -2147483643
         BorderStyle     =   1
         Appearance      =   1
         BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
            Name            =   "Tahoma"
            Size            =   8.25
            Charset         =   0
            Weight          =   400
            Underline       =   0   'False
            Italic          =   0   'False
            Strikethrough   =   0   'False
         EndProperty
         NumItems        =   3
         BeginProperty ColumnHeader(1) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "Base"
            Object.Width           =   3175
         EndProperty
         BeginProperty ColumnHeader(2) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   1
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "Size"
            Object.Width           =   1587
         EndProperty
         BeginProperty ColumnHeader(3) {0713E8C7-850A-101B-AFC0-4210102A8DA7} 
            SubItemIndex    =   2
            Key             =   ""
            Object.Tag             =   ""
            Text            =   "Path"
            Object.Width           =   13229
         EndProperty
      End
   End
   Begin VB.Menu mnuClient 
      Caption         =   "mnuClient"
      Visible         =   0   'False
      Begin VB.Menu mnuCO 
         Caption         =   "Get Time"
         Index           =   0
      End
      Begin VB.Menu mnuCO 
         Caption         =   "Set Time"
         Index           =   1
      End
   End
   Begin VB.Menu mnuFile 
      Caption         =   "mnuFile"
      Visible         =   0   'False
      Begin VB.Menu mnuFSO 
         Caption         =   "Create File..."
         Index           =   0
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "Create Folder..."
         Index           =   1
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "-"
         Index           =   2
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "Copy..."
         Index           =   3
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "Delete..."
         Index           =   4
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "Rename..."
         Index           =   5
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "-"
         Index           =   6
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "Set Attribute..."
         Index           =   7
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "Get Attribute..."
         Index           =   8
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "-"
         Index           =   9
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "Download from HTTP link..."
         Index           =   10
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "-"
         Index           =   11
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "Get File CRC32..."
         Index           =   12
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "-"
         Index           =   13
      End
      Begin VB.Menu mnuFSO 
         Caption         =   "Delete / Rename after Reboot..."
         Index           =   14
      End
   End
   Begin VB.Menu mnuReg 
      Caption         =   "mnuReg"
      Visible         =   0   'False
      Begin VB.Menu mnuRGO 
         Caption         =   "Create Key..."
         Index           =   0
      End
      Begin VB.Menu mnuRGO 
         Caption         =   "Create Value..."
         Index           =   1
      End
      Begin VB.Menu mnuRGO 
         Caption         =   "-"
         Index           =   2
      End
      Begin VB.Menu mnuRGO 
         Caption         =   "Rename..."
         Index           =   3
      End
      Begin VB.Menu mnuRGO 
         Caption         =   "Delete..."
         Index           =   4
      End
   End
   Begin VB.Menu mnuProc 
      Caption         =   "mnuProc"
      Visible         =   0   'False
      Begin VB.Menu mnuPRO 
         Caption         =   "Refresh"
         Index           =   0
      End
      Begin VB.Menu mnuPRO 
         Caption         =   "-"
         Index           =   1
      End
      Begin VB.Menu mnuPRO 
         Caption         =   "Kill Process..."
         Index           =   2
      End
   End
   Begin VB.Menu mnuProcMod 
      Caption         =   "mnuProcMod"
      Visible         =   0   'False
      Begin VB.Menu mnuPMO 
         Caption         =   "Refresh"
         Index           =   0
      End
      Begin VB.Menu mnuPMO 
         Caption         =   "-"
         Index           =   1
      End
      Begin VB.Menu mnuPMO 
         Caption         =   "Load Module..."
         Index           =   2
      End
   End
End
Attribute VB_Name = "frmMain"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
'/*
'    Author:      Axt Mueller
'    Description: Windows-Batch-Deployment Server Demonstration.
'*/
Option Explicit

'################################################################################
' WIN32API CONSTANT
'################################################################################
Private Const MEM_RELEASE As Long = &H8000
Private Const SW_SHOW As Long = 5
Private Const LVM_FIRST As Long = &H1000
Private Const LVS_EX_FULLROWSELECT As Long = &H20
Private Const LVM_SETEXTENDEDLISTVIEWSTYLE As Long = LVM_FIRST + 54
Private Const LVM_GETEXTENDEDLISTVIEWSTYLE As Long = LVM_FIRST + 55

'################################################################################
' WIN32API STRUCTURE
'################################################################################
Private Type SYSTEMTIME
    wYear As Integer
    wMonth As Integer
    wDayOfWeek As Integer
    wDay As Integer
    wHour As Integer
    wMinute As Integer
    wSecond As Integer
    wMilliseconds As Integer
End Type

'################################################################################
' WIN32API DECLARATION
'################################################################################
Private Declare Sub ExitProcess Lib "kernel32" (ByVal dwExitCode As Long)
Private Declare Sub memcpy Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
Private Declare Function VirtualAlloc Lib "kernel32" (ByVal dwAddr As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flNewProtect As Long) As Long
Private Declare Function VirtualFree Lib "kernel32" (ByVal dwAddr As Long, ByVal dwSize As Long, ByVal dwType As Long) As Long
Private Declare Function VirtualProtect Lib "kernel32" (ByVal dwAddr As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, ByRef lpflOldProtect As Long) As Long
Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function lstrcpyA Lib "kernel32" (ByVal lpString1 As Long, ByVal lpString2 As Long) As Long
Private Declare Function lstrcpyW Lib "kernel32" (ByVal lpString1 As Long, ByVal lpString2 As Long) As Long
Private Declare Function SendMessageA Lib "user32" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function MessageBoxA Lib "user32" (ByVal hWnd As Long, ByVal txt As Long, ByVal title As Long, ByVal dwType As Long) As Long
Private Declare Function MessageBoxW Lib "user32" (ByVal hWnd As Long, ByVal txt As Long, ByVal title As Long, ByVal dwType As Long) As Long
Private Declare Function LoadLibraryA Lib "kernel32.dll" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32.dll" (ByVal hModule As Long, ByVal lpProcName As String) As Long

'################################################################################
' WINDOWS BATCH DEPLOYMENT CONSTANT
'################################################################################
Private Const SERVER_MAX_CLIENTS As Long = 4096
Private Const CLIENT_CONFIG_SERVER As Long = 0
Private Const CLIENT_STATUS_ONLINE As String = "online"
Private Const CLIENT_STATUS_OFFLINE As String = "offline"
Private Const CLIENT_STATUS_CONNECTED As String = "connected"
Private Const CLIENT_AUTORUN_EMPTY As String = "((LEER))"
Private Const CLIENT_AUTORUN_TYPE_SYS As Long = 0
Private Const CLIENT_AUTORUN_TYPE_EXE As Long = 1
Private Const CLIENT_AUTORUN_TYPE_DLL As Long = 2
Private Const CLIENT_RUN_DLL_P1 As Byte = &HFE
Private Const CLIENT_RUN_DLL_P2 As Long = &HFFFFFFFF
Private Const CLIENT_RUN_SYS_P1 As Byte = &HFF
Private Const CLIENT_RUN_SYS_P2 As Long = &HFFFFFFFF
Private Const CLIENT_FSO_CREATE_FILE As Long = 0
Private Const CLIENT_FSO_CREATE_DIRECTORY As Long = 1
Private Const CLIENT_FSO_COPY As Long = 2
Private Const CLIENT_FSO_DELETE As Long = 3
Private Const CLIENT_FSO_RENAME As Long = 4
Private Const CLIENT_FSO_SET_ATTRIB As Long = 5
Private Const CLIENT_FSO_GET_ATTRIB As Long = 6
Private Const CLIENT_FSO_HTTP_DOWNLOAD As Long = 7
Private Const CLIENT_FSO_GET_CRC32 As Long = 8
Private Const CLIENT_FSO_DELAY_MOV_DEL As Long = 9
Private Const CLIENT_REG_CREATE_KEY As Long = 0
Private Const CLIENT_REG_DELETE_KEY As Long = 1
Private Const CLIENT_REG_RENAME_KEY As Long = 2
Private Const CLIENT_REG_DELETE_VALUE As Long = 3
Private Const CLIENT_REG_QUERY_VALUE As Long = 4
Private Const CLIENT_REG_SET_VALUE As Long = 5
Private Const CLIENT_QSI_QUERY_TICK_TIME = 0
Private Const CLIENT_QSI_ENUM_PROCESS = 1
Private Const CLIENT_QSI_ENUM_PROC_MOD = 2
Private Const CLIENT_SSI_SET_LOCAL_TIME = 100
Private Const CLIENT_SSI_KILL_PROCESS = 101
Private Const CLIENT_SSI_INJECT_DLL = 102
Private Const CLIENT_DISK_QUERY_PARTITION = 0
Private Const CLIENT_DISK_QUERY_FILE_POS = 1
Private Const CLIENT_DISK_READ_SECTOR = 2
Private Const CLIENT_DISK_WRITE_SECTOR = 3

'################################################################################
' WINDOWS BATCH DEPLOYMENT STRUCTURE DECLARATION
'################################################################################
Private Type SENDRECV_CALLBACK
    id As Long          'Client Id.
    reserved As Long    'Internal use.
    callback As Long    'User-defined function that conforms to prototype SENDRECVCALLBACK.
End Type

Private Type CLIENT_INFO
    id As Long
    hash_low As Long
    hash_high As Long
    szAddr(31) As Byte
    szStatus(31) As Byte
    szDescription(51) As Byte
End Type

Private Type BDP_FILE_TIME
    Year As Integer
    Month As Byte
    Day As Byte
    Hour As Byte
    Minute As Byte
    Second As Byte
    Weekday As Byte
End Type

Private Type BDP_FILE_INFO
    FileModifyTime As BDP_FILE_TIME
    FileSizeLow As Long
    FileSizeHigh As Long
    FileName(247) As Integer
End Type

Private Type BDP_REG_INFO
    ItemType As Byte         'Such as REG_SZ, REG_KEY = 0xFF.
    NameTooLong As Byte      'If name length > 255, it will be set to 1.
    reserved(1)  As Byte
    DataLength As Long
    ItemName(255) As Integer 'Information from MSDN: KEY_NAME_MAX_LENGTH = 255, VALUE_NAME_MAX_LENGTH = 16383.
    Data(503) As Byte        'If the data length is too long, nothing will be copied to this buffer.
End Type

Private Type BDP_DISK_QUERY_READ_WRITE_FILE
    Path(259) As Integer
    buffer(0) As Byte
End Type

Private Type BDP_DISK_QUERY_READ_WRITE
    PartitionId_or_DiskId As Long
    LBA As Currency
    CountLBA As Long
    SectorSize As Long
    unused(499) As Byte
    buffer(511) As Byte
    '"buffer" member is a dynamic array in C definition,
    'its size can be an integer multiple of SectorSize (it would be N*512 in most cases),
    'because it is not allowed to define a variable length structure in VB6,
    'in order to facilitate testing, I set a fixed size to 512 bytes.
End Type

Private Type BDP_PARTITION_INFO
    DiskId As Long
    SectorsPerCluster As Long
    BytesPerSector As Long
    'there is nothing like "#pragma pack(1)" in VB6,
    'so I have to use a 18 bytes buffer to represent following members.
    buffer(17) As Byte
    'DosDevice As Integer
    'StartingOffset As Currency
    'ExtentLength As Currency
End Type

Private Type BDP_SECTION
    Begin As Currency
    End As Currency
End Type

Private Type BDP_FILE_CLUSTERS
    DiskId As Long
    PartitionId As Long
    SectorsPerCluster As Long
    BytesPerSector As Long
    SectionCount As Long
    PartitionStartingOffset As Currency
    MftStartingOffset As Currency
    FileSize As Currency
    Sections(254) As BDP_SECTION
    '"Sections" member is a dynamic array in C definition, its size can be any amount,
    'because it is not allowed to define a variable length structure in VB6,
    'in order to facilitate testing, I set its size to 254*sizeof(BDP_SECTION).
End Type

Private Type BDP_SI_SYSTEM_TIME
    TickCount As Currency
    LocalTime As SYSTEMTIME
End Type

Private Type BDP_SI_PROCESS_INFO
    Object As Currency
    id As Currency
    Path(259) As Integer
End Type

Private Type BDP_SI_PROCESS_MOD_INFO
    Base As Currency
    Size As Currency
    Path(259) As Integer
End Type

'################################################################################
' WINDOWS BATCH DEPLOYMENT API DECLARATION
'################################################################################
Private Declare Function init Lib "Server32.dll" (ByVal port As Long) As Byte
Private Declare Function uninit Lib "Server32.dll" () As Byte
Private Declare Function ClientList Lib "Server32.dll" (ByVal pInfoAddress As Long) As Long
Private Declare Function ClientConnect Lib "Server32.dll" (ByVal id As Long) As Byte
Private Declare Function ClientDisconnect Lib "Server32.dll" (ByVal id As Long) As Byte
Private Declare Function ClientTest Lib "Server32.dll" (ByVal id As Long, ByVal pVersion As Long) As Byte
Private Declare Function ClientReboot Lib "Server32.dll" (ByVal id As Long) As Byte
Private Declare Function ClientShutdown Lib "Server32.dll" (ByVal id As Long) As Byte
Private Declare Function ClientUpdate Lib "Server32.dll" (ByVal id As Long, ByVal wsLocalFile As Long) As Byte
Private Declare Function ClientConfig Lib "Server32.dll" (ByVal id As Long, ByVal ConfigId As Byte, ByVal wsLocalConfigFilePath As Long) As Byte
Private Declare Function CmdQueryDirectory Lib "Server32.dll" (ByVal id As Long, ByVal wsPath As Long, ByVal pStructAddress As Long, ByRef pCount As Long) As Byte
Private Declare Function CmdUploadFileTo Lib "Server32.dll" (ByVal id As Long, ByVal wsLocalFile As Long, ByVal wsRemoteSaveTo As Long, ByVal pCallback As Long) As Byte
Private Declare Function CmdDownloadFileFrom Lib "Server32.dll" (ByVal id As Long, ByVal wsRemoteFile As Long, ByVal wsLocalSaveTo As Long, ByVal pCallback As Long) As Byte
Private Declare Function CmdExecuteBinary Lib "Server32.dll" (ByVal id As Long, ByVal wsPath As Long, ByVal wndmode As Byte, ByVal waittmo As Long, ByRef pRetVal As Currency) As Byte
Private Declare Function CmdSystemShell Lib "Server32.dll" (ByVal id As Long, ByVal wsParam As Long, ByVal szBuffer As Long, ByVal Length As Long) As Byte
Private Declare Function CmdFileOperation Lib "Server32.dll" (ByVal id As Long, ByVal fn As Byte, ByVal wsPath1 As Long, ByVal wsPath2 As Long, ByRef pRetVal As Long) As Byte
Private Declare Function CmdAddAutoRunBin Lib "Server32.dll" (ByVal id As Long, ByVal bType As Byte, ByVal wsName As Long, ByVal wsPath As Long, ByVal wsParam As Long) As Byte
Private Declare Function CmdDelAutoRunBin Lib "Server32.dll" (ByVal id As Long, ByVal bType As Byte, ByVal wsName As Long) As Byte
Private Declare Function CmdQueryAutoRunBin Lib "Server32.dll" (ByVal id As Long, ByVal bType As Byte, ByVal ppNames As Long) As Byte
Private Declare Function CmdClearAutoRunBin Lib "Server32.dll" (ByVal id As Long, ByVal bType As Byte) As Byte
Private Declare Function CmdQueryRegistry Lib "Server32.dll" (ByVal id As Long, ByVal wsPath As Long, ByVal pStructAddress As Long, ByRef pCount As Long) As Byte
Private Declare Function CmdRegistryOperation Lib "Server32.dll" (ByVal id As Long, ByVal fn As Byte, ByVal wsPath As Long, ByVal wsName As Long, ByRef pType As Long, ByVal pBuffer As Long, ByRef pLength As Long) As Byte
Private Declare Function CmdQuerySetSystemInformation Lib "Server32.dll" (ByVal id As Long, ByVal fn As Byte, ByVal pIn As Long, ByVal pInLen As Long, ByVal pOut As Long, ByRef pOutLen As Long) As Byte
Private Declare Function CmdReadWriteDisk Lib "Server32.dll" (ByVal id As Long, ByVal fn As Byte, ByVal pParam As Long, ByVal pOut As Long, ByRef pLength As Long) As Byte
Private Declare Function UpdateClient Lib "Server32.dll" (ByVal LastestVersion As String, ByVal SaveTo32 As String, ByVal SaveTo64 As String) As Byte
Private Declare Function UpdateServer Lib "Server32.dll" (ByVal CurrentVersion As String, ByVal LastestVersion As String, ByVal SaveTo32 As String, ByVal SaveTo64 As String) As Byte

'################################################################################
' DEMONSTRATION PROGRAM CODE
'################################################################################
Private Function Hexx(ByVal v As Variant, Optional ByVal minlen As Long = 2) As String
    Dim s As String
    s = Hex$(v) ':Hexx = IIf(Len(s) = 1, "0" & s, s)
    If Len(s) < minlen Then
        Hexx = String(minlen - Len(s), "0") & s
    Else
        Hexx = s
    End If
End Function

Private Function sz2bstr(ByRef ba() As Byte) As String
    sz2bstr = StrConv(ba, vbUnicode, 0)
End Function

Private Function StrFromPtr(ByVal lpString As Long, Optional bUnicode As Boolean = False) As String
    On Error Resume Next
    If bUnicode Then
        StrFromPtr = String(lstrlenW(lpString), Chr(0))
        lstrcpyW StrPtr(StrFromPtr), ByVal lpString
    Else
        StrFromPtr = String(lstrlenA(lpString), Chr(0))
        lstrcpyA ByVal StrFromPtr, ByVal lpString
    End If
End Function

Private Function GetParentDirectory(ByVal szPath As String) As String
    Dim i As Long
    Dim sa() As String
    Dim sz As String: sz = ""
    If Trim$(szPath) <> "\" Then
        sa = Split(szPath, "\")
        If UBound(sa) = 1 And Len(szPath) = 3 Then
            sz = "\"
        Else
            For i = 0 To UBound(sa) - 1
                sz = sz & sa(i) & "\"
            Next
            If Len(sz) > 3 Then
                sz = Left$(sz, Len(sz) - 1)
            End If
        End If
    Else
        sz = "\"
    End If
    GetParentDirectory = sz
End Function

Private Function GetNameFromPath(ByVal szPath As String) As String
    On Error GoTo errHandler
    Dim sa() As String
    sa = Split(szPath, "\")
    GetNameFromPath = sa(UBound(sa))
    Exit Function
errHandler:
    GetNameFromPath = ""
End Function

Private Function GetNameFromURL(ByVal szPath As String) As String
    On Error GoTo errHandler
    Dim sa() As String
    sa = Split(szPath, "/")
    GetNameFromURL = sa(UBound(sa))
    Exit Function
errHandler:
    GetNameFromURL = ""
End Function

Private Sub AddClientInfo(ByRef lv As ListView, ByVal id As Long, ByVal ip As String, ByVal desc As String, _
                            ByVal status As String, ByVal hash_lo As Long, ByVal hash_hi As Long)
    Dim ltmItem As ListItem
    Set ltmItem = lv.ListItems.Add()
    ltmItem.Text = CStr(id)
    ltmItem.SubItems(1) = ip
    ltmItem.SubItems(2) = Mid(desc, 2, InStr(desc, ")") - 2)
    ltmItem.SubItems(3) = Mid(desc, InStr(desc, ")") + 1)
    ltmItem.SubItems(4) = Replace$(status, " ", "") ': MsgBox Len(ltmItem.SubItems(4))
    Dim szlo As String: szlo = Hex$(hash_lo)
    Dim szhi As String: szhi = Hex$(hash_hi)
    ltmItem.SubItems(5) = String(8 - Len(szhi), "0") & szhi & String(8 - Len(szlo), "0") & szlo
End Sub

Private Sub AddFileInfo(ByRef lv As ListView, ByRef FileInfo As BDP_FILE_INFO)
    Dim ltmItem As ListItem
    Dim szFileName As String
    szFileName = StrFromPtr(VarPtr(FileInfo) + 16, True)
    If szFileName <> "." Then
        Set ltmItem = lv.ListItems.Add()
        ltmItem.Text = szFileName
        If FileInfo.FileSizeLow = &HFFFFFFFF And FileInfo.FileSizeLow = &HFFFFFFFF Then
            If FileInfo.FileModifyTime.Year = &HFFFF And FileInfo.FileModifyTime.Month = &HFF And FileInfo.FileModifyTime.Day = &HFF And _
                FileInfo.FileModifyTime.Hour = &HFF And FileInfo.FileModifyTime.Minute = &HFF And FileInfo.FileModifyTime.Second = &HFF And _
                FileInfo.FileModifyTime.Weekday = &HFF Then
                ltmItem.SubItems(1) = "<Drive>"
                ltmItem.SubItems(2) = "-"
            Else
                If ltmItem.Text = ".." Then
                    ltmItem.SubItems(1) = "<Directory>"
                    ltmItem.SubItems(2) = ""
                Else
                    ltmItem.SubItems(1) = "<Directory>"
                    ltmItem.SubItems(2) = CStr(FileInfo.FileModifyTime.Year) & "-" & CStr(FileInfo.FileModifyTime.Month) & "-" & CStr(FileInfo.FileModifyTime.Day) & " " & _
                                            CStr(FileInfo.FileModifyTime.Hour) & ":" & CStr(FileInfo.FileModifyTime.Minute) & ":" & CStr(FileInfo.FileModifyTime.Second)
                End If
            End If
        Else
            If FileInfo.FileSizeHigh = 0 Then
                If FileInfo.FileSizeLow < 0 Then
                    'a trick that make VB6 displays unsigned long
                    ltmItem.SubItems(1) = CStr(CCur(FileInfo.FileSizeLow) + 4294967296@)
                Else
                    ltmItem.SubItems(1) = CStr(FileInfo.FileSizeLow)
                End If
            Else
                'a trick that make VB6 displays unsigned long long (up to 0x7FFFFFFF`FFFFFFFF)
                Dim szlo As String: szlo = Hex$(FileInfo.FileSizeLow)
                Dim szhi As String: szhi = Hex$(FileInfo.FileSizeHigh)
                ltmItem.SubItems(1) = CStr(CDec("&H" & szhi & String(8 - Len(szlo), "0") & szlo))
            End If
            ltmItem.SubItems(2) = CStr(FileInfo.FileModifyTime.Year) & "-" & CStr(FileInfo.FileModifyTime.Month) & "-" & CStr(FileInfo.FileModifyTime.Day) & " " & _
                                    CStr(FileInfo.FileModifyTime.Hour) & ":" & CStr(FileInfo.FileModifyTime.Minute) & ":" & CStr(FileInfo.FileModifyTime.Second)
        End If
    End If
End Sub

Private Function GetRegTypeString(ByVal dw As Byte) As String
    Select Case dw
        Case 0
            GetRegTypeString = "REG_NONE"
        Case 1
            GetRegTypeString = "REG_SZ"
        Case 2
            GetRegTypeString = "REG_EXPAND_SZ"
        Case 3
            GetRegTypeString = "REG_BINARY"
        Case 4
            GetRegTypeString = "REG_DWORD"
        Case 5
            GetRegTypeString = "REG_DWORD_BIG_ENDIAN"
        Case 6
            GetRegTypeString = "REG_LINK"
        Case 7
            GetRegTypeString = "REG_MULTI_SZ"
        Case 8
            GetRegTypeString = "REG_RESOURCE_LIST"
        Case 9
            GetRegTypeString = "REG_FULL_RESOURCE_DESCRIPTOR"
        Case 10
            GetRegTypeString = "REG_RESOURCE_REQUIREMENTS_LIST"
        Case 11
            GetRegTypeString = "REG_QWORD"
        Case 255
            GetRegTypeString = "[REG_KEY]"
        Case Else
            GetRegTypeString = "REG_UNKNOWN"
    End Select
End Function

Private Function GetRegStringType(ByVal sz As String) As Long
    Select Case sz
        Case "REG_NONE"
            GetRegStringType = 0
        Case "REG_SZ"
            GetRegStringType = 1
        Case "REG_EXPAND_SZ"
            GetRegStringType = 2
        Case "REG_BINARY"
            GetRegStringType = 3
        Case "REG_DWORD"
            GetRegStringType = 4
        Case "REG_DWORD_BIG_ENDIAN"
            GetRegStringType = 5
        Case "REG_LINK"
            GetRegStringType = 6
        Case "REG_MULTI_SZ"
            GetRegStringType = 7
        Case "REG_RESOURCE_LIST"
            GetRegStringType = 8
        Case "REG_FULL_RESOURCE_DESCRIPTOR"
            GetRegStringType = 9
        Case "REG_RESOURCE_REQUIREMENTS_LIST"
            GetRegStringType = 10
        Case "REG_QWORD"
            GetRegStringType = 11
        Case Else
            GetRegStringType = 255
    End Select
End Function

Private Function GetCharZeroPos(ByRef ba() As Byte, ByVal StartPos As Long, ByRef NextStringExist As Boolean) As Long
    Dim i As Long
    For i = StartPos To UBound(ba) Step 2
        If (ba(i) = 0 And ba(i + 1) = 0 And ba(i + 2) <> 0) Then
            NextStringExist = True
            GetCharZeroPos = i + 2
            Exit Function
        ElseIf (ba(i) = 0 And ba(i + 1) = 0 And ba(i + 2) = 0 And ba(i + 3) = 0) Then
            NextStringExist = False
            GetCharZeroPos = i + 2
            Exit Function
        End If
    Next
    GetCharZeroPos = 0
End Function

Private Function MultiWideCharStringToVBString(ByVal p As Long, ByVal l As Long) As String
    On Error GoTo exx:
    Dim ba() As Byte, tba() As Byte
    Dim pos As Long, cur_pos As Long
    Dim sz As String
    Dim b As Boolean
    ReDim ba(l + 1)
    ReDim tba(l + 1)
    Call memcpy(VarPtr(ba(0)), p, l)
    Do
        cur_pos = pos
        pos = GetCharZeroPos(ba, pos, b)
        Call memcpy(VarPtr(tba(0)), VarPtr(ba(cur_pos)), pos - cur_pos)
        sz = sz & StrFromPtr(VarPtr(tba(0)), True) & vbCrLf
    Loop While (b = True)
    MultiWideCharStringToVBString = Left(sz, Len(sz) - 2)
    Exit Function
exx:
    MultiWideCharStringToVBString = ""
End Function

Private Function BinaryToString(ByVal p As Long, ByVal l As Long) As String
    Dim ba() As Byte
    Dim i As Long
    If l > 0 Then
        ReDim ba(l - 1)
        Call memcpy(VarPtr(ba(0)), p, l)
        For i = 0 To l - 1
            BinaryToString = BinaryToString & Hexx(ba(i)) & " "
        Next
    End If
    BinaryToString = Trim$(BinaryToString)
End Function

Private Function GetRegDataString(ByRef RegInfo As BDP_REG_INFO, ByVal RegPath As String) As String
    If RegInfo.DataLength > UBound(RegInfo.Data) + 1 Then
        Dim ba() As Byte
        Dim dwDatLen As Long
        If CmdRegistryOperation(CLng(lvClient.SelectedItem.Text), CLIENT_REG_QUERY_VALUE, StrPtr(RegPath), VarPtr(RegInfo) + 8, 0, 0, dwDatLen) Then
            ReDim ba(dwDatLen - 1)
            If CmdRegistryOperation(CLng(lvClient.SelectedItem.Text), CLIENT_REG_QUERY_VALUE, StrPtr(RegPath), VarPtr(RegInfo) + 8, 0, VarPtr(ba(0)), dwDatLen) Then
                If RegInfo.ItemType = 1 Or RegInfo.ItemType = 2 Then
                    GetRegDataString = StrFromPtr(VarPtr(ba(0)), True)
                ElseIf RegInfo.ItemType = 7 Then
                    GetRegDataString = MultiWideCharStringToVBString(VarPtr(ba(0)), dwDatLen)
                Else
                    GetRegDataString = BinaryToString(VarPtr(ba(0)), dwDatLen)
                End If
            End If
        End If
    Else
        If RegInfo.ItemType = 1 Or RegInfo.ItemType = 2 Then
            GetRegDataString = StrFromPtr(VarPtr(RegInfo) + 8 + 512, True)
        ElseIf RegInfo.ItemType = 4 Then
            Dim dw As Long
            Call memcpy(VarPtr(dw), VarPtr(RegInfo) + 8 + 512, 4)
            GetRegDataString = "0x" & Hex(dw)
        ElseIf RegInfo.ItemType = 11 Then
            Dim qw As Currency
            Call memcpy(VarPtr(qw), VarPtr(RegInfo) + 8 + 512, 8)
            GetRegDataString = "0x" & UInt64ToHex64(qw)
        ElseIf RegInfo.ItemType = 7 Then
            GetRegDataString = MultiWideCharStringToVBString(VarPtr(RegInfo) + 8 + 512, RegInfo.DataLength)
        Else
            GetRegDataString = BinaryToString(VarPtr(RegInfo) + 8 + 512, RegInfo.DataLength)
        End If
    End If
End Function

Private Sub AddRegInfo(ByRef lv As ListView, ByRef RegInfo As BDP_REG_INFO, ByVal RegPath As String)
    If RegInfo.ItemType <> 254 Then 'this is a special signal for empty key
        Dim ltmItem As ListItem
        Set ltmItem = lv.ListItems.Add()
        ltmItem.Text = GetRegTypeString(RegInfo.ItemType)
        ltmItem.SubItems(1) = StrFromPtr(VarPtr(RegInfo) + 8, True)
        ltmItem.SubItems(2) = IIf(RegInfo.DataLength > 0, GetRegDataString(RegInfo, RegPath), "")
        ltmItem.SubItems(3) = IIf(RegInfo.ItemType <> 255, CStr(RegInfo.DataLength), "")
    End If
End Sub

Private Sub btnClient_Click(Index As Integer)
    Dim b As Byte
    Static dwLatestClientVersion As Long
    Static szLatestClientVersion As String * 100
    If lvClient.ListItems.count = 0 Then Exit Sub
    Select Case Index
        Case 0
            b = ClientConnect(CLng(lvClient.SelectedItem.Text))
            If b = 0 Then
                MsgBox "Connect client unsuccessfully.", vbCritical
            End If
        Case 1
            b = ClientDisconnect(CLng(lvClient.SelectedItem.Text))
            If b = 0 Then
                MsgBox "Disconnect client unsuccessfully.", vbCritical
            End If
        Case 2
            b = ClientShutdown(CLng(lvClient.SelectedItem.Text))
            If b = 0 Then
                MsgBox "Shutdown client unsuccessfully.", vbCritical
            End If
        Case 3
            b = ClientReboot(CLng(lvClient.SelectedItem.Text))
            If b = 0 Then
                MsgBox "Reboot client unsuccessfully.", vbCritical
            End If
        Case 4
            Dim szNewFile As String
            Dim dwVersion(1) As Long
            Dim bForceUpdate As Boolean: bForceUpdate = False
            Const szUpdateTips As String = "Do you want to use an unknown version of file to update?"
            'get current client version
            ClientTest CLng(lvClient.SelectedItem.Text), ByVal VarPtr(dwVersion(0))
            'check client file update and download the latest file
            If dwLatestClientVersion = 0 Then
                If UpdateClient(szLatestClientVersion, App.Path & "\Latest32.sys", App.Path & "\Latest64.sys") Then
                    dwLatestClientVersion = CLng(szLatestClientVersion)
                    MsgBox "Latest Client Version: " & CStr(dwLatestClientVersion), vbInformation
                    If InStr(1, lvClient.SelectedItem.SubItems(2), "WIN32-", vbTextCompare) Then
                        szNewFile = App.Path & "\Latest32.sys"
                    Else
                        szNewFile = App.Path & "\Latest64.sys"
                    End If
                Else
                    If vbYes = MsgBox("Check update unsuccessfully." & vbCrLf & vbCrLf & szUpdateTips, vbCritical + vbYesNo) Then
                        bForceUpdate = True
                    End If
                End If
            End If
            'if check update failed, go to force update, otherwise go to normal update.
            If bForceUpdate = False Then
                If dwVersion(0) = dwLatestClientVersion Then
                    If vbYes = MsgBox("The client is up to date: " & CStr(dwVersion(0)) & vbCrLf & vbCrLf & szUpdateTips, vbExclamation + vbYesNo) Then
                        bForceUpdate = True
                    End If
                Else
                    b = ClientUpdate(CLng(lvClient.SelectedItem.Text), StrPtr(szNewFile))
                    If b = 0 Then
                        MsgBox "Update client unsuccessfully. Current version: " & CStr(dwVersion(0)), vbCritical
                    Else
                        MsgBox "Update client successfully. Old version: " & CStr(dwVersion(0)), vbInformation
                    End If
                End If
            End If
            If bForceUpdate Then
                Dim szUnknownNewFile As String
                If InStr(1, lvClient.SelectedItem.SubItems(2), "WIN32-", vbTextCompare) Then
                    szNewFile = App.Path & "\UpdateTest32.sys"
                Else
                    szNewFile = App.Path & "\UpdateTest64.sys"
                End If
                szUnknownNewFile = InputBox("New File:", "Update Client", szNewFile)
                If StrPtr(szUnknownNewFile) <> 0 Then
                    b = ClientUpdate(CLng(lvClient.SelectedItem.Text), StrPtr(szUnknownNewFile))
                    If b = 0 Then
                        MsgBox "Update client unsuccessfully. Current version: " & CStr(dwVersion(0)), vbCritical
                    Else
                        MsgBox "Update client successfully. Old version: " & CStr(dwVersion(0)), vbInformation
                    End If
                End If
            End If
        Case 5
            b = ClientUpdate(CLng(lvClient.SelectedItem.Text), 0)
            If b = 0 Then
                MsgBox "Uninstall client unsuccessfully.", vbCritical
            Else
                MsgBox "Uninstall client successfully.", vbInformation
            End If
        Case 6
            Dim szCfgFile As String
            szCfgFile = InputBox("Input new configuration file:", "Update", App.Path & "\test.cfg")
            If StrPtr(szCfgFile) Then
                b = ClientConfig(CLng(lvClient.SelectedItem.Text), CLIENT_CONFIG_SERVER, StrPtr(szCfgFile))
                If b = 0 Then
                    MsgBox "Configure client unsuccessfully.", vbCritical
                Else
                    MsgBox "Configure client successfully.", vbInformation
                End If
            End If
        Case 7
            Call Timer1_Timer
        Case Else
    End Select
End Sub

Private Sub btnFile_Click(Index As Integer)
    Dim b As Byte
    Dim lf As String
    Dim rf As String
    Dim NewName As String
    Dim SendCallBack As SENDRECV_CALLBACK
    Dim RecvCallBack As SENDRECV_CALLBACK
    If lvClient.ListItems.count = 0 Then Exit Sub
    Select Case Index
        Case 0
            lf = Replace(File1.Path & "\" & File1.FileName, "\\", "\")
            rf = Replace(txtFilePath.Text & "\" & File1.FileName, "\\", "\")
            SendCallBack.callback = CodePtr(AddressOf SendProgress)
            SendCallBack.id = CLng(lvClient.SelectedItem.Text)
            btnFile(Index).Enabled = False
            NewName = btnFile(Index).Caption
            b = CmdUploadFileTo(CLng(lvClient.SelectedItem.Text), StrPtr(lf), StrPtr(rf), VarPtr(SendCallBack))
            If b = 0 Then
                MsgBox "Upload file unsuccessfully.", vbCritical
            Else
                btnOperate_Click 0
            End If
            btnFile(Index).Caption = NewName
            btnFile(Index).Enabled = True
        Case 1
            rf = Replace(txtFilePath.Text & "\" & lvFile.SelectedItem.Text, "\\", "\")
            lf = Replace(File1.Path & "\" & lvFile.SelectedItem.Text, "\\", "\")
            RecvCallBack.callback = CodePtr(AddressOf RecvProgress)
            RecvCallBack.id = CLng(lvClient.SelectedItem.Text)
            btnFile(Index).Enabled = False
            NewName = btnFile(Index).Caption
            b = CmdDownloadFileFrom(CLng(lvClient.SelectedItem.Text), StrPtr(rf), StrPtr(lf), VarPtr(RecvCallBack))
            If b = 0 Then
                MsgBox "Download file unsuccessfully.", vbCritical
            Else
                File1.Refresh
            End If
            btnFile(Index).Caption = NewName
            btnFile(Index).Enabled = True
        Case 2
            NewName = InputBox("Input directory name:", "Create Directory")
            If StrPtr(NewName) Then
                rf = Replace(txtFilePath.Text & "\" & NewName, "\\", "\")
                b = CmdFileOperation(CLng(lvClient.SelectedItem.Text), CLIENT_FSO_CREATE_DIRECTORY, StrPtr(rf), StrPtr(""), 0)
                If b = 0 Then
                    MsgBox "Create directory unsuccessfully.", vbCritical
                Else
                    btnOperate_Click 0
                End If
            End If
        Case 3
            NewName = InputBox("Input new file full path name:", "Copy")
            If StrPtr(NewName) Then
                rf = Replace(txtFilePath.Text & "\" & lvFile.SelectedItem.Text, "\\", "\")
                b = CmdFileOperation(CLng(lvClient.SelectedItem.Text), CLIENT_FSO_COPY, StrPtr(rf), StrPtr(NewName), 0)
                If b = 0 Then
                    MsgBox "Copy unsuccessfully.", vbCritical
                Else
                    btnOperate_Click 0
                End If
            End If
        Case 4
            rf = Replace(txtFilePath.Text & "\" & lvFile.SelectedItem.Text, "\\", "\")
            b = CmdFileOperation(CLng(lvClient.SelectedItem.Text), CLIENT_FSO_DELETE, StrPtr(rf), StrPtr(""), 0)
            If b = 0 Then
                MsgBox "Delete unsuccessfully.", vbCritical
            Else
                btnOperate_Click 0
            End If
        Case 5
            NewName = InputBox("Input new name:", "Rename")
            If StrPtr(NewName) Then
                NewName = Replace(txtFilePath.Text & "\" & NewName, "\\", "\")
                rf = Replace(txtFilePath.Text & "\" & lvFile.SelectedItem.Text, "\\", "\")
                b = CmdFileOperation(CLng(lvClient.SelectedItem.Text), CLIENT_FSO_RENAME, StrPtr(rf), StrPtr(NewName), 0)
                If b = 0 Then
                    MsgBox "Rename unsuccessfully.", vbCritical
                Else
                    btnOperate_Click 0
                End If
            End If
        Case 6
            NewName = InputBox("Input numerical value of file attribute constants:", "Set Attribute")
            If StrPtr(NewName) Then
                rf = Replace(txtFilePath.Text & "\" & lvFile.SelectedItem.Text, "\\", "\")
                b = CmdFileOperation(CLng(lvClient.SelectedItem.Text), CLIENT_FSO_SET_ATTRIB, StrPtr(rf), StrPtr(NewName), 0)
                If b = 0 Then
                    MsgBox "Set file attribute unsuccessfully.", vbCritical
                Else
                    MsgBox "Set file attribute successfully.", vbInformation
                End If
            End If
        Case 7
            Dim rv As Long
            rf = Replace(txtFilePath.Text & "\" & lvFile.SelectedItem.Text, "\\", "\")
            b = CmdFileOperation(CLng(lvClient.SelectedItem.Text), CLIENT_FSO_GET_ATTRIB, StrPtr(rf), StrPtr(""), rv)
            If b = 0 Then
                MsgBox "Query file attribute unsuccessfully.", vbCritical
            Else
                MsgBox "Attribute: " & CStr(rv), vbInformation
            End If
        Case 8
            rf = InputBox("Input URL:", "HTTP Download", btnFile(8).Tag)
            If StrPtr(rf) Then
                lf = Replace(txtFilePath.Text & "\" & GetNameFromURL(rf), "\\", "\") ': MsgBox rf, , lf
                b = CmdFileOperation(CLng(lvClient.SelectedItem.Text), CLIENT_FSO_HTTP_DOWNLOAD, StrPtr(rf), StrPtr(lf), 0)
                If b = 0 Then
                    MsgBox "Download unsuccessfully.", vbCritical
                Else
                    btnOperate_Click 0
                End If
            End If
        Case 9
            rf = Replace(txtFilePath.Text & "\" & lvFile.SelectedItem.Text, "\\", "\")
            b = CmdFileOperation(CLng(lvClient.SelectedItem.Text), CLIENT_FSO_GET_CRC32, StrPtr(rf), StrPtr(""), rv)
            If b = 0 Then
                MsgBox "Query file CRC32 unsuccessfully.", vbCritical
            Else
                MsgBox "CRC32: " & "0x" & Hex$(rv), vbInformation
            End If
        Case 10
            NewName = InputBox("Input new filename (input nothing = commit delete):", "Delete / Rename after Reboot")
            If StrPtr(NewName) Then
                rf = Replace(txtFilePath.Text & "\" & lvFile.SelectedItem.Text, "\\", "\")
                b = CmdFileOperation(CLng(lvClient.SelectedItem.Text), CLIENT_FSO_DELAY_MOV_DEL, StrPtr(rf), StrPtr(NewName), 0)
                If b = 0 Then
                    MsgBox "Delete / Rename after Reboot unsuccessfully.", vbCritical
                Else
                    MsgBox "Delete / Rename after Reboot successfully.", vbInformation
                End If
            End If
        Case 11
            NewName = InputBox("Input file name:", "Create File")
            If StrPtr(NewName) Then
                rf = Replace(txtFilePath.Text & "\" & NewName, "\\", "\")
                lf = InputBox("Input file content:", "Create File")
                b = CmdFileOperation(CLng(lvClient.SelectedItem.Text), CLIENT_FSO_CREATE_FILE, StrPtr(rf), StrPtr(lf), 0)
                If b = 0 Then
                    MsgBox "Create file unsuccessfully.", vbCritical
                Else
                    btnOperate_Click 0
                End If
            End If
    End Select
End Sub

Private Sub EnumFileProc(ByVal id As Long, ByVal bShowMsgIfErrorHappens As Boolean)
    'A lazy way: assume the maximum item count is 16384...
    Dim i, sc As Long: sc = 16384
    Dim fs(16383) As BDP_FILE_INFO
    If CmdQueryDirectory(id, StrPtr(txtFilePath.Text), VarPtr(fs(0)), sc) = 0 Then
        txtFilePath.Text = GetParentDirectory(txtFilePath.Text)
        If bShowMsgIfErrorHappens = True Then
            MsgBox "Query directory unsuccessfully.", vbCritical
        End If
    Else
        lvFile.ListItems.Clear
        For i = 0 To sc - 1
            AddFileInfo lvFile, fs(i)
        Next
    End If
End Sub

Private Sub EnumRegistryProc(ByVal id As Long, ByVal bShowMsgIfErrorHappens As Boolean)
    'A lazy way: assume the maximum item count is 16384...
    Dim i, sc As Long: sc = 16384
    Dim rg(16383) As BDP_REG_INFO
    If CmdQueryRegistry(id, StrPtr(txtRegPath.Text), VarPtr(rg(0)), sc) = 0 Then
        If LCase(txtRegPath.Text) <> "\registry" Then
            txtRegPath.Text = GetParentDirectory(txtRegPath.Text)
        End If
        If bShowMsgIfErrorHappens = True Then
            MsgBox "Query registry unsuccessfully.", vbCritical
        End If
    Else
        lvReg.ListItems.Clear
        For i = 0 To sc - 1
            AddRegInfo lvReg, rg(i), txtRegPath.Text
        Next
    End If
End Sub

Private Function Signed2Unsigned(ByVal dw As Variant) As Variant
    If dw < 0 Then
        Signed2Unsigned = CDec(dw) + CDec("&H7fffffff") * 2 + 2
    Else
        Signed2Unsigned = dw
    End If
End Function

Private Sub EnumPartitionProc(ByVal id As Long)
    Dim dqrw As BDP_DISK_QUERY_READ_WRITE
    Dim iRet As BDP_PARTITION_INFO
    Dim lRet As Long: lRet = LenB(iRet)
    Dim pid As Long, fc As Long, EverSucceed As Boolean
    txtDiskInfo.Text = ""
    Do While 1
        Dim wDosDevice As Integer, qStartOffset As Currency, qExtentLength As Currency
        pid = pid + 1
        dqrw.PartitionId_or_DiskId = pid
        If CmdReadWriteDisk(id, CLIENT_DISK_QUERY_PARTITION, VarPtr(dqrw), VarPtr(iRet), lRet) Then
            txtDiskInfo.Text = txtDiskInfo.Text & Replace("[HarddiskVolume%ld] (If a partition has multiple segments, only the first one is displayed.)", "%ld", CStr(pid)) & vbCrLf
            txtDiskInfo.Text = txtDiskInfo.Text & "|-DiskId:            " & CStr(iRet.DiskId) & vbCrLf
            txtDiskInfo.Text = txtDiskInfo.Text & "|-SectorsPerCluster: " & CStr(iRet.SectorsPerCluster) & vbCrLf
            txtDiskInfo.Text = txtDiskInfo.Text & "|-BytesPerSector:    " & CStr(iRet.BytesPerSector) & vbCrLf
            Call memcpy(VarPtr(wDosDevice), VarPtr(iRet.buffer(0)), 2)
            Call memcpy(VarPtr(qStartOffset), VarPtr(iRet.buffer(2)), 8)
            Call memcpy(VarPtr(qExtentLength), VarPtr(iRet.buffer(10)), 8)
            txtDiskInfo.Text = txtDiskInfo.Text & "|-DosDevice:         " & IIf(wDosDevice, ChrW(wDosDevice), "(NONE)") & vbCrLf
            txtDiskInfo.Text = txtDiskInfo.Text & "|-StartingOffset:    0x" & UInt64ToHex64(qStartOffset) & " (DiskLBA: " & CStr(Signed2Unsigned(CDec("&H" & UInt64ToHex64(qStartOffset))) / CDec(iRet.BytesPerSector)) & ")" & vbCrLf
            txtDiskInfo.Text = txtDiskInfo.Text & "|-ExtentLength:      0x" & UInt64ToHex64(qExtentLength) & " (LogicBlockCount: " & CStr(Signed2Unsigned(CDec("&H" & UInt64ToHex64(qExtentLength))) / CDec(iRet.BytesPerSector)) & ")" & vbCrLf & vbCrLf
            EverSucceed = True
        Else
            fc = fc + 1
        End If
        If fc >= 4 Then
            Exit Do
        End If
    Loop
    If EverSucceed = False Then
        txtDiskInfo.Text = "Query partition information unsuccessfully."
    End If
End Sub

Private Sub EnumFilePosProc(ByVal id As Long)
    Dim sz As String: sz = txtFileForPos.Text
    Dim dqrw As BDP_DISK_QUERY_READ_WRITE_FILE
    Dim sRet As BDP_FILE_CLUSTERS
    Dim bRet(4095) As Byte
    Dim i As Long, lRet As Long: lRet = 4096
    Dim PartitionStartingLBA As Variant, cc As Variant: cc = CDec(0)
    memcpy VarPtr(dqrw.Path(0)), StrPtr(sz), Len(sz) * 2
    If CmdReadWriteDisk(id, CLIENT_DISK_QUERY_FILE_POS, VarPtr(dqrw), VarPtr(bRet(0)), lRet) Then
        txtDiskInfo.Text = ""
        memcpy VarPtr(sRet), VarPtr(bRet(0)), LenB(sRet)
        If sRet.MftStartingOffset <> 0 Or sRet.SectionCount <> 0 Then
            txtDiskInfo.Text = txtDiskInfo.Text & "Located on Disk: " & CStr(sRet.DiskId) & vbCrLf
            txtDiskInfo.Text = txtDiskInfo.Text & "Located on Partition: \\Device\\HarddiskVolume" & CStr(sRet.PartitionId) & vbCrLf
            'txtDiskInfo.Text = txtDiskInfo.Text & "Sectors per Cluster: " & CStr(sRet.SectorsPerCluster) & vbCrLf
            'txtDiskInfo.Text = txtDiskInfo.Text & "Bytes per Sector:    " & CStr(sRet.BytesPerSector) & vbCrLf
            'txtDiskInfo.Text = txtDiskInfo.Text & "Partition Starting Offset On Disk: 0x" & UInt64ToHex64(sRet.PartitionStartingOffset) & " (DiskLBA: " & Signed2Unsigned(CDec("&H" & UInt64ToHex64(sRet.PartitionStartingOffset))) / CDec(sRet.BytesPerSector) & ")" & vbCrLf
            txtDiskInfo.Text = txtDiskInfo.Text & "MFT Starting Offset On Partition: 0x" & UInt64ToHex64(sRet.MftStartingOffset) & " (DiskLBA: " & Signed2Unsigned(CDec("&H" & UInt64ToHex64(sRet.MftStartingOffset + sRet.PartitionStartingOffset))) / CDec(sRet.BytesPerSector) & ")" & vbCrLf
            txtDiskInfo.Text = txtDiskInfo.Text & "File Size: " & IIf(sRet.FileSize <> 0, CStr(CDec("&H" & UInt64ToHex64(sRet.FileSize)) - 1), "Unknown") & vbCrLf
            txtDiskInfo.Text = txtDiskInfo.Text & "Cluster Count: %lddd" & vbCrLf
            txtDiskInfo.Text = txtDiskInfo.Text & "Cluster Fragments: " & CStr(sRet.SectionCount) & vbCrLf
            PartitionStartingLBA = CDec("&H" & UInt64ToHex64(sRet.PartitionStartingOffset)) / sRet.BytesPerSector
            If sRet.SectionCount > 254 Then sRet.SectionCount = 254
            For i = 0 To sRet.SectionCount - 1
                txtDiskInfo.Text = txtDiskInfo.Text & "PttClst[%I64d1] ~ PttClst[%I64d2]  <-->  DiskLBA[%I64d3] ~ DiskLBA[%I64d4]" & vbCrLf
                txtDiskInfo.Text = Replace(txtDiskInfo.Text, "%I64d1", CStr(CDec("&H" & UInt64ToHex64(sRet.Sections(i).Begin))))
                txtDiskInfo.Text = Replace(txtDiskInfo.Text, "%I64d2", CStr(CDec("&H" & UInt64ToHex64(sRet.Sections(i).End))))
                txtDiskInfo.Text = Replace(txtDiskInfo.Text, "%I64d3", CStr(CDec("&H" & UInt64ToHex64(sRet.Sections(i).Begin)) * sRet.SectorsPerCluster + PartitionStartingLBA)) '
                txtDiskInfo.Text = Replace(txtDiskInfo.Text, "%I64d4", CStr(CDec("&H" & UInt64ToHex64(sRet.Sections(i).End)) * sRet.SectorsPerCluster + PartitionStartingLBA))  '
                cc = cc + CDec(CDec("&H" & UInt64ToHex64(sRet.Sections(i).End)) - CDec("&H" & UInt64ToHex64(sRet.Sections(i).Begin)) + 1)
            Next
            txtDiskInfo.Text = Replace(txtDiskInfo.Text, "%lddd", CStr(cc))
        Else
            txtDiskInfo.Text = "Query file layout information unsuccessfully."
        End If
    Else
        txtDiskInfo.Text = "Query file layout information unsuccessfully."
    End If
End Sub

Private Sub ReadDiskProc(ByVal id As Long)
    Dim dqrw As BDP_DISK_QUERY_READ_WRITE
    Dim ret() As Byte, lRet As Long, i As Long, szData As String, szAddr As String
    Dim LBA As Long
    dqrw.PartitionId_or_DiskId = CLng(txtDiskId.Text)
    'the maxinum LBA can only be 2147483647 in VB6, if you want to read a LBA that larger than 2147483647, you must fill dqrw.LBA manually
    txtLBA.Text = Replace$(txtLBA.Text, "(", ""): txtLBA.Text = Replace$(txtLBA.Text, ")", ""): txtLBA.Text = Trim$(txtLBA.Text)
    txtLBA.Text = Replace$(txtLBA.Text, "[", ""): txtLBA.Text = Replace$(txtLBA.Text, "]", ""): LBA = CLng(txtLBA.Text)
    memcpy VarPtr(dqrw.LBA), VarPtr(LBA), 4
    dqrw.CountLBA = CLng(txtLBC.Text)
    dqrw.SectorSize = CLng(txtLBS.Text)
    lRet = dqrw.CountLBA * dqrw.SectorSize
    ReDim ret(lRet - 1)
    If CmdReadWriteDisk(id, CLIENT_DISK_READ_SECTOR, VarPtr(dqrw), VarPtr(ret(0)), lRet) Then
        'output the first disk offset
        If CDec(CDec(LBA) * CDec(dqrw.SectorSize)) = CDec(0) Then
            szData = "0000" & vbTab
        Else
            szData = Dec64ToHex64(CStr(CDec(LBA) * CDec(dqrw.SectorSize)))
            If Len(szData) < 4 Then
                szData = String(4 - Len(szData), "0") & szData
            End If
            szData = szData & vbTab
        End If
        For i = 0 To lRet - 1
            'output data
            szData = szData & Hexx(ret(i)) & " "
            'output other disk offsets
            If (i + 1) Mod 16 = 0 And (i + 1) < lRet Then
                szAddr = Dec64ToHex64(CStr(CDec(LBA) * CDec(dqrw.SectorSize) + i + 1))
                If Len(szAddr) < 4 Then
                    szAddr = String(4 - Len(szAddr), "0") & szAddr
                End If
                szData = szData & vbCrLf & szAddr & vbTab
            End If
        Next
        txtDiskInfo.Text = szData
    Else
        txtDiskInfo.Text = "Read disk unsuccessfully."
    End If
End Sub

Private Function GetBufferFromTextBox(ByRef ba() As Byte) As Boolean
    On Error GoTo exx
    Dim i As Long, sa() As String, TabPos As Long, sz As String, szba() As String
    sa = Split(txtDiskInfo.Text, vbCrLf)
    If UBound(sa) <> 31 Then
        MsgBox "Data must be 512 bytes and written in 32 lines.", vbExclamation
        Exit Function
    End If
    For i = 0 To 31
        TabPos = InStr(1, sa(i), vbTab)
        If TabPos = 0 Then
            MsgBox Replace("Data format in line %ld is not correct.", "%ld", i + 1), vbExclamation
            Exit Function
        Else
            sa(i) = Mid$(sa(i), TabPos + 1)
            sz = sz & sa(i)
        End If
    Next
    sz = Trim$(sz)
    szba = Split(sz, " ") ': MsgBox UBound(szba)
    If UBound(szba) <> 511 Then
        MsgBox "Data length must be 512 bytes. Actual length: " & CStr(UBound(szba) + 1) & ".", vbExclamation
        Exit Function
    Else
        sz = ""
        For i = 0 To 511
            ba(i) = CByte("&H" & szba(i))
            sz = sz & Hexx(ba(i)) & " "
            If (i + 1) Mod 16 = 0 Then
                sz = sz & vbCrLf
            End If
        Next
        If MessageBoxW(Me.hWnd, StrPtr(sz), StrPtr("Are you sure these bytes are correct?"), 4) = 7 Then
            GetBufferFromTextBox = False
        Else
            GetBufferFromTextBox = True
        End If
        Exit Function
    End If
exx:
    MsgBox "Unrecognizable input is found on position 0x" & Hexx(i) & ".", vbExclamation
End Function

Private Sub WriteDiskProc(ByVal id As Long, Optional ByVal szHexData As String = "")
    Dim dqrw As BDP_DISK_QUERY_READ_WRITE
    Dim iRet As Long, lRet As Long, i As Long, szData As String, szAddr As String
    Dim LBA As Long, bFlag As Boolean, szba() As String
    dqrw.PartitionId_or_DiskId = CLng(txtDiskId.Text)
    'The maxinum LBA can only be 2147483647 in VB6, if you want to write a LBA that larger than 2147483647, you must fill dqrw.LBA manually.
    txtLBA.Text = Replace$(txtLBA.Text, "(", ""): txtLBA.Text = Replace$(txtLBA.Text, ")", ""): txtLBA.Text = Trim$(txtLBA.Text)
    txtLBA.Text = Replace$(txtLBA.Text, "[", ""): txtLBA.Text = Replace$(txtLBA.Text, "]", ""): LBA = CLng(txtLBA.Text)
    memcpy VarPtr(dqrw.LBA), VarPtr(LBA), 4
    'Only allow users to write one logical block to test the effect.
    'In actual use, multiple logical blocks can be written at one time (check the sample written in C).
    dqrw.CountLBA = 1: txtLBC.Text = "1"
    dqrw.SectorSize = CLng(txtLBS.Text)
    If szHexData = "" Then
        If GetBufferFromTextBox(dqrw.buffer) Then
            bFlag = True
        End If
    Else
        szHexData = Replace(Trim$(szHexData), "  ", " ")
        szba = Split(szHexData, " ")
        If UBound(szba) <> 511 Then
            txtDiskInfo.Text = "Data length must be 512 bytes. Actual length: " & CStr(UBound(szba) + 1) & "."
        Else
            For i = 0 To 511
                dqrw.buffer(i) = CByte("&H" & szba(i))
            Next
            bFlag = True
        End If
    End If
    If bFlag Then
        If CmdReadWriteDisk(id, CLIENT_DISK_WRITE_SECTOR, VarPtr(dqrw), 0, 0) Then
            txtDiskInfo.Text = "Write disk successfully."
        Else
            txtDiskInfo.Text = "Write disk unsuccessfully."
        End If
    End If
End Sub

Private Sub btnOperate_Click(Index As Integer)
    If lvClient.ListItems.count = 0 Then Exit Sub
    Select Case Index
        Case 0
            EnumFileProc CLng(lvClient.SelectedItem.Text), True
        Case 1
            txtFilePath.Text = GetParentDirectory(txtFilePath.Text)
            btnOperate_Click 0
        Case 2
            'A lazy way: assume the maximum string length is 16384...
            Dim baReturn(16383) As Byte
            If CmdSystemShell(CLng(lvClient.SelectedItem.Text), StrPtr(txtCMD.Text), VarPtr(baReturn(0)), 16383) Then
                txtCmdRet.Text = "COMMAND: " & txtCMD.Text & vbCrLf & sz2bstr(baReturn)
            Else
                txtCmdRet.Text = "COMMAND: " & txtCMD.Text & vbCrLf & "Execute system shell unsuccessfully."
            End If
        Case 3
            txtCmdRet.Text = ""
        Case 6, 10, 14
            Dim bType As Byte
            Dim ppNames As Long
            Dim CurrentName As String
            If Index = 6 Then
                bType = CLIENT_AUTORUN_TYPE_SYS
                lstDrv.Clear
            ElseIf Index = 10 Then
                bType = CLIENT_AUTORUN_TYPE_EXE
                lstExe.Clear
            Else
                bType = CLIENT_AUTORUN_TYPE_DLL
                lstDLL.Clear
            End If
            If CmdQueryAutoRunBin(CLng(lvClient.SelectedItem.Text), bType, VarPtr(ppNames)) Then
                CurrentName = StrFromPtr(ppNames, True)
                If CurrentName <> CLIENT_AUTORUN_EMPTY Then
                    Do While 1
                        CurrentName = StrFromPtr(ppNames, True)
                        If Len(CurrentName) = 0 Then Exit Do
                        If Index = 6 Then
                            lstDrv.AddItem CurrentName
                        ElseIf Index = 10 Then
                            lstExe.AddItem CurrentName
                        Else
                            lstDLL.AddItem CurrentName
                        End If
                        ppNames = ppNames + Len(CurrentName) * 2 + 2
                    Loop
                End If
            Else
                MsgBox "Query auto-run information unsuccessfully.", vbCritical
            End If
        Case 7, 11, 15
            Dim NewName As String
            Dim newFile As String
            Dim newParam As String
            Dim defPath As String
            Dim defParam As String
            If Index = 7 Then
                bType = CLIENT_AUTORUN_TYPE_SYS
                defPath = "c:\windows\system32\drivers\usb8023.sys"
            ElseIf Index = 11 Then
                bType = CLIENT_AUTORUN_TYPE_EXE
                defPath = "c:\windows\system32\write.exe"
                defParam = "c:\windows\win.ini"
            Else
                bType = CLIENT_AUTORUN_TYPE_DLL
                defPath = "c:\windows\system32\shell32.dll"
                defParam = "Control_RunDLL intl.cpl,,1"
            End If
            newFile = InputBox("Input file on the client:", "Add auto-run", defPath)
            If StrPtr(newFile) Then
                NewName = GetNameFromPath(newFile): NewName = Left$(NewName, 19) 'max-name-len=19
                If Index <> 7 Then
                    newParam = InputBox("Input parameter(s):", "Add auto-run", defParam)
                End If
                If CmdAddAutoRunBin(CLng(lvClient.SelectedItem.Text), bType, StrPtr(NewName), StrPtr(newFile), StrPtr(newParam)) Then
                    If Index = 7 Then
                        btnOperate_Click 6
                    ElseIf Index = 11 Then
                        btnOperate_Click 10
                    Else
                        btnOperate_Click 14
                    End If
                Else
                    MsgBox "Add auto-run unsuccessfully.", vbCritical
                End If
            End If
        Case 8, 12, 16
            If Index = 8 Then
                bType = CLIENT_AUTORUN_TYPE_SYS
                newFile = lstDrv.Text
            ElseIf Index = 12 Then
                bType = CLIENT_AUTORUN_TYPE_EXE
                newFile = lstExe.Text
            Else
                bType = CLIENT_AUTORUN_TYPE_DLL
                newFile = lstDLL.Text
            End If
            If StrPtr(newFile) Then
                If CmdDelAutoRunBin(CLng(lvClient.SelectedItem.Text), bType, StrPtr(newFile)) Then
                    If Index = 8 Then
                        btnOperate_Click 6
                    ElseIf Index = 12 Then
                        btnOperate_Click 10
                    Else
                        btnOperate_Click 14
                    End If
                Else
                    MsgBox "Delete auto-run unsuccessfully.", vbCritical
                End If
            End If
        Case 9, 13, 17
            If Index = 9 Then
                bType = CLIENT_AUTORUN_TYPE_SYS
            ElseIf Index = 13 Then
                bType = CLIENT_AUTORUN_TYPE_EXE
            Else
                bType = CLIENT_AUTORUN_TYPE_DLL
            End If
            If CmdClearAutoRunBin(CLng(lvClient.SelectedItem.Text), bType) Then
                If Index = 9 Then
                    btnOperate_Click 6
                ElseIf Index = 13 Then
                    btnOperate_Click 10
                Else
                    btnOperate_Click 14
                End If
            Else
                MsgBox "Clear auto-run unsuccessfully.", vbCritical
            End If
        Case 18
            EnumRegistryProc CLng(lvClient.SelectedItem.Text), True
        Case 19
            If LCase(txtRegPath.Text) <> "\registry" Then
                txtRegPath.Text = GetParentDirectory(txtRegPath.Text)
            End If
            btnOperate_Click 18
        Case 4
            EnumPartitionProc CLng(lvClient.SelectedItem.Text)
        Case 5
            EnumFilePosProc CLng(lvClient.SelectedItem.Text)
        Case 20
            ReadDiskProc CLng(lvClient.SelectedItem.Text)
        Case 21
            If MsgBox("The integrity of the partition(s) / file system(s) on the disk may be severely damaged by this operation." & vbCrLf & vbCrLf & _
                        "Do you want to continue?", vbExclamation + vbYesNo) = vbYes Then
                WriteDiskProc CLng(lvClient.SelectedItem.Text)
            End If
        Case 22
            If IsNumeric(txtLBA.Text) Then
                If CDec(txtLBA.Text) >= 0 And CDec(txtLBA.Text) <= &H7FFFFFFF Then
                    If CLng(txtLBA.Text) < &H7FFFFFFF Then
                        txtLBA.Text = CStr(CLng(txtLBA.Text) + 1)
                    End If
                End If
            End If
        Case 23
            If IsNumeric(txtLBA.Text) Then
                If CDec(txtLBA.Text) >= 0 And CDec(txtLBA.Text) <= &H7FFFFFFF Then
                    If CLng(txtLBA.Text) > 0 Then
                        txtLBA.Text = CStr(CLng(txtLBA.Text) - 1)
                    End If
                End If
            End If
        Case 24
            Clipboard.Clear
            Clipboard.SetText txtDiskInfo.Text
        Case 25
            txtDiskInfo.Text = ""
    End Select
End Sub

Private Sub Check1_Click()
    If Check1.Value = 1 Then
        Timer1.Enabled = True
    Else
        Timer1.Enabled = False
    End If
End Sub

Private Sub Check2_Click()
    txtDiskInfo.Locked = Check2.Value
End Sub

Private Sub Dir1_Change()
    On Error Resume Next
    File1.Path = Dir1.Path
End Sub

Private Sub Dir1_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = 2 Then
        Dir1.Refresh
    End If
End Sub

Private Sub Drive1_Change()
    On Error Resume Next
    Dir1.Path = Drive1.Drive
End Sub

Private Sub File1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = 2 Then
        File1.Refresh
    End If
End Sub

Private Sub Form_Initialize()
    On Error Resume Next
    Dim b As Byte
    Dim port As Long: port = 9999
    If IsNumeric(Command$) Then
        port = CLng(Command$)
    End If
    Me.Tag = CStr(port)
    Kill "c:\input." & CStr(Me.Tag)
    Kill "c:\output." & CStr(Me.Tag)
    Kill "c:\progress." & CStr(Me.Tag)
    b = init(port)
    If b = 0 Then
        MsgBox "Initialization failed.", vbCritical
        ExitProcess 0
    Else
        Me.Caption = Me.Caption & " (Port: " & CStr(port) & ")"
    End If
End Sub

Private Sub Form_Load()
    On Error Resume Next
    SendMessageA lvClient.hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, -1
    SendMessageA lvFile.hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, -1
    SendMessageA lvReg.hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, -1
    SendMessageA lvProc.hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, -1
    SendMessageA lvMod.hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, -1
    Drive1.Drive = Environ("HOMEDRIVE")
    Dir1.Path = Drive1.Drive
    File1.Path = Dir1.Path
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Dim b As Byte
    b = uninit() ': MsgBox b, , "uninit"
    ExitProcess 0
End Sub

Private Sub lvClient_DblClick()
    btnClient_Click 0
End Sub

Private Sub lvClient_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = 2 Then PopupMenu mnuClient
End Sub

Private Sub lvFile_DblClick()
    If lvFile.ListItems.count = 0 Then Exit Sub
    If Trim$(txtFilePath.Text) = "\" Then txtFilePath.Text = ""
    If lvFile.SelectedItem.SubItems(1) = "<Directory>" Or _
        lvFile.SelectedItem.SubItems(1) = "<Drive>" Or _
        lvFile.SelectedItem.SubItems(1) = "" Then
        txtFilePath.Text = txtFilePath.Text & "\" & lvFile.SelectedItem.Text
        If Left$(txtFilePath.Text, 1) = "\" Then
            txtFilePath.Text = Mid$(txtFilePath.Text, 2)
        End If
        txtFilePath.Text = Replace(txtFilePath.Text, "\\", "\")
        If Right$(txtFilePath.Text, 3) = "\.." Then
            txtFilePath.Text = Left$(txtFilePath.Text, Len(txtFilePath.Text) - 3)
            txtFilePath.Text = GetParentDirectory(txtFilePath.Text) ': MsgBox txtFilePath.Text
            If Trim$(txtFilePath.Text) = "" Then
                txtFilePath.Text = "\"
            End If
        End If
        btnOperate_Click 0
    Else
        Dim rv As Currency
        Dim dwParam As Long
        Dim szParam As String
        Dim szDefault As String
        Dim szRemoteFile As String
        szRemoteFile = txtFilePath.Text & "\" & lvFile.SelectedItem.Text
        szRemoteFile = Replace(szRemoteFile, "\\", "\")
        If LCase$(Right$(lvFile.SelectedItem.Text, 4)) = ".exe" Then
            If InStr(lvFile.SelectedItem.Text, "write.exe") Then
                szDefault = "c:\windows\win.ini"
            End If
            szParam = InputBox("Input program parameter(s):", lvFile.SelectedItem.Text, szDefault)
            If StrPtr(szParam) Then
                szRemoteFile = szRemoteFile & " " & szParam
            End If
            If vbYes = MsgBox("Do you want to run this program with SYSTEM privilege?", vbQuestion + vbYesNo + vbDefaultButton2) Then
                dwParam = SW_SHOW + 100
            Else
                dwParam = SW_SHOW
            End If
            If CmdExecuteBinary(CLng(lvClient.SelectedItem.Text), StrPtr(szRemoteFile), dwParam, 0, rv) = 0 Then
                MsgBox "Run program unsuccessfully.", vbCritical
            Else
                If rv <> 0 Then
                    MsgBox "Run program successfully.", vbInformation, "PID = " & CStr(CDec("&H" & UInt64ToHex64(rv)))
                Else
                     MsgBox "Run program unsuccessfully.", vbCritical
                End If
            End If
        ElseIf LCase$(Right$(lvFile.SelectedItem.Text, 4)) = ".sys" Then
            If vbYes = MsgBox("Do you want to load the driver?", vbYesNo + vbQuestion, lvFile.SelectedItem.Text) Then
                If CmdExecuteBinary(CLng(lvClient.SelectedItem.Text), StrPtr(szRemoteFile), CLIENT_RUN_SYS_P1, CLIENT_RUN_SYS_P2, rv) = 0 Then
                    MsgBox "Load driver unsuccessfully.", vbCritical
                Else
                    If rv <> 0 Then
                        MsgBox "Load driver successfully.", vbInformation, "DriverObject = " & UInt64ToHex64(rv)
                    Else
                        MsgBox "Load driver unsuccessfully.", vbCritical
                    End If
                End If
            End If
        ElseIf LCase$(Right$(lvFile.SelectedItem.Text, 4)) = ".dll" Then
            If InStr(lvFile.SelectedItem.Text, "shell32.dll") Then
                szDefault = "Control_RunDLL intl.cpl,,1"
            End If
            szParam = InputBox("Input export function name and parameter(s):", lvFile.SelectedItem.Text, szDefault)
            If StrPtr(szParam) Then
                szRemoteFile = szRemoteFile & "," & szParam
                If CmdExecuteBinary(CLng(lvClient.SelectedItem.Text), StrPtr(szRemoteFile), CLIENT_RUN_DLL_P1, CLIENT_RUN_DLL_P2, rv) = 0 Then
                    MsgBox "Load DLL unsuccessfully.", vbCritical
                Else
                    If rv <> 0 Then
                        MsgBox "Load DLL successfully.", vbInformation, "RunDll32-PID = " & CStr(CDec("&H" & UInt64ToHex64(rv)))
                    Else
                        MsgBox "Load DLL unsuccessfully.", vbCritical
                    End If
                End If
            End If
        End If
    End If
End Sub

Private Sub lvFile_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = 2 Then PopupMenu mnuFile
End Sub

Private Function SetRegValueInternal(ByVal ClientId As Long, ByVal KeyName As String, ByVal ValueName As String, ByVal ValueType As Long, ByVal szValueData As String) As Boolean
    On Error GoTo exx
    Dim pValueData As Long, dwValueDataLength As Long
    If ValueType = 1 Or ValueType = 2 Then
        '//REG_SZ or REG_EXPAND_SZ
        pValueData = StrPtr(szValueData)
        dwValueDataLength = Len(szValueData) * 2
    ElseIf ValueType = 4 Then
        '//REG_DWORD
        Dim dw As Long
        If LCase$(Left$(szValueData, 2)) = "0x" Then
            dw = CLng("&H" & Mid$(szValueData, 3))
        Else
            dw = CLng(szValueData)
        End If
        pValueData = VarPtr(dw)
        dwValueDataLength = 4
    ElseIf ValueType = 11 Then
        '//REG_QWORD
        Dim qw As Currency
        Dim s1 As String, s2 As String
        Dim dw1 As Long, dw2 As Long
        If LCase$(Left$(szValueData, 2)) = "0x" Then
            szValueData = Mid$(szValueData, 3)
            szValueData = String(16 - Len(szValueData), "0") & szValueData
            s1 = Left$(szValueData, 8): dw1 = CLng("&H" & s1)
            s2 = Mid$(szValueData, 9): dw2 = CLng("&H" & s2)
            Call memcpy(VarPtr(qw) + 0, VarPtr(dw2), 4)
            Call memcpy(VarPtr(qw) + 4, VarPtr(dw1), 4)
        Else
            'MsgBox "You must use hexadecimal number for REG_QWORD.", vbCritical
            GoTo exx
        End If
        pValueData = VarPtr(qw)
        dwValueDataLength = 8
    ElseIf ValueType = 7 Then
        '//REG_MULTI_SZ
        szValueData = szValueData & vbCrLf
        szValueData = Replace(szValueData, vbCrLf, ChrW(0))
        pValueData = StrPtr(szValueData)
        dwValueDataLength = Len(szValueData) * 2
    Else
        '//REG_BINARY
        Dim sba() As String
        Dim ba() As Byte
        Dim i As Long
        sba = Split(szValueData, " ")
        ReDim ba(UBound(sba))
        For i = 0 To UBound(sba)
            ba(i) = CByte("&H" & sba(i))
        Next
        pValueData = VarPtr(ba(0))
        dwValueDataLength = UBound(ba) + 1
    End If
    SetRegValueInternal = CmdRegistryOperation(ClientId, CLIENT_REG_SET_VALUE, StrPtr(KeyName), StrPtr(ValueName), ValueType, pValueData, dwValueDataLength)
    Exit Function
exx:
    SetRegValueInternal = False
End Function

Private Sub SetRegValueProc()
    If txtTempRegData.Tag = "" Then Exit Sub
    Dim ClientId As Long: ClientId = CLng(lvClient.SelectedItem.Text)
    Dim KeyName As String: KeyName = txtRegPath.Text
    Dim ValueName As String: ValueName = txtTempRegData.ToolTipText
    Dim ValueType As Long: ValueType = GetRegStringType(txtTempRegData.Tag)
    Dim szValueData As String: szValueData = txtTempRegData.Text
    Dim b As Boolean
    b = SetRegValueInternal(ClientId, KeyName, ValueName, ValueType, szValueData)
    If b = 0 Then
        MsgBox "Edit value unsuccessfully.", vbCritical
    Else
        btnOperate_Click 18
    End If
End Sub

Private Sub lvReg_DblClick()
    If lvReg.ListItems.count = 0 Then Exit Sub
    If lvReg.SelectedItem.Text = "[REG_KEY]" Then
        txtRegPath.Text = Replace(txtRegPath.Text & "\" & lvReg.SelectedItem.SubItems(1), "\\", "\")
        btnOperate_Click 18
    Else
        Load frmRegistryEditor
        frmRegistryEditor.Text1.Text = lvReg.SelectedItem.SubItems(1)
        frmRegistryEditor.Frame1.Enabled = False
        frmRegistryEditor.Text2.Text = lvReg.SelectedItem.SubItems(2)
        frmRegistryEditor.Frame3.Enabled = False
        If lvReg.SelectedItem.Text = "REG_SZ" Then
            frmRegistryEditor.Option1.Value = True
        ElseIf lvReg.SelectedItem.Text = "REG_EXPAND_SZ" Then
            frmRegistryEditor.Option2.Value = True
        ElseIf lvReg.SelectedItem.Text = "REG_MULTI_SZ" Then
            frmRegistryEditor.Option3.Value = True
        ElseIf lvReg.SelectedItem.Text = "REG_BINARY" Then
            frmRegistryEditor.Option4.Value = True
        ElseIf lvReg.SelectedItem.Text = "REG_DWORD" Then
            frmRegistryEditor.Option5.Value = True
        ElseIf lvReg.SelectedItem.Text = "REG_QWORD" Then
            frmRegistryEditor.Option6.Value = True
        End If
        frmRegistryEditor.Show vbModal, Me  ':MsgBox txtTempRegData.Text
        SetRegValueProc
    End If
End Sub

Private Sub lvReg_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = 2 Then PopupMenu mnuReg
End Sub

Private Function GetSetClientTimeProc(ByVal id As Long, ByVal bSet As Integer, Optional ByVal szDateTime As String = "") As String
    On Error GoTo exx
    Dim sa() As String
    Dim info As BDP_SI_SYSTEM_TIME
    Dim iLen As Long: iLen = LenB(info)
    If bSet = 0 Then
        If CmdQuerySetSystemInformation(id, CLIENT_QSI_QUERY_TICK_TIME, 0, 0, VarPtr(info), iLen) Then
            GetSetClientTimeProc = "TickCount: " & UInt64ToDec64(info.TickCount) & vbCrLf & _
                                    "Local Time: " & CStr(info.LocalTime.wYear) & "-" & CStr(info.LocalTime.wMonth) & "-" & CStr(info.LocalTime.wDay) & _
                                                    " " & CStr(info.LocalTime.wHour) & ":" & CStr(info.LocalTime.wMinute) & ":" & CStr(info.LocalTime.wSecond)
        End If
    Else
        If szDateTime <> "" Then
            szDateTime = Replace(szDateTime, "-", " ")
            szDateTime = Replace(szDateTime, ":", " ")
            sa = Split(szDateTime, " ")
            If UBound(sa) = 5 Then
                info.LocalTime.wYear = CInt(sa(0))
                info.LocalTime.wMonth = CInt(sa(1))
                info.LocalTime.wDay = CInt(sa(2))
                info.LocalTime.wHour = CInt(sa(3))
                info.LocalTime.wMinute = CInt(sa(4))
                info.LocalTime.wSecond = CInt(sa(5))
            End If
            If CmdQuerySetSystemInformation(id, CLIENT_SSI_SET_LOCAL_TIME, VarPtr(info), LenB(info), 0, 0) Then
                GetSetClientTimeProc = szDateTime
            End If
        End If
    End If
exx:
End Function

Private Sub mnuCO_Click(Index As Integer)
    Dim szRet As String, szNewDT As String
    If Index = 1 Then
        szNewDT = InputBox("Input new date and time:", "Set Time", "2222-2-22 22:22:22")
        If StrPtr(szNewDT) = 0 Then
            Exit Sub
        End If
    End If
    szRet = GetSetClientTimeProc(CLng(lvClient.SelectedItem.Text), Index, szNewDT)
    If szRet = "" Then
        MsgBox IIf(Index = 0, "Get", "Set") & " time unsuccessfully.", vbCritical
    Else
        MsgBox IIf(Index = 0, szRet, "Set time successfully."), vbInformation
    End If
End Sub

Private Sub mnuFSO_Click(Index As Integer)
    Select Case Index
        Case 0
            btnFile_Click 11
        Case 1
            btnFile_Click 2
        Case 3
            btnFile_Click 3
        Case 4
            btnFile_Click 4
        Case 5
            btnFile_Click 5
        Case 7
            btnFile_Click 6
        Case 8
            btnFile_Click 7
        Case 10
            btnFile_Click 8
        Case 12
            btnFile_Click 9
        Case 14
            btnFile_Click 10
    End Select
End Sub

Private Sub lvMod_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = 2 Then PopupMenu mnuProcMod
End Sub

Private Sub EnumProcessModuleProc(ByVal id As Long, ByVal pid As Long, ByVal bShowMsgIfErrorHappens As Boolean)
    Dim pi As BDP_SI_PROCESS_INFO
    If pid = 4 Then pid = 0
    memcpy VarPtr(pi.id), VarPtr(pid), 4
    'A lazy way: assume the maximum item count is 16384...
    Dim info(16383) As BDP_SI_PROCESS_MOD_INFO
    Dim i, sc As Long: sc = 16384
    Dim iLen As Long: iLen = sc * LenB(info(0))
    If CmdQuerySetSystemInformation(id, CLIENT_QSI_ENUM_PROC_MOD, VarPtr(pi), LenB(pi), VarPtr(info(0)), iLen) = 0 Then
        If bShowMsgIfErrorHappens = True Then
            MsgBox "Query process module unsuccessfully.", vbCritical
        End If
    Else
        lvMod.ListItems.Clear
        sc = iLen / LenB(info(0))
        For i = 0 To sc - 1
            Dim ltmItem As ListItem
            Set ltmItem = lvMod.ListItems.Add()
            ltmItem.Text = "0x" & UInt64ToHex64(info(i).Base)
            ltmItem.SubItems(1) = "0x" & UInt64ToHex64(info(i).Size)
            ltmItem.SubItems(2) = StrFromPtr(VarPtr(info(i).Path(0)), True)
        Next
    End If
End Sub

Private Sub lvProc_DblClick()
    EnumProcessModuleProc CLng(lvClient.SelectedItem.Text), CLng(lvProc.SelectedItem.SubItems(1)), True
End Sub

Private Sub lvProc_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = 2 Then PopupMenu mnuProc
End Sub

Private Sub EnumProcessProc(ByVal id As Long, ByVal bShowMsgIfErrorHappens As Boolean)
    'A lazy way: assume the maximum item count is 16384...
    Dim info(16383) As BDP_SI_PROCESS_INFO
    Dim i, sc As Long: sc = 16384
    Dim iLen As Long: iLen = sc * LenB(info(0))
    If CmdQuerySetSystemInformation(id, CLIENT_QSI_ENUM_PROCESS, 0, 0, VarPtr(info(0)), iLen) = 0 Then
        If bShowMsgIfErrorHappens = True Then
            MsgBox "Query process unsuccessfully.", vbCritical
        End If
    Else
        lvProc.ListItems.Clear
        sc = iLen / LenB(info(0))
        For i = 0 To sc - 1
            Dim ltmItem As ListItem
            Set ltmItem = lvProc.ListItems.Add()
            ltmItem.Text = "0x" & UInt64ToHex64(info(i).Object)
            ltmItem.SubItems(1) = CStr(CDec("&H" & UInt64ToHex64(info(i).id)))
            ltmItem.SubItems(2) = StrFromPtr(VarPtr(info(i).Path(0)), True)
        Next
    End If
End Sub

Private Sub mnuPMO_Click(Index As Integer)
    Select Case Index
    Case 0
        lvProc_DblClick
    Case 2
        Dim ProcInfo As BDP_SI_PROCESS_INFO, pid As Long, szDll As String
        pid = CLng(lvProc.SelectedItem.SubItems(1))
        memcpy VarPtr(ProcInfo.id), VarPtr(pid), 4
        szDll = InputBox("Input module path:", "Load Module", IIf(pid <> 4, "c:\windows\system32\aclui.dll", "c:\windows\system32\drivers\usb8023.sys"))
        If StrPtr(szDll) <> 0 Then
            If pid <> 4 Then
                memcpy VarPtr(ProcInfo.Path(0)), StrPtr(szDll), Len(szDll) * 2
                If CmdQuerySetSystemInformation(CLng(lvClient.SelectedItem.Text), CLIENT_SSI_INJECT_DLL, VarPtr(ProcInfo), LenB(ProcInfo), 0, 0) = 0 Then
                    MsgBox "Load module unsuccessfully.", vbCritical
                Else
                    mnuPMO_Click 0
                End If
            Else
                If CmdExecuteBinary(CLng(lvClient.SelectedItem.Text), StrPtr(szDll), CLIENT_RUN_SYS_P1, CLIENT_RUN_SYS_P2, 0) = 0 Then
                    MsgBox "Load driver unsuccessfully.", vbCritical
                Else
                    mnuPMO_Click 0
                End If
            End If
        End If
    End Select
End Sub

Private Sub mnuPRO_Click(Index As Integer)
    Select Case Index
    Case 0
        EnumProcessProc CLng(lvClient.SelectedItem.Text), True
    Case 2
        If MsgBox("Are you sure to kill this process?", vbYesNo + vbQuestion) = vbYes Then
            Dim KillProcInfo As BDP_SI_PROCESS_INFO, pid As Long
            pid = CLng(lvProc.SelectedItem.SubItems(1))
            memcpy VarPtr(KillProcInfo.id), VarPtr(pid), 4
            If CmdQuerySetSystemInformation(CLng(lvClient.SelectedItem.Text), CLIENT_SSI_KILL_PROCESS, VarPtr(KillProcInfo), LenB(KillProcInfo), 0, 0) = 0 Then
                MsgBox "Kill process unsuccessfully.", vbCritical
            Else
                mnuPRO_Click 0
            End If
        End If
    End Select
End Sub

Private Sub mnuRGO_Click(Index As Integer)
    Dim NewName As String
    Dim KeyName As String
    Dim b As Boolean
    Select Case Index
    Case 0
        NewName = InputBox("Input key name:", "Create Key")
        If StrPtr(NewName) Then
            KeyName = Replace(txtRegPath.Text & "\" & NewName, "\\", "\")
            b = CmdRegistryOperation(CLng(lvClient.SelectedItem.Text), CLIENT_REG_CREATE_KEY, StrPtr(KeyName), 0, 0, 0, 0)
            If b = 0 Then
                MsgBox "Create key unsuccessfully.", vbCritical
            Else
                btnOperate_Click 18
            End If
        End If
    Case 1
        frmRegistryEditor.Show vbModal, Me
        SetRegValueProc
    Case 3
        If lvReg.SelectedItem.Text = "[REG_KEY]" Then
            NewName = InputBox("Input new key name:", "Rename Key")
            If StrPtr(NewName) Then
                KeyName = Replace(txtRegPath.Text & "\" & lvReg.SelectedItem.SubItems(1), "\\", "\") ': MsgBox KeyName, , "KeyName"
                b = CmdRegistryOperation(CLng(lvClient.SelectedItem.Text), CLIENT_REG_RENAME_KEY, StrPtr(KeyName), StrPtr(NewName), 0, 0, 0)
                If b = 0 Then
                    MsgBox "Rename key unsuccessfully.", vbCritical
                Else
                    btnOperate_Click 18
                End If
            End If
        Else
            MsgBox "There is no direct operation to rename a value, you must create a new value with the same data and then delete the old value.", vbCritical
        End If
    Case 4
        If lvReg.SelectedItem.Text = "[REG_KEY]" Then
            KeyName = Replace(txtRegPath.Text & "\" & lvReg.SelectedItem.SubItems(1), "\\", "\") ': MsgBox KeyName, , "KeyName"
            b = CmdRegistryOperation(CLng(lvClient.SelectedItem.Text), CLIENT_REG_DELETE_KEY, StrPtr(KeyName), 0, 0, 0, 0)
            If b = 0 Then
                MsgBox "Delete key unsuccessfully.", vbCritical
            Else
                btnOperate_Click 18
            End If
        Else
            KeyName = txtRegPath.Text
            NewName = lvReg.SelectedItem.SubItems(1)
            b = CmdRegistryOperation(CLng(lvClient.SelectedItem.Text), CLIENT_REG_DELETE_VALUE, StrPtr(KeyName), StrPtr(NewName), 0, 0, 0)
            If b = 0 Then
                MsgBox "Delete value unsuccessfully.", vbCritical
            Else
                btnOperate_Click 18
            End If
        End If
    End Select
End Sub

Private Sub Timer1_Timer()
    Dim c As Long, i As Long, lv_sel As Long
    Dim ci(SERVER_MAX_CLIENTS - 1) As CLIENT_INFO
    c = ClientList(VarPtr(ci(0))): Frame1.Caption = "Client: " & CStr(c)
    If c > 0 Then
        'get current selection of listview
        lv_sel = 0
        For i = 1 To lvClient.ListItems.count
            If lvClient.ListItems(i).Selected = True Then
                lv_sel = i
                Exit For
            End If
        Next
        'clear old items
        lvClient.ListItems.Clear
        'add latest items
        For i = 0 To c - 1
            AddClientInfo lvClient, ci(i).id, sz2bstr(ci(i).szAddr), sz2bstr(ci(i).szDescription), _
                            sz2bstr(ci(i).szStatus), ci(i).hash_low, ci(i).hash_high
        Next
        'set selection
        If lv_sel Then
            If lv_sel > lvClient.ListItems.count Then
                lv_sel = lvClient.ListItems.count
            End If
            If lv_sel Then
                lvClient.ListItems.Item(lv_sel).Selected = True
            End If
        End If
    End If
End Sub

'################################################################################
' CODE FOR WEB CONTROL PANEL
'################################################################################
Private Function IsStringArrayElementValid(ByRef sa() As String, ByVal id As Long) As Boolean
    On Error GoTo exx
    Dim s As String: s = sa(id)
    IsStringArrayElementValid = True
    Exit Function
exx:
    IsStringArrayElementValid = False
End Function

Private Function LenX(ByVal sz As String) As Long
    Dim s As String
    Dim i As Long, l As Long
    For i = 1 To Len(sz)
        s = Mid(sz, i, 1)
        l = AscW(s)
        If l > 255 Or l < 0 Then
            LenX = LenX + 2
        Else
            LenX = LenX + 1
        End If
    Next
End Function

Private Function GetArrayStringsMaxLen(ByRef sa() As String) As Long
    On Error GoTo exx
    Dim i As Long, max As Long
    For i = 0 To UBound(sa)
        If max < LenX(sa(i)) Then
            max = LenX(sa(i))
        End If
    Next
exx:
    GetArrayStringsMaxLen = max
End Function

Private Sub AddBlanksForStringArray(ByRef sa() As String)
    On Error GoTo exx
    Dim i As Long, maxlen As Long
    maxlen = GetArrayStringsMaxLen(sa)
    For i = 0 To UBound(sa)
        sa(i) = sa(i) & String(maxlen - LenX(sa(i)), " ")
    Next
exx:
End Sub

Private Sub TryDelete(ByVal szFile As String)
    On Error Resume Next
    Kill szFile
End Sub

Private Function HandleCommand(ByVal sz As String) As String
    On Error GoTo exx
    Dim i As Long
    Dim bRet As Byte
    Dim iType As Byte
    Dim sa() As String
    Dim rv As Currency
    Dim SendCallBack As SENDRECV_CALLBACK
    Dim RecvCallBack As SENDRECV_CALLBACK
    If LCase(sz) = "lc" Then
        Call btnClient_Click(7)
        If lvClient.ListItems.count <> 0 Then
            Dim ctsa0() As String
            Dim ctsa1() As String
            Dim ctsa2() As String
            Dim ctsa3() As String
            Dim ctsa4() As String
            Dim ctsa5() As String
            ReDim ctsa0(lvClient.ListItems.count + 1)
            ReDim ctsa1(lvClient.ListItems.count + 1)
            ReDim ctsa2(lvClient.ListItems.count + 1)
            ReDim ctsa3(lvClient.ListItems.count + 1)
            ReDim ctsa4(lvClient.ListItems.count + 1)
            ReDim ctsa5(lvClient.ListItems.count + 1)
            ctsa0(0) = "ID"
            ctsa1(0) = "IP"
            ctsa2(0) = "System"
            ctsa3(0) = "Name"
            ctsa4(0) = "Status"
            ctsa5(0) = "Hash"
            ctsa0(1) = String(Len(ctsa0(0)), "=")
            ctsa1(1) = String(Len(ctsa1(0)), "=")
            ctsa2(1) = String(Len(ctsa2(0)), "=")
            ctsa3(1) = String(Len(ctsa3(0)), "=")
            ctsa4(1) = String(Len(ctsa4(0)), "=")
            ctsa5(1) = String(Len(ctsa5(0)), "=")
            For i = 1 To lvClient.ListItems.count
                ctsa0(i + 1) = lvClient.ListItems(i).Text
                ctsa1(i + 1) = Trim$(lvClient.ListItems(i).SubItems(1))
                ctsa2(i + 1) = lvClient.ListItems(i).SubItems(2)
                ctsa3(i + 1) = lvClient.ListItems(i).SubItems(3)
                ctsa4(i + 1) = lvClient.ListItems(i).SubItems(4)
                ctsa5(i + 1) = lvClient.ListItems(i).SubItems(5)
            Next
            AddBlanksForStringArray ctsa0
            AddBlanksForStringArray ctsa1
            AddBlanksForStringArray ctsa2
            AddBlanksForStringArray ctsa3
            AddBlanksForStringArray ctsa4
            AddBlanksForStringArray ctsa5
            For i = 0 To lvClient.ListItems.count + 1
                HandleCommand = HandleCommand & ctsa0(i) & " " & _
                                                 ctsa1(i) & " " & _
                                                 ctsa2(i) & " " & _
                                                 ctsa3(i) & " " & _
                                                 ctsa4(i) & " " & _
                                                 ctsa5(i) & vbCrLf
            Next
            If Len(HandleCommand) > 2 Then
                HandleCommand = Mid(HandleCommand, 1, Len(HandleCommand) - 2)
            End If
        Else
            HandleCommand = "No client is online."
        End If
    ElseIf Left$(LCase(sz), 2) = "cc" Then
        sa = Split(sz, vbCrLf) 'cc 1234
        If IsStringArrayElementValid(sa, 1) Then
            If IsNumeric(sa(1)) Then
                bRet = ClientConnect(CLng(sa(1)))
                HandleCommand = IIf(bRet, "Connection request is sent successfully.", "Failed to send connection request.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 2) = "dc" Then
        sa = Split(sz, vbCrLf) 'dc 1234
        If IsStringArrayElementValid(sa, 1) Then
            If IsNumeric(sa(1)) Then
                bRet = ClientDisconnect(CLng(sa(1)))
                HandleCommand = IIf(bRet, "Disconnection request is sent successfully.", "Failed to send disconnection request.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 2) = "tc" Then
        sa = Split(sz, vbCrLf) 'tc 1234
        If IsStringArrayElementValid(sa, 1) Then
            If IsNumeric(sa(1)) Then
                Dim dwVersion(1) As Long
                bRet = ClientTest(CLng(sa(1)), ByVal VarPtr(dwVersion(0)))
                HandleCommand = IIf(bRet, "Version: " & CStr(dwVersion(0)), "Failed to test specific client.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 2) = "sc" Then
        sa = Split(sz, vbCrLf) 'sc 1234
        If IsStringArrayElementValid(sa, 1) Then
            If IsNumeric(sa(1)) Then
                bRet = ClientShutdown(CLng(sa(1)))
                HandleCommand = IIf(bRet, "Shutdown request is sent successfully.", "Failed to send shutdown request.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 2) = "rc" Then
        sa = Split(sz, vbCrLf) 'rc 1234
        If IsStringArrayElementValid(sa, 1) Then
            If IsNumeric(sa(1)) Then
                bRet = ClientReboot(CLng(sa(1)))
                HandleCommand = IIf(bRet, "Reboot request is sent successfully.", "Failed to send reboot request.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 2) = "uc" Then
        sa = Split(sz, vbCrLf) 'uc 1234 || uc 1234 xxx.sys
        If IsStringArrayElementValid(sa, 1) = True Then
            If IsNumeric(sa(1)) Then
                If IsStringArrayElementValid(sa, 2) = True Then
                    bRet = ClientUpdate(CLng(sa(1)), StrPtr(sa(2)))
                    HandleCommand = IIf(bRet, "Update request is sent successfully.", "Failed to send update request.")
                Else
                    bRet = ClientUpdate(CLng(sa(1)), 0)
                    HandleCommand = IIf(bRet, "Uninstall request is sent successfully.", "Failed to send uninstall request.")
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 6) = "config" Then
        sa = Split(sz, vbCrLf) 'config 1234 xxx.cfg
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                bRet = ClientConfig(CLng(sa(1)), CLIENT_CONFIG_SERVER, StrPtr(sa(2)))
                HandleCommand = IIf(bRet, "Configuration is set successfully.", "Failed to set configuration.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    '//-------------------------------------------------------------------------
    ElseIf Left$(LCase(sz), 3) = "dir" Then
        sa = Split(sz, vbCrLf) 'dir 1234 c:\xxx
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                txtFilePath.Text = sa(2)
                EnumFileProc CLng(sa(1)), False
                If lvFile.ListItems.count <> 0 Then
                    Dim tsa0() As String
                    Dim tsa1() As String
                    Dim tsa2() As String
                    ReDim tsa0(lvFile.ListItems.count + 1)
                    ReDim tsa1(lvFile.ListItems.count + 1)
                    ReDim tsa2(lvFile.ListItems.count + 1)
                    tsa0(0) = "Name"
                    tsa1(0) = "Size"
                    tsa2(0) = "Date Modified"
                    tsa0(1) = String(Len(tsa0(0)), "=")
                    tsa1(1) = String(Len(tsa1(0)), "=")
                    tsa2(1) = String(Len(tsa2(0)), "=")
                    For i = 1 To lvFile.ListItems.count
                        tsa0(i + 1) = lvFile.ListItems(i).Text
                        tsa1(i + 1) = lvFile.ListItems(i).SubItems(1)
                        tsa2(i + 1) = lvFile.ListItems(i).SubItems(2)
                    Next
                    AddBlanksForStringArray tsa0
                    AddBlanksForStringArray tsa1
                    AddBlanksForStringArray tsa2
                    For i = 0 To lvFile.ListItems.count + 1
                        HandleCommand = HandleCommand & tsa0(i) & " " & _
                                                        tsa1(i) & " " & _
                                                        tsa2(i) & vbCrLf
                    Next
                Else
                    HandleCommand = "Failed to query directory."
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 3) = "upf" Then
        sa = Split(sz, vbCrLf) 'upf 1234 c:\local.exe c:\remote.exe
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                SendCallBack.callback = CodePtr(AddressOf SendProgressForWCP)
                SendCallBack.id = CLng(sa(1))
                bRet = CmdUploadFileTo(CLng(sa(1)), StrPtr(sa(2)), StrPtr(sa(3)), VarPtr(SendCallBack))
                HandleCommand = IIf(bRet, "File is uploaded successfully.", "Failed to upload file.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 3) = "dlf" Then
        sa = Split(sz, vbCrLf) 'dlf 1234 c:\remote.exe c:\local.exe
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                RecvCallBack.callback = CodePtr(AddressOf RecvProgressForWCP)
                RecvCallBack.id = CLng(sa(1))
                bRet = CmdDownloadFileFrom(CLng(sa(1)), StrPtr(sa(2)), StrPtr(sa(3)), VarPtr(RecvCallBack))
                HandleCommand = IIf(bRet, "File is downloaded successfully.", "Failed to download file.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 3) = "exe" Then
        sa = Split(sz, vbCrLf) 'exe 1234 xxxx
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                Dim pn_pm() As String: pn_pm = Split(sa(2), " ")
                If LCase$(Right$(pn_pm(0), 4)) = ".exe" Then 'c:\xxx.exe p1 p2 p3
                    bRet = CmdExecuteBinary(CLng(sa(1)), StrPtr(sa(2)), SW_SHOW, 0, rv)
                    HandleCommand = IIf(bRet, "PID = " & CStr(CDec("&H" & UInt64ToHex64(rv))), "Execute program unsuccessfully.")
                ElseIf LCase$(Right$(pn_pm(0), 4)) = ".sys" Then 'c:\xxx.sys
                    bRet = CmdExecuteBinary(CLng(sa(1)), StrPtr(sa(2)), CLIENT_RUN_SYS_P1, CLIENT_RUN_SYS_P2, rv)
                    HandleCommand = IIf(bRet, "DriverObject = " & UInt64ToHex64(rv), "Load driver unsuccessfully.")
                ElseIf LCase$(Right$(pn_pm(0), 4)) = ".dll" Then 'shell32.dll Control_RunDLL
                    bRet = CmdExecuteBinary(CLng(sa(1)), StrPtr(sa(2)), CLIENT_RUN_DLL_P1, CLIENT_RUN_DLL_P2, rv)
                    HandleCommand = IIf(bRet, "RunDll32-PID = " & CStr(CDec("&H" & UInt64ToHex64(rv))), "Execute unsuccessfully.")
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 3) = "cmd" Then
        sa = Split(sz, vbCrLf) 'cmd 1234 netstat -a -n
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                Dim baReturn(16383) As Byte
                bRet = CmdSystemShell(CLng(sa(1)), StrPtr(sa(2)), VarPtr(baReturn(0)), 16383)
                HandleCommand = IIf(bRet, Replace(sz2bstr(baReturn), vbNullChar, ""), "Execute system shell unsuccessfully.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 3) = "reg" Then
        sa = Split(sz, vbCrLf) 'reg 1234 \registry\machine
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                txtRegPath.Text = sa(2)
                EnumRegistryProc CLng(sa(1)), False
                If lvReg.ListItems.count <> 0 Then
                    Dim rtsa0() As String
                    Dim rtsa1() As String
                    Dim rtsa2() As String
                    Dim rtsa3() As String
                    ReDim rtsa0(lvReg.ListItems.count + 1)
                    ReDim rtsa1(lvReg.ListItems.count + 1)
                    ReDim rtsa2(lvReg.ListItems.count + 1)
                    ReDim rtsa3(lvReg.ListItems.count + 1)
                    rtsa0(0) = "Type"
                    rtsa1(0) = "Name"
                    rtsa2(0) = "Data"
                    rtsa3(0) = "Length"
                    rtsa0(1) = String(Len(rtsa0(0)), "=")
                    rtsa1(1) = String(Len(rtsa1(0)), "=")
                    rtsa2(1) = String(Len(rtsa2(0)), "=")
                    rtsa3(1) = String(Len(rtsa3(0)), "=")
                    For i = 1 To lvReg.ListItems.count
                        rtsa0(i + 1) = lvReg.ListItems(i).Text
                        rtsa1(i + 1) = lvReg.ListItems(i).SubItems(1)
                        rtsa2(i + 1) = lvReg.ListItems(i).SubItems(2)
                        rtsa3(i + 1) = lvReg.ListItems(i).SubItems(3)
                    Next
                    AddBlanksForStringArray rtsa0
                    AddBlanksForStringArray rtsa1
                    AddBlanksForStringArray rtsa2
                    AddBlanksForStringArray rtsa3
                    For i = 0 To lvReg.ListItems.count + 1
                        HandleCommand = HandleCommand & rtsa0(i) & " " & _
                                                        rtsa1(i) & " " & _
                                                        rtsa2(i) & " " & _
                                                        rtsa3(i) & vbCrLf
                    Next
                Else
                    HandleCommand = "Failed to query registry."
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    '//-------------------------------------------------------------------------
    ElseIf Left$(LCase(sz), 6) = "addbin" Then
        sa = Split(sz, vbCrLf) 'addbin 1234 CLIENT_AUTORUN_TYPE_EXE notepad notepad.exe [c:\boot.ini]
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) And IsStringArrayElementValid(sa, 4) Then
            If IsNumeric(sa(1)) Then
                sa(2) = LCase$(Trim$(sa(2)))
                If sa(2) = "SYS" Or sa(2) = "0" Then
                    iType = 0
                ElseIf sa(2) = "EXE" Or sa(2) = "1" Then
                    iType = 1
                ElseIf sa(2) = "DLL" Or sa(2) = "2" Then
                    iType = 2
                Else
                    iType = 255
                End If
                If iType <> 255 Then
                    bRet = CmdAddAutoRunBin(CLng(sa(1)), iType, StrPtr(sa(3)), StrPtr(sa(4)), IIf(IsStringArrayElementValid(sa, 5), StrPtr(sa(5)), StrPtr("")))
                    HandleCommand = IIf(bRet, "Auto-Run item is added successfully.", "Failed to add Auto-Run item.")
                Else
                    HandleCommand = "Type is invalid."
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 6) = "delbin" Then
        sa = Split(sz, vbCrLf) 'addbin 1234 CLIENT_AUTORUN_TYPE_EXE notepad
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                sa(2) = LCase$(Trim$(sa(2)))
                If sa(2) = "SYS" Or sa(2) = "0" Then
                    iType = 0
                ElseIf sa(2) = "EXE" Or sa(2) = "1" Then
                    iType = 1
                ElseIf sa(2) = "DLL" Or sa(2) = "2" Then
                    iType = 2
                Else
                    iType = 255
                End If
                If iType <> 255 Then
                    bRet = CmdDelAutoRunBin(CLng(sa(1)), iType, StrPtr(sa(3)))
                    HandleCommand = IIf(bRet, "Auto-Run item is deleted successfully.", "Failed to delete Auto-Run item.")
                Else
                    HandleCommand = "Type is invalid."
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 6) = "clrbin" Then
        sa = Split(sz, vbCrLf) 'clrbin 1234 CLIENT_AUTORUN_TYPE_EXE
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                sa(2) = LCase$(Trim$(sa(2)))
                If sa(2) = "SYS" Or sa(2) = "0" Then
                    iType = 0
                ElseIf sa(2) = "EXE" Or sa(2) = "1" Then
                    iType = 1
                ElseIf sa(2) = "DLL" Or sa(2) = "2" Then
                    iType = 2
                Else
                    iType = 255
                End If
                If iType <> 255 Then
                    bRet = CmdClearAutoRunBin(CLng(sa(1)), iType)
                    HandleCommand = IIf(bRet, "All Auto-Run items are deleted successfully.", "Failed to delete all Auto-Run items.")
                Else
                    HandleCommand = "Type is invalid."
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 6) = "qrybin" Then
        sa = Split(sz, vbCrLf) 'clrbin 1234 CLIENT_AUTORUN_TYPE_EXE
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                sa(2) = LCase$(Trim$(sa(2)))
                If sa(2) = "SYS" Or sa(2) = "0" Then
                    iType = 0
                ElseIf sa(2) = "EXE" Or sa(2) = "1" Then
                    iType = 1
                ElseIf sa(2) = "DLL" Or sa(2) = "2" Then
                    iType = 2
                Else
                    iType = 255
                End If
                If iType <> 255 Then
                    Dim ppNames As Long
                    Dim CurrentName As String
                    If CmdQueryAutoRunBin(CLng(sa(1)), iType, VarPtr(ppNames)) Then
                        CurrentName = StrFromPtr(ppNames, True)
                        If CurrentName <> CLIENT_AUTORUN_EMPTY Then
                            Do While 1
                                CurrentName = StrFromPtr(ppNames, True)
                                If Len(CurrentName) = 0 Then Exit Do
                                HandleCommand = HandleCommand & CurrentName & vbCrLf
                                ppNames = ppNames + Len(CurrentName) * 2 + 2
                            Loop
                        Else
                            HandleCommand = "(No auto-run items in this type.)"
                        End If
                    Else
                        HandleCommand = "Query auto-run information unsuccessfully."
                    End If
                Else
                    HandleCommand = "Type is invalid."
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    '//-------------------------------------------------------------------------
    ElseIf Left$(LCase(sz), 6) = "rgo_ck" Then
        sa = Split(sz, vbCrLf) 'rgo_ck 1234 \\Registry\\Machine\\System\\123456
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                bRet = CmdRegistryOperation(CLng(sa(1)), CLIENT_REG_CREATE_KEY, StrPtr(sa(2)), 0, 0, 0, 0)
                HandleCommand = IIf(bRet, "Registry key is created successfully.", "Failed to create registry key.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 6) = "rgo_dk" Then
        sa = Split(sz, vbCrLf) 'rgo_dk 1234 \\Registry\\Machine\\System\\123456
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                bRet = CmdRegistryOperation(CLng(sa(1)), CLIENT_REG_DELETE_KEY, StrPtr(sa(2)), 0, 0, 0, 0)
                HandleCommand = IIf(bRet, "Registry key is deleted successfully.", "Failed to delete registry key.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 6) = "rgo_rk" Then
        sa = Split(sz, vbCrLf) 'rgo_rk 1234 \\Registry\\Machine\\System\\123456 789
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                bRet = CmdRegistryOperation(CLng(sa(1)), CLIENT_REG_RENAME_KEY, StrPtr(sa(2)), StrPtr(sa(3)), 0, 0, 0)
                HandleCommand = IIf(bRet, "Registry key is renamed successfully.", "Failed to rename registry key.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 6) = "rgo_dv" Then
        sa = Split(sz, vbCrLf) 'rgo_dv 1234 \\Registry\\Machine\\System\\123456 789
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                bRet = CmdRegistryOperation(CLng(sa(1)), CLIENT_REG_DELETE_VALUE, StrPtr(sa(2)), StrPtr(sa(3)), 0, 0, 0)
                HandleCommand = IIf(bRet, "Registry value is deleted successfully.", "Failed to delete registry value.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 6) = "rgo_qv" Then
        sa = Split(sz, vbCrLf) 'rgo_dv 1234 \\Registry\\Machine\\System\\123456 789
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                Dim ba() As Byte
                Dim dwDatLen As Long, dwRegValType As Long
                If CmdRegistryOperation(CLng(sa(1)), CLIENT_REG_QUERY_VALUE, StrPtr(sa(2)), StrPtr(sa(3)), 0, 0, dwDatLen) Then
                    ReDim ba(dwDatLen - 1)
                    If CmdRegistryOperation(CLng(sa(1)), CLIENT_REG_QUERY_VALUE, StrPtr(sa(2)), StrPtr(sa(3)), dwRegValType, VarPtr(ba(0)), dwDatLen) Then
                        If dwRegValType = 1 Or dwRegValType = 2 Then
                            HandleCommand = StrFromPtr(VarPtr(ba(0)), True)
                        ElseIf dwRegValType = 4 Then
                            Dim dw As Long
                            Call memcpy(VarPtr(dw), VarPtr(ba(0)) + 8 + 512, 4)
                            HandleCommand = "0x" & Hex(dw)
                        ElseIf dwRegValType = 11 Then
                            Dim qw As Currency
                            Call memcpy(VarPtr(qw), VarPtr(ba(0)) + 8 + 512, 8)
                            HandleCommand = "0x" & UInt64ToHex64(qw)
                        ElseIf dwRegValType = 7 Then
                            HandleCommand = MultiWideCharStringToVBString(VarPtr(ba(0)), dwDatLen)
                        Else
                            HandleCommand = BinaryToString(VarPtr(ba(0)), dwDatLen)
                        End If
                    End If
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 6) = "rgo_sv" Then
        sa = Split(sz, vbCrLf) 'rgo_sv 1234 \\Registry\\Machine\\System\\123456 789 REG_SZ string
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) And _
            IsStringArrayElementValid(sa, 4) And IsStringArrayElementValid(sa, 5) Then
            If IsNumeric(sa(1)) Then
                Dim dwKeyType As Long
                If IsNumeric(sa(4)) = False Then
                    dwKeyType = GetRegStringType(sa(4))
                Else
                    dwKeyType = CLng(sa(4))
                End If
                If dwKeyType = 2 Then   'REG_EXPEND_SZ
                    sa(5) = Replace(sa(5), "|", "%")
                ElseIf dwKeyType = 7 Then   'REG_MULTI_SZ
                    sa(5) = Replace(sa(5), "||", vbCrLf)
                End If
                bRet = SetRegValueInternal(CLng(sa(1)), sa(2), sa(3), dwKeyType, sa(5))
                HandleCommand = IIf(bRet, "Registry value is set successfully.", "Failed to set registry value.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    '//-------------------------------------------------------------------------
    ElseIf Left$(LCase(sz), 7) = "fso_c_f" Then
        sa = Split(sz, vbCrLf) 'fso_c_f 1234 c:\123.txt HelloWorld
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                If IsStringArrayElementValid(sa, 3) Then
                    sa(3) = Replace(sa(3), "<br>", vbCrLf)
                    bRet = CmdFileOperation(CLng(sa(1)), CLIENT_FSO_CREATE_FILE, StrPtr(sa(2)), StrPtr(sa(3)), 0)
                Else
                    bRet = CmdFileOperation(CLng(sa(1)), CLIENT_FSO_CREATE_FILE, StrPtr(sa(2)), StrPtr(""), 0)
                End If
                HandleCommand = IIf(bRet, "File is created successfully.", "Failed to create file.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "fso_c_d" Then
        sa = Split(sz, vbCrLf) 'fso_c_d 1234 c:\123
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                bRet = CmdFileOperation(CLng(sa(1)), CLIENT_FSO_CREATE_DIRECTORY, StrPtr(sa(2)), StrPtr(""), 0)
                HandleCommand = IIf(bRet, "Directory is created successfully.", "Failed to create directory.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "fso_cpy" Then
        sa = Split(sz, vbCrLf) 'fso_cpy 1234 c:\windows\win.ini c:\win.txt
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                bRet = CmdFileOperation(CLng(sa(1)), CLIENT_FSO_COPY, StrPtr(sa(2)), StrPtr(sa(3)), 0)
                HandleCommand = IIf(bRet, "File / Directory is copied successfully.", "Failed to copy file / directory.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "fso_del" Then
        sa = Split(sz, vbCrLf)  'fso_del 1234 c:\windows\win.ini
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                bRet = CmdFileOperation(CLng(sa(1)), CLIENT_FSO_DELETE, StrPtr(sa(2)), StrPtr(""), 0)
                HandleCommand = IIf(bRet, "File / Directory is deleted successfully.", "Failed to delete file / directory.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "fso_ren" Then
        sa = Split(sz, vbCrLf) 'fso_ren 1234 c:\windows\win.ini win.txt
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                bRet = CmdFileOperation(CLng(sa(1)), CLIENT_FSO_RENAME, StrPtr(sa(2)), StrPtr(sa(3)), 0)
                HandleCommand = IIf(bRet, "File / Directory is renamed successfully.", "Failed to rename file / directory.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "fso_s_a" Then
        sa = Split(sz, vbCrLf) 'fso_s_a 1234 c:\boot.ini 128
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                bRet = CmdFileOperation(CLng(sa(1)), CLIENT_FSO_SET_ATTRIB, StrPtr(sa(2)), StrPtr(sa(3)), 0)
                HandleCommand = IIf(bRet, "Attribute is set successfully.", "Failed to set attribute.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "fso_g_a" Then
        sa = Split(sz, vbCrLf) 'fso_s_a 1234 c:\boot.ini
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                Dim fav As Long
                bRet = CmdFileOperation(CLng(sa(1)), CLIENT_FSO_GET_ATTRIB, StrPtr(sa(2)), StrPtr(""), fav)
                HandleCommand = IIf(bRet, "Attribute: " & CStr(fav), "Failed to query attribute.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "fso_h_d" Then
        sa = Split(sz, vbCrLf) 'fso_s_a 1234 http://www.xxx.de/xxx.exe c:\xxx.exe
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                bRet = CmdFileOperation(CLng(sa(1)), CLIENT_FSO_HTTP_DOWNLOAD, StrPtr(sa(2)), StrPtr(sa(3)), 0)
                HandleCommand = IIf(bRet, "File (from HTTP link) is downloaded successfully.", "Failed to download file (from HTTP link).")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "fso_gfc" Then
        sa = Split(sz, vbCrLf) 'fso_gfc 1234 c:\boot.ini
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                Dim fhv As Long
                bRet = CmdFileOperation(CLng(sa(1)), CLIENT_FSO_GET_CRC32, StrPtr(sa(2)), StrPtr(""), fhv)
                HandleCommand = IIf(bRet, "CRC32: " & "0x" & Hex(fhv), "Failed to get file CRC32.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "fso_mfx" Then
        sa = Split(sz, vbCrLf) 'fso_mfx 1234 c:\windows\win.ini c:\win.txt
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                bRet = CmdFileOperation(CLng(sa(1)), CLIENT_FSO_DELAY_MOV_DEL, StrPtr(sa(2)), StrPtr(sa(3)), 0)
                HandleCommand = IIf(bRet, "Delay file operation is set successfully.", "Failed to set delay file operation")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    '//-------------------------------------------------------------------------
    ElseIf Left$(LCase(sz), 9) = "disk_enum" Then
        sa = Split(sz, vbCrLf) 'disk_enum 1234
        If IsStringArrayElementValid(sa, 1) Then
            If IsNumeric(sa(1)) Then
                EnumPartitionProc CLng(sa(1))
                HandleCommand = txtDiskInfo.Text
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 8) = "disk_qfp" Then
        sa = Split(sz, vbCrLf) 'disk_qfp 1234 c:\xxx.dll
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                txtFileForPos.Text = sa(2)
                EnumFilePosProc CLng(sa(1))
                HandleCommand = txtDiskInfo.Text
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 9) = "disk_read" Then
        sa = Split(sz, vbCrLf) 'disk_read 1234 0 512 0 1
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) And _
            IsStringArrayElementValid(sa, 4) And IsStringArrayElementValid(sa, 5) Then
            If IsNumeric(sa(1)) Then
                txtDiskId.Text = sa(2)
                txtLBS.Text = sa(3)
                txtLBA.Text = sa(4)
                txtLBC.Text = sa(5)
                ReadDiskProc CLng(sa(1))
                HandleCommand = txtDiskInfo.Text
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 10) = "disk_write" Then
        sa = Split(sz, vbCrLf) 'disk_write 1234 0 512 0 AABBCCDD
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) And _
            IsStringArrayElementValid(sa, 4) And IsStringArrayElementValid(sa, 5) Then
            If IsNumeric(sa(1)) Then
                txtDiskId.Text = sa(2)
                txtLBS.Text = sa(3)
                txtLBA.Text = sa(4)
                txtLBC.Text = "1"
                WriteDiskProc CLng(sa(1)), sa(5)
                HandleCommand = txtDiskInfo.Text
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    '//-------------------------------------------------------------------------
    ElseIf Left$(LCase(sz), 6) = "qsi_gt" Then
        sa = Split(sz, vbCrLf) 'qsi_gt 1234
        If IsStringArrayElementValid(sa, 1) Then
            If IsNumeric(sa(1)) Then
                Dim szDateTime As String
                szDateTime = GetSetClientTimeProc(CLng(sa(1)), 0)
                HandleCommand = IIf(szDateTime <> "", szDateTime, "Failed to query time.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 6) = "ssi_st" Then
        sa = Split(sz, vbCrLf) 'fso_gfc 1234 c:\boot.ini
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                szDateTime = GetSetClientTimeProc(CLng(sa(1)), 1, sa(2))
                HandleCommand = IIf(szDateTime <> "", "Time is set successfully", "Failed to set time.")
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "qsi_epc" Then
        sa = Split(sz, vbCrLf) 'qsi_epc 1234
        If IsStringArrayElementValid(sa, 1) Then
            If IsNumeric(sa(1)) Then
                EnumProcessProc CLng(sa(1)), False
                If lvProc.ListItems.count <> 0 Then
                    ReDim rtsa0(lvProc.ListItems.count + 1)
                    ReDim rtsa1(lvProc.ListItems.count + 1)
                    ReDim rtsa2(lvProc.ListItems.count + 1)
                    rtsa0(0) = "EPROCESS"
                    rtsa1(0) = "PID"
                    rtsa2(0) = "Path"
                    rtsa0(1) = String(Len(rtsa0(0)), "=")
                    rtsa1(1) = String(Len(rtsa1(0)), "=")
                    rtsa2(1) = String(Len(rtsa2(0)), "=")
                    For i = 1 To lvProc.ListItems.count
                        rtsa0(i + 1) = lvProc.ListItems(i).Text
                        rtsa1(i + 1) = lvProc.ListItems(i).SubItems(1)
                        rtsa2(i + 1) = lvProc.ListItems(i).SubItems(2)
                    Next
                    AddBlanksForStringArray rtsa0
                    AddBlanksForStringArray rtsa1
                    AddBlanksForStringArray rtsa2
                    For i = 0 To lvProc.ListItems.count + 1
                        HandleCommand = HandleCommand & rtsa0(i) & " " & _
                                                        rtsa1(i) & " " & _
                                                        rtsa2(i) & vbCrLf
                    Next
                Else
                    HandleCommand = "Failed to query process."
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "ssi_kpc" Then
        sa = Split(sz, vbCrLf) 'ssi_kpc 1234 8888
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                Dim KillProcInfo As BDP_SI_PROCESS_INFO, pid As Long
                pid = CLng(sa(2)): memcpy VarPtr(KillProcInfo.id), VarPtr(pid), 4
                If CmdQuerySetSystemInformation(CLng(sa(1)), CLIENT_SSI_KILL_PROCESS, VarPtr(KillProcInfo), LenB(KillProcInfo), 0, 0) Then
                    HandleCommand = "Process is killed successfully."
                Else
                    HandleCommand = "Failed to kill process."
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "qsi_epm" Then
        sa = Split(sz, vbCrLf) 'qsi_epm 1234 8888
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) Then
            If IsNumeric(sa(1)) Then
                EnumProcessModuleProc CLng(sa(1)), CLng(sa(2)), False
                If lvMod.ListItems.count <> 0 Then
                    ReDim rtsa0(lvMod.ListItems.count + 1)
                    ReDim rtsa1(lvMod.ListItems.count + 1)
                    ReDim rtsa2(lvMod.ListItems.count + 1)
                    rtsa0(0) = "Base"
                    rtsa1(0) = "Size"
                    rtsa2(0) = "Path"
                    rtsa0(1) = String(Len(rtsa0(0)), "=")
                    rtsa1(1) = String(Len(rtsa1(0)), "=")
                    rtsa2(1) = String(Len(rtsa2(0)), "=")
                    For i = 1 To lvMod.ListItems.count
                        rtsa0(i + 1) = lvMod.ListItems(i).Text
                        rtsa1(i + 1) = lvMod.ListItems(i).SubItems(1)
                        rtsa2(i + 1) = lvMod.ListItems(i).SubItems(2)
                    Next
                    AddBlanksForStringArray rtsa0
                    AddBlanksForStringArray rtsa1
                    AddBlanksForStringArray rtsa2
                    For i = 0 To lvMod.ListItems.count + 1
                        HandleCommand = HandleCommand & rtsa0(i) & " " & _
                                                        rtsa1(i) & " " & _
                                                        rtsa2(i) & vbCrLf
                    Next
                Else
                    HandleCommand = "Failed to query process module."
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    ElseIf Left$(LCase(sz), 7) = "ssi_lpm" Then
        sa = Split(sz, vbCrLf) 'ssi_lpm 1234 8888 c:\xxx.dll
        If IsStringArrayElementValid(sa, 1) And IsStringArrayElementValid(sa, 2) And IsStringArrayElementValid(sa, 3) Then
            If IsNumeric(sa(1)) Then
                Dim ProcInfo As BDP_SI_PROCESS_INFO, szDll As String
                pid = CLng(sa(2)): memcpy VarPtr(ProcInfo.id), VarPtr(pid), 4
                szDll = sa(3)
                If pid <> 4 Then
                    memcpy VarPtr(ProcInfo.Path(0)), StrPtr(szDll), Len(szDll) * 2
                    If CmdQuerySetSystemInformation(CLng(sa(1)), CLIENT_SSI_INJECT_DLL, VarPtr(ProcInfo), LenB(ProcInfo), 0, 0) = 0 Then
                        HandleCommand = "Failed to load module."
                    Else
                        HandleCommand = "Module is loaded successfully."
                    End If
                Else
                    If CmdExecuteBinary(CLng(sa(1)), StrPtr(szDll), CLIENT_RUN_SYS_P1, CLIENT_RUN_SYS_P2, 0) = 0 Then
                        HandleCommand = "Failed to load driver."
                    Else
                        HandleCommand = "Driver is loaded successfully."
                    End If
                End If
            Else
                HandleCommand = "Client ID is invalid."
            End If
        Else
            HandleCommand = "Command format is invalid."
        End If
    '//-------------------------------------------------------------------------
    Else
        HandleCommand = "Unknown command: " & CStr(Date) & " " & CStr(Time)
    End If
    Exit Function
exx:
    HandleCommand = "An error occurred during command execution."
End Function

Private Sub Timer2_Timer()
    Dim InputFile As String: InputFile = "c:\input." & CStr(Me.Tag)
    Dim OutputFile As String: OutputFile = "c:\output." & CStr(Me.Tag)
    Dim ProgressFile As String: ProgressFile = "c:\progress." & CStr(Me.Tag)
    If Dir(InputFile, vbNormal) <> "" Then
        SaveText "utf-8", OutputFile, HandleCommand(Trim$(LoadText("utf-8", InputFile)))
        TryDelete InputFile
        TryDelete ProgressFile
    End If
End Sub
