tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル グループ名の取得について
投稿日: 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
---------------------------------------------------------------------------------

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。