DWORD WNetOpenEnum( HANDLE hEnum, LPDWORD ResNum, LPVOID Buf, LPDWORD BufSize);
引数の意味は以下の通り。
| hEnum | (IN) | 列挙ハンドル。 |
| ResNum | (IN/OUT) | 返されるリソース情報の数。関数の実行後、実際に返されたリソースの数が設定される。 |
| Buf | (OUT) | 取得結果のリソース情報を示すNETRESOURCE構造体の配列。 |
| BufSize | (IN/OUT) | Bufのサイズ。Bufが小さすぎる場合、必要なサイズが返される。 |
戻り値は、発生したエラーを表すエラー値である。
void DispMachines()
{
NETRESOURCE parent;
LPNETRESOURCE pnr;
HANDLE hEnum;
DWORD BufSize;
DWORD ResNum;
ZeroMemory(&parent, sizeof(parent));
pnr = GlobalAlloc(GMEM_FIXED, 1000);
parent.dwScope = RESOURCE_GLOBALNET;
parent.dwType = RESOURCETYPE_ANY;
parent.dwDisplayType = RESOURCEDISPLAYTYPE_DOMAIN;
parent.dwUsage = RESOURCEUSAGE_CONTAINER;
parent.lpRemoteName = "FOOBAR";
parent.lpProvider = "Microsoft Windows Network";
WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, &parent, &hEnum);
while(BufSize = 1000, ResNum = 1, WNetEnumResource(hEnum, &ResNum, pnr, &BufSize) == NO_ERROR) {
printf("%s\n", pnr->lpRemoteName);
}
WNetCloseEnum(hEnum);
GlobalFree(pnr);
}
------------------ 以下は、modAPI.bas のソース ------------------
Option Explicit
Public Type NETRESOURCE
dwScope As Long
dwType As Long
dwDisplayType As Long
dwUsage As Long
lpLocalName As Long
lpRemoteName As Long
lpComment As Long
lpProvider As Long
buf(1000) As Byte
End Type
Public Const RESOURCE_GLOBALNET As Long = 2
Public Const RESOURCETYPE_ANY As Long = 0
Public Const RESOURCEUSAGE_CONTAINER As Long = 2
Public Const ERROR_NO_MORE_ITEMS As Long = 259
Public Const NO_ERROR As Long = 0
Public Const FORMAT_MESSAGE_FROM_SYSTEM As Long = &H1000
Public Const FORMAT_MESSAGE_IGNORE_INSERTS As Long = &H200
Public Const DEFAULT_LANG_ID As Long = &H400
Declare Function WNetOpenEnum Lib "mpr" Alias "WNetOpenEnumA" ( _
ByVal ResScope As Long, _
ByVal ResType As Long, _
ByVal ResUsage As Long, _
ByRef Res As NETRESOURCE, _
ByRef hEnum As Long) As Long
Declare Function WNetOpenEnumForRoot Lib "mpr" Alias "WNetOpenEnumA" ( _
ByVal ResScope As Long, _
ByVal ResType As Long, _
ByVal ResUsage As Long, _
ByVal pRes As Long, _
ByRef hEnum As Long) As Long
Declare Function WNetCloseEnum Lib "mpr" (ByVal hEnum As Long) As Long
Declare Function WNetEnumResource Lib "mpr" Alias "WNetEnumResourceA" ( _
ByVal hEnum As Long, _
ByRef EntryNum As Long, _
ByRef buf As NETRESOURCE, _
ByRef BufSize As Long) As Long
Declare Function lstrcpyFromPtr Lib "kernel32" Alias "lstrcpyA" (ByVal S As String, ByVal ptr As Long) As Long
Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" ( _
ByVal Flags As Long, _
ByVal pSource As Long, _
ByVal MessageID As Long, _
ByVal LangID As Long, _
ByVal Message As String, _
ByVal MessageSize As Long, _
ByVal pArgs As Long) As Long
' ptrで指定されたアドレスに存在する文字列を取得し、結果をString型で返す
Public Function PtrToStr(ptr As Long) As String
Dim S As String * 1000
lstrcpyFromPtr S, ptr
PtrToStr = Left(S, InStr(S, vbNullChar) - 1)
End Function
------------------ 以下は、frmMain.frm のソース ------------------
Option Explicit
Private Res(1000) As NETRESOURCE
Private ResCount As Long
Private Const RESIDX_PREFIX As String = "RESIDX:"
Private Const INTERNAL_NODE_NAME As String = "internal node"
' ツリービューに全ての子供を追加。
' ContainerIdx: 列挙元のネットワークリソース
' ParentNodeIdx: 追加先のノード
Private Sub AddChilds(ParentNodeIdx As Long, ContainterIdx As Long)
Dim lResult As Long
Dim ResIdx As Long
Dim EntryNum As Long
Dim BufSize As Long
Dim hEnum As Long
'列挙開始
If ContainterIdx = -1 Then
lResult = WNetOpenEnumForRoot(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, 0, hEnum)
Else
lResult = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, Res(ContainterIdx), hEnum)
End If
If lResult <> NO_ERROR Then
DispDllError
Exit Sub
End If
Do '子供を全て追加
ResIdx = AllocNewRes()
EntryNum = 1
BufSize = 1000
lResult = WNetEnumResource(hEnum, EntryNum, Res(ResIdx), BufSize)
If lResult = ERROR_NO_MORE_ITEMS Then Exit Do
If lResult <> NO_ERROR Then
DispDllError
Exit Do
End If
AddNewNode ParentNodeIdx, ResIdx
Loop
WNetCloseEnum hEnum
End Sub
' ツリービューにノードを追加
Private Function AddNewNode(ParentIdx As Long, ResIdx As Long) As Long
Dim RemoteName As String
Dim NewNode As Node
RemoteName = PtrToStr(Res(ResIdx).lpRemoteName)
If ParentIdx <> -1 Then
Set NewNode = tvwNetView.Nodes.Add(tvwNetView.Nodes(ParentIdx), tvwChild, RESIDX_PREFIX & ResIdx, RemoteName)
Else
Set NewNode = tvwNetView.Nodes.Add(, , RESIDX_PREFIX & ResIdx, RemoteName)
End If
If (Res(ResIdx).dwUsage And RESOURCEUSAGE_CONTAINER) <> 0 Then
tvwNetView.Nodes.Add NewNode.Index, tvwChild, , INTERNAL_NODE_NAME
End If
End Function
' NETRESOURCEの配列から未使用のインデックスを取得
Private Function AllocNewRes() As Long
ResCount = ResCount + 1
'ReDim文を使用するときは、既存のデータの格納位置が移動することによって
'lpXXが不正なポインタになる可能性があるので注意。
AllocNewRes = ResCount
End Function
' APIエラーの表示
Private Sub DispDllError()
Dim errno As Long
Dim buf As String * 1000
errno = Err.LastDllError
errno = FormatMessage( _
FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, _
0, errno, DEFAULT_LANG_ID, buf, 1000, 0)
MsgBox Left(buf, InStr(buf, vbNullChar) - 1), vbOKOnly Or vbExclamation
End Sub
Private Sub Form_Load()
Dim lResult As Long
Dim hEnum As Long
Dim EntryNum As Long
Dim BufSize As Long
Dim RemoteName As String
Dim ResIdx As Long
ResCount = 0
'ネットワークプロバイダをツリービューに表示しておく
AddChilds -1, -1
End Sub
' ツリービューのノードが展開されたときは、子供を検索・追加する
Private Sub tvwNetView_Expand(ByVal Node As ComctlLib.Node)
Dim hEnum As Long
Dim ParentIdx As Long
Dim lResult As Long
Dim ResIdx As Long
Dim EntryNum As Long
Dim BufSize As Long
If Node.Children > 0 Then
If Node.Child.Text = INTERNAL_NODE_NAME Then
tvwNetView.MousePointer = ccHourglass
tvwNetView.Nodes.Remove Node.Child.Index
tvwNetView.Refresh
ParentIdx = CLng(Mid(Node.Key, Len(RESIDX_PREFIX) + 1))
AddChilds Node.Index, CLng(Mid(Node.Key, Len(RESIDX_PREFIX) + 1))
tvwNetView.MousePointer = ccDefault
End If
End If
End Sub