[戻る]

Form1.vb

Credential Provider Extender のサンプル "vb-simple" のソースコードです。

パッケージ中の C:\cpe\module\source\vb-simple\Form1.vb にあります。

  1. Imports System.Runtime.InteropServices
  2.  
  3. Public Class Form1
  4.     Inherits System.Windows.Forms.Form
  5.  
  6. #Region "Win32 関数用宣言"
  7.     ' LogonUserA 関数の宣言
  8.     Declare Function LogonUserA Lib "advapi32.dll" _
  9.         (ByVal lpszUsername As String, _
  10.         ByVal lpszDomain As String, _
  11.         ByVal lpszPassword As String, _
  12.         ByVal dwLogonType As Integer, _
  13.         ByVal dwLogonProvider As Integer, _
  14.         ByRef phToken As IntPtr) As Integer
  15.  
  16.     ' CloseHandle 関数の宣言
  17.     Declare Function CloseHandle Lib "kernel32.dll" _
  18.         (ByVal hObject As IntPtr) As Boolean
  19.  
  20.     ' FormatMessage 関数の宣言
  21.     Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" _
  22.         (ByVal dwFlags As Integer, _
  23.         ByRef lpSource As IntPtr, _
  24.         ByVal dwMessageId As Integer, _
  25.         ByVal dwLanguageId As Integer, _
  26.         ByRef lpBuffer As [String], _
  27.         ByVal nSize As Integer, ByRef Arguments As IntPtr) As Integer
  28.  
  29.  
  30.     ' LogonUserA 関数の第4引数 dwLogonType の定義
  31.     Private Enum LogonType
  32.         LOGON32_LOGON_INTERACTIVE = 2
  33.         LOGON32_LOGON_NETWORK = 3
  34.         LOGON32_LOGON_BATCH = 4
  35.         LOGON32_LOGON_SERVICE = 5
  36.         LOGON32_LOGON_UNLOCK = 7
  37.         LOGON32_LOGON_NETWORK_CLEARTEXT = 8
  38.         LOGON32_LOGON_NEW_CREDENTIALS = 9
  39.     End Enum
  40.  
  41.     ' LogonUserA 関数の第5引数 dwLogonProvider の定義
  42.     Private Enum LogonProvider
  43.         LOGON32_PROVIDER_DEFAULT = 0
  44.         LOGON32_PROVIDER_WINNT35 = 1
  45.         LOGON32_PROVIDER_WINNT40 = 2
  46.         LOGON32_PROVIDER_WINNT50 = 3
  47.     End Enum
  48.  
  49.     Private Const ERROR_PASSWORD_EXPIRED As Integer = 1330
  50.     Private Const ERROR_PASSWORD_MUST_CHANGE As Integer = 1907
  51. #End Region
  52.  
  53. #Region " Windows フォーム デザイナで生成されたコード "
  54.  
  55.     Public Sub New()
  56.         MyBase.New()
  57.  
  58.         ' この呼び出しは Windows フォーム デザイナで必要です。
  59.         InitializeComponent()
  60.  
  61.         ' InitializeComponent() 呼び出しの後に初期化を追加します。
  62.  
  63.     End Sub
  64.  
  65.     ' Form は、コンポーネント一覧に後処理を実行するために dispose をオーバーライドします。
  66.     Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
  67.         If disposing Then
  68.             If Not (components Is Nothing) Then
  69.                 components.Dispose()
  70.             End If
  71.         End If
  72.         MyBase.Dispose(disposing)
  73.     End Sub
  74.  
  75.     ' Windows フォーム デザイナで必要です。
  76.     Private components As System.ComponentModel.IContainer
  77.  
  78.     ' メモ : 以下のプロシージャは、Windows フォーム デザイナで必要です。
  79.     'Windows フォーム デザイナを使って変更してください。  
  80.     ' コード エディタを使って変更しないでください。
  81.     Friend WithEvents Label1 As System.Windows.Forms.Label
  82.     Friend WithEvents Label2 As System.Windows.Forms.Label
  83.     Friend WithEvents Label3 As System.Windows.Forms.Label
  84.     Friend WithEvents ButtonOk As System.Windows.Forms.Button
  85.     Friend WithEvents ButtonCancel As System.Windows.Forms.Button
  86.     Friend WithEvents TextUsername As System.Windows.Forms.TextBox
  87.     Friend WithEvents TextPassword As System.Windows.Forms.TextBox
  88.     Friend WithEvents TextDomain As System.Windows.Forms.TextBox
  89.     <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
  90.         Me.Label1 = New System.Windows.Forms.Label
  91.         Me.TextUsername = New System.Windows.Forms.TextBox
  92.         Me.TextPassword = New System.Windows.Forms.TextBox
  93.         Me.Label2 = New System.Windows.Forms.Label
  94.         Me.TextDomain = New System.Windows.Forms.TextBox
  95.         Me.Label3 = New System.Windows.Forms.Label
  96.         Me.ButtonOk = New System.Windows.Forms.Button
  97.         Me.ButtonCancel = New System.Windows.Forms.Button
  98.         Me.SuspendLayout()
  99.         '
  100.         'Label1
  101.         '
  102.         Me.Label1.Location = New System.Drawing.Point(8, 8)
  103.         Me.Label1.Name = "Label1"
  104.         Me.Label1.Size = New System.Drawing.Size(100, 16)
  105.         Me.Label1.TabIndex = 0
  106.         Me.Label1.Text = "ユーザー名(&U):"
  107.         '
  108.         'TextUsername
  109.         '
  110.         Me.TextUsername.Location = New System.Drawing.Point(104, 8)
  111.         Me.TextUsername.Name = "TextUsername"
  112.         Me.TextUsername.Size = New System.Drawing.Size(176, 19)
  113.         Me.TextUsername.TabIndex = 1
  114.         '
  115.         'TextPassword
  116.         '
  117.         Me.TextPassword.Location = New System.Drawing.Point(104, 40)
  118.         Me.TextPassword.Name = "TextPassword"
  119.         Me.TextPassword.PasswordChar = Microsoft.VisualBasic.ChrW(42)
  120.         Me.TextPassword.Size = New System.Drawing.Size(176, 19)
  121.         Me.TextPassword.TabIndex = 3
  122.         '
  123.         'Label2
  124.         '
  125.         Me.Label2.Location = New System.Drawing.Point(8, 40)
  126.         Me.Label2.Name = "Label2"
  127.         Me.Label2.Size = New System.Drawing.Size(100, 16)
  128.         Me.Label2.TabIndex = 2
  129.         Me.Label2.Text = "パスワード(&P):"
  130.         '
  131.         'TextDomain
  132.         '
  133.         Me.TextDomain.Location = New System.Drawing.Point(104, 72)
  134.         Me.TextDomain.Name = "TextDomain"
  135.         Me.TextDomain.Size = New System.Drawing.Size(176, 19)
  136.         Me.TextDomain.TabIndex = 5
  137.         '
  138.         'Label3
  139.         '
  140.         Me.Label3.Location = New System.Drawing.Point(8, 72)
  141.         Me.Label3.Name = "Label3"
  142.         Me.Label3.Size = New System.Drawing.Size(100, 16)
  143.         Me.Label3.TabIndex = 4
  144.         Me.Label3.Text = "ドメイン(&D):"
  145.         '
  146.         'ButtonOk
  147.         '
  148.         Me.ButtonOk.Location = New System.Drawing.Point(8, 104)
  149.         Me.ButtonOk.Name = "ButtonOk"
  150.         Me.ButtonOk.Size = New System.Drawing.Size(75, 23)
  151.         Me.ButtonOk.TabIndex = 6
  152.         Me.ButtonOk.Text = "OK"
  153.         '
  154.         'ButtonCancel
  155.         '
  156.         Me.ButtonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
  157.         Me.ButtonCancel.Location = New System.Drawing.Point(104, 104)
  158.         Me.ButtonCancel.Name = "ButtonCancel"
  159.         Me.ButtonCancel.Size = New System.Drawing.Size(75, 23)
  160.         Me.ButtonCancel.TabIndex = 6
  161.         Me.ButtonCancel.Text = "キャンセル"
  162.         '
  163.         'Form1
  164.         '
  165.         Me.AcceptButton = Me.ButtonOk
  166.         Me.AutoScaleBaseSize = New System.Drawing.Size(5, 12)
  167.         Me.CancelButton = Me.ButtonCancel
  168.         Me.ClientSize = New System.Drawing.Size(312, 133)
  169.         Me.ControlBox = False
  170.         Me.Controls.Add(Me.ButtonOk)
  171.         Me.Controls.Add(Me.TextUsername)
  172.         Me.Controls.Add(Me.Label1)
  173.         Me.Controls.Add(Me.TextPassword)
  174.         Me.Controls.Add(Me.Label2)
  175.         Me.Controls.Add(Me.TextDomain)
  176.         Me.Controls.Add(Me.Label3)
  177.         Me.Controls.Add(Me.ButtonCancel)
  178.         Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
  179.         Me.MaximizeBox = False
  180.         Me.MinimizeBox = False
  181.         Me.Name = "Form1"
  182.         Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
  183.         Me.Text = "Windows へログオン"
  184.         Me.TopMost = True
  185.         Me.ResumeLayout(False)
  186.         Me.PerformLayout()
  187.  
  188.     End Sub
  189.  
  190. #End Region
  191.  
  192.     ' ウインドウ初期化時
  193.     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  194.         ' コマンドライン引数の4つ以上あり、1つめが lock だった場合、
  195.         ' ロック用の表示を行う
  196.         ' (例) vb-simple.exe lock username domain
  197.         Dim args() As String = Environment.GetCommandLineArgs()
  198.         If args.Length > 3 Then
  199.             If args(1).ToLower() = "lock" Then
  200.                 TextUsername.Text = args(2)
  201.                 TextUsername.Enabled = False
  202.                 TextDomain.Text = args(3)
  203.                 TextDomain.Enabled = False
  204.             End If
  205.         End If
  206.     End Sub
  207.  
  208.     ' OK ボタン押下時
  209.     Private Sub ButtonOk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonOk.Click
  210.         Dim token As IntPtr = IntPtr.Zero
  211.         Dim result As Boolean
  212.  
  213.         result = LogonUserA(TextUsername.Text, TextDomain.Text, TextPassword.Text, LogonType.LOGON32_LOGON_INTERACTIVE, LogonProvider.LOGON32_PROVIDER_DEFAULT, token)
  214.         Dim errorCode As Integer = Marshal.GetLastWin32Error()
  215.         If result Or errorCode = ERROR_PASSWORD_EXPIRED Or errorCode = ERROR_PASSWORD_MUST_CHANGE Then
  216.             ' ログオン成功
  217.             If token <> IntPtr.Zero Then
  218.                 CloseHandle(token)
  219.             End If
  220.  
  221.             Console.WriteLine("action=logon")
  222.             Console.WriteLine("msusername=" + TextUsername.Text)
  223.             Console.WriteLine("mspassword=" + TextPassword.Text)
  224.             Console.WriteLine("msdomain=" + TextDomain.Text)
  225.  
  226.             Close()
  227.         Else
  228.             ' ログオン失敗
  229.             Dim errorMessage As String = GetErrorMessage(Marshal.GetLastWin32Error())
  230.             MessageBox.Show(errorMessage, "ログオンに失敗しました")
  231.         End If
  232.     End Sub
  233.  
  234.     ' キャンセルボタン押下時
  235.     Private Sub ButtonCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonCancel.Click
  236.         Close()
  237.     End Sub
  238.  
  239.     ' エラー文字列を取得
  240.     ' (参考) http://support.microsoft.com/kb/841699/ja
  241.     Public Shared Function GetErrorMessage(ByVal errorCode As Integer) As String
  242.         Dim FORMAT_MESSAGE_ALLOCATE_BUFFER As Integer = &H100
  243.         Dim FORMAT_MESSAGE_IGNORE_INSERTS As Integer = &H200
  244.         Dim FORMAT_MESSAGE_FROM_SYSTEM As Integer = &H1000
  245.  
  246.         Dim msgSize As Integer = 255
  247.         Dim lpMsgBuf As String = ""
  248.         Dim dwFlags As Integer = FORMAT_MESSAGE_ALLOCATE_BUFFER Or FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS
  249.  
  250.         Dim lpSource As IntPtr = IntPtr.Zero
  251.         Dim lpArguments As IntPtr = IntPtr.Zero
  252.         'Call the FormatMessage function to format the message.
  253.         Dim returnVal As Integer = FormatMessage(dwFlags, lpSource, errorCode, 0, lpMsgBuf, _
  254.                 msgSize, lpArguments)
  255.         If returnVal = 0 Then
  256.             Throw New Exception("Failed to format message for error code " + errorCode.ToString() + ". ")
  257.         End If
  258.         Return lpMsgBuf
  259.     End Function
  260. End Class
  261.