I'm trying to write a VB.NET application that will interface with DFS
(Distributed File System) There are WIN32 API to do this but I’m having
problems marshalling the data correctly and trying to figure out how to exact
the data returned by the function. Below is an example of the WIN32 API that
I’m calling.
NET_API_STATUS NetDfsEnum(
LPWSTR DfsName,
DWORD Level,
DWORD PrefMaxLen,
LPBYTE* Buffer,
LPDWORD EntriesRead,
LPDWORD ResumeHandle
);
It returns the following Pointer to a Structure. Below is the Structure.
typedef struct _DFS_INFO_1 {
LPWSTR EntryPath;
}
DFS_INFO_1,
*PDFS_INFO_1,
*LPDFS_INFO_1;
Here is my conversion to VB.Net..
<DllImport("netapi32.dll")> _
Private Shared Function NetDfsEnum(<MarshalAs(UnmanagedType.LPWStr)>
ByVal DfsName As String, ByVal Level As Integer, ByVal PrefMaxLen As Integer,
ByRef Buffer As Byte(), ByRef EntriesRead As Integer, ByRef ResumeHandle As
Integer) As Integer
End Function
<StructLayout(LayoutKind.Explicit)> _
Structure DFS_INFO_1
<FieldOffset(0)> Public EntryPath As String
End Structure
Have I declared this function correctly for VB.Net? If so how do I get
“ByRef Buffer as Byte()” converted into a VB.NET Structure. I’m very new to
this so if I’m doing anything else wrong let me know. Thanks
Greg Pepper
Mattias Sj?gren - 08 Nov 2004 22:27 GMT
Greg,
>Have I declared this function correctly for VB.Net? If so how do I get
>ByRef Buffer as Byte() converted into a VB.NET Structure. Im very new to
>this so if Im doing anything else wrong let me know. Thanks
I suggest you change the parameter type to ByRef As IntPtr, then use
the Marshal class to retieve the structure elements. For a general
example of the idea, see
http://www.dotnetinterop.com/faq/?q=CalleeAllocatedStructArray
Mattias

Signature
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Greg Pepper - 10 Nov 2004 21:27 GMT
Thanks that worked great. But now I want to take this one step further and
use the following Structure.
typedef struct _DFS_INFO_3 {
LPWSTR EntryPath;
LPWSTR Comment;
DWORD State;
DWORD NumberOfStorages;
LPDFS_STORAGE_INFO Storage;
} DFS_INFO_3, *PDFS_INFO_3, *LPDFS_INFO_3;
You'll notice it has a pointer to the following Structure.
typedef struct _DFS_STORAGE_INFO {
ULONG State;
LPWSTR ServerName;
LPWSTR ShareName;
} DFS_STORAGE_INFO, *PDFS_STORAGE_INFO, *LPDFS_STORAGE_INFO;
Below is how I convetered them to VB.NET
<StructLayout(LayoutKind.Sequential)> _
Structure DFS_STORAGE_INFO
Public Shared ReadOnly SIZEOF_str1 As Integer
Shared Sub New()
SIZEOF_str1 = Marshal.SizeOf(GetType(DFS_STORAGE_INFO))
End Sub
Public State As Integer
<MarshalAs(UnmanagedType.LPWStr)> Public ServerName As String
<MarshalAs(UnmanagedType.LPWStr)> Public ShareName As String
End Structure
<StructLayout(LayoutKind.Sequential)> _
Structure DFS_INFO_3
Public Shared ReadOnly SIZEOF_CI1 As Integer
Shared Sub New()
SIZEOF_CI1 = Marshal.SizeOf(GetType(DFS_INFO_3))
End Sub
<MarshalAs(UnmanagedType.LPWStr)> Public EntryPath As String
<MarshalAs(UnmanagedType.LPWStr)> Public Comment As String
Public State As Integer
Public NumOfStorages As Integer
<MarshalAs(UnmanagedType.LPStruct)> Public StorageStruct As
DFS_STORAGE_INFO
End Structure
When I run the Application it throws an exception saying it can't correctly
deterimine the size of the Structure. How to I calculate the size of a
Structure that references another Structure? Thanks in Advance.
"Mattias Sjögren" wrote:
> Greg,
>
[quoted text clipped - 8 lines]
>
> Mattias
Robert Jordan - 10 Nov 2004 21:48 GMT
Hi,
[...]
> When I run the Application it throws an exception saying it can't correctly
> deterimine the size of the Structure. How to I calculate the size of a
> Structure that references another Structure? Thanks in Advance.
The marshaler doesn't support nested structs.
In your case you may just add the 3 DFS_STORAGE_INFO
members to the end of your DFS_INFO struct.
bye
Rob
VB.NET.KIRK - 07 Dec 2004 10:48 GMT
Hello,
Did you ever come up with a final solution? I am interested in this also, I am using VB.NET. So far using what you posted it does not return the information I thought it would, simply the character "\" as the entry path every time.