Imports System.Runtime.InteropServices
Public Class Form1
Inherits System.Windows.Forms.Form
#Region "Win32 関数用宣言"
' LogonUserA 関数の宣言
Declare Function LogonUserA Lib "advapi32.dll" _
(ByVal lpszUsername As String, _
ByVal lpszDomain As String, _
ByVal lpszPassword As String, _
ByVal dwLogonType As Integer, _
ByVal dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Integer
' CloseHandle 関数の宣言
Declare Function CloseHandle Lib "kernel32.dll" _
(ByVal hObject As IntPtr) As Boolean
' FormatMessage 関数の宣言
Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" _
(ByVal dwFlags As Integer, _
ByRef lpSource As IntPtr, _
ByVal dwMessageId As Integer, _
ByVal dwLanguageId As Integer, _
ByRef lpBuffer As [String], _
ByVal nSize As Integer, ByRef Arguments As IntPtr) As Integer
' LogonUserA 関数の第4引数 dwLogonType の定義
Private Enum LogonType
LOGON32_LOGON_INTERACTIVE = 2
LOGON32_LOGON_NETWORK = 3
LOGON32_LOGON_BATCH = 4
LOGON32_LOGON_SERVICE = 5
LOGON32_LOGON_UNLOCK = 7
LOGON32_LOGON_NETWORK_CLEARTEXT = 8
LOGON32_LOGON_NEW_CREDENTIALS = 9
End Enum
' LogonUserA 関数の第5引数 dwLogonProvider の定義
Private Enum LogonProvider
LOGON32_PROVIDER_DEFAULT = 0
LOGON32_PROVIDER_WINNT35 = 1
LOGON32_PROVIDER_WINNT40 = 2
LOGON32_PROVIDER_WINNT50 = 3
End Enum
Private Const ERROR_PASSWORD_EXPIRED As Integer = 1330
Private Const ERROR_PASSWORD_MUST_CHANGE As Integer = 1907
#End Region
#Region " Windows フォーム デザイナで生成されたコード "
Public Sub New()
MyBase.New()
' この呼び出しは Windows フォーム デザイナで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後に初期化を追加します。
End Sub
' Form は、コンポーネント一覧に後処理を実行するために dispose をオーバーライドします。
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
' Windows フォーム デザイナで必要です。
Private components As System.ComponentModel.IContainer
' メモ : 以下のプロシージャは、Windows フォーム デザイナで必要です。
'Windows フォーム デザイナを使って変更してください。
' コード エディタを使って変更しないでください。
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents Label3 As System.Windows.Forms.Label
Friend WithEvents ButtonOk As System.Windows.Forms.Button
Friend WithEvents ButtonCancel As System.Windows.Forms.Button
Friend WithEvents TextUsername As System.Windows.Forms.TextBox
Friend WithEvents TextPassword As System.Windows.Forms.TextBox
Friend WithEvents TextDomain As System.Windows.Forms.TextBox
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.Label1 = New System.Windows.Forms.Label
Me.TextUsername = New System.Windows.Forms.TextBox
Me.TextPassword = New System.Windows.Forms.TextBox
Me.Label2 = New System.Windows.Forms.Label
Me.TextDomain = New System.Windows.Forms.TextBox
Me.Label3 = New System.Windows.Forms.Label
Me.ButtonOk = New System.Windows.Forms.Button
Me.ButtonCancel = New System.Windows.Forms.Button
Me.SuspendLayout()
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(8, 8)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(100, 16)
Me.Label1.TabIndex = 0
Me.Label1.Text = "ユーザー名(&U):"
'
'TextUsername
'
Me.TextUsername.Location = New System.Drawing.Point(104, 8)
Me.TextUsername.Name = "TextUsername"
Me.TextUsername.Size = New System.Drawing.Size(176, 19)
Me.TextUsername.TabIndex = 1
'
'TextPassword
'
Me.TextPassword.Location = New System.Drawing.Point(104, 40)
Me.TextPassword.Name = "TextPassword"
Me.TextPassword.PasswordChar = Microsoft.VisualBasic.ChrW(42)
Me.TextPassword.Size = New System.Drawing.Size(176, 19)
Me.TextPassword.TabIndex = 3
'
'Label2
'
Me.Label2.Location = New System.Drawing.Point(8, 40)
Me.Label2.Name = "Label2"
Me.Label2.Size = New System.Drawing.Size(100, 16)
Me.Label2.TabIndex = 2
Me.Label2.Text = "パスワード(&P):"
'
'TextDomain
'
Me.TextDomain.Location = New System.Drawing.Point(104, 72)
Me.TextDomain.Name = "TextDomain"
Me.TextDomain.Size = New System.Drawing.Size(176, 19)
Me.TextDomain.TabIndex = 5
'
'Label3
'
Me.Label3.Location = New System.Drawing.Point(8, 72)
Me.Label3.Name = "Label3"
Me.Label3.Size = New System.Drawing.Size(100, 16)
Me.Label3.TabIndex = 4
Me.Label3.Text = "ドメイン(&D):"
'
'ButtonOk
'
Me.ButtonOk.Location = New System.Drawing.Point(8, 104)
Me.ButtonOk.Name = "ButtonOk"
Me.ButtonOk.Size = New System.Drawing.Size(75, 23)
Me.ButtonOk.TabIndex = 6
Me.ButtonOk.Text = "OK"
'
'ButtonCancel
'
Me.ButtonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.ButtonCancel.Location = New System.Drawing.Point(104, 104)
Me.ButtonCancel.Name = "ButtonCancel"
Me.ButtonCancel.Size = New System.Drawing.Size(75, 23)
Me.ButtonCancel.TabIndex = 6
Me.ButtonCancel.Text = "キャンセル"
'
'Form1
'
Me.AcceptButton = Me.ButtonOk
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 12)
Me.CancelButton = Me.ButtonCancel
Me.ClientSize = New System.Drawing.Size(312, 133)
Me.ControlBox = False
Me.Controls.Add(Me.ButtonOk)
Me.Controls.Add(Me.TextUsername)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.TextPassword)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.TextDomain)
Me.Controls.Add(Me.Label3)
Me.Controls.Add(Me.ButtonCancel)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.Name = "Form1"
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
Me.Text = "Windows へログオン"
Me.TopMost = True
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
#End Region
' ウインドウ初期化時
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' コマンドライン引数の4つ以上あり、1つめが lock だった場合、
' ロック用の表示を行う
' (例) vb-simple.exe lock username domain
Dim args() As String = Environment.GetCommandLineArgs()
If args.Length > 3 Then
If args(1).ToLower() = "lock" Then
TextUsername.Text = args(2)
TextUsername.Enabled = False
TextDomain.Text = args(3)
TextDomain.Enabled = False
End If
End If
End Sub
' OK ボタン押下時
Private Sub ButtonOk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonOk.Click
Dim token As IntPtr = IntPtr.Zero
Dim result As Boolean
result = LogonUserA(TextUsername.Text, TextDomain.Text, TextPassword.Text, LogonType.LOGON32_LOGON_INTERACTIVE, LogonProvider.LOGON32_PROVIDER_DEFAULT, token)
Dim errorCode As Integer = Marshal.GetLastWin32Error()
If result Or errorCode = ERROR_PASSWORD_EXPIRED Or errorCode = ERROR_PASSWORD_MUST_CHANGE Then
' ログオン成功
If token <> IntPtr.Zero Then
CloseHandle(token)
End If
Console.WriteLine("action=logon")
Console.WriteLine("msusername=" + TextUsername.Text)
Console.WriteLine("mspassword=" + TextPassword.Text)
Console.WriteLine("msdomain=" + TextDomain.Text)
Close()
Else
' ログオン失敗
Dim errorMessage As String = GetErrorMessage(Marshal.GetLastWin32Error())
MessageBox.Show(errorMessage, "ログオンに失敗しました")
End If
End Sub
' キャンセルボタン押下時
Private Sub ButtonCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonCancel.Click
Close()
End Sub
' エラー文字列を取得
' (参考) http://support.microsoft.com/kb/841699/ja
Public Shared Function GetErrorMessage(ByVal errorCode As Integer) As String
Dim FORMAT_MESSAGE_ALLOCATE_BUFFER As Integer = &H100
Dim FORMAT_MESSAGE_IGNORE_INSERTS As Integer = &H200
Dim FORMAT_MESSAGE_FROM_SYSTEM As Integer = &H1000
Dim msgSize As Integer = 255
Dim lpMsgBuf As String = ""
Dim dwFlags As Integer = FORMAT_MESSAGE_ALLOCATE_BUFFER Or FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS
Dim lpSource As IntPtr = IntPtr.Zero
Dim lpArguments As IntPtr = IntPtr.Zero
'Call the FormatMessage function to format the message.
Dim returnVal As Integer = FormatMessage(dwFlags, lpSource, errorCode, 0, lpMsgBuf, _
msgSize, lpArguments)
If returnVal = 0 Then
Throw New Exception("Failed to format message for error code " + errorCode.ToString() + ". ")
End If
Return lpMsgBuf
End Function
End Class