WinAPI関数を使用してVB.NetアプリケーションからWindows資格情報を列挙する際に問題があります。私のコードは以下の通りです。WinAPI CredEnumerate Marshal.PtrToStructure例外
<DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Private Shared Function CredEnumerate(filter As String, flag As Integer, ByRef count As Integer, ByRef pCredentials As IntPtr) As Boolean
End Function
Public Enum CRED_PERSIST As UInteger
SESSION = 1
LOCAL_MACHINE = 2
ENTERPRISE = 3
End Enum
Public Enum CRED_TYPE As UInteger
GENERIC = 1
DOMAIN_PASSWORD = 2
DOMAIN_CERTIFICATE = 3
DOMAIN_VISIBLE_PASSWORD = 4
GENERIC_CERTIFICATE = 5
DOMAIN_EXTENDED = 6
MAXIMUM = 7
' Maximum supported cred type
MAXIMUM_EX = (MAXIMUM + 1000)
' Allow new applications to run on old OSes
End Enum
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
Public Structure CREDENTIAL_ATTRIBUTE
Private Keyword As String
Private Flags As UInteger
Private ValueSize As UInteger
Private Value As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Private Class Credential
Public Flags As UInt32
Public Type As CRED_TYPE
Public TargetName As String
Public Comment As String
Public LastWritten As ComTypes.FILETIME
Public CredentialBlobSize As UInt32
Public CredentialBlob As IntPtr
Public Persist As CRED_PERSIST
Public AttributeCount As UInt32
Public Attributes As IntPtr
Public TargetAlias As String
Public UserName As String
End Class
Private Function GetCredentials() As Credential()
Dim count As Integer = 0
Dim pCredentials As IntPtr = IntPtr.Zero
Dim credentials As List(Of Credential) = New List(Of Credential)
Dim ret As Boolean = CredEnumerate(Nothing, 0, count, pCredentials)
If ret <> False Then
Dim p As IntPtr = pCredentials
For n As Integer = 0 To count - 1
If Marshal.SizeOf(p) = 4 Then
p = New IntPtr(p.ToInt32() + n)
Else
p = New IntPtr(p.ToInt64() + n)
End If
credentials.Add(Marshal.PtrToStructure(Marshal.ReadIntPtr(p), GetType(Credential)))
Next
End If
Return credentials.ToArray
End Function
Marshal.PtrToStructure
機能は、任意の有用な情報なしSystem.ExecetionEngineException
をスローします。私は間違った資格の構造で疑いましたが、それは私には正しいようです。何が間違っているか分かっているなら、私はあなたの答えを待っています。 ありがとう
編集:@Zagglerのおかげで、ここに私の修正された機能が追加されました。しかし、構造全体が空です。 ここに新しい機能があります。
Private Function GetCredentials() As Credential()
Dim count As Integer = 0
Dim pCredentials As IntPtr = IntPtr.Zero
Dim credentials As List(Of Credential) = New List(Of Credential)
Dim ret As Boolean = CredEnumerate(Nothing, 0, count, pCredentials)
If ret <> False Then
Dim p As IntPtr = pCredentials
For n As Integer = 0 To count - 1
Dim cred As Credential = New Credential
Dim pnt As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cred))
Try
If Marshal.SizeOf(p) = 4 Then
p = New IntPtr(p.ToInt32() + n)
Else
p = New IntPtr(p.ToInt64() + n)
End If
Marshal.StructureToPtr(cred, pnt, False)
credentials.Add(Marshal.PtrToStructure(pnt, GetType(Credential)))
Finally
Marshal.FreeHGlobal(pnt)
End Try
Next
End If
Return credentials.ToArray
End Function
[** this **](https://msdn.microsoft.com/en-us/library/4ca6d5z7(v=vs.110).aspx?cs-save-lang = 1&cs-lang = vb#code-snippet-2)記事... – Codexer
@Zagglerがあなたの答えに感謝します。あなたが今私に別の問題を抱えているという情報源に基づいて私のスニペットを編集しました。返された資格情報構造は空です。私は私のメインポストを編集しました。 –
ああ私はCredEnumerate関数の後にCredRead関数を使用する必要があります。 –