タイトル | : グループ名の取得について |
記事No | : 1185 |
投稿日 | : 2004/12/02(Thu) 14:42 |
投稿者 | : Hamiltonian |
[OSのVer]:WindowsXP Pro [VBのVer]:VB.NET
こんにちは。 以前「Unicode変換について」という質問をさせていただきました。 申し訳ないのですが、また同じような質問をさせていただきます。
順を追って説明しますと、VB6からVB.NETへの移行を行った際、 ユーザーがAdministrator権限を持っているかを判定する関数があるのですが、 そこで使用しているAPI関数のNetUserGetLocalGroupsが移行後、 機能しなくなってしまいました。 原因は、この関数は引数をUnicodeで渡さなくてはならず、 VB6ではそのためStrConv([文字列],vbUnicode)を使用していました。 しかしVB.NETではオプションのvbUnicodeがなくなってしまったため、 正しく移行されませんでした。
これに対し、魔界の仮面弁士さんに @VB.NETの場合、宣言時に文字列の扱いを明示できるので、そこでUnicodeを指定すればいい。 ANetUserGetLocalGroupsを使わずに、Administrator権限を判定する関数例。 と二通りの回答をいただきました。 結果、Aの提案していただいた関数を採用することで解決しました。
今回質問したいのは、この関数はそのまま使うとローカルマシンに対して判定を行うので、 ほかのマシンにも判定を行うよう変更を加えようと試みましたが、まったくわかりませんでした。 そこで、上記@の提案を取り入れてみたところ、NetUserGetLocalGroups関数は 正しい戻り値を返すようになったのですが、その後の処理がVB6とは 異なった結果になってしまいます。 この原因がわからず困っています。
以下は某サイトを参考に作成し、.NETに移行した実際の関数コードです。 どの部分に問題があるのかご指摘いただけるとうれしくおもいます。 よろしくお願いします。
--------------------------------------------------------------------------------- '指定されたユーザーが所属するローカルグループのリストを取得する関数の宣言 Public Declare Unicode Function NetUserGetLocalGroups Lib "netapi32.dll" (ByVal ServerName As String, ByVal username As String, ByVal level As Integer, ByVal flag As Integer, ByRef bufptr As Integer, ByVal prefmaxlen As Integer, ByRef entriesread As Integer, ByRef totalentries As Integer) As Integer 'メモリを解放する関数の宣言 Public Declare Function NetApiBufferFree Lib "netapi32.dll" (ByVal Buffer As Int eger) As Integer 'メモリを移動する関数の宣言 Public Declare Sub RtlMoveMemory Lib "Kernel32.dll" (ByRef Destination As Intege r, ByRef Source As Integer, ByVal Length As Integer) '文字列をコピーする関数の宣言 Public Declare Function lstrcpy Lib "Kernel32.dll" Alias "lstrcpyW"(B yRef lpszString1 As Byte, ByRef lpszString2 As Integer) As Integer '文字列の長さを返す関数の宣言 Public Declare Function lstrlen Lib "Kernel32.dll" Alias "lstrlenW"(B yVal lpszString As Integer) As Integer 'ローカルグループ情報を格納する構造体 Public Structure LOCALGROUP_USER_INFO_0 Dim lgrui0_name As Integer End Structure
Public Const LG_INCLUDE_INDIRECT As Short = &H1s Public Const MAX_PREFERRED_LENGTH As Short = -1 Public Const ERROR_MORE_DATA As Short = 234 Public Const NERR_Success As Short = 0
Public Function GfAdminChk() As Boolean
Dim lngWin32apiResultCode As Integer Dim strServerName As String Dim strUserName As String Dim lngBufPtr As Integer Dim lngEntriesRead As Integer Dim lngTotalEntries As Integer Dim lngResumeHandle As Integer Dim udtGInfo0 As LOCALGROUP_USER_INFO_0 Dim lngEntry As Integer Dim strGroup As String
GfAdminChk = False ' サーバー名を設定(空文字の場合はローカルコンピュータ) strServerName = "AAA"
' ユーザー名 strUserName = "BBB"
' ローカルグループのリストを取得する lngWin32apiResultCode = NetUserGetLocalGroups(strServerName, strUserName, 0, LG_INCLUDE_INDIRECT, lngBufPtr, MAX_PREFERRED_LENGTH, lngEntriesRead, lngTotalEntries) ' リストの取得に成功したときは If (lngWin32apiResultCode = NERR_Success) Or (lngWin32apiResultCode = ERROR_MORE_DATA) Then For lngEntry = 0 To lngEntriesRead - 1 ' バッファを構造体にコピー RtlMoveMemory(udtGInfo0.lgrui0_name, lngBufPtr + Len(udtGInfo0.lgrui0_name) * lngEntry, Len(udtGInfo0.lgrui0_name)) strGroup = PointerToString(udtGInfo0.lgrui0_name) If strGroup = "Administrators" Then GfAdminChk = True End If Next End If ' メモリを解放 If lngBufPtr <> 0 Then NetApiBufferFree(lngBufPtr) End If End Function
Function PointerToString(ByRef lngPointer As Integer) As String 'ポインタを文字列に変換 Dim bytBuffer(255) As Byte 'ポインタが指す文字列をバイト配列へコピー lstrcpy(bytBuffer(0), lngPointer) 'null文字以降を切り捨て PointerToString = Left(System.Text.UnicodeEncoding.Unicode.GetString(bytBuffer), lstrlen (lngPointer)) End Function ---------------------------------------------------------------------------------
|