I'm attempting to implement NetLocalGroupAddMembers via pinvoke. I want to
be able to use either type as the member argument, whcih means using an
intptr rather than a ref to a specific LOCALGROUP_MEMBERS_INFO structure.
My pinvoke signatures:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct LOCALGROUP_MEMBERS_INFO_3
{
[MarshalAs(UnmanagedType.LPWStr)] public string lgrmi3_domainandname;
}
[DllImport("NetAPI32.dll", CharSet=CharSet.Unicode)]
public extern static int NetLocalGroupAddMembers(
[MarshalAs(UnmanagedType.LPWStr)] string servername,
[MarshalAs(UnmanagedType.LPWStr)] string localgroupname,
int level,
ref IntPtr bufptr,
int totalentries);
My test code:
public void TestNetLocalGroupAddMembers()
{
LOCALGROUP_MEMBERS_INFO_3 MemberToAdd;
LOCALGROUP_MEMBERS_INFO_3[] MembersToAdd;
long NetAPIStatus=0;
IntPtr bufPtr=IntPtr.Zero;
MemberToAdd.lgrmi3_domainandname = "TESTCOMPUTER\\administrator";
MembersToAdd = new LOCALGROUP_MEMBERS_INFO_3[1] { MemberToAdd };
bufPtr =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LOCALGROUP_MEMBERS_INFO_3)) *
MembersToAdd.Length);
Marshal.StructureToPtr(MembersToAdd[0], bufPtr, true);
NetAPIStatus = NetAPI32.NetLocalGroupAddMembers(null, "Users", 3, ref
bufPtr, 1);
NetAPI32.NetApiBufferFree(bufPtr);
Assert.IsFalse((NetAPIStatus == LMErrorConstants.NERR_GroupNotFound),
"The local group specified by the groupname parameter does not exist.");
Assert.IsFalse((NetAPIStatus == Win32ErrorConstants.ERROR_ACCESS_DENIED),
"The user does not have access to the requested information.");
Assert.IsFalse((NetAPIStatus ==
Win32ErrorConstants.ERROR_NO_SUCH_MEMBER), "One or more of the members
specified do not exist. Therefore, no new members were added.");
Assert.IsFalse((NetAPIStatus ==
Win32ErrorConstants.ERROR_MEMBER_IN_ALIAS), "One or more of the members
specified were already members of the local group. No new members were
added.");
Assert.IsFalse((NetAPIStatus ==
Win32ErrorConstants.ERROR_INVALID_MEMBER), "One or more of the members cannot
be added because their account type is invalid. No new members were added.");
Assert.AreEqual(NetAPIStatus, LMErrorConstants.NERR_Success, "Member
added successfully");
}
The call seems to return ERROR_NO_SUCH_MEMBER. I've played with a bunch of
different ways to express the pointer, nothing is particularly happy with it.
Anyone have any ideas?
Mattias Sj?gren - 27 Jan 2005 20:41 GMT
>I'm attempting to implement NetLocalGroupAddMembers via pinvoke. I want to
>be able to use either type as the member argument, whcih means using an
>intptr rather than a ref to a specific LOCALGROUP_MEMBERS_INFO structure.
You could save yourself a lot of work by declaring the parameter type
as LOCALGROUP_MEMBERS_INFO_x and use overloading to support different
struct types.
> [DllImport("NetAPI32.dll", CharSet=CharSet.Unicode)]
> public extern static int NetLocalGroupAddMembers(
[quoted text clipped - 3 lines]
> ref IntPtr bufptr,
> int totalentries);
The bufptr should be passed by value, not be a ref parameter.
Mattias

Signature
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Brandon Langley - 27 Jan 2005 22:13 GMT
Yes, that seemed to do the trick! thanks a ton!
"Mattias Sjögren" wrote:
> >I'm attempting to implement NetLocalGroupAddMembers via pinvoke. I want to
> >be able to use either type as the member argument, whcih means using an
[quoted text clipped - 15 lines]
>
> Mattias
Brandon Langley - 28 Jan 2005 18:01 GMT
I guess I spoke too soon. Two problems remaining:
1. When I use anything in this code other than literal string constants
(eg, if I try to use a string variable or a string property of another class)
I frequently get the NetAPIStatus to return a '1337' - INVALID_SID. Odd
because it's not a standard return coe for this function.
2. As I was testing this I happened to have task manager running, and
noticed when I try to exit the app I'm gonig to 100% CPU from this
application. I've isolated it to the following lines:
bufPtr =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LOCALGROUP_MEMBERS_INFO_3)) *
MembersToAdd.Length);
Marshal.StructureToPtr(MembersToAdd[0], bufPtr, true);
Whether or not I call Marshal.FreeHGlobal(bufPtr); seems to be irrelevat.
Am I (a) using the wrong allocation method or (b) misallocating the memory
somehow or (c) somethign completely different I'm not seeing?
> Yes, that seemed to do the trick! thanks a ton!
>
[quoted text clipped - 19 lines]
> >
> > Mattias
Brandon Langley - 28 Jan 2005 20:05 GMT
It looks like the issue is a memory size problem. when I increase the buffer
size to something substantially larger, i get no errors at all.
I would however like to understand the correct way to size this buffer. :)
Thanks,
Brandon
> I guess I spoke too soon. Two problems remaining:
>
[quoted text clipped - 39 lines]
> > >
> > > Mattias